home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / tek / pegIo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-26  |  28.5 KB  |  1,126 lines

  1. /* $Header: pegIo.c,v 1.4 89/10/10 10:29:30 rws Exp $ */
  2. /***********************************************************
  3. Portions modified by Tektronix, Inc.  Copyright 1987 Tektronix, Inc.
  4.  
  5. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  6. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  7.  
  8.                         All Rights Reserved
  9.  
  10. Permission to use, copy, modify, and distribute this software and its 
  11. documentation for any purpose and without fee is hereby granted, 
  12. provided that the above copyright notice appear in all copies and that
  13. both that copyright notice and this permission notice appear in 
  14. supporting documentation, and that the names of Digital or MIT not be
  15. used in advertising or publicity pertaining to distribution of the
  16. software without specific, written prior permission.  
  17.  
  18. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  19. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  20. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  21. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  23. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  24. SOFTWARE.
  25.  
  26. ******************************************************************/
  27. #include "X.h"
  28. #define  NEED_EVENTS
  29. #include "Xproto.h"
  30. #include "inputstr.h"
  31. #include "miscstruct.h"
  32. #include "scrnintstr.h"
  33. #include "cursorstr.h"
  34. #include "pixmap.h"
  35. #include "windowstr.h"
  36. #include "regionstr.h"
  37. #include "resource.h"
  38.  
  39. #include "mi.h"
  40.  
  41. #ifdef    UTEK
  42. #include <box/keyboard.h>
  43. #endif    /* UTEK */
  44.  
  45. #ifdef    UTEKV
  46. #include "redwing/keyboard.h"
  47. #endif    /* UTEKV */
  48.  
  49. #include "peg.h"
  50.  
  51. static void pegChangePointerControl();
  52. static void pegChangeKeyboardControl();
  53. static void xtlChangeKeyboardControl();
  54. static void pegBell();
  55. static void xtlBell();
  56. extern int errno;
  57. extern InitInfo    pegInfo;
  58.  
  59. Bool
  60. pegSaveScreen(pScreen, on)
  61.     ScreenPtr pScreen;
  62.     int on;
  63.  
  64. {
  65.     switch (on) {
  66.     case SCREEN_SAVER_FORCER:
  67.     case SCREEN_SAVER_OFF:
  68.         pegInfo.screenIsSaved = SCREEN_SAVER_OFF;
  69.         DisplayOn();
  70.         break;
  71.     case SCREEN_SAVER_ON:
  72.     default:
  73.         pegInfo.screenIsSaved = SCREEN_SAVER_ON;
  74.         DisplayOff();
  75.         break;
  76.     }
  77.  
  78.     return TRUE;
  79. }
  80.  
  81.  
  82. /*
  83.  * This routine is needed by a os/4.2 routine to implement screensaver.  It is
  84.  * not documented in ddx.doc
  85.  */
  86. TimeSinceLastInputEvent()
  87. {
  88.         return (pegInfo.dsp->ds_ltime - pegInfo.dsp->ds_lastevent);
  89. }
  90.  
  91. int
  92. pegGetMotionEvents()
  93. {
  94.     return 0;
  95. }
  96.  
  97. int
  98. pegMouseProc(pDev, onoff, argc, argv)
  99.     DevicePtr pDev;
  100.     int onoff;
  101.     int argc;
  102.     char **argv;
  103. {
  104.     BYTE map[8];
  105.     SvcCursorXY    upperLeft, lowerRight;
  106.  
  107.     debug4(("MouseProc(0x%x,%d,%d,0x%x)\n", pDev, onoff, argc, argv));
  108.  
  109.     switch (onoff)
  110.     {
  111.     case DEVICE_INIT: 
  112.         pegInfo.pPointer = pDev;
  113.         pDev->devicePrivate = (pointer) pegInfo.queue;
  114.         /*
  115.          * Mouse button map so that the leftmost mouse button comes out as
  116.          * 1, middle as 2 and the rightmost button as 3.  Any thing else
  117.          * comes out as 0 (the driver only gives us one button at a
  118.          * time).
  119.          */
  120.         map[0] = map[1] = map[2] = map[3] = map[4] = map[5] = map[6] =
  121.         map[7] = 0;
  122.         map[Button_L] = 1;
  123.         map[Button_M] = 2;
  124.         map[Button_R] = 3;
  125.         InitPointerDeviceStruct(pegInfo.pPointer,
  126.                     map,
  127.                     8,
  128.                     pegGetMotionEvents,
  129.                     pegChangePointerControl,
  130.                     0);
  131. #ifndef XPEG_TANDEM
  132.         SetInputCheck(&pegInfo.queue->head, &pegInfo.queue->tail);
  133. #endif /* XPEG_TANDEM */
  134.  
  135.         /*
  136.          * Turn on driver.  Enable the mouse.
  137.          */
  138.         SetCursorMode(0);
  139.         MousePanOn(); /* this is only effective on a 4405 anyway */
  140.         JoyPanOff(); /* if there is panning... we do it */
  141.         upperLeft.x = upperLeft.y = 0;
  142.         lowerRight.x = pegInfo.scrWidth - 1;
  143.         lowerRight.y = pegInfo.scrHeight - 1;
  144.         SetCursorBounds(&upperLeft, &lowerRight);
  145.  
  146.         break;
  147.     case DEVICE_ON: 
  148.         pDev->on = TRUE;
  149.         AddEnabledDevice(pegInfo.eventFd);
  150.         CursorEnable();
  151.  
  152.         /*
  153.          * XXX - the driver has not issued an event yet, so the time of the
  154.          * last event is 0, and the time returned by
  155.          * TimeSinceLastInputEvent() will be very large, and
  156.          * WaitForSomething() will compute a negative
  157.          * time for select(), and select will return with an error... ad
  158.          * infinitum.  The bug in WaitForSomething should really be fixed.
  159.          * 2/10/87 Todd B.
  160.          */
  161.         pegInfo.dsp->ds_lastevent = pegInfo.dsp->ds_ltime;
  162.  
  163.         break;
  164.     case DEVICE_OFF: 
  165.         pDev->on = FALSE;
  166.         RemoveEnabledDevice(pegInfo.eventFd);
  167.         CursorDisable();
  168.         break;
  169.     case DEVICE_CLOSE: 
  170.         break;
  171.     }
  172.     return Success;
  173.  
  174. }
  175.  
  176. /*
  177.  * These are the "main row" keys.  These are repeatable.
  178.  */
  179. static char mainrow_PEG[] = {
  180.     KBBackSpace,KBTab,      KBLineFeed, KBReturn,
  181.     KBSpaceBar, KBQuote,    KBComma,    KBHyphon,
  182.     KBPeriod,   KBSlash,    KB0,        KB1,
  183.     KB2,        KB3,        KB4,        KB5,        
  184.     KB6,        KB7,        KB8,        KB9,        
  185.     KBSemiColon,KBEqual,    KBA,        KBB,    
  186.     KBC,        KBD,        KBE,        KBF,        
  187.     KBG,        KBH,        KBI,        KBJ,        
  188.     KBK,        KBL,        KBM,        KBN,        
  189.     KBO,        KBP,        KBQ,        KBR,        
  190.     KBS,        KBT,        KBU,        KBV,        
  191.     KBW,        KBX,        KBY,        KBZ,        
  192.     KBBraceL,   KBBackSlash,KBBraceR,   KBBar,  
  193.     KBRubOut,   KBJoyRight, KBJoyUp,    KBJoyLeft,  
  194.     KBJoyDown
  195. };
  196. static char mainrow_XTL[] = {
  197.     KEY_BackSpace,KEY_Tab,      KEY_Linefeed, KEY_Return,
  198.     KEY_Space,    KEY_Quote,    KEY_Comma,    KEY_Minus,
  199.     KEY_Period,   KEY_Slash,    KEY_0,        KEY_1,
  200.     KEY_2,        KEY_3,        KEY_4,        KEY_5,        
  201.     KEY_6,        KEY_7,        KEY_8,        KEY_9,        
  202.     KEY_SemiColon,KEY_Equal,    KEY_a,        KEY_b,    
  203.     KEY_c,        KEY_d,        KEY_e,        KEY_f,        
  204.     KEY_g,        KEY_h,        KEY_i,        KEY_j,        
  205.     KEY_k,        KEY_l,        KEY_m,        KEY_n,        
  206.     KEY_o,        KEY_p,        KEY_q,        KEY_r,        
  207.     KEY_s,        KEY_t,        KEY_u,        KEY_v,        
  208.     KEY_w,        KEY_x,        KEY_y,        KEY_z,        
  209.     KEY_LBrace,   KEY_VertBar,  KEY_RBrace,   KEY_Tilde,  
  210.     KEY_RubOut,   KEY_Cursor_R, KEY_Cursor_U, KEY_Cursor_L,  
  211.     KEY_Cursor_D
  212. };
  213.  
  214. int
  215. pegKeybdProc(pDev, onoff, argc, argv)
  216.     DevicePtr pDev;
  217.     int onoff;
  218.     int argc;
  219.     char **argv;
  220. {
  221.     KeySymsRec keySyms;
  222.     CARD8 modMap[MAP_LENGTH];
  223.     int    i;
  224.  
  225.     switch (onoff)
  226.     {
  227.     case DEVICE_INIT: 
  228.         pegInfo.pKeyboard = pDev;
  229.         pDev->devicePrivate = (pointer) pegInfo.queue;
  230. #ifdef    UTEK
  231.         if (KEYIDSTYLE(pegInfo.softp) ==  KB_STYLE_VT200)
  232. #endif    /* UTEK */
  233. #ifdef    UTEKV
  234.         if (KEYIDSTYLE(pegInfo.dsp) ==  KB_STYLE_VT200)
  235. #endif    /* UTEKV */
  236.           {
  237.         /* XTL style */
  238.         gfbXTLKBMappings(&keySyms, modMap);
  239.         InitKeyboardDeviceStruct(
  240.             pegInfo.pKeyboard, &keySyms, modMap, xtlBell,
  241.             xtlChangeKeyboardControl);
  242.         for (i=0; i<sizeof(mainrow_XTL); i++) {
  243.             MakeRawKeyRepeatable(mainrow_XTL[ i ]);
  244.         }
  245.           }
  246. #ifdef    UTEK
  247.         else if (KEYIDSTYLE(pegInfo.softp) ==  KB_STYLE_YELLOW_JACKET)
  248. #endif    /* UTEK */
  249. #ifdef    UTEKV
  250.         else if (KEYIDSTYLE(pegInfo.dsp) ==  KB_STYLE_YELLOW_JACKET)
  251. #endif    /* UTEKV */
  252.           {
  253.             /* 4207 YELLOW JACKET style */
  254.         GetPEGKBMappings(&keySyms, modMap);
  255.         InitKeyboardDeviceStruct(
  256.             pegInfo.pKeyboard, &keySyms, modMap, xtlBell,
  257.             pegChangeKeyboardControl);
  258.         for (i=0; i<sizeof(mainrow_XTL); i++) {
  259.             MakeRawKeyRepeatable(mainrow_XTL[ i ]);
  260.         }
  261.         } else {
  262.         /* default to Pegasus style */
  263.         GetPEGKBMappings(&keySyms, modMap);
  264.         InitKeyboardDeviceStruct(
  265.             pegInfo.pKeyboard, &keySyms, modMap, pegBell,
  266.             pegChangeKeyboardControl);
  267.         for (i=0; i<sizeof(mainrow_PEG); i++) {
  268.             MakeRawKeyRepeatable(mainrow_PEG[ i ]);
  269.         }
  270.         }
  271.         Xfree((pointer)keySyms.map);
  272.         ((DeviceIntPtr)pDev)->kbdfeed->ctrl.autoRepeat = True;
  273.         break;
  274.     case DEVICE_ON: 
  275.         pDev->on = TRUE;
  276.         AddEnabledDevice(pegInfo.eventFd);
  277.         break;
  278.     case DEVICE_OFF: 
  279.         pDev->on = FALSE;
  280. /*        RemoveEnabledDevice(pegInfo.eventFd);  */
  281.         break;
  282.     case DEVICE_CLOSE: 
  283.         break;
  284.     }
  285.     return Success;
  286. }
  287.  
  288. static void
  289. pegChangeKeyboardControl(pDevice, ctrl)
  290.     DevicePtr pDevice;
  291.     KeybdCtrl *ctrl;
  292. {
  293.     /* ctrl->click: not possible */
  294.  
  295.     /* ctrl->bell: the DIX layer handles the base volume for the bell */
  296.  
  297.     /* ctrl->bell_pitch: can't set now */
  298.  
  299.     /* ctrl->bell_duration: as far as I can tell, you can't set this  */
  300.  
  301.     /* ctrl->leds: We have only one LED, but it is owned by ddx... */
  302.  
  303.     /* ctrl->autoRepeat: We need do nothing here... dix maintains this */
  304.  
  305.     /* ctrl->autoRepeats: Force on the joypad, if necessary */
  306.     if (pegInfo.kv.panEnabled) {
  307.     MakeRawKeyRepeatable(KBJoyLeft);
  308.     MakeRawKeyRepeatable(KBJoyRight);
  309.     MakeRawKeyRepeatable(KBJoyUp);
  310.     MakeRawKeyRepeatable(KBJoyDown);
  311.     }
  312. }
  313.  
  314.  
  315. /*
  316.  *    NAME
  317.  *        setXTLBellVolume - Set bell volume on XTL Keyboard
  318.  *
  319.  *    SYNOPSIS
  320.  */
  321. static void
  322. setXTLBellVolume(volume)
  323.     int volume;        /* in: volume (0-100)        */
  324. /*
  325.  *    DESCRIPTION
  326.  *        This routines sets the bell volume level on the XTL
  327.  *        Keyboard.
  328.  *
  329.  *    RETURNS
  330.  *        None
  331.  */
  332. {
  333.     assert(volume >= 0 && volume <= 100);
  334.  
  335.     if (pegInfo.bells.fd < 0) {
  336.     /*
  337.      * Unable to open /dev/bell
  338.      */
  339.     return;
  340.     }
  341.  
  342.     /*
  343.      * XTL keyboard has only 3 distinct bell volumes.
  344.      * Volume is a value between 0 and 100 with 100 being loudest.
  345.      */
  346.     if ( volume < 34 ) {
  347.     /*
  348.      * Make ioctl() call to /dev/bell to set bell volume to SOFT
  349.      */
  350.     if (ioctl(pegInfo.bells.fd, BELL_KEYBD_BELL_ON_SOFT, (char*)0) == -1) {
  351. #ifdef XDEBUG
  352.         ErrorF("ioctl() returns error %d for BELL_KEYBD_BELL_ON_SOFT\n",
  353.             errno);
  354. #endif /* XDEBUG */
  355.     }
  356.     } else if (volume < 68 ) {
  357.     /*
  358.      * Make ioctl() call to /dev/bell to set bell volume to MEDIUM
  359.      */
  360.     if (ioctl(pegInfo.bells.fd, BELL_KEYBD_BELL_ON_MED, (char*)0) == -1) {
  361. #ifdef XDEBUG
  362.         ErrorF("ioctl() returns error %d for BELL_KEYBD_BELL_ON_MED\n",
  363.             errno);
  364. #endif /* XDEBUG */
  365.     }
  366.     } else {
  367.     /*
  368.      * Make ioctl() call to /dev/bell to set bell volume to LOUD
  369.      */
  370.     if (ioctl(pegInfo.bells.fd, BELL_KEYBD_BELL_ON_LOUD, (char*)0) == -1) {
  371. #ifdef XDEBUG
  372.         ErrorF("ioctl() returns error %d for BELL_KEYBD_BELL_ON_LOUD\n",
  373.             errno);
  374. #endif /* XDEBUG */
  375.     }
  376.     }
  377. }
  378.  
  379.  
  380.  
  381. /*
  382.  *    NAME
  383.  *        xtlChangeKeyboardControl - Changes Keyboard Controls
  384.  *            for XTL keyboard
  385.  *
  386.  *    SYNOPSIS
  387.  */
  388. static void
  389. xtlChangeKeyboardControl(pDevice, pKbCtrl)
  390.     DevicePtr pDevice;    /* in: pointer to keyboard device    */
  391.     KeybdCtrl *pKbCtrl;    /* in: pointer to kb control structure    */
  392. /*
  393.  *    DESCRIPTION
  394.  *        Changes keyboard control as specified in the KeybdCtrl
  395.  *        structure (i.e., autorepeat, keyclick volume, bell
  396.  *        volume, bell duration, LEDs.
  397.  *
  398.  *    RETURNS
  399.  *        None
  400.  *
  401.  */
  402. {
  403.     int lbval = 0;    /* low-byte value for bell duration ioctl */
  404.  
  405.     /*
  406.      * pKbCtrl->autoRepeat: We need do nothing here... dix maintains this
  407.      */
  408.  
  409.     /*
  410.      * pKbCtrl->autoRepeats: Force on the joypad, if necessary
  411.      */
  412.     if (pegInfo.kv.panEnabled) {
  413.     MakeRawKeyRepeatable(KEY_Cursor_R);
  414.     MakeRawKeyRepeatable(KEY_Cursor_U);
  415.     MakeRawKeyRepeatable(KEY_Cursor_L);
  416.     MakeRawKeyRepeatable(KEY_Cursor_D);
  417.     }
  418.  
  419.     /*
  420.      * pKbCtrl->click:
  421.      */
  422.     if (pegInfo.bells.fd > 0 && 0 <= pKbCtrl->click && pKbCtrl->click <= 100) {
  423.     if (pKbCtrl->click == 0) {
  424.         /*
  425.          * Make ioctl() call to /dev/bell to:
  426.          *      Turn KeyClick OFF
  427.          */
  428.         if (ioctl(pegInfo.bells.fd, BELL_KEYBD_CLICK_OFF, (char*)0) == -1) {
  429. #ifdef XDEBUG
  430.         ErrorF("ioctl() returns error %d for BELL_KEYBD_CLICK_OFF\n",
  431.             errno);
  432. #endif /* XDEBUG */
  433.         }
  434.     } else if (pKbCtrl->click < 34) {
  435.         /*
  436.          * Make ioctl() call to /dev/bell to:
  437.          *      Set KeyClick volume to SOFT
  438.          */
  439.         if (ioctl(pegInfo.bells.fd, BELL_KEYBD_CLICK_ON_SOFT, (char*)0)
  440.         == -1) {
  441. #ifdef XDEBUG
  442.         ErrorF("ioctl() returns error %d for BELL_KEYBD_CLICK_ON_SOFT\n",
  443.             errno);
  444. #endif /* XDEBUG */
  445.         }
  446.     } else if (pKbCtrl->click < 68) {
  447.         /*
  448.          * Make ioctl() call to /dev/bell to:
  449.          *      Set KeyClick volume to MEDIUM
  450.          */
  451.         if (ioctl(pegInfo.bells.fd, BELL_KEYBD_CLICK_ON_MED, (char*)0)
  452.         == -1) {
  453. #ifdef XDEBUG
  454.         ErrorF("ioctl() returns error %d for BELL_KEYBD_CLICK_ON_MED\n",
  455.             errno);
  456. #endif /* XDEBUG */
  457.         }
  458.     } else if (pKbCtrl->click <= 100) {
  459.         /*
  460.          * Make ioctl() call to /dev/bell to:
  461.          *      Set KeyClick volume to LOUD
  462.          */
  463.         if (ioctl(pegInfo.bells.fd, BELL_KEYBD_CLICK_ON_LOUD, (char*)0)
  464.         == -1) {
  465. #ifdef XDEBUG
  466.         ErrorF("ioctl() returns error %d for BELL_KEYBD_CLICK_ON_LOUD\n",
  467.             errno);
  468. #endif /* XDEBUG */
  469.         }
  470.     }
  471.     }
  472.  
  473.     /*
  474.      * pKbCtrl->bell:
  475.      *    The DIX layer handles the base volume for the bell, however, ...
  476.      *  the DIX stored base volume level is applied only with a call
  477.      *  to xtlBell().  Ringing of the bell through any other means
  478.      *  (e.g., echo "^G") would result in a volume as set by the
  479.      *  last xtlBell() call.  Therefore, we set the base volume here!
  480.      */
  481.     setXTLBellVolume(pKbCtrl->bell);
  482.  
  483.     /*
  484.      * pKbCtrl->bell_pitch:
  485.      *    not possible on XTL keyboard.
  486.      */
  487.  
  488.     /*
  489.      * pKbCtrl->bell_duration:
  490.      *
  491.      * The Kernel stores the bell duration that is set via ioctl().
  492.      *
  493.      * For the XTL keyboard, the duration (pKbCtrl->bell_duration) is
  494.      * established by the low-order byte (lbval) of the "RING BELL" command
  495.      * (4X hex) and equals the decimal value of lbval times 40 milliseconds
  496.      * (pKbCtrl->bell_duration=lbval*40 msec).
  497.      * If the bell_duration >= 0 then convert to an lbval.
  498.      * Note that if duration <= 0 then the command 40 (Key Click 2.5 msec) will
  499.      * be executed.
  500.      */
  501.  
  502.     if (pegInfo.bells.fd > 0) {
  503.         /*
  504.          * Was able to open /dev/xdev
  505.          */
  506.     if (pKbCtrl->bell_duration > (0xf * 40)) {
  507.         lbval = 0xf;
  508.     } else if (pKbCtrl->bell_duration > 0) {
  509.         lbval = (int)(pKbCtrl->bell_duration/40) & 0xf;
  510.     }
  511.     if (ioctl(pegInfo.bells.fd, BELL_KEYBD_BELL_DURATION_SET,
  512.       (char *)(&lbval)) == -1 ) {
  513. #ifdef XDEBUG
  514.         ErrorF("ioctl() returns error %d for BELL_KEYBD_BELL_DURATION_SET\n",
  515.         errno);
  516. #endif /* XDEBUG */
  517.     }
  518.     }
  519.  
  520.     /*
  521.      * pKbCtrl->leds:
  522.      *
  523.      * The XTL keyboard has 3 LEDs that are worth manipulating;  these are
  524.      *     name         X LED #
  525.      *     ----------   -------
  526.      *     Hold Screen = LED 1
  527.      *     Compose     = LED 2
  528.      *     Wait        = LED 3
  529.      *     Tek         = LED 4
  530.      *     Xmt         = LED 5
  531.      *     Rcv         = LED 6
  532.      * The Lock LED is reserved to be used by the system to indicate when the
  533.      * Lock key is considered on.
  534.      */
  535.  
  536.     if (pegInfo.eventFd > 0) {
  537.         /*
  538.          * Was able to open /dev/xdev
  539.          */
  540.  
  541.     /*
  542.      * HOLD SCREEN
  543.      */
  544.  
  545.     if (pKbCtrl->leds & 0x1) {
  546.         if (ioctl(pegInfo.eventFd, KEYBD_HOLD_LED_ON, (char*)0) == -1) {
  547. #ifdef XDEBUG
  548.         ErrorF("ioctl() returns error %d for KEYBD_HOLD_LED_ON\n", errno);
  549. #endif /* XDEBUG */
  550.         }
  551.     } else {
  552.         if (ioctl(pegInfo.eventFd, KEYBD_HOLD_LED_OFF, (char*)0) == -1) {
  553. #ifdef XDEBUG
  554.         ErrorF("ioctl() returns error %d for KEYBD_HOLD_LED_OFF\n", errno);
  555. #endif /* XDEBUG */
  556.         }
  557.     }
  558.  
  559.     /*
  560.      * COMPOSE
  561.      */
  562.      if (pKbCtrl->leds & 0x2) {
  563.         if (ioctl(pegInfo.eventFd, KEYBD_COMPOSE_LED_ON, (char*)0) == -1) {
  564. #ifdef XDEBUG
  565.         ErrorF("ioctl() returns error %d for KEYBD_COMPOSE_LED_ON\n", errno);
  566. #endif /* XDEBUG */
  567.         }
  568.      } else {
  569.         if (ioctl(pegInfo.eventFd, KEYBD_COMPOSE_LED_OFF, (char*)0) == -1) {
  570. #ifdef XDEBUG
  571.         ErrorF("ioctl() returns error %d for KEYBD_COMPOSE_LED_OFF\n", errno);
  572. #endif /* XDEBUG */
  573.         }
  574.      }
  575.  
  576.      /*
  577.       * WAIT
  578.       */
  579.      if (pKbCtrl->leds & 0x4) {
  580.         if (ioctl(pegInfo.eventFd, KEYBD_WAIT_LED_ON, (char*)0) == -1) {
  581. #ifdef XDEBUG
  582.         ErrorF("ioctl() returns error %d for KEYBD_WAIT_LED_ON\n", errno);
  583. #endif /* XDEBUG */
  584.         }
  585.      } else {
  586.         if (ioctl(pegInfo.eventFd, KEYBD_WAIT_LED_OFF, (char*)0)) {
  587. #ifdef XDEBUG
  588.         ErrorF("ioctl() returns error %d for KEYBD_WAIT_LED_OFF\n", errno);
  589. #endif /* XDEBUG */
  590.         }
  591.      }
  592.  
  593.     /*
  594.      * TEK
  595.      */
  596.      if (pKbCtrl->leds & 0x8) {
  597.         if (ioctl(pegInfo.eventFd, KEYBD_TEK_LED_ON, (char*)0) == -1) {
  598. #ifdef XDEBUG
  599.         ErrorF("ioctl() returns error %d for KEYBD_TEK_LED_ON\n", errno);
  600. #endif /* XDEBUG */
  601.         }
  602.      } else {
  603.         if (ioctl(pegInfo.eventFd, KEYBD_TEK_LED_OFF, (char*)0) == -1) {
  604. #ifdef XDEBUG
  605.         ErrorF("ioctl() returns error %d for KEYBD_TEK_LED_OFF\n", errno);
  606. #endif /* XDEBUG */
  607.         }
  608.      }
  609.  
  610.     /*
  611.      * XMT
  612.      */
  613.      if (pKbCtrl->leds & 0x10) {
  614.         if (ioctl(pegInfo.eventFd, KEYBD_XMT_LED_ON, (char*)0) == -1) {
  615. #ifdef XDEBUG
  616.         ErrorF("ioctl() returns error %d for KEYBD_XMT_LED_ON\n", errno);
  617. #endif /* XDEBUG */
  618.         }
  619.      } else {
  620.         if (ioctl(pegInfo.eventFd, KEYBD_XMT_LED_OFF, (char*)0) == -1) {
  621. #ifdef XDEBUG
  622.         ErrorF("ioctl() returns error %d for KEYBD_XMT_LED_OFF\n", errno);
  623. #endif /* XDEBUG */
  624.         }
  625.      }
  626.  
  627.     /*
  628.      * RCV
  629.      */
  630.      if (pKbCtrl->leds & 0x20) {
  631.         if (ioctl(pegInfo.eventFd, KEYBD_RCV_LED_ON, (char*)0) == -1) {
  632. #ifdef XDEBUG
  633.         ErrorF("ioctl() returns error %d for KEYBD_RCV_LED_ON\n", errno);
  634. #endif /* XDEBUG */
  635.  
  636.         }
  637.      } else {
  638.         if (ioctl(pegInfo.eventFd, KEYBD_RCV_LED_OFF, (char*)0) == -1) {
  639. #ifdef XDEBUG
  640.         ErrorF("ioctl() returns error %d for KEYBD_RCV_LED_OFF\n", errno);
  641. #endif /* XDEBUG */
  642.         }
  643.      }
  644.     }
  645. }
  646.  
  647. static void
  648. pegBell(loud, pDevice)
  649.     int loud;
  650.     DevicePtr pDevice;
  651. {
  652.     int i;
  653.  
  654.     assert(loud >= 0 && loud <= 100);
  655.  
  656.     /*
  657.      * We have only 8 distinct bell volumes, named 0-7
  658.      */
  659.     i = loud / 14;
  660.  
  661.     if (pegInfo.bells.fd > 0 && pegInfo.bells.len[ i ])
  662.     write(pegInfo.bells.fd,
  663.         pegInfo.bells.str[ i ],
  664.         pegInfo.bells.len[ i ]);
  665. }
  666.  
  667. /*
  668.  *    NAME
  669.  *        xtlBell - ring bell on XTL Keyboard
  670.  *
  671.  *    SYNOPSIS
  672.  */
  673. static void
  674. xtlBell(volume, pDevice)
  675.     int volume;        /* in: volume (0-100)        */
  676.     DevicePtr pDevice;    /* in: ptr to keyboard device    */
  677. /*
  678.  *    DESCRIPTION
  679.  *        This routines sets the bell volume level then rings
  680.  *        the bell.  DIX has already applied the base volume
  681.  *        level to the client requested adjustment level.
  682.  *
  683.  *    RETURNS
  684.  *        None
  685.  */
  686. {
  687.     assert(volume >= 0 && volume <= 100);
  688.  
  689.     if (pegInfo.bells.fd < 0) {
  690.         /*
  691.          * Unable to open /dev/bell
  692.          */
  693.         return;
  694.     }
  695.  
  696.     /*
  697.      * Set the XTL keyboard volume before ringing bell.
  698.      */
  699.     setXTLBellVolume(volume);
  700.  
  701.     /*
  702.      * Finally, RING THE BELL!!
  703.      */
  704.     write(pegInfo.bells.fd, "", 0);
  705.  
  706.     /*
  707.      * Reset the XTL keyboard volume to base volume.
  708.      */
  709.     volume = ((DeviceIntPtr)pDevice)->kbdfeed->ctrl.bell;
  710.     setXTLBellVolume(volume);
  711. }
  712.  
  713. static void
  714. pegChangePointerControl(pDevice, ctrl)
  715.     DevicePtr pDevice;
  716.     PtrCtrl   *ctrl;
  717. {
  718.     SvcCursorSpeed new;
  719.     int acceleration;
  720.  
  721.     if (!(new.multiplier = ctrl->num / ctrl->den))
  722.     new.multiplier = 1;    /* watch for den > num */
  723.     new.threshold = ctrl->threshold;
  724.     new.divisor = 1;
  725.     if (SetCursorSpeed(&new) < 0)
  726.     Error("SetCursorSpeed");
  727. }
  728.  
  729.     
  730. Bool
  731. pegSetCursorPosition( pScr, newx, newy, generateEvent)
  732.     ScreenPtr    pScr;
  733.     int        newx;
  734.     int        newy;
  735.     Bool    generateEvent;
  736. {
  737.     xEvent    motion;
  738.     int        xlimit, ylimit;
  739.     SvcCursorXY new;
  740.     static Bool    firstTime = True;
  741.  
  742.     if (firstTime) {
  743. #ifdef    UTEK
  744.     if (CPU_BOARD(pegInfo.softp) == HC_CPU_4405PLUS) {
  745.         debug4(("first-time cursor position shifted from (%d,%d) to ",
  746.         newx, newy));
  747.         newx = SCREEN_X(pegInfo.softp) / 2;
  748.         newy = SCREEN_Y(pegInfo.softp) / 2;
  749.     }
  750. #endif    /* UTEK */
  751.     firstTime = False;
  752.     }
  753.     xlimit = pegInfo.scrWidth-1;
  754.     ylimit = pegInfo.scrHeight-1;
  755.     new.x = newx;
  756.     new.y = newy;
  757.  
  758.     /*
  759.      * Insure the position is still visible
  760.      */
  761.     if (new.x < 0)
  762.     new.x = 0;
  763.     else if (new.x > xlimit)
  764.     new.x = xlimit;
  765.  
  766.     if (new.y < 0)
  767.     new.y = 0;
  768.     else if (new.y > ylimit)
  769.     new.y = ylimit;
  770.  
  771.     debug4(("SetCursorPosition(%d,%d)-->(%d,%d), %sgenerate an event\n",
  772.     newx, newy, new.x, new.y, generateEvent ? "" : "don't"));
  773. #ifdef  XTESTEXT1
  774.     LastMousePosition.x = new.x;
  775.     LastMousePosition.y = new.y;
  776. #endif  /* XTESTEXT1 */
  777.     /*
  778.      * Use ioctl to move cursor without causing an event to get
  779.      * generated.  If this OS does not have this ioctl, just use
  780.      * SetCursorPoint which may or may not actually generate an event
  781.      */
  782.     if (ioctl(pegInfo.eventFd, CE_NEW_MOUSE_POSITION_NO_EVT,
  783.          (char *)(&new)) == -1) {
  784.  
  785.     if (SetCursorPoint(&new) < 0)
  786.         Error("SetCursorPoint");
  787.     }
  788.     /*
  789.      * XXX - these don't get updated 'till the next vertical sync, so
  790.      * we could force them here.  But we don't because that suppresses an
  791.      * event being generated (very useful because of the 4405 hack above).
  792.      *
  793.      * pegInfo.dsp->ds_x = new.x;
  794.      * pegInfo.dsp->ds_y = new.y;
  795.      */
  796.  
  797.     if (generateEvent)
  798.     {
  799.     if (pegInfo.queue->head != pegInfo.queue->tail)
  800.         ProcessInputEvents();
  801.     motion.u.keyButtonPointer.rootX = newx;
  802.     motion.u.keyButtonPointer.rootY = newy;
  803.     motion.u.keyButtonPointer.time = pegInfo.lastEventTime;
  804.     motion.u.u.type = MotionNotify;
  805.     (*pegInfo.pPointer->processInputProc) (&motion, pegInfo.pPointer, 1);
  806.     }
  807.  
  808.     return TRUE;
  809. }
  810.  
  811. /*
  812.  *    NAME
  813.  *        pegRecolorCursor - Change cursor color
  814.  *
  815.  *    SYNOPSIS
  816.  */
  817. void
  818. pegRecolorCursor( pScr, pCurs, displayed)
  819.     ScreenPtr   pScr;
  820.     CursorPtr   pCurs;
  821.     Bool        displayed;    /* TRUE if this cursor is currently displayed */
  822. /*
  823.  *    DESCRIPTION
  824.  *        Dix is telling us that the colors in the pCurs structure
  825.  *        have changed.  Since we are not storing color info in the
  826.  *        devPrivate field of pCurs we do not need to update that
  827.  *        structure.  We must change the color of the current
  828.  *        cursor if parameter "displayed" is TRUE.
  829.  *
  830.  *    RETURNS
  831.  *        None
  832.  *
  833.  */
  834. {
  835.     /*
  836.      * Calling DisplayCursor does a little more work than is necessary but
  837.      * makes the process simpler to code.  All we really need to do is call
  838.      * SetCursorColor.
  839.      */
  840.     if (displayed)
  841.     (* pScr->DisplayCursor)( pScr, pCurs);
  842.  
  843. }
  844.  
  845. Bool
  846. pegDisplayCursor(pScr, pCurs)
  847.     ScreenPtr    pScr;
  848.     CursorPtr    pCurs;
  849. {
  850.     SvcCursorFormPtr    new;
  851.     SvcCursorColor    colors;
  852.  
  853. #ifdef XDEBUG
  854.     if (xflg_debug & 0x10) {
  855.     x_debug("DisplayCursor %dX%d, hot=(%d,%d)\n",
  856.         pCurs->width, pCurs->height,
  857.         pCurs->xhot, pCurs->yhot);
  858.     x_debug("cursor colors=<%x %x %x><%x %x %x>\n",
  859.         pCurs->foreRed,
  860.         pCurs->foreGreen,
  861.         pCurs->foreBlue,
  862.         pCurs->backRed,
  863.         pCurs->backGreen,
  864.         pCurs->backBlue);
  865.     }
  866. #endif /* XDEBUG */
  867.  
  868.     if (pegInfo.depth == 1) {
  869.     unsigned short r, g, b;
  870.  
  871.     /*
  872.      * We are assuming here that if depth is one (-mono option or a
  873.      * 4316/4406+), then there is only one visual: the 0th one for the
  874.      * screen.  Otherwise we must call the screen ListInstalledColormaps()
  875.      * and lookup the visual associated with it.
  876.      */
  877.     r = pCurs->foreRed;
  878.     g = pCurs->foreGreen;
  879.     b = pCurs->foreBlue;
  880.     (*pScr->ResolveColor)(&r, &g, &b, &pScr->visuals[0]);
  881.     colors.redFore = r;
  882.     colors.greenFore = g;
  883.     colors.blueFore = b;
  884.  
  885.     r = pCurs->backRed;
  886.     g = pCurs->backGreen;
  887.     b = pCurs->backBlue;
  888.     (*pScr->ResolveColor)(&r, &g, &b, &pScr->visuals[0]);
  889.     colors.redBack = r;
  890.     colors.greenBack = g;
  891.     colors.blueBack = b;
  892.     } else {
  893. #ifdef NOTDEF
  894.     if (!FGammaCorrectionDisabled) {
  895.         DisplayLookUpGammaCorrectedColor(
  896.             (unsigned short) pCurs->foreRed,
  897.             (unsigned short) pCurs->foreGreen,
  898.             (unsigned short) pCurs->foreBlue,
  899.             &colors.redFore,
  900.             &colors.greenFore,
  901.             &colors.blueFore);
  902.         DisplayLookUpGammaCorrectedColor(
  903.             (unsigned short) pCurs->backRed,
  904.             (unsigned short) pCurs->backGreen,
  905.             (unsigned short) pCurs->backBlue,
  906.             &colors.redBack,
  907.             &colors.greenBack,
  908.             &colors.blueBack);
  909.     }
  910.      else
  911. #endif
  912.      {
  913.         colors.redFore   = (short) pCurs->foreRed;
  914.         colors.greenFore = (short) pCurs->foreGreen;
  915.         colors.blueFore  = (short) pCurs->foreBlue;
  916.         colors.redBack   = (short) pCurs->backRed;
  917.         colors.greenBack = (short) pCurs->backGreen;
  918.         colors.blueBack  = (short) pCurs->backBlue;
  919.     }
  920.     }
  921.     if (SetCursorColor(&colors) < 0)
  922.     Error("SetCursorColor");
  923.  
  924.     /*
  925.      * load the cursor
  926.      */
  927.     new = (SvcCursorFormPtr) pCurs->devPriv[pScr->myNum];
  928.     new->xoff = pCurs->bits->xhot;
  929.     new->yoff = pCurs->bits->yhot;
  930.     if (SetCursorSourceAndMask(new))
  931.     Error("SetCursorSourceAndMask");
  932. }
  933.  
  934. void
  935. pegPointerNonInterestBox( pScr, pBox)
  936.     ScreenPtr    pScr;
  937.     BoxPtr    pBox;
  938. {
  939.  
  940.     debug5(("PointerNonInterestBox: Box = x1 %d y1 %d x2 %d y2 %d\n",
  941.     pBox->x1, pBox->y1, pBox->x2, pBox->y2));
  942.     pegInfo.dsp->ds_box.bottom = pBox->y2;
  943.     pegInfo.dsp->ds_box.top = pBox->y1;
  944.     pegInfo.dsp->ds_box.left = pBox->x1;
  945.     pegInfo.dsp->ds_box.right = pBox->x2;
  946. }
  947.  
  948. void
  949. pegConstrainCursor( pScr, pBox)
  950.     ScreenPtr    pScr;
  951.     BoxPtr    pBox;
  952. {
  953.     SvcCursorXY    upperLeft, lowerRight;
  954.  
  955.     debug4(("ConstrainCursor(0x%x)@(%d,%d),(%d,%d)\n", pScr,
  956.     pBox->x1, pBox->y1, pBox->x2, pBox->y2));
  957.  
  958.     pegInfo.constraintBox = *pBox;
  959. #ifdef XPEG_TANDEM
  960.     if (!pegTandem)
  961. #endif /* XPEG_TANDEM */
  962.     {
  963.     upperLeft.x = pBox->x1;
  964.     upperLeft.y = pBox->y1;
  965.     lowerRight.x = pBox->x2;
  966.     lowerRight.y = pBox->y2;
  967.     SetCursorBounds(&upperLeft, &lowerRight);
  968.     }
  969. }
  970.  
  971. void
  972. pegCursorLimits( pScr, pCurs, pHotBox, pTopLeftBox)
  973.     ScreenPtr    pScr;
  974.     CursorPtr    pCurs;
  975.     BoxPtr    pHotBox;
  976.     BoxPtr    pTopLeftBox;    /* return value */
  977. {
  978.     pTopLeftBox->x1 = max( pHotBox->x1, 0);
  979.     pTopLeftBox->y1 = max( pHotBox->y1, 0);
  980.     pTopLeftBox->x2 = min( pHotBox->x2, pegInfo.width);
  981.     pTopLeftBox->y2 = min( pHotBox->y2, pegInfo.height);
  982. }
  983.  
  984. /*
  985.  * Copy data in (pegasus) bitmap format to fill a 64 x 64 bitmap.
  986.  * Pad with zeros.
  987.  */
  988. static void
  989. CopyCursorImage(src, dest, width, height)
  990.     long *src, *dest;
  991.     int width, height;
  992. {
  993.     int x, y;
  994.     long edgeMask;
  995.  
  996.     /*
  997.      * We know pegasus bitmaps have four bytes per scanline if width <= 32,
  998.      * eight bytes per scanline if 32 < width <= SvcCursorSize (64).
  999.      * Set all unused bits to zero, only mask when needed.
  1000.      */
  1001.     if (width < 32) {
  1002.     edgeMask = 0xffffffff << (32 - width);
  1003.     for (y = 0; y < height; y++) {
  1004.         *dest++ = src[y] & edgeMask;
  1005.         *dest++ = 0;
  1006.     }
  1007.     } else if (width == 32) {
  1008.     for (y = 0; y < height; y++) {
  1009.         *dest++ = src[y];
  1010.         *dest++ = 0;
  1011.     }
  1012.     } else if (width < SvcCursorSize) {
  1013.     edgeMask = 0xffffffff << (SvcCursorSize - width);
  1014.     for (y = 0; y < 2 * height; y += 2) {
  1015.         *dest++ = src[y];
  1016.         *dest++ = src[y+1] & edgeMask;
  1017.     }
  1018.     } else {
  1019.     for (y = 0; y < 2 * height; y += 2) {
  1020.         *dest++ = src[y];
  1021.         *dest++ = src[y+1];
  1022.     }
  1023.     }
  1024.     /* zero the remaining lines */
  1025.     for (y = height; y < SvcCursorSize; y++) {
  1026.     *dest++ = 0;
  1027.     *dest++ = 0;
  1028.     }
  1029. }
  1030.  
  1031. Bool
  1032. pegRealizeCursor( pScr, pCurs)
  1033.     ScreenPtr pScr;
  1034.     CursorPtr    pCurs;    /* a SERVER-DEPENDENT cursor */
  1035. {
  1036.     SvcCursorForm    *data;
  1037.  
  1038.     data = (SvcCursorForm *)Xalloc(sizeof(SvcCursorForm));
  1039.     if (!data)
  1040.     return(FALSE);
  1041.  
  1042.     if (pCurs->bits->height < SvcCursorSize
  1043.      || pCurs->bits->width < SvcCursorSize) {
  1044.     data->src = (unsigned long *)Xalloc(SvcCursorDataSize * sizeof(long));
  1045.     data->mask = (unsigned long *)Xalloc(SvcCursorDataSize * sizeof(long));
  1046.     if (!data->src || !data->mask)
  1047.         return(FALSE);
  1048.     CopyCursorImage((long *)pCurs->bits->source, data->src,
  1049.         pCurs->bits->width, pCurs->bits->height);
  1050.     CopyCursorImage((long *)pCurs->bits->mask, data->mask,
  1051.         pCurs->bits->width, pCurs->bits->height);
  1052.     } else {
  1053.     data->src = (unsigned long *)pCurs->bits->source;
  1054.     data->mask = (unsigned long *)pCurs->bits->mask;
  1055.     }
  1056.  
  1057.     pCurs->devPriv[pScr->myNum] = (pointer)data;
  1058.  
  1059.     return(TRUE);  /* Failure can happen only in Xalloc() */
  1060. }
  1061.  
  1062. Bool
  1063. pegUnrealizeCursor( pScr, pCurs)
  1064.     ScreenPtr    pScr;
  1065.     CursorPtr    pCurs;
  1066. {
  1067.     SvcCursorForm    *data = (SvcCursorForm *)pCurs->devPriv[pScr->myNum];
  1068.  
  1069.     if (data->src != (unsigned long *)pCurs->bits->source) {
  1070.     Xfree(data->src);
  1071.     Xfree(data->mask);
  1072.     }
  1073.     Xfree(data);
  1074.  
  1075.     return(TRUE);
  1076. }
  1077.  
  1078. /*
  1079.  *    NAME
  1080.  *        pegQueryBestSize - return best sizes for cursor and patterns
  1081.  *
  1082.  *    SYNOPSIS
  1083.  */
  1084. void
  1085. pegQueryBestSize(class, pwidth, pheight)
  1086.     int class;        /* in: CursorShape, TileShape, or StippleShape */
  1087.     short *pwidth;    /* in/out: width */
  1088.     short *pheight;    /* in/out: height */
  1089. /*
  1090.  *    DESCRIPTION
  1091.  *        Return best sizes for cursors, tiles, and stiples in
  1092.  *        response to client requests.  For CursorShape, return
  1093.  *        the maximum width and height for cursors that we can
  1094.  *        handle.  For TileShape and StippleShape, start with the
  1095.  *        suggested values in *pwidth and  *pheight and modify them
  1096.  *        in place to be optimal values that are greater than or
  1097.  *        equal to the suggested values.
  1098.  *
  1099.  *    RETURNS
  1100.  *        None
  1101.  *
  1102.  */
  1103. {
  1104.  
  1105.     switch(class) {
  1106.     case CursorShape:
  1107.     *pwidth = SvcCursorSize;
  1108.     *pheight = SvcCursorSize;
  1109.     break;
  1110.  
  1111.     /*
  1112.      * Return nearest, multiple of 32 not less than width
  1113.      * Do nothing for height
  1114.      */
  1115.     case TileShape:
  1116.     case StippleShape:
  1117.     if (*pwidth <= 32)
  1118.         *pwidth = 32;
  1119.     else
  1120.         *pwidth = (*pwidth + 31) & ~0x1f;
  1121.  
  1122.         /* We don't care what height they use */
  1123.         break;
  1124.     }
  1125. }
  1126.