* POTFILES.in: add gnome/gcustom-layout.c file
[midnight-commander.git] / src / cons.handler.c
blobc73a521902c5796a583891132ade76edc55e5962
1 /* Client interface for General purpose Linux console save/restore server
2 Copyright (C) 1994 Janne Kukonlehto <jtklehto@stekt.oulu.fi>
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.
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.
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. */
18 /* The cons saver can't have a pid of 1, used to prevent bunches of */
19 /*#ifdef linux */
20 #include <config.h>
22 int cons_saver_pid = 1;
23 extern int rxvt_extensions;
24 signed char console_flag = 0;
26 #if defined(linux) || defined(__linux__)
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"
43 static int pipefd1 [2] = {-1, -1}, pipefd2 [2] = {-1, -1};
45 void show_console_contents (int starty, unsigned char begin_line, unsigned char end_line)
47 unsigned char message = 0;
48 unsigned short bytes = 0;
49 int i;
51 standend ();
53 if (look_for_rxvt_extensions ()) {
54 show_rxvt_contents (starty, begin_line, end_line);
55 return;
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;
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;
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);
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);
90 /* Read the value of the console_flag */
91 read (pipefd2[0], &message, 1);
94 void handle_console (unsigned char action)
96 char *tty_name;
97 char *mc_conssaver;
98 int status;
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);
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;
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;
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);
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;
188 break;
189 default:
190 /* Nothing */
194 #endif /* #ifdef linux */
196 #ifdef SCO_FLAVOR
198 ** SCO console save/restore handling routines
199 ** Copyright (C) 1997 Alex Tkachenko <alex@bcs.zaporizhzhe.ua>
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"
214 static int FD_OUT = 2;
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;
221 #define SIG_ACQUIRE 21 /* originally: handset, line status change (?) */
223 static int
224 vt_active()
226 struct vid_info vi;
227 int adapter = ioctl(FD_OUT, CONS_CURRENT, 0);
229 vi.size = sizeof(struct vid_info);
230 ioctl(FD_OUT, CONS_GETINFO, &(vi));
231 return (vi.m_num == ioctl(FD_OUT,CONSADP,adapter));
234 static void
235 console_acquire_vt()
237 struct vt_mode smode;
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);
246 static void
247 console_shutdown()
249 if (!console_flag)
251 return;
253 if (screen != NULL)
255 g_free (screen);
257 console_flag = 0;
260 static void
261 console_save()
263 struct m6845_info mi;
265 if (!console_flag)
267 return;
270 if (!vt_active())
272 struct vt_mode smode;
275 ** User switched out of our vt. Let's wait until we get SIG_ACQUIRE,
276 ** otherwise we could save wrong screen image
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);
284 pause();
287 saved_attr = ioctl(FD_OUT, GIO_ATTR, 0);
289 vidbuf = (unsigned short*) ioctl(FD_OUT, MAPCONS, 0);
291 mi.size = sizeof(struct m6845_info);
292 ioctl(FD_OUT, CONS_6845INFO, &mi);
295 unsigned short* start = vidbuf + mi.screen_top;
296 memcpy(screen, start, width * height * 2);
299 write(FD_OUT,"\0337",2); /* save cursor position */
302 static void
303 console_restore()
305 struct m6845_info mi;
306 unsigned short* start;
308 if (!console_flag)
310 return;
313 write (FD_OUT, "\033[2J", 4);
315 mi.size = sizeof(struct m6845_info);
316 ioctl(FD_OUT, CONS_6845INFO, &mi);
318 start = vidbuf + mi.screen_top;
319 memcpy(start, screen, width * height * 2);
320 write(FD_OUT,"\0338",2); /* restore cursor position */
323 static void
324 console_init()
326 struct vid_info vi;
327 int adapter = ioctl(FD_OUT, CONS_CURRENT, 0);
329 console_flag = 0;
331 if (adapter != -1)
333 vi.size = sizeof(struct vid_info);
334 ioctl(FD_OUT, CONS_GETINFO, &(vi));
336 if (vt_active())
338 console_flag = 1;
340 height = vi.mv_rsz;
341 width = vi.mv_csz;
343 screen = (unsigned short*) g_malloc (height * width * 2);
344 if (screen == NULL)
346 console_shutdown();
347 return;
349 console_save();
350 mode = ioctl(FD_OUT, CONS_GET, 0);
351 ioctl(FD_OUT, MODESWITCH | mode, 0);
352 console_restore();
357 void
358 handle_console (unsigned char action)
360 if (look_for_rxvt_extensions ())
361 return;
362 switch (action){
363 case CONSOLE_INIT:
364 console_init();
365 break;
367 case CONSOLE_DONE:
368 console_shutdown();
369 break;
371 case CONSOLE_SAVE:
372 console_save();
373 break;
375 case CONSOLE_RESTORE:
376 console_restore();
377 break;
378 default:
379 /* Nothing */;
383 void
384 show_console_contents (int starty, unsigned char begin_line, unsigned char end_line)
386 register int i, len = (end_line - begin_line) * width;
388 if (look_for_rxvt_extensions ()) {
389 show_rxvt_contents (starty, begin_line, end_line);
390 return;
392 attrset(DEFAULT_COLOR);
393 for (i = 0; i < len; i++)
395 if ((i % width) == 0)
396 move (starty+(i/width), 0);
397 addch ((unsigned char)screen[width*starty + i]);
401 #endif /* SCO_FLAVOR */
404 #if !defined(linux) && !defined(__linux__) && !defined(SCO_FLAVOR)
406 #include "tty.h"
408 void show_console_contents (int starty, unsigned char begin_line, unsigned char end_line)
410 standend ();
412 if (look_for_rxvt_extensions ()) {
413 show_rxvt_contents (starty, begin_line, end_line);
414 return;
416 console_flag = 0;
419 void handle_console (unsigned char action)
421 look_for_rxvt_extensions ();
424 #endif /* !defined(linux) && !defined(__linux__) && !defined(SCO_FLAVOR) */