home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / mc454src.zip / mc-4.5.4.src / mc-4.5.4 / src / cons.handler.c < prev    next >
C/C++ Source or Header  |  1999-01-04  |  10KB  |  427 lines

  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.  
  427.