home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / macII / macIIKbd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-02  |  14.7 KB  |  581 lines

  1. /************************************************************ 
  2. Copyright 1988 by Apple Computer, Inc, Cupertino, California
  3.             All Rights Reserved
  4.  
  5. Permission to use, copy, modify, and distribute this software
  6. for any purpose and without fee is hereby granted, provided
  7. that the above copyright notice appear in all copies.
  8.  
  9. APPLE MAKES NO WARRANTY OR REPRESENTATION, EITHER EXPRESS,
  10. OR IMPLIED, WITH RESPECT TO THIS SOFTWARE, ITS QUALITY,
  11. PERFORMANCE, MERCHANABILITY, OR FITNESS FOR A PARTICULAR
  12. PURPOSE. AS A RESULT, THIS SOFTWARE IS PROVIDED "AS IS,"
  13. AND YOU THE USER ARE ASSUMING THE ENTIRE RISK AS TO ITS
  14. QUALITY AND PERFORMANCE. IN NO EVENT WILL APPLE BE LIABLE 
  15. FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  16. DAMAGES RESULTING FROM ANY DEFECT IN THE SOFTWARE.
  17.  
  18. THE WARRANTY AND REMEDIES SET FORTH ABOVE ARE EXCLUSIVE
  19. AND IN LIEU OF ALL OTHERS, ORAL OR WRITTEN, EXPRESS OR
  20. IMPLIED.
  21.  
  22. ************************************************************/
  23. /*-
  24.  * macIIKbd.c --
  25.  *    Functions for retrieving data from a keyboard.
  26.  *
  27.  * Copyright (c) 1987 by the Regents of the University of California
  28.  *
  29.  * Permission to use, copy, modify, and distribute this
  30.  * software and its documentation for any purpose and without
  31.  * fee is hereby granted, provided that the above copyright
  32.  * notice appear in all copies.  The University of California
  33.  * makes no representations about the suitability of this
  34.  * software for any purpose.  It is provided "as is" without
  35.  * express or implied warranty.
  36.  *
  37.  */
  38.  
  39. /************************************************************
  40. Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
  41.  
  42.                     All Rights Reserved
  43.  
  44. Permission  to  use,  copy,  modify,  and  distribute   this
  45. software  and  its documentation for any purpose and without
  46. fee is hereby granted, provided that the above copyright no-
  47. tice  appear  in all copies and that both that copyright no-
  48. tice and this permission notice appear in  supporting  docu-
  49. mentation,  and  that the names of Sun or MIT not be used in
  50. advertising or publicity pertaining to distribution  of  the
  51. software  without specific prior written permission. Sun and
  52. M.I.T. make no representations about the suitability of this
  53. software for any purpose. It is provided "as is" without any
  54. express or implied warranty.
  55.  
  56. SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
  57. INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
  58. NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
  59. ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  60. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
  61. PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
  62. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
  63. THE USE OR PERFORMANCE OF THIS SOFTWARE.
  64.  
  65. ********************************************************/
  66.  
  67.  
  68. #define NEED_EVENTS
  69. #include "macII.h"
  70. #include <stdio.h>
  71. #include "Xproto.h"
  72. #include "inputstr.h"
  73.  
  74. extern CARD8 *macIIModMap[];
  75. extern KeySymsRec macIIKeySyms[];
  76. extern struct timeval lastEventTimeTv;
  77.  
  78. static void       macIIBell();
  79. static void       macIIKbdCtrl();
  80. void             macIIKbdEnqueueEvent();
  81. static int      autoRepeatKeyDown = 0;
  82. static int      autoRepeatReady;
  83. static int      autoRepeatFirst;
  84. static struct timeval autoRepeatLastKeyDownTv;
  85. static struct timeval autoRepeatDeltaTv;
  86. static KeybdCtrl  sysKbCtrl;
  87.  
  88. static KbPrivRec      sysKbPriv = {
  89.     -1,                /* Type of keyboard */
  90.     macIIKbdEnqueueEvent,    /* Function to process an event */
  91.     0,                /* offset for device keycodes */
  92.     &sysKbCtrl,                 /* Initial full duration = .20 sec. */
  93. };
  94.  
  95. extern int consoleFd;
  96. int devosmFd = 0;
  97.  
  98. /*-
  99.  *-----------------------------------------------------------------------
  100.  * macIIKbdProc --
  101.  *    Handle the initialization, etc. of a keyboard.
  102.  *
  103.  * Results:
  104.  *    None.
  105.  *
  106.  * Side Effects:
  107.  *
  108.  * Note:
  109.  *    When using macII, all input comes off a single fd, stored in the
  110.  *    global consoleFd.  Therefore, only one device should be enabled and
  111.  *    disabled, even though the application still sees both mouse and
  112.  *    keyboard.  We have arbitrarily chosen to enable and disable consoleFd
  113.  *    in the keyboard routine macIIKbdProc rather than in macIIMouseProc.
  114.  *
  115.  *-----------------------------------------------------------------------
  116.  */
  117.  
  118. int
  119. macIIKbdProc (pKeyboard, what)
  120.     DevicePtr      pKeyboard;    /* Keyboard to manipulate */
  121.     int              what;            /* What to do to it */
  122. {
  123.     switch (what) {
  124.     case DEVICE_INIT:
  125.         if (pKeyboard != LookupKeyboardDevice()) {
  126.         ErrorF ("Cannot open non-system keyboard. \r\n");
  127.         return (!Success);
  128.         }
  129.         if (consoleFd == 0) {
  130.         if ((consoleFd = open("/dev/console", O_RDWR|O_NDELAY)) < 0) {
  131.             FatalError("Could not open /dev/console. \r\n");
  132.             return (!Success);
  133.         }
  134.             }
  135.         if (devosmFd == 0) {
  136.         if ((devosmFd = open("/dev/osm", O_RDONLY)) < 0) {
  137.             MessageF("Could not open /dev/osm. \r\n");
  138.         }
  139.             }
  140.  
  141.         /*
  142.          * Perform final initialization of the system private keyboard
  143.          * structure and fill in various slots in the device record
  144.          * itself which couldn't be filled in before.
  145.          */
  146.         pKeyboard->devicePrivate = (pointer)&sysKbPriv;
  147.         pKeyboard->on = FALSE;
  148.         sysKbCtrl = defaultKeyboardControl;
  149.         sysKbPriv.ctrl = &sysKbCtrl;
  150.  
  151.         /*
  152.          * ensure that the keycodes on the wire are >= MIN_KEYCODE
  153.          */
  154.  
  155.         sysKbPriv.type = KBTYPE_MACII;  
  156.  
  157.         if (macIIKeySyms[sysKbPriv.type].minKeyCode < MIN_KEYCODE) {
  158.         int offset = MIN_KEYCODE -macIIKeySyms[sysKbPriv.type].minKeyCode;
  159.  
  160.         macIIKeySyms[sysKbPriv.type].minKeyCode += offset;
  161.         macIIKeySyms[sysKbPriv.type].maxKeyCode += offset;
  162.         sysKbPriv.offset = offset;
  163.         }
  164.         InitKeyboardDeviceStruct(
  165.             pKeyboard,
  166.             &(macIIKeySyms[sysKbPriv.type]),
  167.             (macIIModMap[sysKbPriv.type]),
  168.             macIIBell,
  169.             macIIKbdCtrl);
  170.         break;
  171.  
  172.     case DEVICE_ON:
  173.         macIIKbdSetUp(consoleFd, TRUE);
  174.  
  175.         AddEnabledDevice(consoleFd);
  176.  
  177.         pKeyboard->on = TRUE;
  178.         break;
  179.  
  180.     case DEVICE_CLOSE:
  181.         macIIKbdSetUp(consoleFd, FALSE);
  182.  
  183.         RemoveEnabledDevice(consoleFd);
  184.  
  185.         pKeyboard->on = FALSE;
  186.  
  187.         if (devosmFd > 0) close(devosmFd);
  188.         close(consoleFd);
  189.         devosmFd = 0;
  190.         consoleFd = 0;
  191.         break;
  192.  
  193.     case DEVICE_OFF:
  194.         macIIKbdSetUp(consoleFd, FALSE);
  195.  
  196.         RemoveEnabledDevice(consoleFd);
  197.  
  198.         pKeyboard->on = FALSE;
  199.         break;
  200.  
  201.     }
  202.     return (Success);
  203. }
  204.  
  205. #include <sys/termio.h>
  206.  
  207. int
  208. macIIKbdSetUp(fd, openClose)
  209.     int        fd;
  210.     Bool    openClose;
  211. {
  212.     struct strioctl ctl;
  213.     struct termio tio;
  214.     static struct termio save_tio;
  215.     char buff[FMNAMESZ+1];
  216.     int iarg;
  217.  
  218.     if (openClose) {
  219.  
  220.     if (ioctl(fd, TCGETA, &save_tio) < 0) {
  221.         FatalError("Failed to ioctl TCGETA.\r\n");
  222.         return (!Success);
  223.     }
  224.  
  225.     /* 
  226.      * Pop all streams modules off /dev/console. Someday we
  227.      * will remember which ones and restore them on exit.
  228.      */
  229.     errno = 0;
  230.     ioctl(fd, I_LOOK, buff);
  231.     while (errno != EINVAL) {
  232.         if(ioctl(fd, I_POP, 0) < 0) {
  233.             FatalError("Failed to ioctl I_POP %s.\r\n", buff);
  234.             return (!Success);
  235.         }
  236.         ioctl(fd, I_LOOK, buff);
  237.     }
  238.         
  239.     iarg = 1;
  240.     if (ioctl(fd, FIONBIO, &iarg) < 0) {
  241.         FatalError("Could not ioctl FIONBIO. \r\n");
  242.         return (!Success);
  243.     }
  244.  
  245.     iarg = 1;
  246.     if (fcntl (fd, F_SETOWN, getpid()) < 0)
  247.     {
  248.         FatalError("Could not fcntl F_SETOWN \r\n");
  249.         return !Success;
  250.     }
  251.  
  252.     if (ioctl(fd, FIOASYNC, &iarg) < 0) {
  253.         FatalError("Could not ioctl FIOASYNC. \r\n");
  254.         return (!Success);
  255.     }
  256.  
  257.     tio.c_iflag = (IGNPAR|IGNBRK) & (~PARMRK) & (~ISTRIP);
  258.     tio.c_oflag = 0;
  259.     tio.c_cflag = CREAD|CS8|B9600;
  260.     tio.c_lflag = 0;
  261.     if (ioctl(fd, TCSETA, &tio) < 0) {
  262.         FatalError("Failed to ioctl TCSETA.\r\n");
  263.         return (!Success);
  264.     }
  265.  
  266.     ctl.ic_len = 0;
  267.     ctl.ic_cmd = VIDEO_RAW;
  268.     if (ioctl(fd, I_STR, &ctl) < 0) {
  269.         FatalError("Failed to ioctl I_STR VIDEO_RAW.\r\n");
  270.         return(!Success);
  271.     }
  272.  
  273.     ctl.ic_len = 0;
  274.     ctl.ic_cmd = VIDEO_MOUSE;
  275.     if (ioctl(fd, I_STR, &ctl) < 0) {
  276.  
  277. #define MSG "Failed to ioctl I_STR VIDEO_MOUSE.\r\n Run Xrepair and try again.\r\n"
  278.         FatalError(MSG);
  279. #undef MSG
  280.         return(!Success);
  281.     }
  282.  
  283.     if (ioctl(fd, I_FLUSH, FLUSHRW) < 0) {
  284.         FatalError("Failed to ioctl I_FLUSH FLUSHRW.\r\n");
  285.         return (!Success);
  286.     }
  287.  
  288. #ifdef CONS_REDIRECT
  289.     ctl.ic_len = 0;
  290.     ctl.ic_cmd = CONS_REDIRECT;
  291.     if (ioctl(fd, I_STR, &ctl) < 0) {
  292.         /*
  293.          * Not fatal! Convenience for A/UX 1.1 and later.
  294.          */
  295.         MessageF("Unable to ioctl I_STR CONS_REDIRECT.\r\n");
  296.     }
  297. #endif
  298.  
  299.     } else {
  300. #ifdef CONS_UNDIRECT
  301.     ctl.ic_len = 0;
  302.     ctl.ic_cmd = CONS_UNDIRECT;
  303.     if (ioctl(fd, I_STR, &ctl) < 0) {
  304.         MessageF("Failed to ioctl I_STR CONS_UNDIRECT.\r\n");
  305.     }
  306. #endif
  307.  
  308.     iarg = 0;
  309.     if (ioctl(fd, FIONBIO, &iarg) < 0) {
  310.         ErrorF("Could not ioctl FIONBIO. \r\n");
  311.     }
  312.  
  313.     iarg = 0;
  314.     if (ioctl(fd, FIOASYNC, &iarg) < 0) {
  315.         ErrorF("Could not ioctl FIOASYNC. \r\n");
  316.     }
  317.  
  318.     if (ioctl(fd, I_FLUSH, FLUSHRW) < 0) {
  319.         MessageF("Failed to ioctl I_FLUSH FLUSHRW.\r\n");
  320.     }
  321.     
  322.     ctl.ic_len = 0;
  323.     ctl.ic_cmd = VIDEO_NOMOUSE;
  324.     if (ioctl(fd, I_STR, &ctl) < 0) {
  325.         MessageF("Failed to ioctl I_STR VIDEO_NOMOUSE.\r\n");
  326.     }
  327.  
  328. #ifdef VIDEO_MAC
  329.         ctl.ic_len = 0;
  330.         ctl.ic_cmd = VIDEO_MAC; /* For A/UX 2.0 and later */
  331.         if (ioctl(fd, I_STR, &ctl) < 0) {
  332.             ctl.ic_len = 0;
  333.             ctl.ic_cmd = VIDEO_ASCII; /* A/UX 1.* */
  334.             if (ioctl(fd, I_STR, &ctl) < 0) {
  335.         MessageF("Failed to ioctl I_STR VIDEO_MAC VIDEO_ASCII.\r\n");
  336.             }
  337.         }
  338. #else
  339.         ctl.ic_len = 0;
  340.         ctl.ic_cmd = VIDEO_ASCII;
  341.         if (ioctl(fd, I_STR, &ctl) < 0) {
  342.         MessageF("Failed to ioctl I_STR VIDEO_ASCII.\r\n");
  343.         }
  344. #endif
  345.  
  346.     ctl.ic_len = 0;
  347.     ctl.ic_cmd = VIDEO_ASCII;
  348.     if (ioctl(fd, I_STR, &ctl) < 0) {
  349.         MessageF("Failed to ioctl I_STR VIDEO_ASCII.\r\n");
  350.     }
  351.  
  352.     if(ioctl(fd, I_PUSH, "line") < 0) {
  353.         MessageF("Failed to ioctl I_PUSH.\r\n");
  354.     }
  355.  
  356.     if (ioctl(fd, TCSETA, &save_tio) < 0) {
  357.         MessageF("Failed to ioctl TCSETA.\r\n");
  358.     }
  359.     }
  360. }
  361.  
  362. /*-
  363.  *-----------------------------------------------------------------------
  364.  * macIIBell --
  365.  *    Ring the terminal/keyboard bell
  366.  *
  367.  * Results:
  368.  *    Ring the keyboard bell for an amount of time proportional to
  369.  *    "loudness."
  370.  *
  371.  * Side Effects:
  372.  *    None, really...
  373.  *
  374.  *-----------------------------------------------------------------------
  375.  */
  376. static void
  377. macIIBell (loudness, pKeyboard)
  378.     int              loudness;        /* Percentage of full volume */
  379.     DevicePtr      pKeyboard;        /* Keyboard to ring */
  380. {
  381.     KbPrivPtr   pPriv = (KbPrivPtr) pKeyboard->devicePrivate;
  382.     struct strioctl ctl;
  383.     long countdown;
  384.  
  385.     if (loudness == 0) {
  386.       return;
  387.     }
  388.  
  389.     countdown = (long)pPriv->ctrl->bell_duration * 100;
  390.     ctl.ic_len = sizeof(long);
  391.     ctl.ic_dp = (char *)&countdown;
  392.     ctl.ic_cmd = VIDEO_BELL;
  393.     if (ioctl(consoleFd, I_STR, &ctl) < 0) {
  394.         MessageF("Failed to ioctl I_STR VIDEO_BELL.\r\n");
  395.     }
  396. }
  397.  
  398. /*-
  399.  *-----------------------------------------------------------------------
  400.  * macIIKbdCtrl --
  401.  *    Alter some of the keyboard control parameters
  402.  *
  403.  * Results:
  404.  *    None.
  405.  *
  406.  * Side Effects:
  407.  *    Some...
  408.  *
  409.  *-----------------------------------------------------------------------
  410.  */
  411. static void
  412. macIIKbdCtrl (pKeyboard, ctrl)
  413.     DevicePtr      pKeyboard;        /* Keyboard to alter */
  414.     KeybdCtrl     *ctrl;
  415. {
  416.     KbPrivPtr   pPriv = (KbPrivPtr) pKeyboard->devicePrivate;
  417.     *pPriv->ctrl = *ctrl;
  418. }
  419.  
  420.  
  421. /*-
  422.  *-----------------------------------------------------------------------
  423.  * macIIKbdEnqueueEvent
  424.  *    Process macIIevent destined for the keyboard.
  425.  *     
  426.  * Results:
  427.  *
  428.  * Side Effects:
  429.  *
  430.  *-----------------------------------------------------------------------
  431.  */
  432.  
  433. static xEvent    autoRepeatEvent;
  434.  
  435. void
  436. macIIKbdEnqueueEvent(pKeyboard,me)
  437.     DeviceRec *pKeyboard;
  438.     register unsigned char *me;
  439. {   
  440.     xEvent        xE;
  441.     PtrPrivPtr          ptrPriv;
  442.     KbPrivPtr           pPriv;
  443.     int                 delta;
  444.     BYTE        key;
  445.     CARD16              keyModifiers;
  446.  
  447.     ptrPriv = (PtrPrivPtr) LookupPointerDevice()->devicePrivate;
  448.  
  449.     key = KEY_DETAIL(*me) + sysKbPriv.offset;
  450.     if ((keyModifiers = ((DeviceIntPtr)pKeyboard)->key->modifierMap[key]) == 0) {
  451.         /*
  452.          * Kill AutoRepeater on any real Kbd event.
  453.          */
  454.         autoRepeatKeyDown = 0;
  455.     }
  456.  
  457.     xE.u.keyButtonPointer.time = lastEventTime;
  458.     xE.u.u.type = (KEY_UP(*me) ? KeyRelease : KeyPress);
  459.     xE.u.u.detail = key;
  460.  
  461.     if ((xE.u.u.type == KeyPress) && (keyModifiers == 0)) {
  462.       /* initialize new AutoRepeater event & mark AutoRepeater on */
  463.         autoRepeatEvent = xE;
  464.         autoRepeatFirst = TRUE;
  465.         autoRepeatKeyDown++;
  466.         autoRepeatLastKeyDownTv = lastEventTimeTv;
  467.     }
  468.  
  469.     mieqEnqueue (&xE);
  470. }
  471.  
  472. static
  473. macIIEnqueueAutoRepeat ()
  474. {
  475.     int    oldmask;
  476.     int    delta;
  477.  
  478.     if (sysKbPriv.ctrl->autoRepeat != AutoRepeatModeOn) {
  479.     autoRepeatKeyDown = 0;
  480.     return;
  481.     }
  482.     /*
  483.      * Generate auto repeat event.    XXX one for now.
  484.      * Update time & pointer location of saved KeyPress event.
  485.      */
  486.  
  487.     delta = TVTOMILLI(autoRepeatDeltaTv);
  488.     autoRepeatFirst = FALSE;
  489.  
  490.     /*
  491.      * Fake a key up event and a key down event
  492.      * for the last key pressed.
  493.      */
  494.     autoRepeatEvent.u.keyButtonPointer.time += delta;
  495.     autoRepeatEvent.u.u.type = KeyRelease;
  496.     oldmask = sigblock (sigmask(SIGIO));
  497.     mieqEnqueue (&autoRepeatEvent);
  498.     autoRepeatEvent.u.u.type = KeyPress;
  499.     mieqEnqueue (&autoRepeatEvent);
  500.     sigsetmask (oldmask);
  501.     /* Update time of last key down */
  502.     tvplus(autoRepeatLastKeyDownTv, autoRepeatLastKeyDownTv, 
  503.             autoRepeatDeltaTv);
  504.  
  505. }
  506.  
  507. Bool
  508. LegalModifier(key, pDev)
  509.     BYTE    key;
  510.     DevicePtr    pDev;
  511. {
  512.     return (TRUE);
  513. }
  514.  
  515. static KeybdCtrl *pKbdCtrl = (KeybdCtrl *) 0;
  516.  
  517. #include <sys/time.h>
  518. /*ARGSUSED*/
  519. void
  520. macIIBlockHandler(nscreen, pbdata, pptv, pReadmask)
  521.     int nscreen;
  522.     pointer pbdata;
  523.     struct timeval **pptv;
  524.     pointer pReadmask;
  525. {
  526.     static struct timeval artv = { 0, 0 };    /* autorepeat timeval */
  527.  
  528.     if (!autoRepeatKeyDown)
  529.         return;
  530.  
  531.     if (pKbdCtrl == (KeybdCtrl *) 0)
  532.       pKbdCtrl = ((KbPrivPtr) LookupKeyboardDevice()->devicePrivate)->ctrl;
  533.  
  534.     if (pKbdCtrl->autoRepeat != AutoRepeatModeOn)
  535.       return;
  536.  
  537.     if (autoRepeatFirst == TRUE)
  538.         artv.tv_usec = 1000 * AUTOREPEAT_INITIATE;
  539.     else
  540.         artv.tv_usec = 1000 * AUTOREPEAT_DELAY;
  541.     *pptv = &artv;
  542.  
  543. }
  544.  
  545. /*ARGSUSED*/
  546. void
  547. macIIWakeupHandler(nscreen, pbdata, err, pReadmask)
  548.     int nscreen;
  549.     pointer pbdata;
  550.     unsigned long err;
  551.     pointer pReadmask;
  552. {
  553.     long now;
  554.  
  555.     if (pKbdCtrl == (KeybdCtrl *) 0)
  556.       pKbdCtrl = ((KbPrivPtr) LookupKeyboardDevice()->devicePrivate)->ctrl;
  557.     
  558.     if (pKbdCtrl->autoRepeat != AutoRepeatModeOn)
  559.       return;
  560.  
  561.     if (autoRepeatKeyDown) {
  562.     struct timeval tv;
  563.  
  564.     gettimeofday (&tv, (struct timezone *)0);
  565.     tvminus(autoRepeatDeltaTv, tv, autoRepeatLastKeyDownTv);
  566.     if (autoRepeatDeltaTv.tv_sec > 0 ||
  567.             (!autoRepeatFirst && autoRepeatDeltaTv.tv_usec >
  568.                 (AUTOREPEAT_DELAY * 1000)) ||
  569.             (autoRepeatDeltaTv.tv_usec >
  570.                 (AUTOREPEAT_INITIATE * 1000)))
  571.         autoRepeatReady++;
  572.     }
  573.  
  574.     if (autoRepeatReady)
  575.     {
  576.         macIIEnqueueAutoRepeat();
  577.     autoRepeatReady = 0;
  578.     }
  579.  
  580. }
  581.