1 /*
2 Terminal management xterm and rxvt support
3
4 Copyright (C) 1995-2025
5 Free Software Foundation, Inc.
6
7 Written by:
8 Andrew Borodin <aborodin@vmail.ru>, 2009.
9
10 This file is part of the Midnight Commander.
11
12 The Midnight Commander is free software: you can redistribute it
13 and/or modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation, either version 3 of the License,
15 or (at your option) any later version.
16
17 The Midnight Commander is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
26 /** \file win.c
27 * \brief Source: Terminal management xterm and rxvt support
28 */
29
30 #include <config.h>
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #ifdef HAVE_SYS_SELECT_H
36 #include <sys/select.h>
37 #else
38 #include <sys/time.h>
39 #include <sys/types.h>
40 #include <unistd.h>
41 #endif
42
43 #include "lib/global.h"
44 #include "lib/util.h" // is_printable()
45 #include "tty-internal.h"
46 #include "tty.h" // tty_gotoyx, tty_print_char
47 #include "win.h"
48
49 /*** global variables ****************************************************************************/
50
51 char *smcup = NULL;
52 char *rmcup = NULL;
53
54 /*** file scope macro definitions ****************************************************************/
55
56 /*** file scope type declarations ****************************************************************/
57
58 /*** forward declarations (file scope functions) *************************************************/
59
60 /*** file scope variables ************************************************************************/
61
62 static gboolean rxvt_extensions = FALSE;
63
64 /* --------------------------------------------------------------------------------------------- */
65 /*** file scope functions ************************************************************************/
66 /* --------------------------------------------------------------------------------------------- */
67
68 /* my own weird protocol base 16 - paul */
69 static int
70 rxvt_getc (void)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
71 {
72 int r;
73 unsigned char c;
74
75 while (read (0, &c, 1) != 1)
76 ;
77 if (c == '\n')
78 return -1;
79 r = (c - 'A') * 16;
80 while (read (0, &c, 1) != 1)
81 ;
82 r += (c - 'A');
83 return r;
84 }
85
86 /* --------------------------------------------------------------------------------------------- */
87
88 static int
89 anything_ready (void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
90 {
91 fd_set fds;
92 struct timeval tv;
93
94 FD_ZERO (&fds);
95 FD_SET (0, &fds);
96 tv.tv_sec = 0;
97 tv.tv_usec = 0;
98 return select (1, &fds, 0, 0, &tv);
99 }
100
101 /* --------------------------------------------------------------------------------------------- */
102 /*** public functions ****************************************************************************/
103 /* --------------------------------------------------------------------------------------------- */
104
105 void
106 show_rxvt_contents (int starty, unsigned char y1, unsigned char y2)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
107 {
108 unsigned char *k;
109 int bytes, i, j, cols = 0;
110
111 y1 += mc_global.keybar_visible != 0 ? 1 : 0; // i don't know why we need this - paul
112 y2 += mc_global.keybar_visible != 0 ? 1 : 0;
113 while (anything_ready ())
114 tty_lowlevel_getch ();
115
116 // my own weird protocol base 26 - paul
117 printf (ESC_STR "CL%c%c%c%c\n", (y1 / 26) + 'A', (y1 % 26) + 'A', (y2 / 26) + 'A',
118 (y2 % 26) + 'A');
119
120 bytes = (y2 - y1) * (COLS + 1) + 1; // *should* be the number of bytes read
121 j = 0;
122 k = g_malloc (bytes);
123 while (TRUE)
124 {
125 int c;
126
127 c = rxvt_getc ();
128 if (c < 0)
129 break;
130 if (j < bytes)
131 k[j++] = c;
132 for (cols = 1;; cols++)
133 {
134 c = rxvt_getc ();
135 if (c < 0)
136 break;
137 if (j < bytes)
138 k[j++] = c;
139 }
140 }
141 for (i = 0; i < j; i++)
142 {
143 if ((i % cols) == 0)
144 tty_gotoyx (starty + (i / cols), 0);
145 tty_print_char (is_printable (k[i]) ? k[i] : ' ');
146 }
147 g_free (k);
148 }
149
150 /* --------------------------------------------------------------------------------------------- */
151
152 gboolean
153 look_for_rxvt_extensions (void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
154 {
155 static gboolean been_called = FALSE;
156
157 if (!been_called)
158 {
159 const char *e = getenv ("RXVT_EXT");
160 rxvt_extensions = ((e != NULL) && (strcmp (e, "1.0") == 0));
161 been_called = TRUE;
162 }
163
164 if (rxvt_extensions)
165 mc_global.tty.console_flag = '\004';
166
167 return rxvt_extensions;
168 }
169
170 /* --------------------------------------------------------------------------------------------- */