home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / x386 / x386Io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-26  |  21.6 KB  |  890 lines

  1. /*
  2.  * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and its
  5.  * documentation for any purpose is hereby granted without fee, provided that
  6.  * the above copyright notice appear in all copies and that both that
  7.  * copyright notice and this permission notice appear in supporting
  8.  * documentation, and that the name of Thomas Roell not be used in
  9.  * advertising or publicity pertaining to distribution of the software without
  10.  * specific, written prior permission.  Thomas Roell makes no representations
  11.  * about the suitability of this software for any purpose.  It is provided
  12.  * "as is" without express or implied warranty.
  13.  *
  14.  * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  16.  * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  19.  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  20.  * PERFORMANCE OF THIS SOFTWARE.
  21.  *
  22.  * $Header: /proj/X11/mit/server/ddx/x386/RCS/x386Io.c,v 1.2 1991/06/27 00:01:38 root Exp $
  23.  */
  24.  
  25. #define NEED_EVENTS
  26. #include "X.h"
  27. #include "Xproto.h"
  28. #include "inputstr.h"
  29. #include "scrnintstr.h"
  30.  
  31. #include "compiler.h"
  32.  
  33. #include "x386Procs.h"
  34. #include "x386OSD.h"
  35. #include "atKeynames.h"
  36.  
  37.  
  38. /*
  39.  * x386KbdBell --
  40.  *    Ring the terminal/keyboard bell for an amount of time proportional to
  41.  *      "loudness".
  42.  */
  43.  
  44. static void
  45. x386KbdBell(loudness, pKeyboard)
  46.      int           loudness;         /* Percentage of full volume */
  47.      DeviceIntPtr  pKeyboard;        /* Keyboard to ring */
  48. {
  49.   /*
  50.    * KDMKTONE is not supported on SCO. To make sound we use KIOCSOUND. The
  51.    * sound must be explicitly turned on and off. The timeout needs to have
  52.    * millisecond precision.
  53.    *
  54.    * And now some notes to KIOCSOUND from the manual:
  55.    * >  This call starts the sound generation.  It turns on
  56.    * >  sound.  The argument is the inverse frequency desired.
  57.    * >  A value of 0 turns off the sound.
  58.    *
  59.    * Interpretion: The value passed is just the reload value for the timer. An
  60.    *               AT386 uses for the times a quarz with 1193180 Hz.
  61.    *
  62.    * NOTE:      ctrl.bell ist not supported.
  63.    */
  64.  
  65.   if (loudness)
  66.     {
  67.       ioctl(x386Info.consoleFd, KIOCSOUND, 1193180 / x386Info.bell_pitch);
  68.       usleep(x386Info.bell_duration * loudness * 20);
  69.       ioctl(x386Info.consoleFd, KIOCSOUND, 0);
  70.     }
  71. }
  72.  
  73.  
  74.  
  75. /*
  76.  * x386KbdLeds --
  77.  *      Update the keyboards leds.
  78.  */
  79.  
  80. void
  81. x386KbdLeds ()
  82. {
  83.  
  84. #ifdef KBIO_SETMODE
  85.   /*
  86.    * We must deal here with the LED's. But there is one problem: If
  87.    * the keyboard is in XT-scancode-mode the LEDs can't be set.
  88.    * Thus we switch here temporarily to AT-scancode-mode.
  89.    *
  90.    * TODO: This way of doing things is NOT portable between
  91.    *       SVR3s. It is standard for SVR4. Is there a common
  92.    *       solution ?
  93.    */
  94.  
  95.   char leds = 0;
  96.  
  97.   if (x386Info.capsLock && !(x386Info.xleds & XLED1))
  98.     leds |= LED_CAP;
  99.  
  100.   if (x386Info.numLock && !(x386Info.xleds & XLED2))
  101.     leds |= LED_NUM;
  102.  
  103.   if ((x386Info.scrollLock || x386Info.modeSwitchLock) && 
  104.       !(x386Info.xleds & XLED3))
  105.     leds |= LED_SCR;
  106.  
  107.   if ((x386Info.leds & x386Info.xleds) & XLED1) leds |= LED_CAP;
  108.   if ((x386Info.leds & x386Info.xleds) & XLED2) leds |= LED_NUM;
  109.   if ((x386Info.leds & x386Info.xleds) & XLED3) leds |= LED_SCR;
  110.  
  111.   ioctl(x386Info.consoleFd, KBIO_SETMODE, KBM_AT);
  112.   ioctl(x386Info.consoleFd, KDSETLED, leds );
  113.   ioctl(x386Info.consoleFd, KBIO_SETMODE, KBM_XT);
  114.  
  115. #endif
  116. }
  117.  
  118.  
  119.  
  120. /*
  121.  * x386KbdCtrl --
  122.  *      Alter some of the keyboard control parameters. All special protocol
  123.  *      values are handled by dix (ProgChangeKeyboardControl)
  124.  */
  125.  
  126. static void
  127. x386KbdCtrl (pKeyboard, ctrl)
  128.      DevicePtr     pKeyboard;        /* Keyboard to alter */
  129.      KeybdCtrl     *ctrl;
  130. {
  131.   x386Info.bell_pitch    = ctrl->bell_pitch;
  132.   x386Info.bell_duration = ctrl->bell_duration;
  133.   x386Info.autoRepeat    = ctrl->autoRepeat;
  134.   x386Info.leds          = (ctrl->leds & ~(XCAPS | XNUM | XSCR));
  135.  
  136.   x386KbdLeds();
  137. }
  138.  
  139.  
  140.  
  141. /*
  142.  * x386InitKBD --
  143.  *      Reinitialize the keyboard. Only set Lockkeys accrding to ours leds.
  144.  *      Depress all other keys.
  145.  */
  146.  
  147. static void
  148. x386InitKBD()
  149. {
  150.   char            leds,rad;
  151.   unsigned int    i;
  152.   xEvent          kevent;
  153.   DevicePtr       pKeyboard = x386Info.pKeyboard;
  154.   KeyClassRec     *keyc = ((DeviceIntPtr)x386Info.pKeyboard)->key;
  155.   KeySym          *map = keyc->curKeySyms.map;
  156.  
  157.   kevent.u.keyButtonPointer.time = GetTimeInMillis();
  158.   kevent.u.keyButtonPointer.rootX = 0;
  159.   kevent.u.keyButtonPointer.rootY = 0;
  160.  
  161.   /*
  162.    * Hmm... here is the biggest hack of every time !
  163.    * It may be possible that a switch-vt procedure has finished BEFORE
  164.    * you released all keys neccessary to do this. That peculiar behavior
  165.    * can fool the X-server pretty much, cause it assumes that some keys
  166.    * were not released. TWM may stuck alsmost completly....
  167.    * OK, what we are doing here is after returning from the vt-switch
  168.    * exeplicitely unrelease all keyboard keys before the input-devices
  169.    * are reenabled.
  170.    */
  171.   for (i = keyc->curKeySyms.minKeyCode; i < keyc->curKeySyms.maxKeyCode; i++)
  172.     if (KeyPressed(i))
  173.       {
  174.     kevent.u.u.detail = i;
  175.     kevent.u.u.type = KeyRelease;
  176.     (* pKeyboard->processInputProc)(&kevent, pKeyboard, 1);
  177.       }
  178.   
  179.   /*
  180.    * we must deal here with the fact, that on some cases the numlock or
  181.    * capslock key are enabled BEFORE the server is started up. So look
  182.    * here at the state on the according LEDS to determine whether a
  183.    * lock-key is allready set.
  184.    */
  185.  
  186.   x386Info.scanPrefix      = 0;
  187.   x386Info.capsLock        = FALSE;
  188.   x386Info.numLock         = FALSE;
  189.   x386Info.scrollLock      = FALSE;
  190.   x386Info.modeSwitchLock  = FALSE;
  191.  
  192.   (void) ioctl(x386Info.consoleFd, KDGETLED, &leds );
  193.  
  194.   for (i = keyc->curKeySyms.minKeyCode;
  195.        i < keyc->curKeySyms.maxKeyCode;
  196.        i++, map += keyc->curKeySyms.mapWidth)
  197.  
  198.     switch(*map) {
  199.  
  200.     case XK_Caps_Lock:
  201.     case XK_Shift_Lock:
  202.       if (leds & LED_CAP) 
  203.     {
  204.       kevent.u.u.detail = i;
  205.       kevent.u.u.type = KeyPress;
  206.       (* pKeyboard->processInputProc)(&kevent, pKeyboard, 1);
  207.       x386Info.capsLock = TRUE;
  208.     }
  209.       break;
  210.  
  211.     case XK_Num_Lock:
  212.       if (leds & LED_NUM)
  213.     {
  214.       kevent.u.u.detail = i;
  215.       kevent.u.u.type = KeyPress;
  216.       (* pKeyboard->processInputProc)(&kevent, pKeyboard, 1);
  217.       x386Info.numLock = TRUE;
  218.     }
  219.       break;
  220.  
  221.     case XK_Scroll_Lock:
  222.     case XK_Kana_Lock:
  223.       if (leds & LED_SCR)
  224.     {
  225.       kevent.u.u.detail = i;
  226.       kevent.u.u.type = KeyPress;
  227.       (* pKeyboard->processInputProc)(&kevent, pKeyboard, 1);
  228.       x386Info.scrollLock = TRUE;
  229.     }
  230.       break;
  231.     }
  232.   x386KbdLeds();
  233.  
  234. #ifdef KDSETRAD
  235.   /*
  236.    * TODO: check whether kdbRate is correctly translated ..
  237.    */
  238.   if      (x386Info.kbdDelay <= 375) rad = 0x00;
  239.   else if (x386Info.kbdDelay <= 625) rad = 0x20;
  240.   else if (x386Info.kbdDelay <= 875) rad = 0x40;
  241.   else                               rad = 0x60;
  242.  
  243.   if      (x386Info.kbdRate <=  2)   rad |= 0x1F;
  244.   else if (x386Info.kbdRate >= 30)   rad |= 0x00;
  245.   else                               rad |= ((58 / x386Info.kbdRate) - 2);
  246.  
  247.   (void) ioctl(x386Info.consoleFd, KDSETRAD, rad );
  248. #endif  
  249. }
  250.  
  251.  
  252.  
  253. /*
  254.  * x386KbdProc --
  255.  *    Handle the initialization, etc. of a keyboard.
  256.  */
  257.  
  258. int
  259. x386KbdProc (pKeyboard, what)
  260.      DevicePtr pKeyboard;    /* Keyboard to manipulate */
  261.      int       what;            /* What to do to it */
  262. {
  263.   static char          *emap;
  264.   static struct termio tty;
  265.   static int           trans;
  266.  
  267.   KeySymsRec           keySyms;
  268.   CARD8                modMap[MAP_LENGTH];
  269.   struct termio        nTty;
  270.  
  271.   switch (what) {
  272.  
  273.   case DEVICE_INIT:
  274.  
  275.     /*
  276.      * First open and find the current state of the keyboard.
  277.      */
  278.     ioctl (x386Info.consoleFd, KDGKBMODE, &trans);
  279.     ioctl (x386Info.consoleFd, TCGETA, &tty); 
  280.     
  281.     /*
  282.      * now handle the the line discipline 0 extended mapping
  283.      *
  284.      * IDEA: After we read the mapping table, we could use the compose -
  285.      *       table for initializing the X-server's one.
  286.      */
  287.     emap = (char *)xalloc(E_TABSZ);
  288.     if (ioctl(x386Info.consoleFd, LDGMAP, emap) < 0)
  289.       {
  290.     xfree(emap);
  291.     emap = NULL;
  292.       }
  293.     
  294.     x386KbdGetMapping(&keySyms, modMap);
  295.     
  296.     /*
  297.      * Get also the initial led settings
  298.      */
  299.     ioctl(x386Info.consoleFd, KDGETLED, &x386Info.leds);
  300.     
  301.     /*
  302.      * Perform final initialization of the system private keyboard
  303.      * structure and fill in various slots in the device record
  304.      * itself which couldn't be filled in before.
  305.      */
  306.     pKeyboard->on = FALSE;
  307.  
  308.  
  309.     InitKeyboardDeviceStruct(x386Info.pKeyboard,
  310.                  &keySyms,
  311.                  modMap,
  312.                  x386KbdBell,
  313.                  x386KbdCtrl);
  314.     
  315.     break;
  316.     
  317.   case DEVICE_ON:
  318.     /*
  319.      * Set the keyboard into "direct" mode and turn on
  320.      * event translation.
  321.      */
  322.  
  323.     ioctl(x386Info.consoleFd, KDSKBMODE, K_RAW);
  324.     ioctl(x386Info.consoleFd, LDNMAP, 0); /* disable mapping completely */
  325.     nTty = tty;
  326.     nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
  327.     nTty.c_oflag = 0;
  328.     nTty.c_cflag = CREAD | CS8 | B9600;
  329.     nTty.c_lflag = 0;
  330.     nTty.c_cc[VTIME]=0; 
  331.     nTty.c_cc[VMIN]=1;
  332.     ioctl(x386Info.consoleFd, TCSETA, &nTty);
  333.  
  334.     AddEnabledDevice(x386Info.consoleFd);
  335.     pKeyboard->on = TRUE;
  336.     x386InitKBD();
  337.     break;
  338.     
  339.   case DEVICE_CLOSE:
  340.   case DEVICE_OFF:
  341.     /*
  342.      * Restore original keyboard directness and translation.
  343.      */
  344.  
  345.     if (emap) ioctl(x386Info.consoleFd, LDSMAP, emap);
  346.     ioctl(x386Info.consoleFd, KDSKBMODE, trans);
  347.     ioctl(x386Info.consoleFd, TCSETA, &(tty));
  348.  
  349.     RemoveEnabledDevice(x386Info.consoleFd); 
  350.     pKeyboard->on = FALSE;
  351.     break;
  352.     
  353.   }
  354.  
  355.   return (Success);
  356. }
  357.  
  358.  
  359.  
  360. /*
  361.  * x386KbdEvents --
  362.  *      Read the new events from the device, and pass them to the eventhandler.
  363.  */
  364.  
  365. void
  366. x386KbdEvents()
  367. {
  368.   unchar rBuf[64];
  369.   int    nBytes,i;
  370.  
  371.   if ((nBytes = read( x386Info.consoleFd, (char *)rBuf, sizeof(rBuf))) >= 1)
  372.     
  373.     for (i = 0; i < nBytes; i++) x386PostKbdEvent(rBuf[i]);
  374. }
  375.  
  376.  
  377.  
  378. /*
  379.  * x386MseCtrl --
  380.  *      Alter the control parameters for the mouse. Note that all special
  381.  *      protocol values are handled by dix.
  382.  */
  383.  
  384. static void
  385. x386MseCtrl(pPointer, ctrl)
  386.      DevicePtr pPointer;
  387.      PtrCtrl   *ctrl;
  388. {
  389.   x386Info.num       = ctrl->num;
  390.   x386Info.den       = ctrl->num;
  391.   x386Info.threshold = ctrl->threshold;
  392. }
  393.  
  394.  
  395.  
  396. /*
  397.  * GetMotionEvents --
  398.  *      Return the (number of) motion events in the "motion history
  399.  *      buffer" (snicker) between the given times.
  400.  */
  401.  
  402. int
  403. GetMotionEvents (buff, start, stop, pScreen)
  404.      CARD32 start, stop;
  405.      xTimecoord *buff;
  406.      ScreenPtr pScreen;
  407. {
  408.   return 0;
  409. }
  410.  
  411.  
  412. static void
  413. x386SetSpeed(old, new, cflag)
  414.      int old, new;
  415.      unsigned short cflag;
  416. {
  417.   struct termio  tty;
  418.   char           *c;
  419.  
  420.   (void) ioctl(x386Info.mseFd, TCGETA, &tty);
  421.   tty.c_iflag = IGNBRK | IGNPAR ;     
  422.   tty.c_oflag = 0;           
  423.   tty.c_lflag = 0;
  424.   tty.c_line = 0;
  425.   tty.c_cc[VTIME]=0; 
  426.   tty.c_cc[VMIN]=1;
  427.   
  428.   switch (old) {
  429.   case 9600:  tty.c_cflag = cflag | B9600;  break;
  430.   case 4800:  tty.c_cflag = cflag | B4800;  break;
  431.   case 2400:  tty.c_cflag = cflag | B2400;  break;
  432.   case 1200:
  433.   default:    tty.c_cflag = cflag | B1200;  break;
  434.   }
  435.   (void) ioctl(x386Info.mseFd, TCSETAW, &tty);  
  436.   
  437.   switch(new) {
  438.   case 9600:  c = "*q";  tty.c_cflag = cflag | B9600;  break;
  439.   case 4800:  c = "*p";  tty.c_cflag = cflag | B4800;  break;
  440.   case 2400:  c = "*o";  tty.c_cflag = cflag | B2400;  break;
  441.   case 1200:
  442.   default:    c = "*n";  tty.c_cflag = cflag | B1200;  break;
  443.   }
  444.  
  445.   write(x386Info.mseFd, c, 2);  
  446.   usleep(100000);
  447.  
  448.   (void) ioctl(x386Info.mseFd, TCSETAW, &tty);  
  449. #ifdef TCMOUSE
  450.   (void) ioctl(x386Info.mseFd, TCMOUSE, 1);  
  451. #endif
  452. }
  453.  
  454.  
  455. /*
  456.  * x386MseProc --
  457.  *      Handle the initialization, etc. of a mouse
  458.  */
  459.  
  460. int
  461. x386MseProc(pPointer, what)
  462.      DevicePtr    pPointer;
  463.      int        what;
  464. {
  465.   unchar                map[4];
  466.  
  467.   static unsigned short cflag[5] =
  468.     {
  469.       (CS7                   | CREAD | CLOCAL | HUPCL ),   /* MicroSoft */
  470.       (CS8 | CSTOPB          | CREAD | CLOCAL | HUPCL ),   /* MouseSystems */
  471.       (CS8 | PARENB | PARODD | CREAD | CLOCAL | HUPCL ),   /* MMSeries */
  472.       (CS8 | CSTOPB          | CREAD | CLOCAL | HUPCL ),   /* Logitech */
  473.       0,                                                   /* BusMouse */
  474.     };
  475.   
  476.   switch (what)
  477.     {
  478.     case DEVICE_INIT: 
  479.       pPointer->on = FALSE;
  480.  
  481.       map[1] = 3;
  482.       map[2] = 2;
  483.       map[3] = 1;
  484.       InitPointerDeviceStruct(pPointer, 
  485.                   map, 
  486.                   3, 
  487.                   GetMotionEvents, 
  488.                   x386MseCtrl, 
  489.                   0);
  490.  
  491.       break;
  492.       
  493.     case DEVICE_ON:
  494.       if ((x386Info.mseFd = open(x386Info.mseDevice, O_RDWR | O_NDELAY)) < 0)
  495.     {
  496.       Error ("Cannot open mouse");
  497.       return (!Success);
  498.     }
  499.  
  500.       if (x386Info.mseType != P_BM) 
  501.     {
  502.       x386SetSpeed(9600, x386Info.baudRate, cflag[x386Info.mseType]);
  503.       x386SetSpeed(4800, x386Info.baudRate, cflag[x386Info.mseType]);
  504.       x386SetSpeed(2400, x386Info.baudRate, cflag[x386Info.mseType]);
  505.       x386SetSpeed(1200, x386Info.baudRate, cflag[x386Info.mseType]);
  506.  
  507.       if (x386Info.mseType == P_LOGI)
  508.         {
  509.           write(x386Info.mseFd, "S", 1);
  510.           x386SetSpeed(x386Info.baudRate, x386Info.baudRate, cflag[P_MM]);
  511.         }
  512.  
  513.       if      (x386Info.sampleRate <=   0)  write(x386Info.mseFd, "O", 1);
  514.       else if (x386Info.sampleRate <=  15)  write(x386Info.mseFd, "J", 1);
  515.       else if (x386Info.sampleRate <=  27)  write(x386Info.mseFd, "K", 1);
  516.       else if (x386Info.sampleRate <=  42)  write(x386Info.mseFd, "L", 1);
  517.       else if (x386Info.sampleRate <=  60)  write(x386Info.mseFd, "R", 1);
  518.       else if (x386Info.sampleRate <=  85)  write(x386Info.mseFd, "M", 1);
  519.       else if (x386Info.sampleRate <= 125)  write(x386Info.mseFd, "Q", 1);
  520.       else                                  write(x386Info.mseFd, "N", 1);
  521.     }
  522.       
  523.       AddEnabledDevice(x386Info.mseFd);
  524.  
  525.       x386Info.lastButtons = 0;
  526.       x386Info.emulateState = 0;
  527.       pPointer->on = TRUE;
  528.       break;
  529.       
  530.     case DEVICE_OFF:
  531.     case DEVICE_CLOSE:
  532.       if (x386Info.mseType == P_LOGI)
  533.     {
  534.       write(x386Info.mseFd, "U", 1);
  535.       x386SetSpeed(x386Info.baudRate, 1200, cflag[P_LOGI]);
  536.     }
  537.       close(x386Info.mseFd);
  538.       RemoveEnabledDevice(x386Info.mseFd);
  539.       pPointer->on = FALSE;
  540.       break;
  541.       
  542.     }
  543.  
  544.   return Success;
  545. }
  546.  
  547.  
  548.  
  549. /*
  550.  * x386MseEvents --
  551.  *      Read the new events from the device, and pass them to the eventhandler.
  552.  */
  553.  
  554. void
  555. x386MseEvents()
  556. {
  557.   unchar               rBuf[64];
  558.   int                  i,nBytes, buttons, dx, dy;
  559.   static int           pBufP = 0;
  560.   static unsigned char pBuf[8];
  561.  
  562.   static unsigned char proto[5][5] = {
  563.     /*  hd_mask hd_id   dp_mask dp_id   nobytes */
  564.     {     0x40,    0x40,    0x40,    0x00,    3     },  /* MicroSoft */
  565.     {    0xf8,    0x80,    0x00,    0x00,    5    },  /* MouseSystems */
  566.     {    0xe0,    0x80,    0x80,    0x00,    3    },  /* MMSeries */
  567.     {    0xe0,    0x80,    0x80,    0x00,    3    },  /* Logitech */
  568.     {    0xf8,    0x80,    0x00,    0x00,    5    },  /* BusMouse */
  569.   };
  570.   
  571.   if (!(nBytes = read(x386Info.mseFd, (char *)rBuf, sizeof(rBuf)))) return;
  572.  
  573.   for ( i=0; i < nBytes; i++) {
  574.     /*
  575.      * Hack for resyncing: We check here for a package that is:
  576.      *  a) illegal (detected by wrong data-package header)
  577.      *  b) invalid (0x80 == -128 and that might be wrong for MouseSystems)
  578.      *  c) bad header-package
  579.      *
  580.      * NOTE: b) is a voilation of the MouseSystems-Protocol, since values of
  581.      *       -128 are allowed, but since they are very seldom we can easily
  582.      *       use them as package-header with no button pressed.
  583.      */
  584.     if (pBufP != 0 && 
  585.     ((rBuf[i] & proto[x386Info.mseType][2]) != proto[x386Info.mseType][3]
  586.      || rBuf[i] == 0x80))
  587.       {
  588.     pBufP = 0;          /* skip package */
  589.       }
  590.  
  591.     if (pBufP == 0 &&
  592.     (rBuf[i] & proto[x386Info.mseType][0]) != proto[x386Info.mseType][1])
  593.       {
  594.     /*
  595.      * Hack for Logitech MouseMan Mouse - Middle button
  596.      *
  597.      * Unfortunately this mouse has variable length packets: the standard
  598.      * Microsoft 3 byte packet plus an optional 4th byte whenever the
  599.      * middle button status changes.
  600.      *
  601.      * We have already processed the standard packet with the movement
  602.      * and button info.  Now post an event message with the old status
  603.      * of the left and right buttons and the updated middle button.
  604.      */
  605.     if (x386Info.mseType == P_MS && (rBuf[i] == 0x20 || rBuf[i] == 0))
  606.       {
  607.         buttons = ((int)(rBuf[i] & 0x20) >> 4)
  608.           | (x386Info.lastButtons & 0x05);
  609.         x386PostMseEvent(buttons, 0, 0);
  610.       }
  611.  
  612.     continue;            /* skip package */
  613.       }
  614.  
  615.  
  616.     pBuf[pBufP++] = rBuf[i];
  617.     if (pBufP != proto[x386Info.mseType][4]) continue;
  618.  
  619.     /*
  620.      * assembly full package
  621.      */
  622.     switch(x386Info.mseType) {
  623.       
  624.     case P_MS:              /* Mircosoft */
  625.       buttons = (x386Info.lastButtons & 2)
  626.     | ((int)(pBuf[0] & 0x20) >> 3)
  627.       | ((int)(pBuf[0] & 0x10) >> 4);
  628.       dx = (char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F));
  629.       dy = (char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F));
  630.       break;
  631.       
  632.     case P_MSC:             /* Mouse Systems Corp */
  633.       buttons = (~pBuf[0]) & 0x07;
  634.       dx =    (char)(pBuf[1]) + (char)(pBuf[3]);
  635.       dy = - ((char)(pBuf[2]) + (char)(pBuf[4]));
  636.       break;
  637.       
  638.     case P_MM:              /* MM Series */
  639.     case P_LOGI:            /* Logitech Mice */
  640.       buttons = pBuf[0] & 0x07;
  641.       dx = (pBuf[0] & 0x10) ?   pBuf[1] : - pBuf[1];
  642.       dy = (pBuf[0] & 0x08) ? - pBuf[2] :   pBuf[2];
  643.       break;
  644.       
  645.     case P_BM:              /* BusMouse */
  646.       buttons = (~pBuf[0]) & 0x07;
  647.       dx =   (char)pBuf[1];
  648.       dy = - (char)pBuf[2];
  649.       break;
  650.     }
  651.  
  652.     x386PostMseEvent(buttons, dx, dy);
  653.     pBufP = 0;
  654.   }
  655. }
  656.  
  657.  
  658.  
  659. #ifdef XQUEUE
  660.  
  661. static xqEventQueue      *XqueQaddr;
  662.  
  663. /*
  664.  * x386XqueRequest --
  665.  *      Notice an i/o request from the xqueue.
  666.  */
  667.  
  668. static void
  669. x386XqueRequest()
  670. {
  671.   xqEvent  *XqueEvents = XqueQaddr->xq_events;
  672.   int      XqueHead = XqueQaddr->xq_head;
  673.  
  674.   while (XqueHead != XqueQaddr->xq_tail)
  675.     {
  676.  
  677.       switch(XqueEvents[XqueHead].xq_type) {
  678.     
  679.       case XQ_BUTTON:
  680.     x386PostMseEvent(~(XqueEvents[XqueHead].xq_code) & 0x07, 0, 0);
  681.     break;
  682.  
  683.       case XQ_MOTION:
  684.     x386PostMseEvent(~(XqueEvents[XqueHead].xq_code) & 0x07,
  685.                XqueEvents[XqueHead].xq_x,
  686.                XqueEvents[XqueHead].xq_y);
  687.     break;
  688.  
  689.       case XQ_KEY:
  690.     x386PostKbdEvent(XqueEvents[XqueHead].xq_code);
  691.     break;
  692.     
  693.       default:
  694.     ErrorF("Unknown Xque Event: 0x%02x\n", XqueEvents[XqueHead].xq_type);
  695.       }
  696.       
  697.       if ((++XqueHead) == XqueQaddr->xq_size) XqueHead = 0;
  698.     }
  699.  
  700.   /* reenable the signal-processing */
  701.   x386Info.inputPending = TRUE;
  702.   signal(SIGUSR2, (void (*)()) x386XqueRequest);
  703.   XqueQaddr->xq_head = XqueQaddr->xq_tail;
  704.   XqueQaddr->xq_sigenable = 1; /* UNLOCK */
  705. }
  706.  
  707.  
  708.  
  709. /*
  710.  * x386XqueEnable --
  711.  *      Enable the handling of the Xque
  712.  */
  713.  
  714. static int
  715. x386XqueEnable()
  716. {
  717.   static struct kd_quemode xqueMode;
  718.   static Bool              was_here = FALSE;
  719.  
  720.   if (!was_here) {
  721.     if ((x386Info.xqueFd = open("/dev/mouse", O_RDONLY|O_NDELAY)) < 0)
  722.       {
  723.     Error ("Cannot open /dev/mouse");
  724.     return (!Success);
  725.       }
  726.     was_here = TRUE;
  727.   }
  728.  
  729.   if (x386Info.xqueSema++ == 0) 
  730.     {
  731.       (void) signal(SIGUSR2, (void (*)()) x386XqueRequest);
  732.       xqueMode.qsize = 64;    /* max events */
  733.       xqueMode.signo = SIGUSR2;
  734.       ioctl(x386Info.consoleFd, KDQUEMODE, NULL);
  735.       
  736.       if (ioctl(x386Info.consoleFd, KDQUEMODE, &xqueMode) < 0) {
  737.     Error ("Cannot set KDQUEMODE");
  738.     /* CONSTCOND */
  739.     return (!Success);
  740.       }
  741.       
  742.       XqueQaddr = (xqEventQueue *)xqueMode.qaddr;
  743.       XqueQaddr->xq_sigenable = 1; /* UNLOCK */
  744.     }
  745.  
  746.   return(Success);
  747. }
  748.  
  749.  
  750.  
  751. /*
  752.  * x386XqueDisable --
  753.  *      disable the handling of the Xque
  754.  */
  755.  
  756. static int
  757. x386XqueDisable()
  758. {
  759.   if (x386Info.xqueSema-- == 1)
  760.     {
  761.       
  762.       XqueQaddr->xq_sigenable = 0; /* LOCK */
  763.       
  764.       if (ioctl(x386Info.consoleFd, KDQUEMODE, NULL) < 0) {
  765.     Error ("Cannot unset KDQUEMODE");
  766.     /* CONSTCOND */
  767.     return (!Success);
  768.       }
  769.     }
  770.  
  771.   return(Success);
  772. }
  773.  
  774.  
  775.  
  776. /*
  777.  * x386XqueMseProc --
  778.  *      Handle the initialization, etc. of a mouse
  779.  */
  780.  
  781. int
  782. x386XqueMseProc(pPointer, what)
  783.      DevicePtr    pPointer;
  784.      int        what;
  785. {
  786.   unchar        map[4];
  787.  
  788.   switch (what)
  789.     {
  790.     case DEVICE_INIT: 
  791.       
  792.       pPointer->on = FALSE;
  793.       
  794.       map[1] = 3;
  795.       map[2] = 2;
  796.       map[3] = 1;
  797.       InitPointerDeviceStruct(pPointer, 
  798.                   map, 
  799.                   3, 
  800.                   GetMotionEvents, 
  801.                   x386MseCtrl, 
  802.                   0);
  803.       break;
  804.       
  805.     case DEVICE_ON:
  806.       x386Info.lastButtons = 0;
  807.       x386Info.emulateState = 0;
  808.       pPointer->on = TRUE;
  809.       return(x386XqueEnable());
  810.       
  811.     case DEVICE_CLOSE:
  812.     case DEVICE_OFF:
  813.       pPointer->on = FALSE;
  814.       return(x386XqueDisable());
  815.     }
  816.   
  817.   return Success;
  818. }
  819.  
  820.  
  821.  
  822. /*
  823.  * x386XqueKbdProc --
  824.  *    Handle the initialization, etc. of a keyboard.
  825.  */
  826.  
  827. int
  828. x386XqueKbdProc (pKeyboard, what)
  829.      DevicePtr pKeyboard;    /* Keyboard to manipulate */
  830.      int       what;            /* What to do to it */
  831. {
  832.   KeySymsRec  keySyms;
  833.   CARD8       modMap[MAP_LENGTH];
  834.  
  835.   switch (what) {
  836.       
  837.   case DEVICE_INIT:
  838.     
  839.     x386KbdGetMapping(&keySyms, modMap);
  840.     
  841.     /*
  842.      * Get also the initial led settings
  843.      */
  844.     ioctl(x386Info.consoleFd, KDGETLED, &x386Info.leds);
  845.     
  846.     /*
  847.      * Perform final initialization of the system private keyboard
  848.      * structure and fill in various slots in the device record
  849.      * itself which couldn't be filled in before.
  850.      */
  851.     pKeyboard->on = FALSE;
  852.     
  853.     InitKeyboardDeviceStruct(x386Info.pKeyboard,
  854.                  &keySyms,
  855.                  modMap,
  856.                  x386KbdBell,
  857.                  x386KbdCtrl);
  858.     
  859.     break;
  860.     
  861.   case DEVICE_ON:
  862.     pKeyboard->on = TRUE;
  863.     x386InitKBD();
  864.     return(x386XqueEnable());
  865.     
  866.   case DEVICE_CLOSE:
  867.   case DEVICE_OFF:
  868.     pKeyboard->on = FALSE;
  869.     return(x386XqueDisable());
  870.   }
  871.   
  872.   return (Success);
  873. }
  874.  
  875.  
  876. /*
  877.  * x386XqueEvents --
  878.  *      Get some events from our queue. Nothing to do here ...
  879.  */
  880.  
  881. void
  882. x386XqueEvents()
  883. {
  884. }
  885.  
  886. #endif /* XQUEUE */
  887.  
  888.  
  889.  
  890.