Reverting on "save file position" after ml clarification...
[midnight-commander.git] / src / cons.handler.c
blob61526296ef3eb1a5e84f4a65de84e5ad6ed040f8
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 #ifdef HAVE_UNISTD_H
23 # include <unistd.h>
24 #endif
25 #include <sys/types.h>
26 #include <signal.h>
28 #include "global.h"
29 #include "tty.h"
30 #include "cons.saver.h"
32 signed char console_flag = 0;
34 #if defined(linux) || defined(__linux__)
35 #include "main.h"
37 int cons_saver_pid = 1;
38 static int pipefd1 [2] = {-1, -1}, pipefd2 [2] = {-1, -1};
40 void show_console_contents (int starty, unsigned char begin_line, unsigned char end_line)
42 unsigned char message = 0;
43 unsigned short bytes = 0;
44 int i;
46 standend ();
48 if (look_for_rxvt_extensions ()) {
49 show_rxvt_contents (starty, begin_line, end_line);
50 return;
53 /* Is tty console? */
54 if (!console_flag)
55 return;
56 /* Paranoid: Is the cons.saver still running? */
57 if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT)){
58 cons_saver_pid = 0;
59 console_flag = 0;
60 return;
63 /* Send command to the console handler */
64 message = CONSOLE_CONTENTS;
65 write (pipefd1[1], &message, 1);
66 /* Check for outdated cons.saver */
67 read (pipefd2[0], &message, 1);
68 if (message != CONSOLE_CONTENTS)
69 return;
71 /* Send the range of lines that we want */
72 write (pipefd1[1], &begin_line, 1);
73 write (pipefd1[1], &end_line, 1);
74 /* Read the corresponding number of bytes */
75 read (pipefd2[0], &bytes, 2);
77 /* Read the bytes and output them */
78 for (i = 0; i < bytes; i++){
79 if ((i % COLS) == 0)
80 move (starty+(i/COLS), 0);
81 read (pipefd2[0], &message, 1);
82 addch (message);
85 /* Read the value of the console_flag */
86 read (pipefd2[0], &message, 1);
89 void handle_console (unsigned char action)
91 char *tty_name;
92 char *mc_conssaver;
93 int status;
95 switch (action){
96 case CONSOLE_INIT:
97 if (look_for_rxvt_extensions ())
98 return;
99 /* Close old pipe ends in case it is the 2nd time we run cons.saver */
100 close (pipefd1[1]);
101 close (pipefd2[0]);
102 /* Create two pipes for communication */
103 pipe (pipefd1);
104 pipe (pipefd2);
105 /* Get the console saver running */
106 cons_saver_pid = fork ();
107 if (cons_saver_pid < 0){
108 /* Cannot fork */
109 /* Delete pipes */
110 close (pipefd1[1]);
111 close (pipefd1[0]);
112 close (pipefd2[1]);
113 close (pipefd2[0]);
114 console_flag = 0;
115 } else if (cons_saver_pid > 0){
116 /* Parent */
117 /* Close the extra pipe ends */
118 close (pipefd1[0]);
119 close (pipefd2[1]);
120 /* Was the child successful? */
121 read (pipefd2[0], &console_flag, 1);
122 if (!console_flag){
123 close (pipefd1[1]);
124 close (pipefd2[0]);
125 waitpid (cons_saver_pid, &status, 0);
127 } else {
128 /* Child */
129 /* Close the extra pipe ends */
130 close (pipefd1[1]);
131 close (pipefd2[0]);
132 tty_name = ttyname (0);
133 /* Bind the pipe 0 to the standard input */
134 close (0);
135 dup (pipefd1[0]);
136 close (pipefd1[0]);
137 /* Bind the pipe 1 to the standard output */
138 close (1);
139 dup (pipefd2[1]);
140 close (pipefd2[1]);
141 /* Bind standard error to /dev/null */
142 close (2);
143 open ("/dev/null", O_WRONLY);
144 if (tty_name) {
145 /* Exec the console save/restore handler */
146 mc_conssaver = concat_dir_and_file (LIBDIR, "cons.saver");
147 execl (mc_conssaver, "cons.saver", tty_name, NULL);
149 /* Console is not a tty or execl() failed */
150 console_flag = 0;
151 write (1, &console_flag, 1);
152 close (1);
153 close (0);
154 _exit (3);
155 } /* if (cons_saver_pid ...) */
156 break;
158 case CONSOLE_DONE:
159 case CONSOLE_SAVE:
160 case CONSOLE_RESTORE:
161 if (look_for_rxvt_extensions ())
162 return;
163 /* Is tty console? */
164 if (!console_flag)
165 return;
166 /* Paranoid: Is the cons.saver still running? */
167 if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT)){
168 cons_saver_pid = 0;
169 console_flag = 0;
170 return;
172 /* Send command to the console handler */
173 write (pipefd1[1], &action, 1);
174 if (action != CONSOLE_DONE){
175 /* Wait the console handler to do its job */
176 read (pipefd2[0], &console_flag, 1);
178 if (action == CONSOLE_DONE || !console_flag){
179 /* We are done -> Let's clean up */
180 close (pipefd1 [1]);
181 close (pipefd2 [0]);
182 waitpid (cons_saver_pid, &status, 0);
183 console_flag = 0;
185 break;
189 #endif /* #ifdef linux */
191 #ifdef SCO_FLAVOR
193 ** SCO console save/restore handling routines
194 ** Copyright (C) 1997 Alex Tkachenko <alex@bcs.zaporizhzhe.ua>
197 #include <stdio.h>
198 #include <sys/types.h>
199 #include <sys/vid.h>
200 #include <sys/console.h>
201 #include <sys/vtkd.h>
202 #include <memory.h>
203 #include <signal.h>
204 #include "tty.h"
205 #include "util.h"
206 #include "color.h"
207 #include "cons.saver.h"
209 static int FD_OUT = 2;
211 static unsigned short* vidbuf = NULL;
212 static unsigned short* screen = NULL;
213 static int height = 0, width = 0, saved_attr = 0;
214 static int mode = 0;
216 #define SIG_ACQUIRE 21 /* originally: handset, line status change (?) */
218 static int
219 vt_active()
221 struct vid_info vi;
222 int adapter = ioctl(FD_OUT, CONS_CURRENT, 0);
224 vi.size = sizeof(struct vid_info);
225 ioctl(FD_OUT, CONS_GETINFO, &(vi));
226 return (vi.m_num == ioctl(FD_OUT,CONSADP,adapter));
229 static void
230 console_acquire_vt()
232 struct vt_mode smode;
234 signal(SIG_ACQUIRE, SIG_DFL);
235 smode.mode = VT_AUTO;
236 smode.waitv = smode.relsig = smode.acqsig = smode.frsig = 0;
237 ioctl(FD_OUT, VT_SETMODE, &smode);
238 ioctl(FD_OUT, VT_RELDISP, VT_ACKACQ);
241 static void
242 console_shutdown()
244 if (!console_flag)
246 return;
248 if (screen != NULL)
250 g_free (screen);
252 console_flag = 0;
255 static void
256 console_save()
258 struct m6845_info mi;
260 if (!console_flag)
262 return;
265 if (!vt_active())
267 struct vt_mode smode;
270 ** User switched out of our vt. Let's wait until we get SIG_ACQUIRE,
271 ** otherwise we could save wrong screen image
273 signal(SIG_ACQUIRE, console_acquire_vt);
274 smode.mode = VT_PROCESS;
275 smode.waitv = 0;
276 smode.waitv = smode.relsig = smode.acqsig = smode.frsig = SIG_ACQUIRE;
277 ioctl(FD_OUT, VT_SETMODE, &smode);
279 pause();
282 saved_attr = ioctl(FD_OUT, GIO_ATTR, 0);
284 vidbuf = (unsigned short*) ioctl(FD_OUT, MAPCONS, 0);
286 mi.size = sizeof(struct m6845_info);
287 ioctl(FD_OUT, CONS_6845INFO, &mi);
290 unsigned short* start = vidbuf + mi.screen_top;
291 memcpy(screen, start, width * height * 2);
294 write(FD_OUT,"\0337",2); /* save cursor position */
297 static void
298 console_restore()
300 struct m6845_info mi;
301 unsigned short* start;
303 if (!console_flag)
305 return;
308 write (FD_OUT, "\033[2J", 4);
310 mi.size = sizeof(struct m6845_info);
311 ioctl(FD_OUT, CONS_6845INFO, &mi);
313 start = vidbuf + mi.screen_top;
314 memcpy(start, screen, width * height * 2);
315 write(FD_OUT,"\0338",2); /* restore cursor position */
318 static void
319 console_init()
321 struct vid_info vi;
322 int adapter = ioctl(FD_OUT, CONS_CURRENT, 0);
324 console_flag = 0;
326 if (adapter != -1)
328 vi.size = sizeof(struct vid_info);
329 ioctl(FD_OUT, CONS_GETINFO, &(vi));
331 if (vt_active())
333 console_flag = 1;
335 height = vi.mv_rsz;
336 width = vi.mv_csz;
338 screen = (unsigned short*) g_malloc (height * width * 2);
339 if (screen == NULL)
341 console_shutdown();
342 return;
344 console_save();
345 mode = ioctl(FD_OUT, CONS_GET, 0);
346 ioctl(FD_OUT, MODESWITCH | mode, 0);
347 console_restore();
352 void
353 handle_console (unsigned char action)
355 if (look_for_rxvt_extensions ())
356 return;
357 switch (action){
358 case CONSOLE_INIT:
359 console_init();
360 break;
362 case CONSOLE_DONE:
363 console_shutdown();
364 break;
366 case CONSOLE_SAVE:
367 console_save();
368 break;
370 case CONSOLE_RESTORE:
371 console_restore();
372 break;
373 default:
374 /* Nothing */;
378 void
379 show_console_contents (int starty, unsigned char begin_line, unsigned char end_line)
381 register int i, len = (end_line - begin_line) * width;
383 if (look_for_rxvt_extensions ()) {
384 show_rxvt_contents (starty, begin_line, end_line);
385 return;
387 attrset(DEFAULT_COLOR);
388 for (i = 0; i < len; i++)
390 if ((i % width) == 0)
391 move (starty+(i/width), 0);
392 addch ((unsigned char)screen[width*starty + i]);
396 #endif /* SCO_FLAVOR */
399 #if !defined(linux) && !defined(__linux__) && !defined(SCO_FLAVOR)
401 #include "tty.h"
403 void show_console_contents (int starty, unsigned char begin_line, unsigned char end_line)
405 standend ();
407 if (look_for_rxvt_extensions ()) {
408 show_rxvt_contents (starty, begin_line, end_line);
409 return;
411 console_flag = 0;
414 void handle_console (unsigned char action)
416 look_for_rxvt_extensions ();
419 #endif /* !defined(linux) && !defined(__linux__) && !defined(SCO_FLAVOR) */