xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

Keyboard.c (8171B)


      1 /*
      2 
      3 Copyright 1993 by Davor Matic
      4 
      5 Permission to use, copy, modify, distribute, and sell this software
      6 and its documentation for any purpose is hereby granted without fee,
      7 provided that the above copyright notice appear in all copies and that
      8 both that copyright notice and this permission notice appear in
      9 supporting documentation.  Davor Matic makes no representations about
     10 the suitability of this software for any purpose.  It is provided "as
     11 is" without express or implied warranty.
     12 
     13 */
     14 
     15 #ifdef HAVE_XNEST_CONFIG_H
     16 #include <xnest-config.h>
     17 #endif
     18 
     19 #ifdef WIN32
     20 #include <X11/Xwindows.h>
     21 #endif
     22 
     23 #include <X11/X.h>
     24 #include <X11/Xproto.h>
     25 #include <X11/keysym.h>
     26 #include "screenint.h"
     27 #include "inputstr.h"
     28 #include "misc.h"
     29 #include "scrnintstr.h"
     30 #include "servermd.h"
     31 
     32 #include "Xnest.h"
     33 
     34 #include "Display.h"
     35 #include "Screen.h"
     36 #include "Keyboard.h"
     37 #include "Args.h"
     38 #include "Events.h"
     39 
     40 #include <X11/extensions/XKB.h>
     41 #include "xkbsrv.h"
     42 #include <X11/extensions/XKBconfig.h>
     43 
     44 extern Bool
     45  XkbQueryExtension(Display * /* dpy */ ,
     46                    int * /* opcodeReturn */ ,
     47                    int * /* eventBaseReturn */ ,
     48                    int * /* errorBaseReturn */ ,
     49                    int * /* majorRtrn */ ,
     50                    int *        /* minorRtrn */
     51     );
     52 
     53 extern XkbDescPtr XkbGetKeyboard(Display * /* dpy */ ,
     54                                  unsigned int /* which */ ,
     55                                  unsigned int   /* deviceSpec */
     56     );
     57 
     58 extern Status XkbGetControls(Display * /* dpy */ ,
     59                              unsigned long /* which */ ,
     60                              XkbDescPtr /* desc */
     61     );
     62 
     63 DeviceIntPtr xnestKeyboardDevice = NULL;
     64 
     65 void
     66 xnestBell(int volume, DeviceIntPtr pDev, void *ctrl, int cls)
     67 {
     68     XBell(xnestDisplay, volume);
     69 }
     70 
     71 void
     72 DDXRingBell(int volume, int pitch, int duration)
     73 {
     74     XBell(xnestDisplay, volume);
     75 }
     76 
     77 void
     78 xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
     79 {
     80 #if 0
     81     unsigned long value_mask;
     82     XKeyboardControl values;
     83     int i;
     84 
     85     value_mask = KBKeyClickPercent |
     86         KBBellPercent | KBBellPitch | KBBellDuration | KBAutoRepeatMode;
     87 
     88     values.key_click_percent = ctrl->click;
     89     values.bell_percent = ctrl->bell;
     90     values.bell_pitch = ctrl->bell_pitch;
     91     values.bell_duration = ctrl->bell_duration;
     92     values.auto_repeat_mode = ctrl->autoRepeat ?
     93         AutoRepeatModeOn : AutoRepeatModeOff;
     94 
     95     XChangeKeyboardControl(xnestDisplay, value_mask, &values);
     96 
     97     /*
     98        value_mask = KBKey | KBAutoRepeatMode;
     99        At this point, we need to walk through the vector and compare it
    100        to the current server vector.  If there are differences, report them.
    101      */
    102 
    103     value_mask = KBLed | KBLedMode;
    104     for (i = 1; i <= 32; i++) {
    105         values.led = i;
    106         values.led_mode =
    107             (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
    108         XChangeKeyboardControl(xnestDisplay, value_mask, &values);
    109     }
    110 #endif
    111 }
    112 
    113 int
    114 xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
    115 {
    116     XModifierKeymap *modifier_keymap;
    117     KeySym *keymap;
    118     int mapWidth;
    119     int min_keycode, max_keycode;
    120     KeySymsRec keySyms;
    121     CARD8 modmap[MAP_LENGTH];
    122     int i, j;
    123     XKeyboardState values;
    124     XkbDescPtr xkb;
    125     int op, event, error, major, minor;
    126 
    127     switch (onoff) {
    128     case DEVICE_INIT:
    129         XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
    130 #ifdef _XSERVER64
    131         {
    132             KeySym64 *keymap64;
    133             int len;
    134 
    135             keymap64 = XGetKeyboardMapping(xnestDisplay,
    136                                            min_keycode,
    137                                            max_keycode - min_keycode + 1,
    138                                            &mapWidth);
    139             len = (max_keycode - min_keycode + 1) * mapWidth;
    140             keymap = xallocarray(len, sizeof(KeySym));
    141             for (i = 0; i < len; ++i)
    142                 keymap[i] = keymap64[i];
    143             XFree(keymap64);
    144         }
    145 #else
    146         keymap = XGetKeyboardMapping(xnestDisplay,
    147                                      min_keycode,
    148                                      max_keycode - min_keycode + 1, &mapWidth);
    149 #endif
    150 
    151         memset(modmap, 0, sizeof(modmap));
    152         modifier_keymap = XGetModifierMapping(xnestDisplay);
    153         for (j = 0; j < 8; j++)
    154             for (i = 0; i < modifier_keymap->max_keypermod; i++) {
    155                 CARD8 keycode;
    156 
    157                 if ((keycode =
    158                      modifier_keymap->modifiermap[j *
    159                                                   modifier_keymap->
    160                                                   max_keypermod + i]))
    161                     modmap[keycode] |= 1 << j;
    162             }
    163         XFreeModifiermap(modifier_keymap);
    164 
    165         keySyms.minKeyCode = min_keycode;
    166         keySyms.maxKeyCode = max_keycode;
    167         keySyms.mapWidth = mapWidth;
    168         keySyms.map = keymap;
    169 
    170         if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor)
    171             == 0) {
    172             ErrorF("Unable to initialize XKEYBOARD extension.\n");
    173             goto XkbError;
    174         }
    175         xkb =
    176             XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask,
    177                            XkbUseCoreKbd);
    178         if (xkb == NULL || xkb->geom == NULL) {
    179             ErrorF("Couldn't get keyboard.\n");
    180             goto XkbError;
    181         }
    182         XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
    183 
    184         InitKeyboardDeviceStruct(pDev, NULL,
    185                                  xnestBell, xnestChangeKeyboardControl);
    186 
    187         XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode,
    188                               keySyms.maxKeyCode - keySyms.minKeyCode + 1,
    189                               modmap, serverClient);
    190 
    191         XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
    192         XkbFreeKeyboard(xkb, 0, False);
    193         free(keymap);
    194         break;
    195     case DEVICE_ON:
    196         xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
    197         for (i = 0; i < xnestNumScreens; i++)
    198             XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
    199         break;
    200     case DEVICE_OFF:
    201         xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
    202         for (i = 0; i < xnestNumScreens; i++)
    203             XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
    204         break;
    205     case DEVICE_CLOSE:
    206         break;
    207     }
    208     return Success;
    209 
    210  XkbError:
    211     XGetKeyboardControl(xnestDisplay, &values);
    212     memmove((char *) defaultKeyboardControl.autoRepeats,
    213             (char *) values.auto_repeats, sizeof(values.auto_repeats));
    214 
    215     InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl);
    216     free(keymap);
    217     return Success;
    218 }
    219 
    220 void
    221 xnestUpdateModifierState(unsigned int state)
    222 {
    223     DeviceIntPtr pDev = xnestKeyboardDevice;
    224     KeyClassPtr keyc = pDev->key;
    225     int i;
    226     CARD8 mask;
    227     int xkb_state;
    228 
    229     if (!pDev)
    230         return;
    231 
    232     xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
    233     state = state & 0xff;
    234 
    235     if (xkb_state == state)
    236         return;
    237 
    238     for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
    239         int key;
    240 
    241         /* Modifier is down, but shouldn't be */
    242         if ((xkb_state & mask) && !(state & mask)) {
    243             int count = keyc->modifierKeyCount[i];
    244 
    245             for (key = 0; key < MAP_LENGTH; key++)
    246                 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
    247                     if (mask == LockMask) {
    248                         xnestQueueKeyEvent(KeyPress, key);
    249                         xnestQueueKeyEvent(KeyRelease, key);
    250                     }
    251                     else if (key_is_down(pDev, key, KEY_PROCESSED))
    252                         xnestQueueKeyEvent(KeyRelease, key);
    253 
    254                     if (--count == 0)
    255                         break;
    256                 }
    257         }
    258 
    259         /* Modifier should be down, but isn't */
    260         if (!(xkb_state & mask) && (state & mask))
    261             for (key = 0; key < MAP_LENGTH; key++)
    262                 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
    263                     xnestQueueKeyEvent(KeyPress, key);
    264                     if (mask == LockMask)
    265                         xnestQueueKeyEvent(KeyRelease, key);
    266                     break;
    267                 }
    268     }
    269 }