home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / d / ddx-mips.zip / MIPSKBD.C < prev    next >
C/C++ Source or Header  |  1992-07-15  |  14KB  |  636 lines

  1. /*
  2.  * $XConsortium$
  3.  *
  4.  * Copyright 1991 MIPS Computer Systems, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of MIPS not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  MIPS makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * MIPS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL MIPS
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  */
  23. #ident    "$Header: mipsKbd.c,v 1.13 92/04/06 21:04:16 dd Exp $"
  24.  
  25. #include <sys/types.h>
  26. #include <sys/times.h>
  27. #include <sys/errno.h>
  28. #include <sys/file.h>
  29. #include <sysv/sys/termio.h>
  30. #include <sysv/sys/kbd_ioctl.h>
  31. #include <sysv/sys/buzzer.h>
  32.  
  33. #include "X.h"
  34. #include "keysym.h"
  35. #define  NEED_EVENTS
  36. #include "Xproto.h"
  37. #include "scrnintstr.h"
  38. #include "inputstr.h"
  39.  
  40. #include "mips.h"
  41. #include "mipsIo.h"
  42. #include "mipsKbd.h"
  43. #include "mipsMouse.h"
  44.  
  45. extern int errno;
  46.  
  47. #if PIXIE
  48. extern int    pixie;
  49. #endif /* PIXIE */
  50. extern int    DDXxled1;
  51. extern int    DDXxled2;
  52. extern int    DDXxled3;
  53. static int    keybdLock = 0;    /* Current Lock key state */
  54. static int    keyClick = 0;    /* KeyClick batching flag */
  55.  
  56. KeybdPriv keybdPriv = {
  57.     -1,
  58.     0,
  59.     0,
  60.     DEFAULT_KEYBOARD,
  61. };
  62.  
  63. KeybdType_t keybdType[] = {
  64.     { { xt_KeyMap, 0x01 + 8, 0x65 + 8, 2, },
  65.     xt_ModMap, 8, xtKeybdEvent },
  66.     { { at_KeyMap, 0x01 + 8, 0x84 + 8, 2, },
  67.     at_ModMap, 8, atKeybdEvent },
  68.     { { unix1_KeyMap, 0x07 + 2, 0x84 + 2, 2, },
  69.     unix1_ModMap, 2, unix1KeybdEvent },
  70. };
  71.  
  72. int
  73. getKeyCode(ks)
  74. KeySym    ks;
  75. {
  76.     KeySymsPtr        pKS;
  77.     int            i, size, kc;
  78.  
  79.     pKS = &keybdType[keybdPriv.type].keySyms;
  80.     size = (pKS->maxKeyCode - pKS->minKeyCode) * pKS->mapWidth;
  81.  
  82.     for (i = 0; i < size; i++) {
  83.     if (pKS->map[i] == ks) {
  84.         kc = (i / pKS->mapWidth) + pKS->minKeyCode;
  85.         return(kc);
  86.     }
  87.     }
  88.     return(-1);
  89. }
  90.  
  91.  
  92. initKeybd()
  93. {
  94.     int type;
  95.     char *cp;
  96.     extern char *getkvar();
  97.     static int swapped;
  98.  
  99.     if ((type = keybdPriv.type) == DEFAULT_KEYBOARD) {
  100.         if (cp = getkvar("keyboard")) {
  101.             switch (cp[0]) {
  102.             case 'A':
  103.                 type = AT_KEYBOARD;
  104.                 break;
  105.             case 'M': /* "MIPS" */
  106.             case 'U':
  107.                 type = UNIX1_KEYBOARD;
  108.                 break;
  109.             case 'X':
  110.                 type = XT_KEYBOARD;
  111.                 break;
  112.             }
  113.         }
  114.         if (type == DEFAULT_KEYBOARD) {
  115.             switch (mipsSysType) {
  116.             case RS2030:
  117.                 type = XT_KEYBOARD;
  118.                 break;
  119.  
  120.             case RS3230:
  121.             default:
  122.                 type = UNIX1_KEYBOARD;
  123.                 break;
  124.  
  125.             case RS4000:
  126.                 type = AT_KEYBOARD;
  127.                 break;
  128.             }
  129.         }
  130.         keybdPriv.type = type;
  131.     }
  132.  
  133.     if (!swapped &&
  134.         (cp = getkvar("keyswtch")) &&
  135.         atoi(cp)) {
  136.         swapped = 1;
  137.         mipsSwapKeys(XK_Caps_Lock, XK_Control_L);
  138.     }
  139. }
  140.  
  141. static
  142. mipsSwapKeys(k1, k2)
  143.     int k1, k2;
  144. {
  145.     int kc1, kc2;
  146.     CARD8 tmpMod, *modMap;
  147.     KeySym tmpSym;
  148.     KeySymsPtr pKS;
  149.     int i;
  150.  
  151.     pKS = &keybdType[keybdPriv.type].keySyms;
  152.     modMap = keybdType[keybdPriv.type].modMap;
  153.  
  154.     if ((kc1 = getKeyCode(k1)) >= 0 &&
  155.         (kc2 = getKeyCode(k2)) >= 0) {
  156.         tmpMod = modMap[kc1];
  157.         modMap[kc1] = modMap[kc2];
  158.         modMap[kc2] = tmpMod;
  159.  
  160.         kc1 = (kc1 - pKS->minKeyCode) * pKS->mapWidth;
  161.         kc2 = (kc2 - pKS->minKeyCode) * pKS->mapWidth;
  162.         for (i = 0; i < pKS->mapWidth; i++) {
  163.             tmpSym = pKS->map[kc1];
  164.             pKS->map[kc1] = pKS->map[kc2];
  165.             pKS->map[kc2] = tmpSym;
  166.             kc1++;
  167.             kc2++;
  168.         }
  169.     }
  170. }
  171.  
  172. setLEDs(pPriv, cmd, on)
  173. KeybdPrivPtr    pPriv;
  174. int        cmd;
  175. int        on;
  176. {
  177.     static int    keybdLights = 0;    /* Current LED value */
  178.  
  179.     if (pPriv->cap & DEV_LIGHTS) {
  180.     switch (cmd) {
  181.         case LEDupdate:
  182.         break;
  183.         case LEDreset:
  184.         keybdLights = 0;
  185.         break;
  186.         case LEDScrollLock:
  187.         if (!DDXxled1) {
  188.             if (on)
  189.             keybdLights |= KLSCRLLOCK;
  190.             else
  191.             keybdLights &= ~KLSCRLLOCK;
  192.         }
  193.         break;
  194.         case LEDCapsLock:
  195.         if (!DDXxled2) {
  196.             if (on)
  197.             keybdLights |= KLCAPSLOCK;
  198.             else
  199.             keybdLights &= ~KLCAPSLOCK;
  200.         }
  201.         break;
  202.         case LEDNumLock:
  203.         if (!DDXxled3) {
  204.             if (on)
  205.             keybdLights |= KLNUMLOCK;
  206.             else
  207.             keybdLights &= ~KLNUMLOCK;
  208.         }
  209.         break;
  210.         case LED1:
  211.         if (DDXxled1) {
  212.             if (on)
  213.             keybdLights |= KLSCRLLOCK;
  214.             else
  215.             keybdLights &= ~KLSCRLLOCK;
  216.         }
  217.         break;
  218.         case LED2:
  219.         if (DDXxled2) {
  220.             if (on)
  221.             keybdLights |= KLCAPSLOCK;
  222.             else
  223.             keybdLights &= ~KLCAPSLOCK;
  224.         }
  225.         break;
  226.         case LED3:
  227.         if (DDXxled3) {
  228.             if (on)
  229.             keybdLights |= KLNUMLOCK;
  230.             else
  231.             keybdLights &= ~KLNUMLOCK;
  232.         }
  233.         break;
  234.         default:
  235.         return;
  236.     }
  237.     if ((ioctl(pPriv->fd, KTCSETLIGHTS, &keybdLights) < 0) && (errno != EBUSY))
  238.         pPriv->cap &= ~DEV_LIGHTS;
  239.     }
  240. }
  241.  
  242. /* ARGSUSED */
  243. static void
  244. mipsKeyClick(pKeybd)
  245. DevicePtr    pKeybd;
  246. {
  247.     KeybdPrivPtr    pPriv;
  248.     struct buzzer    buzz;
  249.     int            i;
  250.  
  251.     pPriv = (KeybdPrivPtr) pKeybd->devicePrivate;
  252.     if (pPriv->cap & DEV_BUZZER) {
  253.     if ((keyClick) && (((DeviceIntPtr) pKeybd)->kbdfeed->ctrl.click)) {
  254.         buzz.buzzer_time = 1;
  255.         buzz.buzzer_load = HZ_TO_LOAD(600);
  256.         buzz.buzzer_flags = 0;
  257.         if ((ioctl(pPriv->fd, KTCPRGMBUZZER, &buzz) < 0) && (errno != EBUSY)) {
  258.         pPriv->cap &= ~DEV_BUZZER;
  259.         Error("cannot ioctl(KTCPRGMBUZZER) keyboard");
  260.         }
  261.     }
  262.     }
  263.     keyClick = 0;
  264. }
  265.  
  266. void
  267. handleKeybd(pKeybd)
  268. DevicePtr    pKeybd;
  269. {
  270.     int            nchar = 0;
  271.     int            i;
  272.     u_char        buf[MAXEVENTS];
  273.     KeybdPrivPtr    pPriv;
  274.  
  275.     pPriv = (KeybdPrivPtr) pKeybd->devicePrivate;
  276.     if (pPriv->cap & DEV_READ) {
  277.     do {
  278.         if ((nchar = read(pPriv->fd, buf, sizeof(buf))) <= 0) {
  279.         if ((nchar < 0) && (errno != EWOULDBLOCK)) {
  280.             pPriv->cap &= ~DEV_READ;
  281.             Error("error reading keyboard");
  282.         }
  283.         return;
  284.         }
  285.  
  286.         if (pPriv->cap & DEV_TIMESTAMP) {
  287.         for (i = 0; i < nchar; ++i)
  288.             timestampKeybd(pKeybd, buf[i]);
  289.         }
  290.         else {
  291.         for (i = 0; i < nchar; ++i)
  292.             keybdType[pPriv->type].keybdEvent(pKeybd, buf[i]);
  293.         }
  294.         mipsKeyClick(pKeybd);
  295.     } while (nchar == sizeof(buf));
  296.     }
  297. }
  298.  
  299. /*ARGSUSED*/
  300. Bool
  301. LegalModifier(key, pDev)
  302.     BYTE key;
  303.     DevicePtr pDev;
  304. {
  305.     return(TRUE);
  306. }
  307.  
  308. static int
  309. stinit(pPriv)
  310. KeybdPrivPtr    pPriv;
  311. {
  312.     if (pPriv->cap & DEV_INIT) {
  313.     struct termio   stmode;
  314.  
  315.     stmode.c_iflag = IGNBRK|IGNPAR;
  316.     stmode.c_oflag = 0;
  317.     stmode.c_cflag = B1200|CS8|CREAD|CLOCAL;
  318.     stmode.c_lflag = 0;
  319.     stmode.c_cc[VMIN] = 1;
  320.     stmode.c_cc[VTIME] = 0;
  321.  
  322.     if (ioctl(pPriv->fd, TCSETAF, &stmode) < 0) {
  323.         pPriv->cap &= ~DEV_INIT;
  324.         Error("cannot ioctl(TCSETAF) keyboard");
  325.         return(-1);
  326.     }
  327.     }
  328.     return(0);
  329. }
  330.  
  331. /* ARGSUSED */
  332. static void
  333. mipsBell(loud, pKeybd)
  334. int        loud;
  335. DevicePtr    pKeybd;
  336. {
  337.     KeybdPrivPtr    pPriv;
  338.     struct buzzer    buzz;
  339.     KeybdCtrl        *pCtrl;
  340.  
  341.     pPriv = (KeybdPrivPtr) pKeybd->devicePrivate;
  342.     if (pPriv->cap & DEV_BUZZER) {
  343.     pCtrl = &((DeviceIntPtr) pKeybd)->kbdfeed->ctrl;
  344.     if (pCtrl->bell) {
  345.         buzz.buzzer_time = pCtrl->bell_duration / 10;
  346.         buzz.buzzer_load = (pCtrl->bell_pitch ? 
  347.                    HZ_TO_LOAD(pCtrl->bell_pitch) : HZ_TO_LOAD(1));
  348.         buzz.buzzer_flags = 0;
  349.         if ((ioctl(pPriv->fd, KTCPRGMBUZZER, &buzz) < 0) && (errno != EBUSY)) {
  350.         pPriv->cap &= ~DEV_BUZZER;
  351.         Error("cannot ioctl(KTCPRGMBUZZER) keyboard");
  352.         }
  353.     }
  354.     }
  355. }
  356.  
  357. /* ARGSUSED */
  358. static void
  359. mipsChangeKeybdCtrl(pKeybd, ctrl)
  360. DevicePtr    pKeybd;
  361. KeybdCtrl    *ctrl;
  362. {
  363.     KeybdPrivPtr    pPriv;
  364.  
  365.     pPriv = (KeybdPrivPtr) pKeybd->devicePrivate;
  366.     setLEDs(pPriv, LED1, (int) ctrl->leds & 1);
  367.     setLEDs(pPriv, LED2, (int) ctrl->leds & 2);
  368.     setLEDs(pPriv, LED3, (int) ctrl->leds & 4);
  369. }
  370.  
  371. openKeybd()
  372. {
  373.     if (keybdPriv.fd < 0) {
  374.     if ((keybdPriv.fd = open(KEYDEV, O_RDWR|O_NDELAY)) >= 0) {
  375. #ifndef SYSV
  376.         int        flags;
  377.  
  378.         if ((flags = fcntl(keybdPriv.fd, F_GETFL, flags)) == -1)
  379.         Error("cannot fcntl(F_GETFL) keyboard");
  380.         flags |= FNDELAY;
  381.         if (fcntl(keybdPriv.fd, F_SETFL, flags) == -1)
  382.         Error("cannot fcntl(F_SETFL) keyboard");
  383. #endif /* SYSV */
  384.         keybdPriv.cap = -1;
  385.     }
  386.     else {
  387.         keybdPriv.cap = 0;
  388.         Error("cannot open keyboard");
  389. #if NETWORK_KEYBD
  390.         keybdPriv.fd = TCPkeybd();
  391. #endif /* NETWORK_KEYBD */
  392.     }
  393. #if MESSED_UP_IOP
  394.     if (mipsSysType == RS2030)
  395.         keybdPriv.cap &= ~DEV_LIGHTS;    /* IOP is messed up */
  396. #endif
  397.     }
  398. }
  399.  
  400. static
  401. keybdAsync(pPriv, set)
  402. KeybdPrivPtr    pPriv;
  403. Bool    set;
  404. {
  405. #if PIXIE
  406.     if (pixie)
  407.     return;
  408. #endif /* PIXIE */
  409.     if (pPriv->cap & DEV_ASYNC) {
  410.     if (mipsStreamAsync(pPriv->fd, set) < 0) {
  411.         pPriv->cap &= ~DEV_ASYNC;
  412.         Error("cannot ioctl(I_SETSIG) keyboard");
  413.     }
  414.     }
  415. }
  416.  
  417. int
  418. mipsKeybdProc(pKeybd, onoff, argc, argv)
  419. DevicePtr    pKeybd;
  420. int        onoff, argc;
  421. char        *argv[];
  422. {
  423.     extern int        stinit();
  424.     KeybdPrivPtr    pPriv;
  425.  
  426.     pPriv = (KeybdPrivPtr) pKeybd->devicePrivate;
  427.     switch (onoff) {
  428.     case DEVICE_INIT:
  429.         pKeybd->on = FALSE;
  430.         pKeybd->devicePrivate = (pointer) &keybdPriv;
  431.         pPriv = (KeybdPrivPtr) pKeybd->devicePrivate;
  432.         openKeybd();
  433.         InitKeyboardDeviceStruct(pKeybd, &(keybdType[pPriv->type].keySyms),
  434.         keybdType[pPriv->type].modMap, mipsBell, mipsChangeKeybdCtrl);
  435.         break;
  436.     case DEVICE_ON:
  437.         if (pPriv->fd >= 0) {
  438.         if (pPriv->cap & DEV_TIMESTAMP) {
  439.             if (ioctl(pPriv->fd, KTCSETTIMESTAMP, 0) < 0) {
  440.             pPriv->cap &= ~DEV_TIMESTAMP;
  441.             Error("cannot ioctl(KTCSETTIMESTAMP) keyboard");
  442.             }
  443.         }
  444.         if (stinit(pPriv) < 0)
  445.             ErrorF("cannot initialize keyboard\n");
  446.         keybdAsync(pPriv, TRUE);
  447.         setLEDs(pPriv, LEDreset, 0);
  448.         AddEnabledDevice(pPriv->fd);
  449.         }
  450.         keybdLock = 0;
  451.         pKeybd->on = TRUE;
  452.         break;
  453.     case DEVICE_CLOSE:
  454.     case DEVICE_OFF:
  455.         pKeybd->on = FALSE;
  456.         if (pPriv->fd >= 0)
  457.         RemoveEnabledDevice(pPriv->fd);
  458.         break;
  459.     }
  460.     return(Success);
  461. }
  462.  
  463. static
  464. timestampKeybd(pKeybd, code)
  465. DevicePtr    pKeybd;
  466. u_char        code;
  467. {
  468.     static int        state = -1;
  469.     static u_char    data;
  470.     static time_t    time;
  471.     u_char        *ptime = (u_char *) &time;
  472.     KeybdPrivPtr    pPriv;
  473.  
  474.     state++;
  475.     switch (state) {
  476.     case 0:    /* Looking for 1st sync byte */
  477.     case 1:    /* Looking for 2nd sync byte */
  478.     case 2:    /* Looking for 3rd sync byte */
  479.         if (code != KBDSYNCCHAR)
  480.         state = -1;
  481.         break;
  482.     case 3:    /* Looking for data */
  483.         data = code;
  484.         break;
  485.     case 4:    /* Looking for 1st time byte */
  486.     case 5:    /* Looking for 2nd time byte */
  487.     case 6:    /* Looking for 3rd time byte */
  488.         ptime[state - 4] = code;
  489.         break;
  490.     case 7:    /* Looking for 4th time byte */
  491.         ptime[state - 4] = code;
  492.         lastEventTime = offsetTime((int) time);
  493.         pPriv = (KeybdPrivPtr) pKeybd->devicePrivate;
  494.         keybdType[pPriv->type].keybdEvent(pKeybd, data);
  495.         state = -1;
  496.         break;
  497.     }
  498. }
  499.  
  500. static KeySym
  501. keyCodeToKeySym(curKeySyms, keyCode)
  502. KeySymsPtr    curKeySyms;
  503. KeyCode        keyCode;
  504. {
  505.     if ((keyCode < curKeySyms->minKeyCode) ||
  506.     (keyCode > curKeySyms->maxKeyCode))
  507.     return(NoSymbol);
  508.  
  509.     return(curKeySyms->map[(keyCode - curKeySyms->minKeyCode) *
  510.     curKeySyms->mapWidth]);
  511. }
  512.  
  513. #ifdef X11R4
  514. #define    mieqEnqueue(event) ((*pKeybd->processInputProc)((event), pKeybd, 1))
  515. #endif /* X11R4 */
  516.  
  517. void
  518. genKeybdEvent(pKeybd, release, kindex)
  519. DevicePtr    pKeybd;
  520. int        release;
  521. u_char        kindex;
  522. {
  523.     static u_char    kindexRepeat = 0x100;
  524.     xEvent        kevent;
  525.     KeySym        ks;
  526.     MousePrivPtr    pMPriv;
  527.     KeybdCtrl        *pCtrl;
  528.     KeybdPrivPtr    pPriv;
  529.     u_char        mod;
  530.  
  531.     pPriv = (KeybdPrivPtr) pKeybd->devicePrivate;
  532.     pCtrl = &((DeviceIntPtr) pKeybd)->kbdfeed->ctrl;
  533.  
  534.     kevent.u.keyButtonPointer.time = lastEventTime;
  535.  
  536.     ks = keyCodeToKeySym(&((DeviceIntPtr) pKeybd)->key->curKeySyms, kindex);
  537.     mod = ((DeviceIntPtr) pKeybd)->key->modifierMap[kindex];
  538.     if (release) {
  539.     kindexRepeat = 0x100;
  540.     if (mod & LockMask)
  541.         return;
  542.     switch (ks) {
  543.         case XK_Num_Lock:
  544.         case XK_Pause:
  545.         /* No KeyRelease for these keys */
  546.         return;
  547.     }
  548.     kevent.u.u.type = KeyRelease;
  549.     kevent.u.u.detail = kindex;
  550.     mieqEnqueue(&kevent);
  551.     }
  552.     else {    /* operate */
  553.     if (kindexRepeat == kindex) {
  554.         /* autorepeat case */
  555.  
  556.         if (pCtrl->autoRepeat != AutoRepeatModeOn)
  557.         return;    /* No autorepeat */
  558.  
  559.         if (mod)
  560.         return;
  561.         switch (ks) {
  562.         case XK_Num_Lock:
  563.         case XK_Pause:
  564.             /* No autorepeat */
  565.             return;
  566.             break;
  567.         }
  568.         kevent.u.u.type = KeyRelease;
  569.         kevent.u.u.detail = kindex;
  570.         keyClick = 1;
  571.         mieqEnqueue(&kevent);
  572.         kevent.u.u.type = KeyPress;
  573.         mieqEnqueue(&kevent);
  574.         kevent.u.u.type = KeyRelease;
  575.         mieqEnqueue(&kevent);
  576.         kevent.u.u.type = KeyPress;
  577.         mieqEnqueue(&kevent);
  578.     }
  579.     else {
  580.         /* Non-autorepeat case */
  581.  
  582.         kevent.u.u.type = KeyPress;
  583.         if (mod & LockMask) {
  584.         keybdLock ^= KLCAPSLOCK;
  585.         if ((keybdLock & KLCAPSLOCK) == 0) {
  586.             kevent.u.u.type = KeyRelease;
  587.             setLEDs(pPriv, LEDCapsLock, 0);
  588.         }
  589.         else
  590.             setLEDs(pPriv, LEDCapsLock, 1);
  591.         }
  592.         else {
  593.         switch (ks) {
  594.             case XK_Num_Lock:
  595.             keybdLock ^= KLNUMLOCK;
  596.             if ((keybdLock & KLNUMLOCK) == 0) {
  597.                 kevent.u.u.type = KeyRelease;
  598.                 setLEDs(pPriv, LEDNumLock, 0);
  599.             }
  600.             else
  601.                 setLEDs(pPriv, LEDNumLock, 1);
  602.             break;
  603.             case XK_Pause:
  604.             keybdLock ^= KLSCRLLOCK;
  605.             if ((keybdLock & KLSCRLLOCK) == 0) {
  606.                 kevent.u.u.type = KeyRelease;
  607.                 setLEDs(pPriv, LEDScrollLock, 0);
  608.             }
  609.             else
  610.                 setLEDs(pPriv, LEDScrollLock, 1);
  611.             break;
  612.         }
  613.         }
  614.         kevent.u.u.detail = kindex;
  615.         keyClick = 1;
  616.         mieqEnqueue(&kevent);
  617.         kindexRepeat = kindex;
  618.     }
  619.     }
  620. }
  621.  
  622. void
  623. specialKeybdEvent()
  624. {
  625. #if MEM_DEBUG || MEM_STATS
  626.     if ((keybdLock & KLNUMLOCK) == 0)
  627.     listMem();
  628.     else
  629.     checkpointMem();
  630. #endif
  631. #if PIXIE
  632.     if (pixie)
  633.     exit(0);
  634. #endif /* PIXIE */
  635. }
  636.