- converted 1st stage setup stub from message box style to property sheet style
[reactos.git] / rosapps / applications / mc / src / cons.handler.c
1 /* Client interface for General purpose Linux console save/restore server
2 Copyright (C) 1994 Janne Kukonlehto <jtklehto@stekt.oulu.fi>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 /* The cons saver can't have a pid of 1, used to prevent bunches of */
19 /*#ifdef linux */
20 #include <config.h>
21
22 int cons_saver_pid = 1;
23 extern int rxvt_extensions;
24 signed char console_flag = 0;
25
26 #if defined(linux) || defined(__linux__)
27
28 #include "tty.h"
29 #ifdef HAVE_UNISTD_H
30 # include <unistd.h>
31 #endif
32 #include <fcntl.h>
33 #include <sys/types.h>
34 #ifdef HAVE_SYS_WAIT_H
35 # include <sys/wait.h>
36 #endif
37 #include <signal.h>
38 #include "util.h"
39 #include "win.h"
40 #include "cons.saver.h"
41 #include "main.h"
42
43 static int pipefd1 [2] = {-1, -1}, pipefd2 [2] = {-1, -1};
44
45 void show_console_contents (int starty, unsigned char begin_line, unsigned char end_line)
46 {
47 unsigned char message = 0;
48 unsigned short bytes = 0;
49 int i;
50
51 standend ();
52
53 if (look_for_rxvt_extensions ()) {
54 show_rxvt_contents (starty, begin_line, end_line);
55 return;
56 }
57
58 /* Is tty console? */
59 if (!console_flag)
60 return;
61 /* Paranoid: Is the cons.saver still running? */
62 if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT)){
63 cons_saver_pid = 0;
64 console_flag = 0;
65 return;
66 }
67
68 /* Send command to the console handler */
69 message = CONSOLE_CONTENTS;
70 write (pipefd1[1], &message, 1);
71 /* Check for outdated cons.saver */
72 read (pipefd2[0], &message, 1);
73 if (message != CONSOLE_CONTENTS)
74 return;
75
76 /* Send the range of lines that we want */
77 write (pipefd1[1], &begin_line, 1);
78 write (pipefd1[1], &end_line, 1);
79 /* Read the corresponding number of bytes */
80 read (pipefd2[0], &bytes, 2);
81
82 /* Read the bytes and output them */
83 for (i = 0; i < bytes; i++){
84 if ((i % COLS) == 0)
85 move (starty+(i/COLS), 0);
86 read (pipefd2[0], &message, 1);
87 addch (message);
88 }
89
90 /* Read the value of the console_flag */
91 read (pipefd2[0], &message, 1);
92 }
93
94 void handle_console (unsigned char action)
95 {
96 char *tty_name;
97 char *mc_conssaver;
98 int status;
99
100 switch (action){
101 case CONSOLE_INIT:
102 if (look_for_rxvt_extensions ())
103 return;
104 /* Close old pipe ends in case it is the 2nd time we run cons.saver */
105 close (pipefd1[1]);
106 close (pipefd2[0]);
107 /* Create two pipes for communication */
108 pipe (pipefd1);
109 pipe (pipefd2);
110 /* Get the console saver running */
111 cons_saver_pid = fork ();
112 if (cons_saver_pid < 0){
113 /* Can't fork */
114 /* Delete pipes */
115 close (pipefd1[1]);
116 close (pipefd1[0]);
117 close (pipefd2[1]);
118 close (pipefd2[0]);
119 console_flag = 0;
120 } else if (cons_saver_pid > 0){
121 /* Parent */
122 /* Close the extra pipe ends */
123 close (pipefd1[0]);
124 close (pipefd2[1]);
125 /* Was the child successful? */
126 read (pipefd2[0], &console_flag, 1);
127 if (!console_flag){
128 close (pipefd1[1]);
129 close (pipefd2[0]);
130 waitpid (cons_saver_pid, &status, 0);
131 }
132 } else {
133 /* Child */
134 /* Close the extra pipe ends */
135 close (pipefd1[1]);
136 close (pipefd2[0]);
137 tty_name = ttyname (0);
138 /* Bind the pipe 0 to the standard input */
139 close (0);
140 dup (pipefd1[0]);
141 close (pipefd1[0]);
142 /* Bind the pipe 1 to the standard output */
143 close (1);
144 dup (pipefd2[1]);
145 close (pipefd2[1]);
146 /* Bind standard error to /dev/null */
147 close (2);
148 open ("/dev/null", O_WRONLY);
149 /* Exec the console save/restore handler */
150 mc_conssaver = concat_dir_and_file (mc_home, "bin/cons.saver");
151 execl (mc_conssaver, "cons.saver", tty_name, NULL);
152 /* Exec failed */
153 console_flag = 0;
154 write (1, &console_flag, 1);
155 close (1);
156 close (0);
157 exit (3);
158 } /* if (cons_saver_pid ...) */
159 break;
160
161 case CONSOLE_DONE:
162 case CONSOLE_SAVE:
163 case CONSOLE_RESTORE:
164 if (look_for_rxvt_extensions ())
165 return;
166 /* Is tty console? */
167 if (!console_flag)
168 return;
169 /* Paranoid: Is the cons.saver still running? */
170 if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT)){
171 cons_saver_pid = 0;
172 console_flag = 0;
173 return;
174 }
175 /* Send command to the console handler */
176 write (pipefd1[1], &action, 1);
177 if (action != CONSOLE_DONE){
178 /* Wait the console handler to do its job */
179 read (pipefd2[0], &console_flag, 1);
180 }
181 if (action == CONSOLE_DONE || !console_flag){
182 /* We are done -> Let's clean up */
183 close (pipefd1 [1]);
184 close (pipefd2 [0]);
185 waitpid (cons_saver_pid, &status, 0);
186 console_flag = 0;
187 }
188 break;
189 default:
190 /* Nothing */
191 }
192 }
193
194 #endif /* #ifdef linux */
195
196 #ifdef SCO_FLAVOR
197 /*
198 ** SCO console save/restore handling routines
199 ** Copyright (C) 1997 Alex Tkachenko <alex@bcs.zaporizhzhe.ua>
200 */
201
202 #include <stdio.h>
203 #include <sys/types.h>
204 #include <sys/vid.h>
205 #include <sys/console.h>
206 #include <sys/vtkd.h>
207 #include <memory.h>
208 #include <signal.h>
209 #include "tty.h"
210 #include "util.h"
211 #include "color.h"
212 #include "cons.saver.h"
213
214 static int FD_OUT = 2;
215
216 static unsigned short* vidbuf = NULL;
217 static unsigned short* screen = NULL;
218 static int height = 0, width = 0, saved_attr = 0;
219 static int mode = 0;
220
221 #define SIG_ACQUIRE 21 /* originally: handset, line status change (?) */
222
223 static int
224 vt_active()
225 {
226 struct vid_info vi;
227 int adapter = ioctl(FD_OUT, CONS_CURRENT, 0);
228
229 vi.size = sizeof(struct vid_info);
230 ioctl(FD_OUT, CONS_GETINFO, &(vi));
231 return (vi.m_num == ioctl(FD_OUT,CONSADP,adapter));
232 }
233
234 static void
235 console_acquire_vt()
236 {
237 struct vt_mode smode;
238
239 signal(SIG_ACQUIRE, SIG_DFL);
240 smode.mode = VT_AUTO;
241 smode.waitv = smode.relsig = smode.acqsig = smode.frsig = 0;
242 ioctl(FD_OUT, VT_SETMODE, &smode);
243 ioctl(FD_OUT, VT_RELDISP, VT_ACKACQ);
244 }
245
246 static void
247 console_shutdown()
248 {
249 if (!console_flag)
250 {
251 return;
252 }
253 if (screen != NULL)
254 {
255 free(screen);
256 }
257 console_flag = 0;
258 }
259
260 static void
261 console_save()
262 {
263 struct m6845_info mi;
264
265 if (!console_flag)
266 {
267 return;
268 }
269
270 if (!vt_active())
271 {
272 struct vt_mode smode;
273
274 /*
275 ** User switched out of our vt. Let's wait until we get SIG_ACQUIRE,
276 ** otherwise we could save wrong screen image
277 */
278 signal(SIG_ACQUIRE, console_acquire_vt);
279 smode.mode = VT_PROCESS;
280 smode.waitv = 0;
281 smode.waitv = smode.relsig = smode.acqsig = smode.frsig = SIG_ACQUIRE;
282 ioctl(FD_OUT, VT_SETMODE, &smode);
283
284 pause();
285 }
286
287 saved_attr = ioctl(FD_OUT, GIO_ATTR, 0);
288
289 vidbuf = (unsigned short*) ioctl(FD_OUT, MAPCONS, 0);
290
291 mi.size = sizeof(struct m6845_info);
292 ioctl(FD_OUT, CONS_6845INFO, &mi);
293
294 {
295 unsigned short* start = vidbuf + mi.screen_top;
296 memcpy(screen, start, width * height * 2);
297 }
298
299 write(FD_OUT,"\0337",2); /* save cursor position */
300 }
301
302 static void
303 console_restore()
304 {
305 struct m6845_info mi;
306 unsigned short* start;
307
308 if (!console_flag)
309 {
310 return;
311 }
312
313 write (FD_OUT, "\033[2J", 4);
314
315 mi.size = sizeof(struct m6845_info);
316 ioctl(FD_OUT, CONS_6845INFO, &mi);
317
318 start = vidbuf + mi.screen_top;
319 memcpy(start, screen, width * height * 2);
320 write(FD_OUT,"\0338",2); /* restore cursor position */
321 }
322
323 static void
324 console_init()
325 {
326 struct vid_info vi;
327 int adapter = ioctl(FD_OUT, CONS_CURRENT, 0);
328
329 console_flag = 0;
330
331 if (adapter != -1)
332 {
333 vi.size = sizeof(struct vid_info);
334 ioctl(FD_OUT, CONS_GETINFO, &(vi));
335
336 if (vt_active())
337 {
338 console_flag = 1;
339
340 height = vi.mv_rsz;
341 width = vi.mv_csz;
342
343 screen = (unsigned short*) xmalloc(height * width * 2,"console_init");
344 if (screen == NULL)
345 {
346 console_shutdown();
347 return;
348 }
349 console_save();
350 mode = ioctl(FD_OUT, CONS_GET, 0);
351 ioctl(FD_OUT, MODESWITCH | mode, 0);
352 console_restore();
353 }
354 }
355 }
356
357 void
358 handle_console (unsigned char action)
359 {
360 if (look_for_rxvt_extensions ())
361 return;
362 switch (action){
363 case CONSOLE_INIT:
364 console_init();
365 break;
366
367 case CONSOLE_DONE:
368 console_shutdown();
369 break;
370
371 case CONSOLE_SAVE:
372 console_save();
373 break;
374
375 case CONSOLE_RESTORE:
376 console_restore();
377 break;
378 default:
379 /* Nothing */;
380 }
381 }
382
383 void
384 show_console_contents (int starty, unsigned char begin_line, unsigned char end_line)
385 {
386 register int i, len = (end_line - begin_line) * width;
387
388 if (look_for_rxvt_extensions ()) {
389 show_rxvt_contents (starty, begin_line, end_line);
390 return;
391 }
392 attrset(DEFAULT_COLOR);
393 for (i = 0; i < len; i++)
394 {
395 if ((i % width) == 0)
396 move (starty+(i/width), 0);
397 addch ((unsigned char)screen[width*starty + i]);
398 }
399 }
400
401 #endif /* SCO_FLAVOR */
402
403
404 #if !defined(linux) && !defined(__linux__) && !defined(SCO_FLAVOR)
405
406 #include "tty.h"
407
408 void show_console_contents (int starty, unsigned char begin_line, unsigned char end_line)
409 {
410 standend ();
411
412 if (look_for_rxvt_extensions ()) {
413 show_rxvt_contents (starty, begin_line, end_line);
414 return;
415 }
416 console_flag = 0;
417 }
418
419 void handle_console (unsigned char action)
420 {
421 look_for_rxvt_extensions ();
422 }
423
424 #endif /* !defined(linux) && !defined(__linux__) && !defined(SCO_FLAVOR) */
425
426