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, >d->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, >s->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, >d->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