home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / SVGALIB / SVGALIB1.TAR / svgalib / src / vga.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-21  |  60.4 KB  |  2,496 lines

  1. /* VGAlib version 1.2 - (c) 1993 Tommy Frandsen            */
  2. /*                                   */
  3. /* This library is free software; you can redistribute it and/or   */
  4. /* modify it without any restrictions. This library is distributed */
  5. /* in the hope that it will be useful, but without any warranty.   */
  6.  
  7. /* Multi-chipset support Copyright (C) 1993 Harm Hanemaayer */
  8. /* partially copyrighted (C) 1993 by Hartmut Schirmer */
  9. /* Changes by Michael Weller. */
  10.  
  11.  
  12. /* The code is a bit of a mess; also note that the drawing functions */
  13. /* are not speed optimized (the gl functions are much faster). */
  14.  
  15. #include <stdlib.h>
  16. #include <stdio.h>
  17. #include <fcntl.h>
  18. #include <signal.h>
  19. #include <termios.h>
  20. #include <string.h>
  21. #include <unistd.h>
  22. #include <stdarg.h>
  23. #include <sys/mman.h>
  24. #include <sys/kd.h>
  25. #include <sys/ioctl.h>
  26. #include <sys/stat.h>
  27. #include <sys/vt.h>
  28. #include <sys/wait.h>
  29. #include <errno.h>
  30. #include <ctype.h>
  31. #include "vga.h"
  32. #include "libvga.h"
  33. #include "driver.h"
  34. #include "config.h"
  35. #include "mouse/vgamouse.h"
  36.  
  37.  
  38. /* Delay in microseconds after a mode is set (screen is blanked during this */
  39. /* time), allows video signals to stabilize */
  40. #define MODESWITCHDELAY 150000
  41.  
  42. /* Define this to disable video output during mode switches, in addition to */
  43. /* 'turning off the screen', which is always done. */
  44. /* Doesn't look very nice on my Cirrus. */
  45. /* #define DISABLE_VIDEO_OUTPUT */
  46.  
  47. /* #define DONT_WAIT_VC_ACTIVE */
  48.  
  49. /* Use /dev/tty instead of /dev/tty0 (the previous behaviour may have been
  50.  * silly). */
  51. #define USE_DEVTTY
  52.  
  53.  
  54. #define SETSIG(sa, sig, fun) \
  55.     sa.sa_handler = fun; \
  56.     sa.sa_flags = 0; \
  57.     sa.sa_mask = 0; \
  58.     sigaction(sig, &sa, NULL);
  59.  
  60. #define SETSIG2(sa, sig, fun, oldsa) \
  61.     sa.sa_handler = fun; \
  62.     sa.sa_flags = 0; \
  63.     sa.sa_mask = 0; \
  64.     sigaction(sig, &sa, &oldsa);
  65.  
  66.  
  67. /* variables used to shift between monchrome and color emulation */
  68. int CRT_I;            /* current CRT index register address */
  69. int CRT_D;            /* current CRT data register address */
  70. int IS1_R;            /* current input status register address */
  71. static int color_text;        /* true if color text emulation */
  72.  
  73.  
  74. struct info infotable[] = {
  75.     {   80,   25,    16,  160, 0 },        /* VGAlib VGA modes */
  76.     {  320,  200,    16,   40, 0 },
  77.     {  640,  200,    16,   80, 0 },
  78.     {  640,  350,    16,   80, 0 },
  79.     {  640,  480,    16,   80, 0 },
  80.     {  320,  200,   256,  320, 1 },
  81.     {  320,  240,   256,   80, 0 },
  82.     {  320,  400,   256,   80, 0 },
  83.     {  360,  480,   256,   90, 0 },
  84.     {  640,  480,     2,   80, 0 },
  85.  
  86.     {  640,  480,   256,  640, 1 },        /* VGAlib SVGA modes */
  87.     {  800,  600,   256,  800, 1 },
  88.     { 1024,  768,   256, 1024, 1 },
  89.     { 1280, 1024,   256, 1280, 1 },
  90.  
  91.     {  320,  200, 1<<15,  640, 2 },        /* Hicolor/truecolor modes */
  92.     {  320,  200, 1<<16,  640, 2 },
  93.     {  320,  200, 1<<24,  320 * 3, 3 },
  94.     {  640,  480, 1<<15,  640 * 2, 2 },
  95.     {  640,  480, 1<<16,  640 * 2, 2 },
  96.     {  640,  480, 1<<24,  640 * 3, 3 },
  97.     {  800,  600, 1<<15,  800 * 2, 2 },
  98.     {  800,  600, 1<<16,  800 * 2, 2 },
  99.     {  800,  600, 1<<24,  800 * 3, 3 },
  100.     { 1024,  768, 1<<15, 1024 * 2, 2 },
  101.     { 1024,  768, 1<<16, 1024 * 2, 2 },
  102.     { 1024,  768, 1<<24, 1024 * 3, 3 },
  103.     { 1280, 1024, 1<<15, 1280 * 2, 2 },
  104.     { 1280, 1024, 1<<16, 1280 * 2, 2 },
  105.     { 1280, 1024, 1<<24, 1280 * 3, 3 },
  106.  
  107.     {  800,  600,    16,  100, 0 },        /* SVGA 16-color modes */
  108.     { 1024,  768,    16,  128, 0 },
  109.     { 1280, 1024,    16,  160, 0 },
  110.  
  111.     {  720,  348,     2,   90, 0 },        /* Hercules emulation mode */
  112.  
  113.     {  320,  200, 1<<24,  320 * 4, 4 },
  114.     {  640,  480, 1<<24,  640 * 4, 4 },
  115.     {  800,  600, 1<<24,  800 * 4, 4 },
  116.     { 1024,  768, 1<<24, 1024 * 4, 4 },
  117.     { 1280, 1024, 1<<24, 1280 * 4, 4 },
  118.  
  119.     {    0,    0,     0,    0, 0 },    /* 16 user definable modes */
  120.     {    0,    0,     0,    0, 0 },
  121.     {    0,    0,     0,    0, 0 },
  122.     {    0,    0,     0,    0, 0 },
  123.     {    0,    0,     0,    0, 0 },
  124.     {    0,    0,     0,    0, 0 },
  125.     {    0,    0,     0,    0, 0 },
  126.     {    0,    0,     0,    0, 0 },
  127.     {    0,    0,     0,    0, 0 },
  128.     {    0,    0,     0,    0, 0 },
  129.     {    0,    0,     0,    0, 0 },
  130.     {    0,    0,     0,    0, 0 },
  131.     {    0,    0,     0,    0, 0 },
  132.     {    0,    0,     0,    0, 0 },
  133.     {    0,    0,     0,    0, 0 },
  134.     {    0,    0,     0,    0, 0 }
  135. };
  136.  
  137. #define MAX_MODES (sizeof(infotable) / sizeof(struct info))
  138.  
  139.  
  140. /* default palette values */
  141. static const unsigned char default_red[256]   
  142.              = { 0, 0, 0, 0,42,42,42,42,21,21,21,21,63,63,63,63,
  143.          0, 5, 8,11,14,17,20,24,28,32,36,40,45,50,56,63,
  144.          0,16,31,47,63,63,63,63,63,63,63,63,63,47,31,16,
  145.          0, 0, 0, 0, 0, 0, 0, 0,31,39,47,55,63,63,63,63,
  146.         63,63,63,63,63,55,47,39,31,31,31,31,31,31,31,31,
  147.         45,49,54,58,63,63,63,63,63,63,63,63,63,58,54,49,
  148.         45,45,45,45,45,45,45,45, 0, 7,14,21,28,28,28,28,
  149.         28,28,28,28,28,21,14, 7, 0, 0, 0, 0, 0, 0, 0, 0,
  150.         14,17,21,24,28,28,28,28,28,28,28,28,28,24,21,17,
  151.         14,14,14,14,14,14,14,14,20,22,24,26,28,28,28,28,
  152.         28,28,28,28,28,26,24,22,20,20,20,20,20,20,20,20,
  153.          0, 4, 8,12,16,16,16,16,16,16,16,16,16,12, 8, 4,
  154.          0, 0, 0, 0, 0, 0, 0, 0, 8,10,12,14,16,16,16,16,
  155.         16,16,16,16,16,14,12,10, 8, 8, 8, 8, 8, 8, 8, 8,
  156.         11,12,13,15,16,16,16,16,16,16,16,16,16,15,13,12,
  157.         11,11,11,11,11,11,11,11, 0, 0, 0, 0, 0, 0, 0, 0};
  158. static const unsigned char default_green[256] 
  159.          = { 0, 0,42,42, 0, 0,21,42,21,21,63,63,21,21,63,63,
  160.          0, 5, 8,11,14,17,20,24,28,32,36,40,45,50,56,63,
  161.          0, 0, 0, 0, 0, 0, 0, 0, 0,16,31,47,63,63,63,63,
  162.         63,63,63,63,63,47,31,16,31,31,31,31,31,31,31,31,
  163.         31,39,47,55,63,63,63,63,63,63,63,63,63,55,47,39,
  164.         45,45,45,45,45,45,45,45,45,49,54,58,63,63,63,63,
  165.         63,63,63,63,63,58,54,49, 0, 0, 0, 0, 0, 0, 0, 0,
  166.          0, 7,14,21,29,28,28,28,28,28,28,28,28,21,14, 7,
  167.         14,14,14,14,14,14,14,14,14,17,21,24,28,28,28,28,
  168.         28,28,28,28,28,24,21,17,20,20,20,20,20,20,20,20,
  169.         20,22,24,26,28,28,28,28,28,28,28,28,28,26,24,22,
  170.          0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8,12,16,16,16,16,
  171.         16,16,16,16,16,12, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8,
  172.          8,10,12,14,16,16,16,16,16,16,16,16,16,14,12,10,
  173.         11,11,11,11,11,11,11,11,11,12,13,15,16,16,16,16,
  174.         16,16,16,16,16,15,13,12, 0, 0, 0, 0, 0, 0, 0, 0};
  175. static const unsigned char default_blue[256]  
  176.              = { 0,42, 0,42, 0,42, 0,42,21,63,21,63,21,63,21,63,
  177.          0, 5, 8,11,14,17,20,24,28,32,36,40,45,50,56,63,
  178.         63,63,63,63,63,47,31,16, 0, 0, 0, 0, 0, 0, 0, 0,
  179.          0,16,31,47,63,63,63,63,63,63,63,63,63,55,47,39,
  180.         31,31,31,31,31,31,31,31,31,39,47,55,63,63,63,63,
  181.         63,63,63,63,63,58,54,49,45,45,45,45,45,45,45,45,
  182.         45,49,54,58,63,63,63,63,28,28,28,28,28,21,14, 7,
  183.          0, 0, 0, 0, 0, 0, 0, 0, 0, 7,14,21,28,28,28,28,
  184.         28,28,28,28,28,24,21,17,14,14,14,14,14,14,14,14,
  185.         14,17,21,24,28,28,28,28,28,28,28,28,28,26,24,22,
  186.         20,20,20,20,20,20,20,20,20,22,24,26,28,28,28,28,
  187.         16,16,16,16,16,12, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0,
  188.          0, 4, 8,12,16,16,16,16,16,16,16,16,16,14,12,10,
  189.          8, 8, 8, 8, 8, 8, 8, 8, 8,10,12,14,16,16,16,16,
  190.         16,16,16,16,16,15,13,12,11,11,11,11,11,11,11,11,
  191.         11,12,13,15,16,16,16,16, 0, 0, 0, 0, 0, 0, 0, 0};
  192.  
  193.  
  194. static unsigned char text_regs[MAX_REGS];   /* VGA registers for saved text mode */   
  195.  
  196.  
  197. /* saved text mode palette values */ 
  198. static unsigned char text_red[256];  
  199. static unsigned char text_green[256];  
  200. static unsigned char text_blue[256];  
  201.  
  202. /* saved graphics mode palette values */ 
  203. static unsigned char graph_red[256];  
  204. static unsigned char graph_green[256];  
  205. static unsigned char graph_blue[256];  
  206.  
  207. static int         prv_mode  = TEXT;    /* previous video mode      */
  208. static int         flip_mode = TEXT;    /* flipped video mode       */
  209.  
  210. int         CM  = TEXT;            /* current video mode       */
  211. struct info CI;                /* current video parameters */
  212. int         COL;            /* current color            */
  213.  
  214.  
  215. static int initialized = 0;   /* flag: initialize() called ?  */
  216. static int flip        = 0;   /* flag: executing vga_flip() ? */
  217.  
  218. /* svgalib additions: */
  219.  
  220. int __svgalib_chipset = UNDEFINED;
  221. int __svgalib_driver_report = 1;
  222.     /* report driver used after chipset detection */
  223. int __svgalib_videomemoryused = -1;
  224. int __svgalib_modeX = 0;    /* true after vga_setmodeX() */
  225. int __svgalib_modeflags = 0;    /* copy of flags for current mode */
  226. int __svgalib_critical = 0;    /* indicates blitter is busy */
  227. int __svgalib_screenon = 1;     /* screen visible if != 0 */
  228. int __svgalib_monitortype = MON1024_43I; /* monitor type */
  229. int __svgalib_modeinfo_linearset = 0;    /* IS_LINEAR handled via extended vga_modeinfo */
  230. const int __svgalib_max_modes = MAX_MODES; /* Needed for dynamical allocated tables in mach32.c */
  231.  
  232. static int lastmodenumber = __GLASTMODE; /* Last defined mode */
  233. static int my_pid      = 0;   /* process PID, used with atexit() */
  234. static int currentpage;
  235. static int currentlogicalwidth;
  236. static int currentdisplaystart;
  237. static int mouse_support = 0;
  238. static int mouse_mode = 0;
  239. static int mouse_type = -1;
  240. static int mouse_modem_ctl = 0;
  241. static int runinbackground = 0;
  242. static int oktowrite = 1;
  243. static int modeinfo_mask= ~0;
  244.  
  245. int __svgalib_mem_fd = -1;    /* /dev/mem file descriptor  */
  246. int __svgalib_tty_fd = -1;    /* /dev/tty file descriptor */
  247. int __svgalib_console_fd = -1;    /* /dev/console file descriptor */
  248.  
  249. /* Dummy buffer for mmapping grahics memory; points to 64K VGA framebuffer. */
  250. unsigned char *__svgalib_graph_mem;
  251. /* Exported variable (read-only) is shadowed from internal variable, for */
  252. /* better shared library performance. */
  253. unsigned char *graph_mem;
  254.  
  255. static unsigned char* graph_buf = NULL;  /* saves graphics data during flip */
  256.  
  257. static unsigned char *font_buf1;    /* saved font data - plane 2 */
  258. static unsigned char *font_buf2;    /* saved font data - plane 3 */
  259.  
  260. static struct termios text_termio;  /* text mode termio parameters     */
  261. static struct termios graph_termio; /* graphics mode termio parameters */
  262.  
  263. int flipchar = '\x1b';   /* flip character - initially  ESCAPE */
  264.  
  265.  
  266. /* Chipset specific functions */
  267.  
  268. DriverSpecs *driverspecs = &vga_driverspecs;
  269.  
  270. static void (*setpage)();  /* gives little faster vga_setpage() */
  271. static void (*setrdpage)();
  272. static void (*setwrpage)();
  273.  
  274. static void readconfigfile();
  275.  
  276. DriverSpecs *driverspecslist[] = {
  277.     NULL,    /* chipset undefined */
  278.     &vga_driverspecs,
  279.     #ifdef INCLUDE_ET4000_DRIVER
  280.     &et4000_driverspecs,
  281.     #else
  282.     NULL,
  283.     #endif
  284.     #ifdef INCLUDE_CIRRUS_DRIVER
  285.     &cirrus_driverspecs,
  286.     #else
  287.     NULL,
  288.     #endif
  289.     #ifdef INCLUDE_TVGA_DRIVER
  290.     &tvga8900_driverspecs,
  291.     #else
  292.     NULL,
  293.     #endif
  294.     #ifdef INCLUDE_OAK_DRIVER
  295.     &oak_driverspecs,
  296.     #else
  297.     NULL,
  298.     #endif
  299.     #ifdef INCLUDE_EGA_DRIVER
  300.     &ega_driverspecs,
  301.     #else
  302.     NULL,
  303.     #endif
  304.     #ifdef INCLUDE_S3_DRIVER
  305.     &s3_driverspecs,
  306.     #else
  307.     NULL,
  308.     #endif
  309.     #ifdef INCLUDE_ET3000_DRIVER
  310.     &et3000_driverspecs,
  311.     #else
  312.     NULL,
  313.     #endif
  314.     #ifdef INCLUDE_MACH32_DRIVER
  315.     &mach32_driverspecs,
  316.     #else
  317.     NULL,
  318.     #endif
  319.     #ifdef INCLUDE_GVGA6400_DRIVER
  320.     &gvga6400_driverspecs,
  321.     #else
  322.     NULL,
  323.     #endif
  324.     #ifdef INCLUDE_ARK_DRIVER
  325.     &ark_driverspecs,
  326.     #else
  327.     NULL,
  328.     #endif
  329.     #ifdef INCLUDE_ATI_DRIVER
  330.     &ati_driverspecs,
  331.     #else
  332.     NULL,
  333.     #endif
  334. };
  335.  
  336. static char *driver_names[]={"","VGA","ET4000","Cirrus","TVGA","Oak","EGA","S3","ET3000","Mach32","GVGA6400","ARK","ATI",NULL};
  337.  
  338. /* Chipset drivers */
  339.  
  340. /* vgadrv    Standard VGA (also used by drivers below) */
  341. /* et4000    Tseng ET4000 (from original vgalib) */
  342. /* cirrus    Cirrus Logic GD542x */
  343. /* tvga8900     Trident TVGA 8900/9000 (derived from tvgalib) */
  344. /* oak        Oak Technologies 037/067/077 */
  345. /* egadrv    IBM EGA (subset of VGA) */
  346. /* s3        S3 911 */
  347. /* mach32    ATI MACH32 */
  348. /* ark        ARK Logic */
  349. /* gvga6400    Genoa 6400 (old SVGA) */
  350. /* ati        ATI */
  351.  
  352. /*#define DEBUG*/
  353. /*#define DEBUG_CONF*/ /*Debug config file parsing..*/
  354.  
  355. #ifdef DEBUG
  356. static void _DEBUG(int dnr) {
  357.   static int first = 1;
  358.   FILE *dfile;
  359.  
  360.   dfile = fopen("svgalib.debug", (first ? "w" : "a"));
  361.   first = 0;
  362.   if (dfile == NULL) exit(-1);
  363.   fprintf(dfile, "debug #%d\n", dnr);
  364.   fclose(dfile);
  365.   sync();
  366. }
  367. #else
  368. #define _DEBUG(d)
  369. #endif
  370.  
  371. static void set_graphtermio()
  372. {
  373.         /* set graphics mode termio parameters */
  374.         ioctl(0, TCSETSW, &graph_termio);
  375. }
  376.  
  377.  
  378. static void set_texttermio()
  379. {
  380.     /* restore text mode termio parameters */
  381.     ioctl(0, TCSETSW, &text_termio);
  382. }
  383.  
  384.  
  385. static void disable_interrupt()
  386. {
  387.     struct termios cur_termio;
  388.  
  389.     ioctl(0, TCGETS, &cur_termio);
  390.     cur_termio.c_lflag &= ~ISIG;
  391.     ioctl(0, TCSETSW, &cur_termio);
  392. }
  393.  
  394.  
  395. static void enable_interrupt()
  396. {
  397.     struct termios cur_termio;
  398.  
  399.     ioctl(0, TCGETS, &cur_termio);
  400.     cur_termio.c_lflag |= ISIG;
  401.     ioctl(0, TCSETSW, &cur_termio);
  402. }
  403.  
  404. /* The following is rather messy and inelegant. The only solution I can */
  405. /* see is getting a extra free VT for graphics like XFree86 does. */
  406.  
  407. void __svgalib_waitvtactive() {
  408.     struct stat chkbuf;
  409. /*    struct vt_stat vtstat; */
  410.     int major, minor;
  411.     int fd;
  412.  
  413.     /* get console number we are running in */
  414.     fd = dup(2);    /* stderr */
  415.     fstat(fd, &chkbuf);
  416.     major = chkbuf.st_rdev >> 8;
  417.     minor = chkbuf.st_rdev & 0xff;    /* console number */
  418.  
  419. /*    printf("major = %d, minor = %d\n", major, minor); */
  420.  
  421.     if (major != 4 || minor >= 64) {
  422.         printf("Not running in graphics-capable virtual console.\n");
  423.         exit(-1);
  424.     }
  425.     close(fd);
  426.  
  427.     fd = dup(2);
  428.     ioctl(fd, VT_WAITACTIVE, minor);
  429.     close(fd);
  430. }
  431.  
  432.  
  433. /* Check whether console is graphics-capable. If not, exit. */
  434.  
  435. #if 0
  436.  
  437. /* Check stderr (silly hack). This means stderr cannot be redirected when */
  438. /* runnning a graphics program. */
  439.  
  440. static void checkconsole() {
  441.     struct stat chkbuf;
  442.     int major, minor;
  443.     int fd;
  444.  
  445.     /* get console number we are running in */
  446.     fd = dup(2);    /* stderr */
  447.     fstat(fd, &chkbuf);
  448.     major = chkbuf.st_rdev >> 8;
  449.     minor = chkbuf.st_rdev & 0xff;    /* console number */
  450.  
  451.     if (major != 4 || minor >= 64) {
  452.         printf("Not running in graphics-capable virtual console.\n");
  453.         exit(-1);
  454.     }
  455.     close(fd);
  456. }
  457.  
  458. #else
  459.  
  460. /* Inspired by MKJ's article in Linux Journal #3 and #4. */
  461.  
  462. static int checkconsole() {
  463.     int e;
  464.     struct vt_mode vtm;
  465.     if (__svgalib_console_fd == -1)
  466.         open_devconsole();
  467.     e = ioctl(__svgalib_console_fd, VT_GETMODE, &vtm);
  468.     if (e < 0)
  469.         return 0;
  470.     return 1;
  471. }
  472.  
  473. static void doconsolecheck() {
  474.     if (!checkconsole()) {
  475.         printf("Not running in graphics-capable virtual console.\n");
  476.         exit(-1);
  477.     }
  478. }
  479.  
  480. #endif
  481.  
  482. /* open /dev/mem */
  483. static void open_mem(void) {
  484.     if (__svgalib_mem_fd < 0) 
  485.     if ((__svgalib_mem_fd = open("/dev/mem", O_RDWR) ) < 0) {
  486.         printf("svgalib: Cannot open /dev/mem.\n");
  487.         exit (-1);
  488.     }
  489. }
  490.  
  491. static void open_devconsole(void) {
  492.     if ((__svgalib_console_fd = open("/dev/console", O_RDONLY) ) < 0) {
  493.         printf("svgalib: Cannot open /dev/console.\n");
  494.         exit (-1);
  495.     }
  496. }
  497.  
  498.  
  499. void __vga_get_perm(void)
  500. {
  501.     static int done = 0;
  502.  
  503.     /* Only do this once. */
  504.     if (done)
  505.             return;
  506.     done = 1;
  507.  
  508.     /* Get I/O permissions for VGA registers. */
  509.     /* If IOPERM is set, assume permissions have already been obtained */
  510.     /* by a calling (exec-ing) process, e.g. ioperm(1). */
  511.  
  512.     if (getenv("IOPERM") == NULL)
  513.             if (ioperm(0x3b4, 0x3df - 0x3b4 + 1, 1)) {
  514.             printf("svgalib: Cannot get I/O permissions.\n");
  515.             exit(-1);
  516.         }
  517.  
  518.     /* Open /dev/mem (also needs supervisor rights; ioperm(1) can be */
  519.     /* used together with a special group that has r/w access on */
  520.     /* /dev/mem to facilitate this). */
  521.     open_mem();
  522.  
  523.      open_devconsole();
  524.  
  525.     /* color or monochrome text emulation? */
  526.     if (CHIPSET != EGA)
  527.     color_text = port_in(MIS_R)&0x01;
  528.     else
  529.         color_text = 1;    /* EGA is assumed color */
  530.  
  531.     /* chose registers for color/monochrome emulation */
  532.     if (color_text) {
  533.     CRT_I = CRT_IC;
  534.     CRT_D = CRT_DC;
  535.     IS1_R = IS1_RC;
  536.     } else {
  537.     CRT_I = CRT_IM;
  538.     CRT_D = CRT_DM;
  539.     IS1_R = IS1_RM;
  540.     }
  541. }
  542.  
  543.  
  544. void __vga_delay() {
  545.     int i;
  546.     for (i = 0; i < 10; i++);
  547. }
  548.  
  549. /* The Xfree server uses a slow copy, may help us too ... */
  550. static void slowcpy(unsigned char *dest, unsigned char *src, unsigned bytes)
  551. {
  552.     while (bytes-- > 0)
  553.     *(dest++) = *(src++);
  554. }
  555.  
  556. int __vga_saveregs(unsigned char *regs)
  557. {
  558.     int i;
  559.  
  560.     if (__svgalib_chipset == EGA) {
  561.         /* Special case: Don't save standard VGA registers. */
  562.         return chipset_saveregs(regs);
  563.     }
  564.  
  565.     /* save VGA registers */
  566.     for (i = 0; i < CRT_C; i++) {
  567.      port_out(i, CRT_I); 
  568.      regs[CRT+i] = port_in(CRT_D); 
  569.     }
  570.     for (i = 0; i < ATT_C; i++) {
  571.            port_in(IS1_R);
  572.            __vga_delay();
  573.          port_out(i, ATT_IW); 
  574.          __vga_delay();
  575.          regs[ATT+i] = port_in(ATT_R); 
  576.          __vga_delay();
  577.     }
  578.     for (i = 0; i < GRA_C; i++) {
  579.             port_out(i, GRA_I); 
  580.             regs[GRA+i] = port_in(GRA_D); 
  581.     }
  582.     for (i = 0; i < SEQ_C; i++) {
  583.             port_out(i, SEQ_I); 
  584.             regs[SEQ+i] = port_in(SEQ_D); 
  585.     }
  586.     regs[MIS] = port_in(MIS_R); 
  587.  
  588.     i = chipset_saveregs(regs);        /* save chipset-specific registers */
  589.                     /* i : additional registers */
  590.     if (!SCREENON) {            /* We turned off the screen */
  591.            port_in(IS1_R);
  592.            __vga_delay();
  593.          port_out(0x20, ATT_IW);
  594.     }
  595.     return CRT_C + ATT_C + GRA_C + SEQ_C + 1 + i;
  596. }
  597.  
  598.  
  599. int __vga_setregs(const unsigned char *regs)
  600. {
  601.     int i;
  602.  
  603.     if (__svgalib_chipset == EGA) {
  604.         /* Enable graphics register modification */
  605.     port_out(0x00, GRA_E0);
  606.     port_out(0x01, GRA_E1);
  607.     }
  608.  
  609.     /* update misc output register */
  610.     port_out(regs[MIS], MIS_W);         
  611.  
  612.     /* synchronous reset on */
  613.     port_out(0x00,SEQ_I); 
  614.     port_out(0x01,SEQ_D);            
  615.   
  616.     /* write sequencer registers */
  617.     port_out(1, SEQ_I);
  618.     port_out(regs[SEQ+1]|0x20, SEQ_D);
  619.     for (i = 2; i < SEQ_C; i++) {       
  620.     port_out(i, SEQ_I); 
  621.     port_out(regs[SEQ+i], SEQ_D); 
  622.     }
  623.  
  624.     /* synchronous reset off */
  625.     port_out(0x00, SEQ_I); 
  626.     port_out(0x03, SEQ_D);            
  627.  
  628.     if (__svgalib_chipset != EGA) {  
  629.         /* deprotect CRT registers 0-7 */
  630.         port_out(0x11, CRT_I);          
  631.         port_out(port_in(CRT_D)&0x7F, CRT_D);   
  632.     }
  633.   
  634.     /* write CRT registers */
  635.     for (i = 0; i < CRT_C; i++) {       
  636.     port_out(i, CRT_I); 
  637.     port_out(regs[CRT+i], CRT_D); 
  638.     }
  639.  
  640.     /* write graphics controller registers */
  641.     for (i = 0; i < GRA_C; i++) {       
  642.     port_out(i, GRA_I); 
  643.     port_out(regs[GRA+i], GRA_D); 
  644.     }
  645.      
  646.     /* write attribute controller registers */
  647.     for (i = 0; i < ATT_C; i++) {       
  648.     port_in(IS1_R);   /* reset flip-flop */
  649.     __vga_delay();
  650.     port_out(i, ATT_IW);
  651.     __vga_delay();
  652.     port_out(regs[ATT+i], ATT_IW);
  653.     __vga_delay();
  654.     }
  655.  
  656.     return 0;
  657. }
  658.  
  659. /* We invoke the old interrupt handler after setting text mode */
  660.  
  661. static struct sigaction old_SIGINT_handler;
  662. static struct sigaction old_SIGFPE_handler;
  663. static struct sigaction old_SIGSEGV_handler;
  664. static struct sigaction old_SIGILL_handler;
  665.  
  666. static void restoretextmode(void) {
  667.     /* handle unexpected interrupts - restore text mode and exit */
  668.     if (CM != TEXT) 
  669.         vga_setmode(TEXT);
  670.     if (!__svgalib_screenon) 
  671.         vga_screenon();
  672.     if (__svgalib_tty_fd >= 0)
  673.         ioctl(__svgalib_tty_fd, KDSETMODE, KD_TEXT);
  674. }
  675.  
  676.  
  677. static void SIGINT_handler( int v ) {
  678.     restoretextmode();
  679.     printf("svgalib: Interrupted (ctrl-c pressed)\n");
  680.     sigaction(SIGINT, &old_SIGINT_handler, NULL);
  681.     raise(SIGINT);
  682. }
  683.  
  684. static void SIGFPE_handler( int v ) {
  685.     restoretextmode();
  686.     printf("svgalib: Floating point exception or division by zero\n");
  687.     sigaction(SIGFPE, &old_SIGFPE_handler, NULL);
  688.     raise(SIGFPE);
  689. }
  690.  
  691. static void SIGSEGV_handler( int v ) {
  692.     restoretextmode();
  693.     printf("svgalib: Segment violation\n");
  694.     sigaction(SIGSEGV, &old_SIGSEGV_handler, NULL);
  695.     raise(SIGSEGV);
  696. }
  697.  
  698. static void SIGILL_handler( int v ) {
  699.     restoretextmode();
  700.     printf("svgalib: Illegal instruction\n");
  701.     sigaction(SIGILL, &old_SIGILL_handler, NULL);
  702.     raise(SIGILL);
  703. }
  704.  
  705. int __vga_getchipset(void) {
  706.     readconfigfile();    /* Make sure the config file is read. */
  707.  
  708.     __vga_get_perm();
  709.     if (CHIPSET == UNDEFINED) {
  710.         CHIPSET = VGA; /* Protect against recursion */
  711.         #ifdef INCLUDE_MACH32_DRIVER_TEST
  712.         if (mach32_driverspecs.test())
  713.             CHIPSET = MACH32;
  714.         else
  715.         #endif
  716.         #ifdef INCLUDE_EGA_DRIVER_TEST
  717.         if (ega_driverspecs.test())
  718.             CHIPSET = EGA;
  719.         else
  720.         #endif
  721.         #ifdef INCLUDE_ET4000_DRIVER_TEST
  722.         if (et4000_driverspecs.test())
  723.             CHIPSET = ET4000;
  724.         else
  725.         #endif
  726.         #ifdef INCLUDE_TVGA_DRIVER_TEST
  727.         if (tvga8900_driverspecs.test())
  728.             CHIPSET = TVGA8900;
  729.         else
  730.         #endif
  731.         #ifdef INCLUDE_CIRRUS_DRIVER_TEST
  732.         /* The Cirrus detection is not very clean. */
  733.         if (cirrus_driverspecs.test())
  734.             CHIPSET = CIRRUS;
  735.         else
  736.         #endif
  737.         #ifdef INCLUDE_OAK_DRIVER_TEST
  738.         if (oak_driverspecs.test())
  739.             CHIPSET = OAK;
  740.         else
  741.         #endif
  742.         #ifdef INCLUDE_S3_DRIVER_TEST
  743.         if (s3_driverspecs.test())
  744.             CHIPSET = S3;
  745.         else
  746.         #endif
  747.         #ifdef INCLUDE_ET3000_DRIVER_TEST
  748.         if (et3000_driverspecs.test())
  749.             CHIPSET = ET3000;
  750.         else
  751.         #endif
  752.         #ifdef INCLUDE_ARK_DRIVER_TEST
  753.         if (ark_driverspecs.test())
  754.             CHIPSET = ARK;
  755.         else
  756.         #endif
  757.         #ifdef INCLUDE_GVGA6400_DRIVER_TEST
  758.         if (gvga6400_driverspecs.test())
  759.             CHIPSET = GVGA6400;
  760.         else
  761.         #endif
  762.         #ifdef INCLUDE_ATI_DRIVER_TEST
  763.         if (ati_driverspecs.test())
  764.             CHIPSET = ATI;
  765.         else
  766.         #endif
  767.         
  768.         if (vga_driverspecs.test())
  769.             CHIPSET = VGA;
  770.         else
  771.         /* else */
  772.         {
  773.             fprintf(stderr, "svgalib: Cannot find EGA or VGA graphics device.\n");
  774.             exit(1);
  775.         }
  776.         setpage = driverspecs->setpage;
  777.         setrdpage = driverspecs->setrdpage;
  778.         setwrpage = driverspecs->setwrpage;
  779.     }
  780.     return CHIPSET;
  781. }
  782.  
  783. void vga_setchipset( int c ) {
  784.     CHIPSET = c;
  785.     #ifdef DEBUG
  786.     printf("Setting chipset\n");
  787.     #endif
  788.     if (c == UNDEFINED)
  789.         return;
  790.     if (driverspecslist[c] == NULL) {
  791.         printf("svgalib: Invalid chipset. The driver may not be compiled in.\n");
  792.         CHIPSET = UNDEFINED;
  793.         return;
  794.     }
  795.     __vga_get_perm();
  796.     driverspecslist[c]->init(0, 0, 0);
  797.     setpage = driverspecs->setpage;
  798.     setrdpage = driverspecs->setrdpage;
  799.     setwrpage = driverspecs->setwrpage;
  800. }
  801.  
  802. void vga_setchipsetandfeatures( int c, int par1, int par2 ) {
  803.     CHIPSET = c;
  804.     #ifdef DEBUG
  805.     printf("Forcing chipset and features\n");
  806.     #endif
  807.     __vga_get_perm();
  808.     driverspecslist[c]->init(1, par1, par2);
  809.     #ifdef DEBUG
  810.     printf("Finished forcing chipset and features\n");
  811.     #endif
  812.     setpage = driverspecs->setpage;
  813.     setrdpage = driverspecs->setrdpage;
  814.     setwrpage = driverspecs->setwrpage;
  815. }
  816.  
  817.  
  818. static void savepalette(unsigned char *red, unsigned char *green, 
  819. unsigned char *blue) {
  820.     int i;
  821.  
  822.     if (CHIPSET == EGA)
  823.         return;
  824.  
  825.     if ((__svgalib_chipset == MACH32) && SVGAMODE(CM))
  826.            {
  827.            /* Actually the same but we are in 8514 mode and the dac
  828.            does not respond to the VGA circuitry anymore... */
  829.  
  830.            port_out(0, PEL8514_IR); 
  831.            for (i = 0; i < 256; i++) {
  832.                __vga_delay();
  833.                *(red++)   = port_in(PEL8514_D);
  834.                __vga_delay();
  835.                *(green++) = port_in(PEL8514_D);
  836.                __vga_delay();
  837.                *(blue++)  = port_in(PEL8514_D);
  838.            }
  839.        return;
  840.        }
  841.  
  842.         /* save graphics mode palette - first select palette index 0 */
  843.         port_out(0, PEL_IR); 
  844.  
  845.         /* read RGB components - index is autoincremented */
  846.         for (i = 0; i < 256; i++) {
  847.             __vga_delay();
  848.             *(red++)   = port_in(PEL_D);
  849.             __vga_delay();
  850.             *(green++) = port_in(PEL_D);
  851.             __vga_delay();
  852.             *(blue++)  = port_in(PEL_D);
  853.         }
  854. }
  855.  
  856. static void restorepalette( const unsigned char *red,
  857. const unsigned char *green, const unsigned char *blue ) {
  858.     int i;
  859.  
  860.     if (CHIPSET == EGA)
  861.         return;
  862.  
  863.     if ((__svgalib_chipset == MACH32) && SVGAMODE(CM))
  864.            {
  865.            /* Actually the same but we are in 8514 mode and the dac
  866.            does not respond to the VGA circuitry anymore... */
  867.  
  868.            port_out(0, PEL8514_IW); 
  869.            for (i = 0; i < 256; i++) {
  870.                __vga_delay();
  871.                port_out(*(red++), PEL8514_D);
  872.                __vga_delay();
  873.                port_out(*(green++), PEL8514_D);
  874.                __vga_delay();
  875.                port_out(*(blue++), PEL8514_D);
  876.            }
  877.        return;
  878.        }
  879.  
  880.         /* restore saved palette */
  881.         port_out(0, PEL_IW); 
  882.  
  883.         /* read RGB components - index is autoincremented */
  884.         for (i = 0; i < 256; i++) {
  885.             __vga_delay();
  886.             port_out(*(red++), PEL_D);
  887.             __vga_delay();
  888.             port_out(*(green++), PEL_D);
  889.             __vga_delay();
  890.             port_out(*(blue++), PEL_D);
  891.         }
  892. }
  893.  
  894.  
  895. /* Virtual console switching */
  896.  
  897. static int forbidvtrelease = 0;
  898. static int forbidvtacquire = 0;
  899. static int lock_count = 0;
  900. static int release_flag = 0;
  901.  
  902. static void takevtcontrol();
  903.  
  904. void __vga_flipaway();
  905. static void vga_flipback();
  906.  
  907. static void releasevt_signal( int n ) {
  908.     struct sigaction siga;
  909.     if (lock_count) {
  910.         release_flag = 1;
  911.         return;
  912.     }
  913.     #ifdef DEBUG
  914.     printf("Release request.\n");
  915.     #endif
  916.     forbidvtacquire = 1;
  917.     SETSIG(siga, SIGUSR1, releasevt_signal);
  918.     if (forbidvtrelease) {
  919.         forbidvtacquire = 0;
  920.         ioctl(__svgalib_tty_fd, VT_RELDISP, 0);
  921.         return;
  922.     }
  923.     __vga_flipaway();
  924.     ioctl(__svgalib_tty_fd, VT_RELDISP, 1);
  925.     #ifdef DEBUG
  926.     printf("Finished release.\n");
  927.     #endif
  928.     forbidvtacquire = 0;
  929.  
  930.     /* Suspend program until switched to again. */
  931.     #ifdef DEBUG
  932.     printf("Suspended.\n");
  933.     #endif
  934.     oktowrite = 0;
  935.     if (!runinbackground)
  936.         __svgalib_waitvtactive();
  937.     #ifdef DEBUG
  938.     printf("Waked.\n");
  939.     #endif
  940.  
  941. static void acquirevt_signal( int n ) {
  942.     struct sigaction siga;
  943.     #ifdef DEBUG
  944.     printf("Acquisition request.\n");
  945.     #endif
  946.     forbidvtrelease = 1;
  947.     SETSIG(siga, SIGUSR2, acquirevt_signal);
  948.     if (forbidvtacquire) {
  949.         forbidvtrelease = 0;
  950.         return;
  951.     }
  952.     vga_flipback();
  953.     ioctl(__svgalib_tty_fd, VT_RELDISP, VT_ACKACQ);
  954.     #ifdef DEBUG
  955.     printf("Finished acquisition.\n");
  956.     #endif
  957.     forbidvtrelease = 0;
  958.     oktowrite = 1;
  959. }
  960.  
  961. static struct vt_mode oldvtmode;
  962. static struct vt_mode newvtmode;
  963.  
  964. void takevtcontrol() {
  965.         struct sigaction siga;
  966.  
  967.         ioctl(__svgalib_tty_fd, VT_GETMODE, &oldvtmode);
  968.         newvtmode = oldvtmode;
  969.         newvtmode.mode = VT_PROCESS;    /* handle VT changes */
  970.         newvtmode.relsig = SIGUSR1;    /* I didn't find SIGUSR1/2 anywhere */
  971.         newvtmode.acqsig = SIGUSR2;    /* in the kernel sources, so I guess */
  972.                         /* they are free */
  973.     SETSIG(siga, SIGUSR1, releasevt_signal);
  974.         SETSIG(siga, SIGUSR2, acquirevt_signal);
  975.         ioctl(__svgalib_tty_fd, VT_SETMODE, &newvtmode);
  976. }
  977.  
  978. static void __vga_mmap()
  979. {
  980.     #if 1
  981.     /* This may waste 64K; mmap can probably do better by now. */
  982.     /* valloc allocates aligned on page boundary */
  983.     if ((__svgalib_graph_mem = valloc(GRAPH_SIZE)) == NULL) {
  984.     printf("svgalib: allocation error \n");
  985.     exit (-1);
  986.     }
  987.     __svgalib_graph_mem = (unsigned char *)mmap(
  988.     (caddr_t)GM,
  989.     GRAPH_SIZE,
  990.     PROT_READ|PROT_WRITE,
  991.     MAP_SHARED|MAP_FIXED,
  992.     __svgalib_mem_fd,
  993.     GRAPH_BASE
  994.     );
  995.     #endif
  996.     #if 0
  997.     /* This assumes pl10+. */
  998.     /* Still seems to waste 64K, so don't bother. */
  999.     GM = (unsigned char *)mmap(
  1000.     (caddr_t) 0,
  1001.     GRAPH_SIZE,
  1002.     PROT_READ|PROT_WRITE,
  1003.     MAP_SHARED,
  1004.     __svgalib_mem_fd,
  1005.     GRAPH_BASE
  1006.     );
  1007.     #endif
  1008.     graph_mem = __svgalib_graph_mem;    /* Exported variable. */
  1009. }
  1010.  
  1011. static void __vga_atexit(void) {
  1012.     if (getpid() == my_pid) /* protect against forked processes */
  1013.     restoretextmode(); 
  1014. }
  1015.  
  1016. static void setcoloremulation() {
  1017.     /* shift to color emulation */
  1018.     CRT_I = CRT_IC;
  1019.     CRT_D = CRT_DC;
  1020.     IS1_R = IS1_RC;
  1021.     if (CHIPSET != EGA)
  1022.     port_out(port_in(MIS_R)|0x01, MIS_W); 
  1023. }
  1024.  
  1025. static void initialize()
  1026. {
  1027.     int i;
  1028.     struct sigaction siga;
  1029.  
  1030.     doconsolecheck();
  1031.  
  1032.     /* Make sure that textmode is restored at exit(). */
  1033.     if (my_pid == 0)
  1034.     my_pid = getpid();
  1035.     atexit(__vga_atexit);
  1036.  
  1037. #ifndef DONT_WAIT_VC_ACTIVE
  1038.     __svgalib_waitvtactive();
  1039. #endif
  1040.  
  1041.     /* save text mode termio parameters */
  1042.     ioctl(0, TCGETS, &text_termio);
  1043.  
  1044.     graph_termio = text_termio;
  1045.  
  1046.     /* change termio parameters to allow our own I/O processing */
  1047.     graph_termio.c_iflag &= ~(BRKINT|PARMRK|INPCK|IUCLC|IXON|IXOFF);
  1048.     graph_termio.c_iflag |=  (IGNBRK|IGNPAR);
  1049.  
  1050.     graph_termio.c_oflag &= ~(ONOCR);
  1051.  
  1052.     graph_termio.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|NOFLSH);
  1053.     graph_termio.c_lflag |= (ISIG);   /* enable interrupt */
  1054.  
  1055.     graph_termio.c_cc[VMIN] = 1;
  1056.     graph_termio.c_cc[VTIME] = 0;
  1057.     graph_termio.c_cc[VSUSP] = 0;   /* disable suspend */
  1058.  
  1059.     disable_interrupt();
  1060.  
  1061.     __vga_getchipset();    /* make sure a chipset has been selected */
  1062.     chipset_unlock();
  1063.     
  1064. #ifdef USE_DEVTTY
  1065.     if ((__svgalib_tty_fd = open("/dev/tty", O_RDONLY)) < 0) {
  1066.     printf("svgalib: can't open /dev/tty \n");
  1067.     exit(-1);
  1068.     }
  1069. #else
  1070.     /* open /dev/tty0 - current virtual console */
  1071.     if ((__svgalib_tty_fd = open("/dev/tty0", O_RDONLY) ) < 0) {
  1072.     printf("svgalib: can't open /dev/tty0 \n");
  1073.     exit (-1);
  1074.     }
  1075. #endif
  1076. /*    console = fdopen(devtty_fd, "r"); */
  1077.  
  1078. #if 0     
  1079.     /* Check for EGA/VGA display */
  1080. /*   linux/kd.h defines this function but doesn't work (or am I wrong) ? */
  1081.     if (ioctl(__svgalib_tty_fd, KDDISPTYPE, &display_type)){
  1082.     printf("VGAlib: can't get display type\n");
  1083.     exit (-1);
  1084.     }
  1085.     if (display_type != KD_EGA) {
  1086.     printf("VGAlib: EGA/VGA display required\n");
  1087.     exit(-1);
  1088.     }
  1089. #endif
  1090.  
  1091.     /* disable text output to console */
  1092.     ioctl(__svgalib_tty_fd, KDSETMODE, KD_GRAPHICS);
  1093.  
  1094. /* What the hell is this?!?? Why should using a mouse prevent  */
  1095. /* you from switching vt's ??                                  */
  1096. /*  if (!mouse_support)       */
  1097.     if (1)
  1098.         takevtcontrol();    /* HH: Take control over VT */
  1099.     
  1100. /*    vga_lockvc(); */
  1101.  
  1102.     /* open /dev/mem */
  1103.     open_mem();
  1104.  
  1105.     /* mmap graphics memory */
  1106.  
  1107.     __vga_mmap();
  1108.  
  1109.     if ((long)GM < 0) {
  1110.     printf("svgalib: mmap error \n");
  1111.     exit (-1);
  1112.     }
  1113.  
  1114.     /* disable video */
  1115.     vga_screenoff();
  1116.  
  1117.     /* Sanity check: (from painful experience) */
  1118.  
  1119.     i = __vga_saveregs(text_regs);
  1120.     if(i > MAX_REGS)
  1121.     {
  1122.     puts("svgalib: FATAL internal error:");
  1123.     printf("Set MAX_REGS at least to %d in src/driver.h and recompile everything.\n",
  1124.         i);
  1125.     exit(1);
  1126.     }
  1127.  
  1128.     /* This appears to fix the Trident 8900 rebooting problem. */
  1129.     if (__svgalib_chipset == TVGA8900) {
  1130.         port_out(0x0c, SEQ_I);              /* reg 12 */
  1131.         text_regs[EXT + 11] = port_in(SEQ_D);
  1132.         port_out(0x1f, CRT_I);
  1133.         text_regs[EXT + 12] = port_in(CRT_D);
  1134.     }
  1135.  
  1136.     /* save text mode palette - first select palette index 0 */
  1137.     port_out(0, PEL_IR);
  1138.  
  1139.     /* read RGB components - index is autoincremented */
  1140.     savepalette(text_red, text_green, text_blue);
  1141.  
  1142.     /* shift to color emulation */
  1143.     setcoloremulation();
  1144.  
  1145.     /* save font data - first select a 16 color graphics mode */
  1146.     driverspecs->setmode(GPLANE16);
  1147.  
  1148.     /* Allocate space for textmode font. */
  1149.     font_buf1 = malloc(FONT_SIZE * 2);
  1150.     font_buf2 = font_buf1 + FONT_SIZE;
  1151.  
  1152.     /* save font data in plane 2 */
  1153.     port_out(0x04, GRA_I); 
  1154.     port_out(0x02, GRA_D); 
  1155.     slowcpy(font_buf1, GM, FONT_SIZE);
  1156.  
  1157.     /* save font data in plane 3 */
  1158.     port_out(0x04, GRA_I); 
  1159.     port_out(0x03, GRA_D);
  1160.     slowcpy(font_buf2, GM, FONT_SIZE);
  1161.  
  1162.     initialized = 1;
  1163.     /* do our own interrupt handling */
  1164.     SETSIG2(siga, SIGINT, SIGINT_handler, old_SIGINT_handler);
  1165.  
  1166.     /* Restore textmode after segment violation and math exception */
  1167.     /* I wonder why vgalib didn't do this */
  1168.         SETSIG2(siga, SIGSEGV, SIGSEGV_handler, old_SIGSEGV_handler);
  1169.         SETSIG2(siga, SIGFPE, SIGFPE_handler, old_SIGFPE_handler);
  1170.         SETSIG2(siga, SIGILL, SIGILL_handler, old_SIGILL_handler);
  1171.  
  1172.     /* VMEM setting moved into setmode - Michael. */
  1173.  
  1174. /*    vga_unlockvc(); */
  1175. }
  1176.  
  1177.  
  1178. inline void vga_setpage( int p ) {
  1179.     if (p == currentpage)
  1180.         return;
  1181.     setpage(p);
  1182.     currentpage = p;
  1183. }
  1184.  
  1185.  
  1186. void vga_setreadpage( int p ) {
  1187.     if ( p == currentpage)
  1188.         return;
  1189.     setrdpage( p);
  1190.     currentpage = -1;
  1191. }
  1192.  
  1193.  
  1194. void vga_setwritepage( int p ) {
  1195.     if ( p == currentpage)
  1196.         return;
  1197.     setwrpage( p);
  1198.     currentpage = -1;
  1199. }
  1200.  
  1201.  
  1202. void vga_safety_fork(void (*shutdown_routine)())
  1203. {
  1204.     int childpid;
  1205.  
  1206.     if (initialized)
  1207.     {    
  1208.         printf("svgalib: warning: vga_safety_fork() called when already initialized\n");
  1209.         return;
  1210.     }
  1211.  
  1212.     initialize();
  1213.  
  1214.     childpid = fork();
  1215.     if (childpid < 0)
  1216.     {
  1217.         printf("VGAlib: warning: can't fork to enhance reliability; proceeding anyway\n");
  1218.         return;
  1219.     }
  1220.     if (childpid)
  1221.     {
  1222.         while (waitpid(childpid, 0, WUNTRACED) != childpid);
  1223.         if (shutdown_routine)
  1224.             shutdown_routine();
  1225.         vga_setmode(TEXT);
  1226.         exit(0); /* XXX pass back true exit status */
  1227.     }
  1228.  
  1229.     /* These need to be done again because the child doesn't inherit them.  */
  1230.     __vga_get_perm();
  1231.     __vga_mmap();
  1232. }
  1233.  
  1234.  
  1235. static void prepareforfontloading() {
  1236.     if (__svgalib_chipset == CIRRUS) {
  1237.         outb(0x3c4, 0x0f);
  1238.         /* Disable CRT FIFO Fast-Page mode. */
  1239.         outb(0x3c5, inb(0x3c5) | 0x40);
  1240.     }
  1241. }
  1242.  
  1243. static void fontloadingcomplete() {
  1244.     if (__svgalib_chipset == CIRRUS) {
  1245.         outb(0x3c4, 0x0f);
  1246.         /* Re-enable CRT FIFO Fast-Page mode. */
  1247.         outb(0x3c5, inb(0x3c5) & 0xbf);
  1248.     }
  1249. }
  1250.  
  1251.  
  1252. int vga_setmode(int mode) 
  1253. {
  1254.     if (!initialized)
  1255.         initialize();
  1256.  
  1257.     if (mode != TEXT && !chipset_modeavailable(mode))
  1258.         return -1;
  1259.  
  1260. /*    if (!flip)
  1261.     vga_lockvc(); */
  1262.     disable_interrupt();
  1263.  
  1264.     prv_mode = CM;
  1265.     CM       = mode;
  1266.  
  1267.     /* disable video */
  1268.     vga_screenoff();
  1269.  
  1270.     /* Should be more robust (eg. grabbed X modes) */
  1271.     if (   __vga_getchipset() == ET4000
  1272.     && prv_mode != G640x480x256
  1273.     && SVGAMODE(prv_mode)           )
  1274.         chipset_setmode(G640x480x256, prv_mode);
  1275.  
  1276.     if (mode == TEXT) {
  1277.         /* Returning to textmode. */
  1278.  
  1279.         if (prv_mode != TEXT && mouse_mode == prv_mode) {
  1280.             #ifdef DEBUG
  1281.             printf("svgalib: Closing mouse.\n");
  1282.             #endif
  1283.             mouse_close();
  1284.             mouse_mode = 0;
  1285.             /* vga_unlockvc(); */
  1286.         }
  1287.     
  1288.     if (SVGAMODE(prv_mode))
  1289.         vga_setpage(0);
  1290.  
  1291.  
  1292.     /* The extended registers are restored either by the */
  1293.     /* chipset setregs function, or the chipset setmode function. */
  1294.  
  1295.         /* restore font data - first select a 16 color graphics mode */
  1296.         /* Note: this should restore the old extended registers if */
  1297.         /* setregs is not defined for the chipset. */
  1298.         driverspecs->setmode(GPLANE16, prv_mode);
  1299.  
  1300.     if (CHIPSET != EGA)
  1301.         /* restore old extended regs */
  1302.         chipset_setregs(text_regs, mode);
  1303.  
  1304.     /* disable Set/Reset Register */
  1305.         port_out(0x01, GRA_I ); 
  1306.         port_out(0x00, GRA_D );   
  1307.  
  1308.     prepareforfontloading();
  1309.  
  1310.         /* restore font data in plane 2 - necessary for all VGA's */
  1311.         port_out(0x02, SEQ_I ); 
  1312.         port_out(0x04, SEQ_D );
  1313.     slowcpy(GM, font_buf1, FONT_SIZE);
  1314.  
  1315.         /* restore font data in plane 3 - necessary for Trident VGA's */
  1316.         port_out(0x02, SEQ_I ); 
  1317.         port_out(0x08, SEQ_D );   
  1318.     slowcpy(GM, font_buf2, FONT_SIZE);
  1319.  
  1320.     fontloadingcomplete();
  1321.  
  1322.         /* change register adresses if monochrome text mode */
  1323.         /* EGA is assumed to use color emulation. */
  1324.         if (!color_text) {
  1325.             CRT_I = CRT_IM;
  1326.             CRT_D = CRT_DM;
  1327.             IS1_R = IS1_RM;
  1328.             port_out(port_in(MIS_R)&0xFE, MIS_W); 
  1329.         }
  1330.  
  1331.         /* restore saved palette */
  1332.         restorepalette(text_red, text_green, text_blue);
  1333.  
  1334.     /* restore text mode VGA registers */
  1335.         __vga_setregs(text_regs);
  1336.  
  1337.     /* Set VMEM to some minimum value .. probably pointless.. */
  1338.         {
  1339.         vga_claimvideomemory(12);
  1340.         }
  1341.  
  1342. /*        if (!flip) */
  1343.         /* enable text output - restores the screen contents */ 
  1344.               ioctl(__svgalib_tty_fd, KDSETMODE, KD_TEXT);
  1345.  
  1346.     usleep(MODESWITCHDELAY);    /* wait for signal to stabilize */
  1347.  
  1348.         /* enable video */
  1349.     vga_screenon();
  1350.  
  1351.       if (!flip)
  1352.             /* restore text mode termio */
  1353.             set_texttermio();
  1354.     } else {
  1355.         /* Setting a graphics mode. */
  1356.  
  1357.     /* disable text output */
  1358.     ioctl(__svgalib_tty_fd, KDSETMODE, KD_GRAPHICS);
  1359.     
  1360.     if (SVGAMODE(prv_mode)) {
  1361.         /* The current mode is an SVGA mode, and we now want to */
  1362.         /* set a standard VGA mode. Make sure the extended regs */
  1363.         /* are restored. */
  1364.         /* Also used when setting another SVGA mode to hopefully */
  1365.         /* eliminate lock-ups. */
  1366.         vga_setpage(0);
  1367.         chipset_setregs(text_regs, mode);
  1368.             /* restore old extended regs */
  1369.     }
  1370.  
  1371.         /* shift to color emulation */
  1372.         setcoloremulation();
  1373.  
  1374.         CI.xdim = infotable[mode].xdim;
  1375.         CI.ydim = infotable[mode].ydim;
  1376.         CI.colors = infotable[mode].colors;
  1377.         CI.xbytes = infotable[mode].xbytes;
  1378.         CI.bytesperpixel = infotable[mode].bytesperpixel;
  1379.  
  1380.     chipset_setmode(mode, prv_mode);
  1381.  
  1382.         MODEX = 0;
  1383.  
  1384.     /* Set default claimed memory (moved here from initialize - Michael.) */
  1385.     if (mode == G320x200x256)
  1386.         VMEM = 65536;
  1387.     else
  1388.     if (STDVGAMODE(mode))
  1389.         VMEM = 256 * 1024; /* Why always 256K ??? - Michael */
  1390.     else {
  1391.         vga_modeinfo *modeinfo;
  1392.  
  1393.         modeinfo = vga_getmodeinfo(mode);
  1394.         VMEM = modeinfo->linewidth * modeinfo->height;
  1395.     }
  1396.  
  1397.         if (!flip) {
  1398.                 /* set default palette */
  1399.                 if (CI.colors <= 256) 
  1400.           restorepalette(default_red, default_green, default_blue);
  1401.  
  1402.                 /* clear screen (sets current color to 15) */
  1403.                 currentpage = -1;
  1404.                 vga_clear();
  1405.  
  1406.                 if (SVGAMODE(__svgalib_cur_mode))
  1407.                     vga_setpage(0);
  1408.         }
  1409.  
  1410.         currentpage = -1;
  1411.         currentlogicalwidth = CI.xbytes;
  1412.         currentdisplaystart = 0;
  1413.  
  1414.     usleep(MODESWITCHDELAY);    /* wait for signal to stabilize */
  1415.  
  1416.         /* enable video */
  1417.     if (!flip)
  1418.       vga_screenon();
  1419.  
  1420.     if (mouse_support) {
  1421.         #ifdef DEBUG
  1422.         printf("svgalib: Opening mouse (type = %x).\n", mouse_type|mouse_modem_ctl);
  1423.         #endif
  1424.         if (mouse_init("/dev/mouse", mouse_type|mouse_modem_ctl, MOUSE_DEFAULTSAMPLERATE))
  1425.             printf("svgalib: Failed to initialize mouse.\n");
  1426.         else {
  1427.             /* vga_lockvc(); */
  1428.             mouse_setxrange(0, CI.xdim - 1);
  1429.             mouse_setyrange(0, CI.ydim - 1);
  1430.             mouse_setwrap(MOUSE_NOWRAP);
  1431.             mouse_mode = mode;
  1432.         }
  1433.     }
  1434.  
  1435.       if (!flip)
  1436.             /* set graphics mode termio */
  1437.             set_graphtermio();
  1438.         else
  1439.             enable_interrupt();
  1440.             
  1441.     {
  1442.         vga_modeinfo *modeinfo;
  1443.         modeinfo = vga_getmodeinfo(mode);
  1444.         MODEX = ((MODEFLAGS=modeinfo->flags) & IS_MODEX);
  1445.     }
  1446.  
  1447.     }
  1448.  
  1449. /*    if (!flip)
  1450.     vga_unlockvc(); */
  1451.  
  1452.     return 0;  
  1453. }
  1454.  
  1455. void vga_gettextfont( void *font ) {
  1456.     memcpy(font, font_buf1, FONT_SIZE);
  1457. }
  1458.  
  1459. void vga_puttextfont( void *font ) {
  1460.     memcpy(font_buf1, font, FONT_SIZE);
  1461.     memcpy(font_buf2, font, FONT_SIZE);
  1462. }
  1463.  
  1464. void vga_gettextmoderegs( void *regs ) {
  1465.     memcpy(regs, text_regs, MAX_REGS);
  1466. }
  1467.  
  1468. void vga_settextmoderegs( void *regs ) {
  1469.     memcpy(text_regs, regs, MAX_REGS);
  1470. }
  1471.  
  1472. int vga_getcurrentmode() {
  1473.     return CM;
  1474. }
  1475.  
  1476. int vga_getcurrentchipset() {
  1477.     return __vga_getchipset();
  1478. }
  1479.  
  1480. void vga_disabledriverreport() {
  1481.     DREP = 0;
  1482. }
  1483.  
  1484. vga_modeinfo *vga_getmodeinfo( int mode ) {
  1485.     static vga_modeinfo modeinfo;
  1486.     int is_modeX = (CM == mode) && MODEX;
  1487.  
  1488.     if (mode > vga_lastmodenumber())
  1489.         return NULL;
  1490.     __vga_getchipset();
  1491.     modeinfo.width = infotable[mode].xdim;
  1492.     modeinfo.height = infotable[mode].ydim;
  1493.     modeinfo.bytesperpixel = infotable[mode].bytesperpixel;
  1494.     modeinfo.colors = infotable[mode].colors;
  1495.     if (is_modeX) {
  1496.         modeinfo.linewidth = modeinfo.width / 4;
  1497.         modeinfo.bytesperpixel = 0;
  1498.     }
  1499.     else
  1500.         modeinfo.linewidth = infotable[mode].xbytes;
  1501.     modeinfo.flags = 0;
  1502.     if (mode == TEXT)
  1503.         return &modeinfo;
  1504.     if ((STDVGAMODE(mode) && mode != G320x200x256) || is_modeX)
  1505.         vga_driverspecs.getmodeinfo(mode, &modeinfo);
  1506.     else
  1507.         /* Get chipset specific info for SVGA modes and */
  1508.         /* 320x200x256 (chipsets may support more pages) */
  1509.         chipset_getmodeinfo(mode, &modeinfo);
  1510.  
  1511.     if (modeinfo.colors == 256 && modeinfo.bytesperpixel == 0)
  1512.       modeinfo.flags |= IS_MODEX;
  1513.     if (mode > __GLASTMODE)
  1514.       modeinfo.flags |= IS_DYNAMICMODE;
  1515.  
  1516.     /* Maskout CAPABLE_LINEAR if requested by config file */
  1517.     modeinfo.flags&=modeinfo_mask;
  1518.  
  1519.     /* If all needed info is here, signal if linear support has been enabled */
  1520.     if( (modeinfo.flags&(CAPABLE_LINEAR|EXT_INFO_AVAILABLE)) ==
  1521.                 (CAPABLE_LINEAR|EXT_INFO_AVAILABLE) ) {
  1522.         modeinfo.flags |= __svgalib_modeinfo_linearset;
  1523.     }
  1524.  
  1525.     return &modeinfo;
  1526. }
  1527.  
  1528. int vga_hasmode(int mode)
  1529. {
  1530.     readconfigfile();    /* Make sure the config file is read. */
  1531.     __vga_getchipset();    /* Make sure the chipset is known. */
  1532.     if (mode == TEXT)
  1533.         return 1;
  1534.     return (chipset_modeavailable(mode) != 0);
  1535. }
  1536.  
  1537.  
  1538. int vga_lastmodenumber(void)
  1539. {
  1540.     __vga_getchipset();
  1541.     return lastmodenumber;
  1542. }
  1543.  
  1544.  
  1545. int __vga_addmode(int xdim, int ydim, int cols, int xbytes, int bytespp)
  1546. {
  1547.     int i;
  1548.  
  1549.     for (i=0; i <= lastmodenumber; ++i)
  1550.        if ( infotable[i].xdim   == xdim &&
  1551.         infotable[i].ydim   == ydim &&
  1552.         infotable[i].colors == cols &&
  1553.         infotable[i].bytesperpixel == bytespp &&
  1554.         infotable[i].xbytes == xbytes  )
  1555.           return i;
  1556.     if (lastmodenumber >= MAX_MODES-1)
  1557.       return -1; /* no more space available */
  1558.     ++lastmodenumber;
  1559.     infotable[lastmodenumber].xdim   = xdim;
  1560.     infotable[lastmodenumber].ydim   = ydim;
  1561.     infotable[lastmodenumber].colors = cols;
  1562.     infotable[lastmodenumber].xbytes = xbytes;
  1563.     infotable[lastmodenumber].bytesperpixel = bytespp;
  1564.     return lastmodenumber;
  1565. }
  1566.  
  1567.  
  1568. int vga_setcolor(int color)
  1569. {
  1570.     switch (CI.colors) {
  1571.     case  2: if (color != 0)
  1572.            color = 15;
  1573.     case 16: /* update set/reset register */
  1574.              port_out(0x00, GRA_I ); 
  1575.              port_out((color&15), GRA_D );
  1576.          break;
  1577.     default: COL = color;
  1578.                  break;
  1579.     }
  1580.  
  1581.     return 0;
  1582. }
  1583.  
  1584.  
  1585. int vga_screenoff()
  1586. {
  1587.     /* Dunno how to support that in MACH32 modes...*/
  1588.     /* But it is used to switch the VGA off for better
  1589.        mem access performance...*/
  1590.     /* turn off screen for faster VGA memory acces */
  1591.     if (CHIPSET != EGA) {
  1592.         port_out(0x01, SEQ_I);           
  1593.         port_out(port_in(SEQ_D)|0x20, SEQ_D);
  1594.     }
  1595.     /* Disable video output */
  1596. #ifdef DISABLE_VIDEO_OUTPUT
  1597.     port_in(IS1_R);
  1598.     __vga_delay();
  1599.     port_out(0x00, ATT_IW);
  1600. #endif
  1601.  
  1602.     SCREENON = 0;
  1603.     return 0;
  1604. }
  1605.  
  1606.  
  1607. int vga_screenon()
  1608. {
  1609.     /* Dunno how to support that in MACH32 modes...*/
  1610.     if ((__svgalib_chipset == MACH32) && SVGAMODE(CM))
  1611.     {
  1612.     /* Warning! This is also used for faking of vgapal.c!*/
  1613.     /* Not needed anymore... had to hack vgapal.c anyway..*/
  1614.     /* Let it in anyway to show that std-vga is disabled */
  1615.  
  1616.     /* Anyway force Mach32 to ATI mode (used by setmode)*/
  1617.     outw(0x4AEE,inw(0x4AEE)|1);
  1618.     SCREENON = 0;
  1619.     return 0;
  1620.     }
  1621.     /* turn screen back on */
  1622.     if (CHIPSET != EGA) {
  1623.         port_out(0x01, SEQ_I);           
  1624.         port_out(port_in(SEQ_D)&0xDF, SEQ_D);
  1625.     }
  1626.  
  1627. /* #ifdef DISABLE_VIDEO_OUTPUT */
  1628.     /* enable video output */
  1629.     port_in(IS1_R);
  1630.     __vga_delay();
  1631.     port_out(0x20, ATT_IW);
  1632. /* #endif */
  1633.  
  1634.     SCREENON = 1;
  1635.     return 0;
  1636. }
  1637.  
  1638.  
  1639. int vga_getxdim()
  1640. {
  1641.     return CI.xdim;
  1642. }
  1643.  
  1644.  
  1645. int vga_getydim()
  1646. {
  1647.     return CI.ydim;
  1648. }
  1649.  
  1650.  
  1651. int vga_getcolors()
  1652. {
  1653.     return CI.colors;
  1654. }
  1655.  
  1656. int vga_white(void)
  1657. {
  1658.     switch (CI.colors) {
  1659.       case     2:
  1660.       case    16:
  1661.       case   256: return 15;
  1662.       case 1<<15: return 32767;
  1663.       case 1<<16: return 65535;
  1664.       case 1<<24: return (1<<24)-1;
  1665.     }
  1666.     return CI.colors-1;
  1667. }
  1668.   
  1669. int vga_claimvideomemory( int m ) {
  1670.     vga_modeinfo *modeinfo;
  1671.     int cardmemory;
  1672.  
  1673.     modeinfo = vga_getmodeinfo(CM);
  1674.     if (m < VMEM)
  1675.         return 0;
  1676.     if (modeinfo->colors == 16)
  1677.         cardmemory = modeinfo->maxpixels / 2;
  1678.     else
  1679.         cardmemory = (modeinfo->maxpixels * modeinfo->bytesperpixel
  1680.             + 2) & 0xffff0000;
  1681.     /* maxpixels * bytesperpixel can be 2 less than video memory in */
  1682.     /* 3 byte-per-pixel modes; assume memory is multiple of 64K */
  1683.     if (m > cardmemory)
  1684.         return -1;
  1685.     VMEM = m;
  1686.     return 0;
  1687. }
  1688.  
  1689. int vga_setmodeX(void)
  1690. {
  1691.   switch (CM) {
  1692.     case TEXT : 
  1693. /*    case G320x200x256: */
  1694.     case G320x240x256:
  1695.     case G320x400x256:
  1696.     case G360x480x256: return 0;
  1697.   }
  1698.   if (CI.colors == 256 && VMEM < 256*1024) {
  1699.     port_out( 4, SEQ_I);                              /* switch from linear to plane memory */
  1700.     port_out( (port_in(SEQ_D) & 0xF7) | 0x04, SEQ_D);
  1701.     port_out( 0x14, CRT_I);                           /* switch double word mode off */
  1702.     port_out( (port_in(CRT_D) & 0xBF), CRT_D);
  1703.     port_out( 0x17, CRT_I); 
  1704.     port_out( (port_in(CRT_D) | 0x40), CRT_D);
  1705.     CI.xbytes = CI.xdim / 4;
  1706.     vga_setpage(0);
  1707.     MODEX = 1;
  1708.     return 1;
  1709.   }
  1710.   return 0;
  1711. }
  1712.  
  1713.  
  1714. static int saved_page;
  1715. static int saved_logicalwidth;
  1716. static int saved_displaystart;
  1717. static int saved_modeX;
  1718.  
  1719. static void savestate() {
  1720.     int i;
  1721.  
  1722.     vga_screenoff();
  1723.  
  1724.     savepalette(graph_red, graph_green, graph_blue);
  1725.  
  1726.     saved_page = currentpage;
  1727.     saved_logicalwidth = currentlogicalwidth;
  1728.     saved_displaystart = currentdisplaystart;
  1729.     saved_modeX = MODEX;
  1730.  
  1731.     if (CM == G320x200x256 && VMEM <= 65536) {
  1732.         /* 320x200x256 is a special case; only 64K is addressable */
  1733.         /* (unless more has been claimed, in which case we assume */
  1734.         /* SVGA bank-switching) */
  1735.             if ((graph_buf = malloc(GRAPH_SIZE)) == NULL) {
  1736.                 printf("Cannot allocate memory for VGA state\n");
  1737.                 vga_setmode(TEXT);
  1738.             exit (-1);
  1739.             }
  1740.             memcpy(graph_buf, GM, GRAPH_SIZE);
  1741.     }
  1742.     else
  1743.     if (MODEX || CM==G800x600x16 || (STDVGAMODE(CM) && CM != G320x200x256)) {
  1744.         /* for planar VGA modes, save the full 256K */
  1745.         vga_driverspecs.setmode(GPLANE16);
  1746.             if ((graph_buf = malloc(4*GRAPH_SIZE)) == NULL) {
  1747.                 printf("Cannot allocate memory for VGA state\n");
  1748.                 vga_setmode(TEXT);
  1749.             exit (-1);
  1750.             }
  1751.  
  1752.             for (i = 0; i < 4; i++) {
  1753.                 /* save plane i */
  1754.                     port_out(0x04, GRA_I); 
  1755.                    port_out(i, GRA_D); 
  1756.                     memcpy(graph_buf + i*GRAPH_SIZE, GM, GRAPH_SIZE);
  1757.         }
  1758.     }
  1759.     else
  1760.     if (CI.colors == 16) {
  1761.         int page, size, sbytes;
  1762.         unsigned char *sp;
  1763.  
  1764.         size = VMEM;
  1765.         if ((graph_buf = malloc(4*size)) == NULL) {
  1766.                 printf("Cannot allocate memory for VGA state\n");
  1767.                 vga_setmode(TEXT);
  1768.             exit(-1);
  1769.             }
  1770.  
  1771.         sp = graph_buf;
  1772.         for (page = 0; size > 0; ++page) {
  1773.             vga_setpage(page);
  1774.             sbytes = (size>GRAPH_SIZE) ? GRAPH_SIZE : size;
  1775.             for (i = 0; i < 4; i++) {
  1776.                 /* save plane i */
  1777.             port_out(0x04, GRA_I); 
  1778.             port_out(i, GRA_D);
  1779.                     memcpy(sp, GM, sbytes);
  1780.             sp += sbytes;
  1781.             }
  1782.             size -= sbytes;
  1783.         }
  1784.     }
  1785.     else {    /* SVGA, and SVGA 320x200x256 if videomemoryused > 65536 */
  1786.             int size;
  1787.             int page;
  1788.  
  1789.         size = VMEM;
  1790.  
  1791.         #ifdef DEBUG
  1792.         printf("Saving %dK of video memory.\n", (size + 2) / 1024);
  1793.         #endif
  1794.             if ((graph_buf = malloc(size)) == NULL) {
  1795.                 printf("Cannot allocate memory for SVGA state.\n");
  1796.                 vga_setmode(TEXT);
  1797.             exit(-1);
  1798.             }
  1799.             page = 0;
  1800.             while (size >= 65536) {
  1801.                 vga_setpage(page);
  1802.                 memcpy(graph_buf + page * 65536, GM, 65536);
  1803.                 page++;
  1804.                 size -= 65536;
  1805.             }
  1806.             if (size > 0) {
  1807.                 vga_setpage(page);
  1808.                 memcpy(graph_buf + page * 65536, GM, size);
  1809.             }
  1810.     }
  1811. }
  1812.  
  1813. static void restorestate() {
  1814.     int i;
  1815.  
  1816.     vga_screenoff();
  1817.  
  1818.     if (saved_modeX)
  1819.         vga_setmodeX();
  1820.  
  1821.     restorepalette(graph_red, graph_green, graph_blue);
  1822.  
  1823.     if (CM == G320x200x256 && VMEM <= 65536) {
  1824.         memcpy(GM, graph_buf, 65536);
  1825.     }
  1826.     else
  1827.     if (MODEX || CM==G800x600x16 || (STDVGAMODE(CM) && CM != G320x200x256)) {
  1828.         int setresetreg, planereg;
  1829.         /* disable Set/Reset Register */
  1830.             port_out(0x01, GRA_I); 
  1831.             setresetreg = inb(GRA_D);
  1832.             port_out(0x00, GRA_D);   
  1833.             outb(SEQ_I, 0x02);
  1834.             planereg = inb(SEQ_D);
  1835.  
  1836.             for (i = 0; i < 4; i++) {
  1837.                 /* restore plane i */
  1838.                 port_out(0x02, SEQ_I ); 
  1839.                 port_out(1<<i, SEQ_D );
  1840.                     memcpy(GM, graph_buf + i*GRAPH_SIZE,GRAPH_SIZE);
  1841.         }
  1842.         outb(GRA_I, 0x01);
  1843.         outb(GRA_D, setresetreg);
  1844.         outb(SEQ_I, 0x02);
  1845.         outb(SEQ_D, planereg);
  1846.     } else
  1847.     if (CI.colors == 16) {
  1848.         int page, size, rbytes;
  1849.         unsigned char *rp;
  1850.         int setresetreg, planereg;
  1851.  
  1852.         /* disable Set/Reset Register */
  1853.             port_out(0x01, GRA_I); 
  1854.             if (CHIPSET == EGA)
  1855.                 setresetreg = 0;
  1856.             else
  1857.                 setresetreg = inb(GRA_D);
  1858.             port_out(0x00, GRA_D);
  1859.         port_out(0x02, SEQ_I);
  1860.         if (CHIPSET == EGA)
  1861.             planereg = 0;
  1862.         else
  1863.                 planereg = inb(SEQ_D);
  1864.  
  1865.         size = VMEM;
  1866.         rp = graph_buf;
  1867.         for (page=0; size > 0; ++page) {
  1868.             vga_setpage(page);
  1869.             rbytes = (size>GRAPH_SIZE) ? GRAPH_SIZE : size;
  1870.             for (i = 0; i < 4; i++) {
  1871.                 /* save plane i */
  1872.             port_out(0x02, SEQ_I); 
  1873.             port_out(1<<i, SEQ_D);
  1874.                     memcpy(GM, rp, rbytes);
  1875.             rp += rbytes;
  1876.             }
  1877.             size -= rbytes;
  1878.         }
  1879.  
  1880.         outb(GRA_I, 0x01);
  1881.         outb(GRA_D, setresetreg);
  1882.         outb(SEQ_I, 0x02);
  1883.         outb(SEQ_D, planereg);
  1884.     }
  1885.     else {
  1886. /*            vga_modeinfo *modeinfo; */
  1887.             int size;
  1888.             int page;
  1889.         size = VMEM;
  1890.  
  1891.         #ifdef DEBUG
  1892.         printf("Restoring %dK of video memory.\n", (size + 2) / 1024);
  1893.         #endif
  1894.             page = 0;
  1895.             while (size >= 65536) {
  1896.                 vga_setpage(page);
  1897.                 memcpy(GM, graph_buf + page * 65536, 65536);
  1898.                 size -= 65536;
  1899.                 page++;
  1900.             }
  1901.             if (size > 0) {
  1902.                 vga_setpage(page);
  1903.                 memcpy(GM, graph_buf + page * 65536, size);
  1904.             }
  1905.     }
  1906.     
  1907.     if (saved_logicalwidth != CI.xbytes)
  1908.         vga_setlogicalwidth(saved_logicalwidth);
  1909.     if (saved_page != 0)
  1910.         vga_setpage(saved_page);
  1911.     if (saved_displaystart != 0)
  1912.         vga_setdisplaystart(saved_displaystart);
  1913.  
  1914.     vga_screenon();
  1915.  
  1916.     free(graph_buf);
  1917. }
  1918.  
  1919.  
  1920. int vga_getch()
  1921. {
  1922.     char c;
  1923.  
  1924.     if (CM == TEXT)
  1925.         return -1;
  1926.  
  1927.     while ((read(__svgalib_tty_fd, &c, 1) < 0) && (errno == EINTR));
  1928.  
  1929.     return c;
  1930. }
  1931.  
  1932. /* I have kept the slightly funny 'flip' terminology. */
  1933.  
  1934. void __vga_flipaway() {
  1935.     /* Leaving console. */
  1936.     flip_mode = CM;
  1937.     if (CM != TEXT) {
  1938.         /* wait for any blitter operation to finish */
  1939.         if (vga_getmodeinfo(CM)->haveblit & HAVE_BLITWAIT)
  1940.             vga_blitwait();
  1941.         /* Save state and go to textmode. */
  1942.         savestate();
  1943.         flip = 1;
  1944.         vga_setmode(TEXT);
  1945.         flip = 0;
  1946.     }
  1947. }
  1948.  
  1949. static void vga_flipback() {
  1950.     /* Entering console. */
  1951.         /* Hmmm... and how about unlocking anything someone else locked? */
  1952.     chipset_unlock();
  1953.     if (flip_mode != TEXT) {
  1954.         /* Restore graphics mode and state. */
  1955.         flip = 1;
  1956.         vga_setmode(flip_mode);
  1957.         flip = 0;
  1958.         restorestate();
  1959.     }
  1960. }
  1961.  
  1962. int vga_flip() {
  1963.     if (CM != TEXT) {        /* save state and go to textmode */
  1964.         savestate();
  1965.         flip_mode = CM;
  1966.         flip = 1;
  1967.         vga_setmode(TEXT);
  1968.         flip = 0;
  1969.     }
  1970.     else {                /* restore graphics mode and state */
  1971.         flip = 1;
  1972.         vga_setmode(flip_mode);
  1973.         flip = 0;
  1974.         restorestate();
  1975.     }
  1976.     return 0;
  1977. }
  1978.  
  1979.  
  1980. int vga_setflipchar(int c)
  1981. /* This function is obsolete. Retained for VGAlib compatibility. */
  1982. {
  1983.     flipchar = c;
  1984.  
  1985.     return 0;
  1986. }
  1987.  
  1988. void vga_setlogicalwidth( int w ) {
  1989.     driverspecs->setlogicalwidth(w);
  1990.     currentlogicalwidth = w;
  1991. }
  1992.  
  1993. void vga_setdisplaystart( int a ) {
  1994.     currentdisplaystart = a;
  1995.     if (CHIPSET != VGA && CHIPSET != EGA)
  1996.         if (MODEX || CI.colors == 16) {
  1997.             /* We are currently using a Mode X-like mode on a */
  1998.             /* SVGA card, use the standard VGA function */
  1999.             /* that works properly for Mode X. */
  2000.             /* Same goes for 16 color modes. */
  2001.             vga_driverspecs.setdisplaystart(a);
  2002.             return;
  2003.         }
  2004.  
  2005.     /* Call the regular display start function for the chipset */
  2006.     driverspecs->setdisplaystart(a);
  2007. }
  2008.  
  2009. void vga_bitblt( int srcaddr, int destaddr, int w, int h, int pitch ) {
  2010.     driverspecs->bitblt(srcaddr, destaddr, w, h, pitch);
  2011. }
  2012.  
  2013. void vga_imageblt( void *srcaddr, int destaddr, int w, int h, int pitch ) {
  2014.     driverspecs->imageblt(srcaddr, destaddr, w, h, pitch);
  2015. }
  2016.  
  2017. void vga_fillblt( int destaddr, int w, int h, int pitch, int c ) {
  2018.     driverspecs->fillblt(destaddr, w, h, pitch, c);
  2019. }
  2020.  
  2021. void vga_hlinelistblt( int ymin, int n, int *xmin, int *xmax, int pitch,
  2022. int c ) {
  2023.     driverspecs->hlinelistblt(ymin, n, xmin, xmax, pitch, c);
  2024. }
  2025.  
  2026. void vga_blitwait(void) {
  2027.     driverspecs->bltwait();
  2028. }
  2029.  
  2030. int vga_ext_set(unsigned what, ...) {
  2031.     va_list params;
  2032.     register int retval;
  2033.  
  2034.     /* Does this use of the arglist corrupt non-AVAIL_ACCEL ext_set? */
  2035.     va_start(params, what);
  2036.     if (what == VGA_EXT_AVAILABLE
  2037.     && va_arg(params, int) == VGA_AVAIL_ACCEL) {
  2038.         if (driverspecs->accelspecs == NULL)
  2039.             return 0;
  2040.         else
  2041.             return driverspecs->accelspecs->operations;
  2042.     }
  2043.     va_end(params);
  2044.  
  2045.     if(MODEFLAGS&HAVE_EXT_SET) {
  2046.         va_start(params,what);
  2047.         retval=driverspecs->ext_set(what, params);
  2048.         va_end(params);
  2049.         return retval;
  2050.         }
  2051.     else    return 0;
  2052. }
  2053.  
  2054.  
  2055.  
  2056. /* Parse a string for options.. str is \0-terminated source,
  2057.    commands is an array of char ptrs (last one is NULL) containing commands
  2058.    to parse for. (if first char is ! case sensitive),
  2059.    func is called with ind the index of the detected command.
  2060.    func has to return the ptr to the next unhandled token returned by strtok(NULL," ").
  2061.    Use strtok(NULL," ") to get the next token from the file..
  2062.    mode is 1 when reading from conffile and 0 when parsing the env-vars. This is to
  2063.    allow disabling of dangerous (hardware damaging) options when reading the ENV-Vars
  2064.    of Joe user.
  2065.    Note: We use strtok, that is str is destroyed!*/
  2066. static void parse_string(char *str, char **commands, char *(*func)(int ind,int mode),int mode) {
  2067.     int index;
  2068.     register char *ptr,**curr;
  2069.  
  2070.     /*Pass one, delete comments,ensure only whitespace is ' '*/
  2071.     for(ptr=str;*ptr;ptr++) {
  2072.         if(*ptr=='#') {
  2073.             while(*ptr && (*ptr!='\n')) {
  2074.                 *ptr++ =' ';
  2075.             }
  2076.             if(*ptr)
  2077.                 *ptr=' ';
  2078.         }
  2079.         else if(isspace(*ptr)) {
  2080.             *ptr=' ';
  2081.         }
  2082.     }
  2083.     /*Pass two, parse commands*/
  2084.     ptr=strtok(str," ");
  2085.     while(ptr) {
  2086.         #ifdef DEBUG_CONF
  2087.         printf("Parsing: %s\n",ptr);
  2088.         #endif
  2089.         for(curr=commands, index=0; *curr; curr++,index++) {
  2090.             #ifdef DEBUG_CONF
  2091.             printf("Checking: %s\n",*curr);
  2092.             #endif
  2093.             if(**curr=='!') {
  2094.                 if(!strcmp(*curr+1,ptr)) {
  2095.                     ptr=(*func)(index,mode);
  2096.                     break;
  2097.                 }
  2098.             }
  2099.             else {
  2100.                 if(!strcasecmp(*curr,ptr)) {
  2101.                     ptr=(*func)(index,mode);
  2102.                     break;
  2103.                 }
  2104.             }
  2105.         }
  2106.         if(!*curr) /*unknow command*/
  2107.             ptr=strtok(NULL," ");    /* skip silently til' next command */
  2108.     }
  2109. }
  2110.  
  2111. static int allowoverride = 0;    /* Allow dangerous options in ENV-Var */
  2112.  
  2113. /* This is a service function for drivers. commands and func are as above,
  2114.    the config file and (afterwards) the contents of the environment variable
  2115.    SVGALIB_CONFIG are parsed..*/
  2116. void __svgalib_read_options(char **commands, char *(*func)(int ind,int mode)) {
  2117. /* Parse configuration file. */
  2118.     FILE *f;
  2119.     char *buf=NULL,*ptr;
  2120.     struct stat st;
  2121.     int i;
  2122.  
  2123.     st.st_size=0; /*safety for readenv*/
  2124.  
  2125.     f = fopen(SVGALIB_CONFIG_FILE, "r");
  2126.     if (f == NULL) {
  2127.         printf("svgalib: Configuration file %s not found.\n",
  2128.             SVGALIB_CONFIG_FILE);
  2129.         goto readenv;
  2130.     }
  2131.     fstat(fileno(f), &st);    /* Some error analysis may be fine here..*/
  2132.     buf = alloca(st.st_size+1); /* + a final \0 */
  2133.     fread(buf, 1, st.st_size, f);
  2134.     fclose(f);
  2135.     /*Erase any maybe embedded \0 */
  2136.     for(i=0,ptr=buf;i<st.st_size;i++,ptr++)    {
  2137.         if(!*ptr)
  2138.             *ptr=' ';
  2139.     }
  2140.     /*Trailing \0*/
  2141.     *ptr=0;
  2142.     /*parse config file*/
  2143.     parse_string(buf,commands,func,1);
  2144.     readenv:
  2145.     if(!(ptr=getenv("SVGALIB_CONFIG")))
  2146.         return;
  2147.     if(!(i=strlen(ptr)))
  2148.         return;
  2149.     if(i>st.st_size) /* Note that we allocated one more char...*/
  2150.         buf = alloca(i+1);
  2151.     strcpy(buf,ptr); /* Copy for safety and strtok!! */
  2152.     /*parse environment variable*/
  2153.     parse_string(buf,commands,func,allowoverride);
  2154. }
  2155.     
  2156. /* Configuration file, mouse interface, initialization. */
  2157.  
  2158. static int configfileread = 0;    /* Boolean. */
  2159.  
  2160. static char *vga_conf_commands[]={
  2161.     "mouse","monitor","!m","!M","chipset","overrideenable","!m0","!m1","!m2","!m3",
  2162.     "!m4","!m9", "!M0","!M1","!M2","!M3","!M4","!M5","!M6","nolinear",
  2163.     "linear","!C0","!C1","!C2","!C3","!C4","!C5","!C6","!C7","!C8","!C9",
  2164.     "!c0","!c1","monotext","colortext","!m5",
  2165.     "leavedtr","cleardtr","setdtr","leaverts","clearrts",
  2166.     "setrts",
  2167.     NULL};
  2168.  
  2169. static char *conf_mousenames[]={
  2170.     "Microsoft","MouseSystems","MMSeries","Logitech","Busmouse","PS2",NULL};
  2171.  
  2172. static int check_digit(char *ptr, char *digits) {
  2173.     if(ptr==NULL)
  2174.         return 0;
  2175.     return strlen(ptr)==strspn(ptr,digits);
  2176. }
  2177.  
  2178. static char *process_option(int command,int mode) {
  2179.     static char digits[]=".0123456789";
  2180.     char *ptr,**tabptr,*ptb;
  2181.     int i,j;
  2182.     float f;
  2183.  
  2184. #ifdef DEBUG_CONF
  2185.     printf("command %d detected.\n",command);
  2186. #endif
  2187.     switch(command) {
  2188.         case 5:
  2189.             #ifdef DEBUG_CONF
  2190.             puts("Allow override");
  2191.             #endif
  2192.             if(mode)
  2193.                 allowoverride=1;
  2194.             else    puts("Overrideenable denied. (Gee.. Do you think I'm that silly?)");
  2195.             break;
  2196.         case 0: /* mouse */
  2197.         case 2: /* m */
  2198.             ptr=strtok(NULL," ");
  2199.             if(ptr==NULL)
  2200.                 goto inv_mouse;
  2201.             if(check_digit(ptr,digits+1)) { /* It is a number.. */
  2202.                 i=atoi(ptr);
  2203.                 if((i!=9)&&(i>5))
  2204.                     goto inv_mouse;
  2205.                 mouse_type=i;
  2206.             }
  2207.             else { /* parse for symbolic name.. */
  2208.                 if(!strcasecmp(ptr,"none")) {
  2209.                     mouse_type=9;
  2210.                     break;
  2211.                 }
  2212.                 for(i=0,tabptr=conf_mousenames;*tabptr;tabptr++,i++) {
  2213.                     if(!strcasecmp(ptr,*tabptr)) {
  2214.                         mouse_type=i;
  2215.                         goto leave;
  2216.                     }
  2217.                 }
  2218.                 inv_mouse:
  2219.                 printf("svgalib: Illegal mouse setting: {mouse|m} %s\n"
  2220.                     "Correct usage: {mouse|m} mousetype\n"
  2221.                     "where mousetype is one of 0, 1, 2, 3, 4, 5, 9,\n",
  2222.                     (ptr!=NULL)?ptr:"");
  2223.                 for(tabptr=conf_mousenames;*tabptr;tabptr++) {
  2224.                     printf("%s, ",*tabptr);
  2225.                 }
  2226.                 puts("or none.");
  2227.                 return ptr;    /* Allow a second parse of str */
  2228.             }
  2229.             break;
  2230.         case 1: /* monitor */
  2231.         case 3: /* M */
  2232.             ptr=strtok(NULL," ");
  2233.             if( check_digit(ptr,digits+1) ) { /* It is an int.. */
  2234.                 i=atoi(ptr);
  2235.                 if(i<7) {
  2236.                     if(!mode)
  2237.                         goto mon_deny;
  2238.                     __svgalib_monitortype = i;
  2239.                 }
  2240.                 else {
  2241.                     f=i;
  2242.                     goto monkhz;
  2243.                 }
  2244.             }
  2245.             else if( check_digit(ptr,digits) ) { /* It is a float.. */
  2246.                 f=atof(ptr);
  2247.                 monkhz:
  2248.                 if(!mode)
  2249.                     goto mon_deny;
  2250.                 if(f>=59.0)
  2251.                     __svgalib_monitortype = 6;
  2252.                 else if(f>=56.0)
  2253.                     __svgalib_monitortype = 5;
  2254.                 else if(f>=48.3)
  2255.                     __svgalib_monitortype = 4;
  2256.                 else if(f>=37.9)
  2257.                     __svgalib_monitortype = 3;
  2258.                 else if(f>=35.5)
  2259.                     __svgalib_monitortype = 2;
  2260.                 else if(f>=35.1)
  2261.                     __svgalib_monitortype = 1;
  2262.                 else
  2263.                     __svgalib_monitortype = 0;
  2264.             }
  2265.             else {
  2266.                 printf("svgalib: Illegal monitor setting: {monitor|M} %s\n"
  2267.                     "Correct usage: {monitor|M} monitortype\n"
  2268.                     "where monitortype is one of 0, 1, 2, 3, 4, 5, 6, or\n"
  2269.                     "maximal horz. scan frequency in khz.\n"
  2270.                     "Example: monitor 36.5\n",
  2271.                     (ptr!=NULL)?ptr:"");
  2272.                 return ptr;    /* Allow a second parse of str */
  2273.             }
  2274.             break;
  2275.         case 4: /* chipset */
  2276.             ptr=strtok(NULL," ");
  2277.             if(ptr==NULL) {
  2278.                 puts("svgalib: Illegal chipset setting: no chipset given");
  2279.                 goto chip_us;
  2280.             }
  2281.             /*First param is chipset*/
  2282.             for(i=0,tabptr=driver_names;*tabptr;tabptr++,i++) {
  2283.                 if( (!strcasecmp(ptr,*tabptr)) && (driverspecslist[i]!=NULL) ) {
  2284.                     ptr=strtok(NULL," ");
  2285.                     if( check_digit(ptr,digits+1) ) {
  2286.                         j=atoi(ptr);
  2287.                         ptr=strtok(NULL," ");
  2288.                         if( check_digit(ptr,digits+1) ) {
  2289.                             if(mode)
  2290.                                 vga_setchipsetandfeatures(i,j,atoi(ptr));
  2291.                             else
  2292.                                 {
  2293.                                 chipdeny:
  2294.                             puts("chipset override from environment denied.");
  2295.                                 }
  2296.                             return strtok(NULL," ");
  2297.                         }
  2298.                         else {
  2299.                 puts("svgalib: Illegal chipset setting: memory is not a number");
  2300.                             goto chip_us;
  2301.                         }
  2302.                     }
  2303.                     if(mode)
  2304.                         vga_setchipset(i);
  2305.                     else puts("chipset override from environment denied.");
  2306.                     return ptr;
  2307.                 }
  2308.             }
  2309.             printf("svgalib: Illegal chipset setting: chipset %s\n",ptr);
  2310.             chip_us:
  2311.             puts("Correct usage: chipset driver [par1 par2]\n"
  2312.                 "where driver is one of:");
  2313.             ptb="%s";
  2314.             for(i=0,tabptr=driver_names;*tabptr;tabptr++,i++) {
  2315.                 if(driverspecslist[i]!=NULL) {
  2316.                     printf(ptb,*tabptr);
  2317.                     ptb=", %s";
  2318.                 }
  2319.             }
  2320.             puts("\npar1 and par2 are river dependant integers.\n"
  2321.                 "Example: Chipset VGA    or\n"
  2322.                 "Chipset VGA 0 512");
  2323.             return ptr;
  2324.         case 6: /* oldstyle config: m0-m4 */
  2325.         case 7:
  2326.         case 8:
  2327.         case 9:
  2328.         case 10:
  2329.             mouse_type = command - 6;
  2330.             break;
  2331.         case 11: /* m9 */
  2332.             mouse_type = 9;
  2333.             break;
  2334.         case 12: /* oldstyle config: M0-M6 */
  2335.         case 13:
  2336.         case 14:
  2337.         case 15:
  2338.         case 16:
  2339.         case 17:
  2340.         case 18:
  2341.             if(!mode) {
  2342.                 mon_deny:
  2343.                 puts("Monitor setting from environment denied.");
  2344.                 break;
  2345.             }
  2346.             __svgalib_monitortype = command - 12;
  2347.             break;
  2348.         case 19: /*nolinear*/
  2349.             modeinfo_mask&= ~CAPABLE_LINEAR;
  2350.             break;
  2351.         case 20: /*linear*/
  2352.             modeinfo_mask|= CAPABLE_LINEAR;
  2353.             break;
  2354.         case 21: /* oldstyle chipset C0 - C9 */
  2355.         case 22:
  2356.         case 23:
  2357.         case 24:
  2358.         case 25:
  2359.         case 26:
  2360.         case 27:
  2361.         case 28:
  2362.         case 29:
  2363.         case 30:
  2364.             if(!mode)
  2365.                 goto chipdeny;
  2366.             vga_setchipset(command-21);
  2367.             break;
  2368.         case 31: /* c0-c1 color-text selection */
  2369.             if(!mode)
  2370.                 {
  2371.                 coltexdeny:
  2372.                 puts("Color/mono text selection from environment denied.");
  2373.                 break;
  2374.                 }
  2375.             color_text = 0;
  2376.             break;
  2377.         case 32:
  2378.             if(!mode)
  2379.                 {
  2380.                 puts("Color/mono text selection from environment denied.");
  2381.                 break;
  2382.                 }
  2383.             color_text = 1;
  2384.             break;
  2385.         case 33:
  2386.         case 34:
  2387.             if(!mode)
  2388.                 goto coltexdeny;
  2389.             color_text=command-32;
  2390.             break;
  2391.         case 35: /* Mouse type 5 - "PS2". */
  2392.             mouse_type = 5;
  2393.             break;
  2394.         case 36:
  2395.             mouse_modem_ctl&= ~(MOUSE_CHG_DTR|MOUSE_DTR_HIGH);
  2396.             break;
  2397.         case 37:
  2398.             mouse_modem_ctl&= ~MOUSE_DTR_HIGH;
  2399.             mouse_modem_ctl|= MOUSE_CHG_DTR;
  2400.             break;
  2401.         case 38:
  2402.             mouse_modem_ctl|= (MOUSE_CHG_RTS|MOUSE_RTS_HIGH);
  2403.             break;
  2404.         case 39:
  2405.             mouse_modem_ctl&= ~(MOUSE_CHG_RTS|MOUSE_RTS_HIGH);
  2406.             break;
  2407.         case 40:
  2408.             mouse_modem_ctl&= ~MOUSE_RTS_HIGH;
  2409.             mouse_modem_ctl|= MOUSE_CHG_RTS;
  2410.             break;
  2411.         case 41:
  2412.             mouse_modem_ctl|= (MOUSE_CHG_RTS|MOUSE_RTS_HIGH);
  2413.             break;
  2414.     }
  2415. leave:
  2416. return strtok(NULL," ");
  2417. }
  2418.  
  2419. static void readconfigfile() {
  2420.     if (configfileread)
  2421.         return;
  2422.     configfileread = 1;
  2423.     mouse_type = -1;
  2424.     __svgalib_monitortype = -1;
  2425.     __svgalib_read_options(vga_conf_commands,process_option);
  2426.     if (mouse_type == -1) {
  2427.         mouse_type = MOUSE_MICROSOFT;    /* Default. */
  2428.         puts("svgalib: Assuming Microsoft mouse.");
  2429.     }
  2430.     if (__svgalib_monitortype == -1)
  2431.         {
  2432.         /* Default monitor is low end SVGA/8514. */
  2433.         __svgalib_monitortype = MON1024_43I;
  2434.         puts("svgalib: Assuming low end SVGA/8514 monitor (35.5 KHz).");
  2435.     }
  2436.     #ifdef DEBUG_CONF
  2437.     printf("Mouse is: %d Monitor is: %d\n",mouse_type,__svgalib_monitortype);
  2438.     #endif
  2439. }
  2440.  
  2441. int vga_getmousetype() {
  2442.     readconfigfile();
  2443.     return mouse_type|mouse_modem_ctl;
  2444. }
  2445.  
  2446. int vga_getmonitortype() {
  2447.     readconfigfile();
  2448.     return __svgalib_monitortype;
  2449. }
  2450.  
  2451. void vga_setmousesupport( int s ) {
  2452.     mouse_support = s;
  2453. }
  2454.  
  2455. void vga_lockvc() {
  2456.     lock_count++;
  2457.     if (flip)
  2458.         __svgalib_waitvtactive();
  2459. }
  2460.  
  2461. void vga_unlockvc() {
  2462.     if (--lock_count <= 0)
  2463.     {
  2464.         lock_count = 0;
  2465.         if (release_flag)
  2466.         {
  2467.             release_flag = 0;
  2468.             releasevt_signal(SIGUSR1);
  2469.         }
  2470.     }
  2471. }
  2472.  
  2473. void vga_runinbackground( int stat ) {
  2474.     runinbackground = stat;
  2475. }
  2476.  
  2477. int vga_oktowrite() {
  2478.     return oktowrite;
  2479. }
  2480.  
  2481. int vga_init() {
  2482.     open_devconsole();
  2483.     if (!checkconsole()) {
  2484.         /* Return with error code. */
  2485.         seteuid(getuid());
  2486.         setegid(getgid());
  2487.         return -1;
  2488.     }
  2489.     readconfigfile();
  2490.     vga_hasmode(TEXT);    /* Force driver message and initialization. */
  2491.     seteuid(getuid());    /* Don't need supervisor rights anymore. */
  2492.     setegid(getgid());
  2493.     return 0;
  2494. }
  2495.