home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / x386 / x386Events.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-30  |  19.7 KB  |  759 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/x386Events.c,v 1.3 1991/06/30 21:02:38 root Exp $
  23.  */
  24.  
  25. #define NEED_EVENTS
  26. #include "X.h"
  27. #include "Xproto.h"
  28. #include "misc.h"
  29. #include "inputstr.h"
  30. #include "scrnintstr.h"
  31.  
  32. #include "compiler.h"
  33.  
  34. #include "x386Procs.h"
  35. #include "x386OSD.h"
  36. #include "atKeynames.h"
  37. #include "osdep.h"
  38.  
  39. #define XE_POINTER  1
  40. #define XE_KEYBOARD 2
  41.  
  42. #ifdef XTESTEXT1
  43.  
  44. #define    XTestSERVER_SIDE
  45. #include "xtestext1.h"
  46. extern short xtest_mousex;
  47. extern short xtest_mousey;
  48. extern int   on_steal_input;          
  49. extern Bool  XTestStealKeyData();
  50. extern void  XTestStealMotionData();
  51.  
  52. #define ENQUEUE(ev, code, direction, dev_type) \
  53.   (ev)->u.u.detail = (code); \
  54.   (ev)->u.u.type   = (direction); \
  55.   if (!on_steal_input ||  \
  56.       XTestStealKeyData((ev)->u.u.detail, (ev)->u.u.type, dev_type, \
  57.             xtest_mousex, xtest_mousey)) \
  58.   mieqEnqueue((ev))
  59.  
  60. #define MOVEPOINTER(dx, dy, time) \
  61.   if (on_steal_input) \
  62.     XTestStealMotionData(dx, dy, XE_POINTER, xtest_mousex, xtest_mousey); \
  63.   miPointerDeltaCursor (dx, dy, time)
  64.  
  65. #else /* ! XTESTEXT1 */
  66.  
  67. #define ENQUEUE(ev, code, direction, dev_type) \
  68.   (ev)->u.u.detail = (code); \
  69.   (ev)->u.u.type   = (direction); \
  70.   mieqEnqueue((ev))
  71.  
  72. #define MOVEPOINTER(dx, dy, time) \
  73.   miPointerDeltaCursor (dx, dy, time)
  74.  
  75. #endif
  76.  
  77.  
  78. Bool x386VTSema = TRUE;
  79.  
  80. extern long EnabledDevices[];
  81.  
  82. static void x386VTSwitch();
  83.  
  84. /*
  85.  * Lets create a simple finite-state machine:
  86.  *
  87.  *   state[?][0]: action1
  88.  *   state[?][1]: action2
  89.  *   state[?][2]: next state
  90.  *
  91.  *   action > 0: ButtonPress
  92.  *   action = 0: nothing
  93.  *   action < 0: ButtonRelease
  94.  *
  95.  * Why this stuff ??? Normally you cannot press both mousebuttons together, so
  96.  * the mouse reports both pressed at the same time ...
  97.  */
  98.  
  99. static char stateTab[48][3] = {
  100.  
  101. /* nothing pressed */
  102.   {  0,  0,  0 },    
  103.   {  0,  0,  8 },    /* 1 right -> delayed right */
  104.   {  0,  0,  0 },       /* 2 nothing */
  105.   {  0,  0,  8 },    /* 3 right -> delayed right */
  106.   {  0,  0, 16 },    /* 4 left -> delayed left */
  107.   {  2,  0, 24 },       /* 5 left & right (middle press) -> middle pressed */
  108.   {  0,  0, 16 },    /* 6 left -> delayed left */
  109.   {  2,  0, 24 },       /* 7 left & right (middle press) -> middle pressed */
  110.  
  111. /* delayed right */
  112.   {  1, -1,  0 },    /* 8 nothing (right event) -> init */
  113.   {  1,  0, 32 },       /* 9 right (right press) -> right pressed */
  114.   {  1, -1,  0 },    /* 10 nothing (right event) -> init */
  115.   {  1,  0, 32 },       /* 11 right (right press) -> right pressed */
  116.   {  1, -1, 16 },       /* 12 left (right event) -> delayed left */
  117.   {  2,  0, 24 },       /* 13 left & right (middle press) -> middle pressed */
  118.   {  1, -1, 16 },       /* 14 left (right event) -> delayed left */
  119.   {  2,  0, 24 },       /* 15 left & right (middle press) -> middle pressed */
  120.  
  121. /* delayed left */
  122.   {  3, -3,  0 },    /* 16 nothing (left event) -> init */
  123.   {  3, -3,  8 },       /* 17 right (left event) -> delayed right */
  124.   {  3, -3,  0 },    /* 18 nothing (left event) -> init */
  125.   {  3, -3,  8 },       /* 19 right (left event) -> delayed right */
  126.   {  3,  0, 40 },    /* 20 left (left press) -> pressed left */
  127.   {  2,  0, 24 },    /* 21 left & right (middle press) -> pressed middle */
  128.   {  3,  0, 40 },    /* 22 left (left press) -> pressed left */
  129.   {  2,  0, 24 },    /* 23 left & right (middle press) -> pressed middle */
  130.  
  131. /* pressed middle */
  132.   { -2,  0,  0 },    /* 24 nothing (middle release) -> init */
  133.   { -2,  0,  0 },    /* 25 right (middle release) -> init */
  134.   { -2,  0,  0 },    /* 26 nothing (middle release) -> init */
  135.   { -2,  0,  0 },    /* 27 right (middle release) -> init */
  136.   { -2,  0,  0 },    /* 28 left (middle release) -> init */
  137.   {  0,  0, 24 },    /* 29 left & right -> pressed middle */
  138.   { -2,  0,  0 },    /* 30 left (middle release) -> init */
  139.   {  0,  0, 24 },    /* 31 left & right -> pressed middle */
  140.  
  141. /* pressed right */
  142.   { -1,  0,  0 },    /* 32 nothing (right release) -> init */
  143.   {  0,  0, 32 },    /* 33 right -> pressed right */
  144.   { -1,  0,  0 },    /* 34 nothing (right release) -> init */
  145.   {  0,  0, 32 },    /* 35 right -> pressed right */
  146.   { -1,  0, 16 },    /* 36 left (right release) -> delayed left */
  147.   { -1,  2, 24 },    /* 37 left & right (r rel, m prs) -> middle pressed */
  148.   { -1,  0, 16 },    /* 38 left (right release) -> delayed left */
  149.   { -1,  2, 24 },    /* 39 left & right (r rel, m prs) -> middle pressed */
  150.  
  151. /* pressed left */
  152.   { -3,  0,  0 },    /* 40 nothing (left release) -> init */
  153.   { -3,  0,  8 },    /* 41 right (left release) -> delayed right */
  154.   { -3,  0,  0 },    /* 42 nothing (left release) -> init */
  155.   { -3,  0,  8 },    /* 43 right (left release) -> delayed right */
  156.   {  0,  0, 40 },    /* 44 left -> left pressed */
  157.   { -3,  2, 24 },    /* 45 left & right (l rel, mprs) -> middle pressed */
  158.   {  0,  0, 40 },    /* 46 left -> left pressed */
  159.   { -3,  2, 24 },    /* 47 left & right (l rel, mprs) -> middle pressed */
  160. };
  161.  
  162.  
  163.  
  164. /*
  165.  * TimeSinceLastInputEvent --
  166.  *      Function used for screensaver purposes by the os module. Retruns the
  167.  *      time in milliseconds since there last was any input.
  168.  */
  169.  
  170. int
  171. TimeSinceLastInputEvent()
  172. {
  173.   if (x386Info.lastEventTime == 0) {
  174.     x386Info.lastEventTime = GetTimeInMillis();
  175.   }
  176.   return GetTimeInMillis() - x386Info.lastEventTime;
  177. }
  178.  
  179.  
  180.  
  181. /*
  182.  * SetTimeSinceLastInputEvent --
  183.  *      Set the lastEventTime to now.
  184.  */
  185.  
  186. void
  187. SetTimeSinceLastInputEvent()
  188. {
  189.   x386Info.lastEventTime = GetTimeInMillis();
  190. }
  191.  
  192.  
  193.  
  194. /*
  195.  * ProcessInputEvents --
  196.  *      Retrieve all waiting input events and pass them to DIX in their
  197.  *      correct chronological order. Only reads from the system pointer
  198.  *      and keyboard.
  199.  */
  200.  
  201. void
  202. ProcessInputEvents ()
  203. {
  204.   int x, y;
  205.   x386Info.inputPending = FALSE;
  206.  
  207.   mieqProcessInputEvents();
  208.   miPointerUpdate();
  209.  
  210.   miPointerPosition(&x, &y);
  211.   x386SetViewport(x386Info.currentScreen, x, y);
  212. }
  213.  
  214.  
  215.  
  216. /*
  217.  * x386PostKbdEvent --
  218.  *    Translate the raw hardware KbdEvent into an XEvent, and tell DIX
  219.  *    about it. Scancode preprocessing and so on is done ...
  220.  */
  221.  
  222. void
  223. x386PostKbdEvent(key)
  224.      unsigned key;
  225. {
  226.   int         scanCode = (key & 0x7f);
  227.   Bool        down = (key & 0x80 ? FALSE : TRUE);
  228.   KeyClassRec *keyc = ((DeviceIntPtr)x386Info.pKeyboard)->key;
  229.   Bool        updateLeds = FALSE;
  230.   Bool        UsePrefix = FALSE;
  231.   Bool        Direction = FALSE;
  232.   xEvent      kevent;
  233.   KeySym      *keysym;
  234.   int         keycode;
  235.  
  236.   /*
  237.    * First do some special scancode remapping ...
  238.    */
  239.   if (x386Info.scanPrefix == 0) {
  240.  
  241.     switch (scanCode) {
  242.       
  243.     case KEY_Prefix0:
  244.     case KEY_Prefix1:
  245.       x386Info.scanPrefix = scanCode;  /* special prefixes */
  246.       return;
  247.  
  248.     case KEY_CapsLock:
  249.     case KEY_NumLock:
  250.     case KEY_ScrollLock:
  251.       updateLeds = TRUE;              /* led changes by firmware */
  252.       break;
  253.     }
  254.   }
  255.     
  256.   else if (x386Info.scanPrefix == KEY_Prefix0) {
  257.     
  258.     x386Info.scanPrefix = 0;
  259.       
  260.     switch (scanCode) {
  261.     case KEY_KP_7:        scanCode = KEY_Home;      break;  /* curs home */
  262.     case KEY_KP_8:        scanCode = KEY_Up;        break;  /* curs up */
  263.     case KEY_KP_9:        scanCode = KEY_PgUp;      break;  /* curs pgup */
  264.     case KEY_KP_4:        scanCode = KEY_Left;      break;  /* curs left */
  265.     case KEY_KP_5:        scanCode = KEY_Begin;     break;  /* curs begin */
  266.     case KEY_KP_6:        scanCode = KEY_Right;     break;  /* curs right */
  267.     case KEY_KP_1:        scanCode = KEY_End;       break;  /* curs end */
  268.     case KEY_KP_2:        scanCode = KEY_Down;      break;  /* curs down */
  269.     case KEY_KP_3:        scanCode = KEY_PgDown;    break;  /* curs pgdown */
  270.     case KEY_KP_0:        scanCode = KEY_Insert;    break;  /* curs insert */
  271.     case KEY_KP_Decimal:  scanCode = KEY_Delete;    break;  /* curs delete */
  272.     case KEY_Enter:       scanCode = KEY_KP_Enter;  break;  /* keypad enter */
  273.     case KEY_LCtrl:       scanCode = KEY_RCtrl;     break;  /* right ctrl */
  274.     case KEY_KP_Multiply: scanCode = KEY_Print;     break;  /* print */
  275.     case KEY_Slash:       scanCode = KEY_KP_Divide; break;  /* keyp divide */
  276.     case KEY_Alt:         scanCode = KEY_AltLang;   break;  /* right alt */
  277.     case KEY_ScrollLock:  scanCode = KEY_Break;     break;  /* curs break */
  278.       /*
  279.        * Ignore virtual shifts (E0 2A, E0 AA, E0 36, E0 B6)
  280.        */
  281.     default:
  282.       return;                                  /* skip illegal */
  283.     }
  284.   }
  285.   
  286.   else if (x386Info.scanPrefix == KEY_Prefix1)
  287.     {
  288.       x386Info.scanPrefix = (scanCode == KEY_LCtrl) ? KEY_LCtrl : 0;
  289.       return;
  290.     }
  291.   
  292.   else if (x386Info.scanPrefix == KEY_LCtrl)
  293.     {
  294.       x386Info.scanPrefix = 0;
  295.       if (scanCode != KEY_NumLock) return;
  296.       scanCode = KEY_Pause;       /* pause */
  297.     }
  298.     
  299.   /*
  300.    * and now get some special keysequences
  301.    */
  302.   if ((ModifierDown(ControlMask | AltMask)) ||
  303.       (ModifierDown(ControlMask | AltLangMask)))
  304.     {
  305.       
  306.       switch (scanCode) {
  307.     
  308.       case KEY_BackSpace:
  309.     if (!x386Info.dontZap) GiveUp();
  310.     return;
  311.     
  312.     /*
  313.      * The idea here is to pass the scancode down to a list of
  314.      * registered routines. There should be some standart conventions
  315.      * for processing certain keys.
  316.      */
  317.       case KEY_KP_Minus:   /* Keypad - */
  318.     if (down) x386ZoomViewport(x386Info.currentScreen, -1);
  319.     return;
  320.     
  321.       case KEY_KP_Plus:   /* Keypad + */
  322.     if (down) x386ZoomViewport(x386Info.currentScreen,  1);
  323.     return;
  324.       } 
  325.     }
  326.     
  327.   /*
  328.    * Now map the scancodes to real X-keycodes ...
  329.    */
  330.   keycode = scanCode + MIN_KEYCODE;
  331.   keysym = (keyc->curKeySyms.map +
  332.         keyc->curKeySyms.mapWidth * 
  333.         (keycode - keyc->curKeySyms.minKeyCode));
  334.   
  335.   /*
  336.    * LockKey special handling:
  337.    * ignore releases, toggle on & off on presses.
  338.    */
  339.   if (keysym[0] == XK_Caps_Lock ||
  340.       keysym[0] == XK_Scroll_Lock ||
  341.       keysym[0] == XK_Num_Lock)
  342.     {
  343.       Bool flag;
  344.  
  345.       if (!down) return;
  346.       if (KeyPressed(keycode)) {
  347.     down = !down;
  348.     flag = FALSE;
  349.       }
  350.       else
  351.     flag = TRUE;
  352.  
  353.       if (keysym[0] == XK_Caps_Lock)   x386Info.capsLock   = flag;
  354.       if (keysym[0] == XK_Num_Lock)    x386Info.numLock    = flag;
  355.       if (keysym[0] == XK_Scroll_Lock) x386Info.scrollLock = flag;
  356.       updateLeds = TRUE;
  357.     }
  358.     
  359.   /*
  360.    * check for an autorepeat-event
  361.    */
  362.   if ((down && KeyPressed(keycode)) &&
  363.       (x386Info.autoRepeat != AutoRepeatModeOn || keyc->modifierMap[keycode]))
  364.     return;
  365.  
  366.   x386Info.lastEventTime = kevent.u.keyButtonPointer.time = GetTimeInMillis();
  367.  
  368.   /*
  369.    * Ooops. Some new ideas here. The Mode_switch key is not defined either as
  370.    * lock key or troggle key. My interpretation is that normally this key will
  371.    * be treated as troggle. Except if KEY_AltL is allready pressed. Then no
  372.    * release event will be sent till Mode_switch without KEY_AltL is pressed
  373.    * again. The ScrollLock Led will signal this lockstate
  374.    */
  375.   if (keysym[0] == XK_Mode_switch) {
  376.     if (ModifierDown(AltMask)) {
  377.       if (down && !x386Info.modeSwitchLock) {
  378.     x386Info.modeSwitchLock = TRUE;
  379.     updateLeds = TRUE;
  380.       }
  381.       else
  382.     return;
  383.     }
  384.     else if (!down && x386Info.modeSwitchLock) {
  385.       x386Info.modeSwitchLock = FALSE;
  386.       updateLeds = TRUE;
  387.     }
  388.   }
  389.  
  390.   /*
  391.    * normal, non-keypad keys
  392.    */
  393.   else if (scanCode < KEY_KP_7 || scanCode > KEY_KP_Decimal) {
  394.  
  395.     /*
  396.      * magic ALT_L key on AT84 keyboards for multilingual support
  397.      */
  398.     if (x386Info.kbdType == KB_84 &&
  399.     ModifierDown(AltMask) &&
  400.     keysym[2] != NoSymbol)
  401.       {
  402.     UsePrefix = TRUE;
  403.     Direction = TRUE;
  404.       }
  405.   }
  406.   /*
  407.    * NumPad special Handling. If necessary a Prefix is sent
  408.    */
  409.   else if (x386Info.serverNumLock && x386Info.numLock) {
  410.     if (!ModifierDown(AltLangMask)) {
  411.       UsePrefix = TRUE;
  412.       Direction = TRUE;
  413.     }
  414.   }
  415.  
  416.   /*
  417.    * NumPad key, but no server numlock, or no numlock pressed. Since the AT
  418.    * Keyboard proposal uses row 2 & 3, we must ensure, that here are no
  419.    * Mode_switch keys are pressed.
  420.    */
  421.   else if (ModifierDown(AltLangMask)) {
  422.     UsePrefix = TRUE;
  423.     Direction = FALSE;
  424.   }
  425.  
  426.   /*
  427.    * And now send these prefixes ...
  428.    * NOTE: There cannot be multible Mode_Switch keys !!!!
  429.    */
  430.   if (UsePrefix)
  431.     {
  432.       ENQUEUE(&kevent,
  433.           keyc->modifierKeyMap[keyc->maxKeysPerModifier*7],
  434.           (Direction ? KeyPress : KeyRelease),
  435.           XE_KEYBOARD);
  436.       ENQUEUE(&kevent, keycode, (down ? KeyPress : KeyRelease), XE_KEYBOARD);
  437.       ENQUEUE(&kevent,
  438.           keyc->modifierKeyMap[keyc->maxKeysPerModifier*7],
  439.           (Direction ? KeyRelease : KeyPress),
  440.           XE_KEYBOARD);
  441.     }
  442.   else 
  443.     {
  444.       ENQUEUE(&kevent, keycode, (down ? KeyPress : KeyRelease), XE_KEYBOARD);
  445.     }
  446.  
  447.   if (updateLeds) x386KbdLeds();
  448. }
  449.  
  450.  
  451.  
  452.  
  453. /*      
  454.  * x386PostMseEvent --
  455.  *    Translate the raw hardware MseEvent into an XEvent(s), and tell DIX
  456.  *    about it. Perform a 3Button emulation if required.
  457.  */
  458.  
  459. void
  460. x386PostMseEvent(buttons, dx, dy)
  461.      int buttons, dx, dy;
  462. {
  463.   int         eventNum = 0;
  464.   int         id, change;
  465.   xEvent      mevent;
  466.  
  467.   x386Info.lastEventTime = mevent.u.keyButtonPointer.time = GetTimeInMillis();
  468.  
  469.   if (dx || dy) {
  470.     
  471.     /*
  472.      * accelerate the baby now if sqrt(dx*dx + dy*dy) > threshold !
  473.      * but do some simpler arithmetic here...
  474.      */
  475.     if ((abs(dx) + abs(dy)) >= x386Info.threshold) {
  476.       dx = (dx * x386Info.num) / x386Info.den;
  477.       dy = (dy * x386Info.num)/ x386Info.den;
  478.     }
  479.  
  480.     MOVEPOINTER(dx, dy, mevent.u.keyButtonPointer.time);
  481.   }
  482.  
  483.   if (x386Info.emulate3Buttons)
  484.     {
  485.       
  486.       /*
  487.        * emulate the third button by the other two
  488.        */
  489.       if (id = stateTab[buttons + x386Info.emulateState][0])
  490.     {
  491.       ENQUEUE(&mevent,
  492.           abs(id), (id < 0 ? ButtonRelease : ButtonPress), 
  493.           XE_POINTER);
  494.     }
  495.  
  496.       if (id = stateTab[buttons + x386Info.emulateState][1])
  497.     {
  498.       ENQUEUE(&mevent,
  499.           abs(id), (id < 0 ? ButtonRelease : ButtonPress), 
  500.           XE_POINTER);
  501.     }
  502.  
  503.       x386Info.emulateState = stateTab[buttons + x386Info.emulateState][2];
  504.     }
  505.   else
  506.     {
  507.       
  508.       /*
  509.        * real three button event
  510.        */
  511.       change = buttons ^ x386Info.lastButtons;
  512.       while (change)
  513.     {
  514.       id = ffs(change);
  515.       change &= ~(1 << (id-1));
  516.       ENQUEUE(&mevent,
  517.           id, (buttons&(1<<(id-1)))? ButtonPress : ButtonRelease,
  518.           XE_POINTER);
  519.     }
  520.       x386Info.lastButtons = buttons;
  521.     }
  522. }
  523.  
  524.  
  525.  
  526. /*
  527.  * x386Block --
  528.  *      Os block handler.
  529.  */
  530.  
  531. /* ARGSUSED */
  532. void
  533. x386Block(blockData, pTimeout, pReadmask)
  534.      pointer blockData;
  535.      pointer pTimeout;
  536.      long *  pReadmask;
  537. {
  538. }
  539.  
  540.  
  541.  
  542. /*
  543.  * x386Wakeup --
  544.  *      Os wakeup handler.
  545.  */
  546.  
  547. /* ARGSUSED */
  548. void
  549. x386Wakeup(blockData, err, pReadmask)
  550.      pointer blockData;
  551.      unsigned long err;
  552.      long *pReadmask;
  553. {
  554.   long devicesWithInput[mskcnt];
  555.  
  556.   if ((int)err >= 0) {
  557.     MASKANDSETBITS(devicesWithInput, pReadmask, EnabledDevices);
  558.     if (ANYSET(devicesWithInput))
  559.       {
  560.     (x386Info.kbdEvents)();
  561.     (x386Info.mseEvents)();
  562.       }
  563.   }
  564.  
  565.   if (x386Info.vtRequestsPending) x386VTSwitch();
  566.   if (x386Info.inputPending) ProcessInputEvents();
  567. }
  568.  
  569.  
  570.  
  571. /*
  572.  * x386VTRequest --
  573.  *      Notice switch requests form the vt manager.
  574.  */
  575.  
  576. void
  577. x386VTRequest(signo)
  578.      int signo;
  579. {
  580.   x386Info.vtRequestsPending = TRUE;
  581.     
  582.   signal(signo, (void(*)()) x386VTRequest);
  583. }
  584.  
  585.  
  586.  
  587. /***************************************************************************
  588.  *
  589.  * THIS WILL DISAPPEAR IN X386 2.0  / VFB
  590.  *
  591.  * There will be a more hardware base system to disable all accesses to/from
  592.  * the screen.
  593.  *
  594.  ***************************************************************************/
  595.  
  596. #include "cursorstr.h"
  597. #include "servermd.h"
  598. #include "windowstr.h"
  599.  
  600. extern WindowPtr *WindowTable;    /* imported from dix */
  601. #define RANDOM_WIDTH 32
  602.  
  603. /*
  604.  * x386VTSwitch --
  605.  *      Handle requests for switching the vt.
  606.  */
  607.  
  608. void
  609. x386VTSwitch()
  610. {
  611.   int j;
  612.   int result;
  613.   XID attributes[3];
  614.   Mask mask;
  615.   CursorMetricRec cm;
  616.   unsigned char *srcbits, *mskbits;
  617.   CursorPtr cursor;
  618.   XID cursorID;
  619.   static WindowPtr pWin;
  620.   static XID Wid;
  621.  
  622.   if (x386VTSema) {
  623.     
  624.     /*
  625.      * this is modeled after ideas from server/dix/windows.c
  626.      */
  627.     attributes[0] = WindowTable[0]->drawable.pScreen->blackPixel;
  628.     attributes[1] = xTrue;
  629.     mask = CWBackPixel | CWOverrideRedirect;
  630.     
  631.     /*
  632.      * create a blank cursor
  633.      */
  634.     cm.width=16;
  635.     cm.height=16;
  636.     cm.xhot=8;
  637.     cm.yhot=8;
  638.     srcbits = (unsigned char *)xalloc( PixmapBytePad(32, 1)*16);
  639.     mskbits = (unsigned char *)xalloc( PixmapBytePad(32, 1)*16);
  640.     if (!srcbits || !mskbits) {
  641.       xfree(srcbits);
  642.       xfree(mskbits);
  643.     } else {
  644.       for (j=0; j<PixmapBytePad(32, 1)*16; j++)
  645.     srcbits[j] = mskbits[j] = 0x0;
  646.       cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
  647.       if (cursor) {
  648.     cursorID = FakeClientID(0);
  649.     if (AddResource (cursorID, RT_CURSOR, (pointer) cursor)) {
  650.       attributes[2] = cursorID;
  651.       mask |= CWCursor;
  652.       cursor->refcnt++;
  653.     }
  654.       }
  655.     }
  656.     
  657.     pWin =
  658.       CreateWindow(Wid,
  659.            WindowTable[0],
  660.            -RANDOM_WIDTH, -RANDOM_WIDTH,
  661.            (ushort)screenInfo.screens[0]->width + RANDOM_WIDTH,
  662.            (ushort)screenInfo.screens[0]->height + RANDOM_WIDTH,
  663.            0, InputOutput, mask, attributes, 0, serverClient,
  664.            wVisual (WindowTable[0]), &result);
  665.     
  666.     if (!pWin) return;
  667.     
  668.     if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin)) return;
  669.     
  670.     MapWindow(pWin, serverClient);
  671.     
  672.     (X386SCRNINFO(x386Info.currentScreen)->EnterLeaveVT)( LEAVE );
  673.       
  674.     DisableDevice(x386Info.pKeyboard);
  675.     DisableDevice(x386Info.pPointer);
  676.       
  677.     if (ioctl(x386Info.consoleFd,VT_RELDISP,1) <0) {
  678.       /*
  679.        * switch failed 
  680.        */
  681.       (X386SCRNINFO(x386Info.currentScreen)->EnterLeaveVT)( ENTER );
  682.       FreeResource(Wid, RT_NONE);
  683.                        
  684.       EnableDevice(x386Info.pKeyboard);
  685.       EnableDevice(x386Info.pPointer);
  686.  
  687.     } else {
  688.       x386VTSema = FALSE;
  689.     }
  690.  
  691.   } else {
  692.       
  693.     if (ioctl(x386Info.consoleFd,VT_RELDISP,VT_ACKACQ) <0) return;
  694.       
  695.     x386VTSema = TRUE;
  696.     (X386SCRNINFO(x386Info.currentScreen)->EnterLeaveVT)( ENTER);
  697.       
  698.     FreeResource(Wid, RT_NONE);
  699.  
  700.     EnableDevice(x386Info.pKeyboard);
  701.     EnableDevice(x386Info.pPointer);
  702.       
  703.   }
  704.  
  705.   x386Info.vtRequestsPending = FALSE;
  706. }
  707.  
  708.  
  709.  
  710. #ifdef XTESTEXT1
  711.  
  712. void
  713. XTestGetPointerPos(fmousex, fmousey)
  714.      short *fmousex;
  715.      short *fmousey;
  716. {
  717.   int x,y;
  718.  
  719.   miPointerPosition(&x, &y);
  720.   *fmousex = x;
  721.   *fmousey = y;
  722. }
  723.  
  724.  
  725.  
  726. void
  727. XTestJumpPointer(jx, jy, dev_type)
  728.      int jx;
  729.      int jy;
  730.      int dev_type;
  731. {
  732.   miPointerAbsoluteCursor(jx, jy, GetTimeInMillis() );
  733. }
  734.  
  735.  
  736.  
  737. void
  738. XTestGenerateEvent(dev_type, keycode, keystate, mousex, mousey)
  739.      int dev_type;
  740.      int keycode;
  741.      int keystate;
  742.      int mousex;
  743.      int mousey;
  744. {
  745.   xEvent tevent;
  746.   
  747.   tevent.u.u.type = (dev_type == XE_POINTER) ?
  748.     (keystate == XTestKEY_UP) ? ButtonRelease : ButtonPress :
  749.       (keystate == XTestKEY_UP) ? KeyRelease : KeyPress;
  750.   tevent.u.u.detail = keycode;
  751.   tevent.u.keyButtonPointer.rootX = mousex;
  752.   tevent.u.keyButtonPointer.rootY = mousey;
  753.   tevent.u.keyButtonPointer.time = x386Info.lastEventTime = GetTimeInMillis();
  754.   mieqEnqueue(&tevent);
  755.   x386Info.inputPending = TRUE;               /* virtual event */
  756. }
  757.  
  758. #endif /* XTESTEXT1 */
  759.