1 /******************************************************************************
2 *   This file is part of TinTin++                                             *
3 *                                                                             *
4 *   Copyright 2004-2020 Igor van den Hoven                                    *
5 *                                                                             *
6 *   TinTin++ is free software; you can redistribute it and/or modify          *
7 *   it under the terms of the GNU General Public License as published by      *
8 *   the Free Software Foundation; either version 3 of the License, or         *
9 *   (at your option) any later version.                                       *
10 *                                                                             *
11 *   This program is distributed in the hope that it will be useful,           *
12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of            *
13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
14 *   GNU General Public License for more details.                              *
15 *                                                                             *
16 *   You should have received a copy of the GNU General Public License         *
17 *   along with TinTin++.  If not, see https://www.gnu.org/licenses.           *
18 ******************************************************************************/
19 
20 /******************************************************************************
21 *                               T I N T I N + +                               *
22 *                                                                             *
23 *                      coded by Igor van den Hoven 2006                       *
24 ******************************************************************************/
25 
26 
27 #include "tintin.h"
28 
29 #ifdef HAVE_SYS_IOCTL_H
30   #include <sys/ioctl.h>
31 #endif
32 #include <termios.h>
33 
init_terminal(struct session * ses)34 void init_terminal(struct session *ses)
35 {
36 	struct termios io;
37 
38 	if (tcgetattr(0, &gtd->old_terminal))
39 	{
40 		syserr_fatal(-1, "init_terminal: tcgetattr 1");
41 	}
42 
43 	io = gtd->old_terminal;
44 
45 	/*
46 		Canonical mode off
47 	*/
48 
49 	DEL_BIT(io.c_lflag, ICANON);
50 
51 	io.c_cc[VMIN]   = 1;
52 	io.c_cc[VTIME]  = 0;
53 	io.c_cc[VSTART] = 255;
54 	io.c_cc[VSTOP]  = 255;
55 	io.c_cc[VINTR]  = 4; // ctrl-d
56 
57 	/*
58 		Make the terminalal as raw as possible
59 	*/
60 
61 /*
62 	DEL_BIT(io.c_iflag, IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
63 	DEL_BIT(io.c_oflag, OPOST);
64 	DEL_BIT(io.c_cflag, CSIZE|PARENB);
65 */
66 
67 
68 	DEL_BIT(io.c_lflag, ECHO|ECHONL|IEXTEN|ISIG);
69 //	DEL_BIT(io.c_lflag, ECHO|ECHONL|IEXTEN|ISIG);
70 
71 	SET_BIT(io.c_cflag, CS8);
72 
73 	if (tcsetattr(0, TCSANOW, &io))
74 	{
75 		syserr_printf(ses, "init_terminal: tcsetattr");
76 	}
77 
78 	if (tcgetattr(0, &gts->cur_terminal))
79 	{
80 		syserr_fatal(-1, "init_terminal: tcgetattr 2");
81 	}
82 
83 	print_stdout(0, 0, "\e[?1004h\e=\e[>4;1m");
84 }
85 
reset_terminal(struct session * ses)86 void reset_terminal(struct session *ses)
87 {
88 	if (gtd->detach_port == 0)
89 	{
90 		if (tcsetattr(0, TCSANOW, &gtd->old_terminal))
91 		{
92 			syserr_printf(ses, "reset_terminal: tcsetattr");
93 		}
94 	}
95 
96 	if (HAS_BIT(gtd->flags, TINTIN_FLAG_MOUSETRACKING))
97 	{
98 		print_stdout(0, 0, "\e[?1000l\e[?1002l\e[?1006l");
99 	}
100 	print_stdout(0, 0, "\e[?25h\e[23t\e[?1004l\e[>4n\e[?47l\e[r\e[0#t");
101 }
102 
103 
save_session_terminal(struct session * ses)104 void save_session_terminal(struct session *ses)
105 {
106 	tcgetattr(0, &ses->cur_terminal);
107 }
108 
refresh_session_terminal(struct session * ses)109 void refresh_session_terminal(struct session *ses)
110 {
111 //	tcsetattr(0, TCSANOW, &ses->cur_terminal);
112 }
113 
echo_off(struct session * ses)114 void echo_off(struct session *ses)
115 {
116 	struct termios io;
117 
118 	tcgetattr(STDIN_FILENO, &io);
119 
120 	DEL_BIT(io.c_lflag, ECHO|ECHONL);
121 
122 	tcsetattr(STDIN_FILENO, TCSADRAIN, &io);
123 }
124 
echo_on(struct session * ses)125 void echo_on(struct session *ses)
126 {
127 	struct termios io;
128 
129 	tcgetattr(STDIN_FILENO, &io);
130 
131 	SET_BIT(io.c_lflag, ECHO|ECHONL);
132 
133 	tcsetattr(STDIN_FILENO, TCSADRAIN, &io);
134 }
135 
init_terminal_size(struct session * ses)136 void init_terminal_size(struct session *ses)
137 {
138 	struct winsize screen;
139 	static int old_rows, old_cols;
140 
141 	push_call("init_terminal_size(%p)",ses);
142 
143 	if (ses == gts)
144 	{
145 		old_rows = gtd->screen->rows;
146 		old_cols = gtd->screen->cols;
147 
148 		if (ioctl(1, TIOCGWINSZ, &screen) >= 0)
149 		{
150 			init_screen(screen.ws_row, screen.ws_col, screen.ws_ypixel, screen.ws_xpixel);
151 
152 			if (gtd->attach_sock)
153 			{
154 				char buf[100];
155 				sprintf(buf, "\e[8;%d;%dt\e[4;%d;%dt\e[7t", screen.ws_row, screen.ws_col, screen.ws_ypixel, screen.ws_xpixel);
156 
157 				if (write(gtd->attach_sock, buf, strlen(buf)) == -1)
158 				{
159 					printf("error: init_terminal_size: write:\n");
160 				}
161 			}
162 		}
163 	}
164 
165 	if (ses->scroll)
166 	{
167 		SET_BIT(ses->scroll->flags, SCROLL_FLAG_RESIZE);
168 	}
169 
170 	if (ses->map)
171 	{
172 		SET_BIT(ses->map->flags, MAP_FLAG_RESIZE);
173 	}
174 
175 	init_split(ses, ses->split->sav_top_row, ses->split->sav_top_col, ses->split->sav_bot_row, ses->split->sav_bot_col);
176 
177 	check_all_events(ses, EVENT_FLAG_SCREEN, 0, 4, "SCREEN RESIZE", ntos(gtd->screen->rows), ntos(gtd->screen->cols), ntos(gtd->screen->height), ntos(gtd->screen->width));
178 
179 	if (old_rows <= old_cols / 2 && gtd->screen->rows > gtd->screen->cols / 2)
180 	{
181 		check_all_events(ses, EVENT_FLAG_SCREEN, 0, 4, "SCREEN ROTATE PORTRAIT", ntos(gtd->screen->rows), ntos(gtd->screen->cols), ntos(gtd->screen->height), ntos(gtd->screen->width));
182 	}
183 	else if (old_rows >= old_cols / 2 && gtd->screen->rows < gtd->screen->cols / 2)
184 	{
185 		check_all_events(ses, EVENT_FLAG_SCREEN, 0, 4, "SCREEN ROTATE LANDSCAPE", ntos(gtd->screen->rows), ntos(gtd->screen->cols), ntos(gtd->screen->height), ntos(gtd->screen->width));
186 	}
187 
188 	msdp_update_all("SCREEN_ROWS",   "%d", gtd->screen->rows);
189 	msdp_update_all("SCREEN_COLS",   "%d", gtd->screen->cols);
190 	msdp_update_all("SCREEN_HEIGHT", "%d", gtd->screen->height);
191 	msdp_update_all("SCREEN_WIDTH",  "%d", gtd->screen->width);
192 
193 	pop_call();
194 	return;
195 }
196 
get_scroll_rows(struct session * ses)197 int get_scroll_rows(struct session *ses)
198 {
199 	return (ses->split->bot_row - ses->split->top_row);
200 }
201 
get_scroll_cols(struct session * ses)202 int get_scroll_cols(struct session *ses)
203 {
204 	return ses->wrap;
205 }
206 
get_charset(struct session * ses)207 char *get_charset(struct session *ses)
208 {
209 	int index;
210 
211 	for (index = 0 ; *charset_table[index].name ; index++)
212 	{
213 		if (ses->charset == charset_table[index].flags)
214 		{
215 			return charset_table[index].name;
216 		}
217 	}
218 	return "ASCII";
219 }
220