105b261ecSmrg/*
205b261ecSmrg
305b261ecSmrgCopyright 1993 by Davor Matic
405b261ecSmrg
505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software
605b261ecSmrgand its documentation for any purpose is hereby granted without fee,
705b261ecSmrgprovided that the above copyright notice appear in all copies and that
805b261ecSmrgboth that copyright notice and this permission notice appear in
905b261ecSmrgsupporting documentation.  Davor Matic makes no representations about
1005b261ecSmrgthe suitability of this software for any purpose.  It is provided "as
1105b261ecSmrgis" without express or implied warranty.
1205b261ecSmrg
1305b261ecSmrg*/
1405b261ecSmrg
1505b261ecSmrg#ifdef HAVE_XNEST_CONFIG_H
1605b261ecSmrg#include <xnest-config.h>
1705b261ecSmrg#endif
1805b261ecSmrg
1935c4bbdfSmrg#ifdef WIN32
2035c4bbdfSmrg#include <X11/Xwindows.h>
2135c4bbdfSmrg#endif
2235c4bbdfSmrg
2305b261ecSmrg#include <X11/X.h>
2405b261ecSmrg#include <X11/Xproto.h>
2505b261ecSmrg#include <X11/keysym.h>
2605b261ecSmrg#include "screenint.h"
2705b261ecSmrg#include "inputstr.h"
2805b261ecSmrg#include "misc.h"
2905b261ecSmrg#include "scrnintstr.h"
3005b261ecSmrg#include "servermd.h"
3105b261ecSmrg
3205b261ecSmrg#include "Xnest.h"
3305b261ecSmrg
3405b261ecSmrg#include "Display.h"
3505b261ecSmrg#include "Screen.h"
3605b261ecSmrg#include "Keyboard.h"
3705b261ecSmrg#include "Args.h"
3805b261ecSmrg#include "Events.h"
3905b261ecSmrg
4005b261ecSmrg#include <X11/extensions/XKB.h>
416747b715Smrg#include "xkbsrv.h"
4205b261ecSmrg#include <X11/extensions/XKBconfig.h>
4305b261ecSmrg
4405b261ecSmrgextern Bool
4535c4bbdfSmrg XkbQueryExtension(Display * /* dpy */ ,
4635c4bbdfSmrg                   int * /* opcodeReturn */ ,
4735c4bbdfSmrg                   int * /* eventBaseReturn */ ,
4835c4bbdfSmrg                   int * /* errorBaseReturn */ ,
4935c4bbdfSmrg                   int * /* majorRtrn */ ,
5035c4bbdfSmrg                   int *        /* minorRtrn */
5135c4bbdfSmrg    );
5235c4bbdfSmrg
5335c4bbdfSmrgextern XkbDescPtr XkbGetKeyboard(Display * /* dpy */ ,
5435c4bbdfSmrg                                 unsigned int /* which */ ,
5535c4bbdfSmrg                                 unsigned int   /* deviceSpec */
5635c4bbdfSmrg    );
5735c4bbdfSmrg
5835c4bbdfSmrgextern Status XkbGetControls(Display * /* dpy */ ,
5935c4bbdfSmrg                             unsigned long /* which */ ,
6035c4bbdfSmrg                             XkbDescPtr /* desc */
6135c4bbdfSmrg    );
6205b261ecSmrg
6305b261ecSmrgDeviceIntPtr xnestKeyboardDevice = NULL;
6405b261ecSmrg
6505b261ecSmrgvoid
6635c4bbdfSmrgxnestBell(int volume, DeviceIntPtr pDev, void *ctrl, int cls)
6705b261ecSmrg{
6835c4bbdfSmrg    XBell(xnestDisplay, volume);
6905b261ecSmrg}
7005b261ecSmrg
7105b261ecSmrgvoid
7205b261ecSmrgDDXRingBell(int volume, int pitch, int duration)
7305b261ecSmrg{
7435c4bbdfSmrg    XBell(xnestDisplay, volume);
7505b261ecSmrg}
7605b261ecSmrg
7705b261ecSmrgvoid
7835c4bbdfSmrgxnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
7905b261ecSmrg{
8005b261ecSmrg#if 0
8135c4bbdfSmrg    unsigned long value_mask;
8235c4bbdfSmrg    XKeyboardControl values;
8335c4bbdfSmrg    int i;
8435c4bbdfSmrg
8535c4bbdfSmrg    value_mask = KBKeyClickPercent |
8635c4bbdfSmrg        KBBellPercent | KBBellPitch | KBBellDuration | KBAutoRepeatMode;
8735c4bbdfSmrg
8835c4bbdfSmrg    values.key_click_percent = ctrl->click;
8935c4bbdfSmrg    values.bell_percent = ctrl->bell;
9035c4bbdfSmrg    values.bell_pitch = ctrl->bell_pitch;
9135c4bbdfSmrg    values.bell_duration = ctrl->bell_duration;
9235c4bbdfSmrg    values.auto_repeat_mode = ctrl->autoRepeat ?
9335c4bbdfSmrg        AutoRepeatModeOn : AutoRepeatModeOff;
9435c4bbdfSmrg
9505b261ecSmrg    XChangeKeyboardControl(xnestDisplay, value_mask, &values);
9635c4bbdfSmrg
9735c4bbdfSmrg    /*
9835c4bbdfSmrg       value_mask = KBKey | KBAutoRepeatMode;
9935c4bbdfSmrg       At this point, we need to walk through the vector and compare it
10035c4bbdfSmrg       to the current server vector.  If there are differences, report them.
10135c4bbdfSmrg     */
10235c4bbdfSmrg
10335c4bbdfSmrg    value_mask = KBLed | KBLedMode;
10435c4bbdfSmrg    for (i = 1; i <= 32; i++) {
10535c4bbdfSmrg        values.led = i;
10635c4bbdfSmrg        values.led_mode =
10735c4bbdfSmrg            (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
10835c4bbdfSmrg        XChangeKeyboardControl(xnestDisplay, value_mask, &values);
10935c4bbdfSmrg    }
11005b261ecSmrg#endif
11105b261ecSmrg}
11205b261ecSmrg
11305b261ecSmrgint
11405b261ecSmrgxnestKeyboardProc(DeviceIntPtr pDev, int onoff)
11505b261ecSmrg{
11635c4bbdfSmrg    XModifierKeymap *modifier_keymap;
11735c4bbdfSmrg    KeySym *keymap;
11835c4bbdfSmrg    int mapWidth;
11935c4bbdfSmrg    int min_keycode, max_keycode;
12035c4bbdfSmrg    KeySymsRec keySyms;
12135c4bbdfSmrg    CARD8 modmap[MAP_LENGTH];
12235c4bbdfSmrg    int i, j;
12335c4bbdfSmrg    XKeyboardState values;
12435c4bbdfSmrg    XkbDescPtr xkb;
12535c4bbdfSmrg    int op, event, error, major, minor;
12635c4bbdfSmrg
12735c4bbdfSmrg    switch (onoff) {
12835c4bbdfSmrg    case DEVICE_INIT:
12935c4bbdfSmrg        XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
13005b261ecSmrg#ifdef _XSERVER64
13135c4bbdfSmrg        {
13235c4bbdfSmrg            KeySym64 *keymap64;
13335c4bbdfSmrg            int len;
13435c4bbdfSmrg
13535c4bbdfSmrg            keymap64 = XGetKeyboardMapping(xnestDisplay,
13635c4bbdfSmrg                                           min_keycode,
13735c4bbdfSmrg                                           max_keycode - min_keycode + 1,
13835c4bbdfSmrg                                           &mapWidth);
13935c4bbdfSmrg            len = (max_keycode - min_keycode + 1) * mapWidth;
14035c4bbdfSmrg            keymap = xallocarray(len, sizeof(KeySym));
14135c4bbdfSmrg            for (i = 0; i < len; ++i)
14235c4bbdfSmrg                keymap[i] = keymap64[i];
14335c4bbdfSmrg            XFree(keymap64);
14435c4bbdfSmrg        }
14505b261ecSmrg#else
14635c4bbdfSmrg        keymap = XGetKeyboardMapping(xnestDisplay,
14735c4bbdfSmrg                                     min_keycode,
14835c4bbdfSmrg                                     max_keycode - min_keycode + 1, &mapWidth);
14905b261ecSmrg#endif
150475c125cSmrg
15135c4bbdfSmrg        memset(modmap, 0, sizeof(modmap));
15235c4bbdfSmrg        modifier_keymap = XGetModifierMapping(xnestDisplay);
15335c4bbdfSmrg        for (j = 0; j < 8; j++)
15435c4bbdfSmrg            for (i = 0; i < modifier_keymap->max_keypermod; i++) {
15535c4bbdfSmrg                CARD8 keycode;
15635c4bbdfSmrg
15735c4bbdfSmrg                if ((keycode =
15835c4bbdfSmrg                     modifier_keymap->modifiermap[j *
15935c4bbdfSmrg                                                  modifier_keymap->
16035c4bbdfSmrg                                                  max_keypermod + i]))
16135c4bbdfSmrg                    modmap[keycode] |= 1 << j;
16235c4bbdfSmrg            }
16335c4bbdfSmrg        XFreeModifiermap(modifier_keymap);
16435c4bbdfSmrg
16535c4bbdfSmrg        keySyms.minKeyCode = min_keycode;
16635c4bbdfSmrg        keySyms.maxKeyCode = max_keycode;
16735c4bbdfSmrg        keySyms.mapWidth = mapWidth;
16835c4bbdfSmrg        keySyms.map = keymap;
16935c4bbdfSmrg
17035c4bbdfSmrg        if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor)
17135c4bbdfSmrg            == 0) {
17235c4bbdfSmrg            ErrorF("Unable to initialize XKEYBOARD extension.\n");
17335c4bbdfSmrg            goto XkbError;
17435c4bbdfSmrg        }
17535c4bbdfSmrg        xkb =
17635c4bbdfSmrg            XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask,
17735c4bbdfSmrg                           XkbUseCoreKbd);
17835c4bbdfSmrg        if (xkb == NULL || xkb->geom == NULL) {
17935c4bbdfSmrg            ErrorF("Couldn't get keyboard.\n");
18035c4bbdfSmrg            goto XkbError;
18135c4bbdfSmrg        }
18235c4bbdfSmrg        XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
18335c4bbdfSmrg
18435c4bbdfSmrg        InitKeyboardDeviceStruct(pDev, NULL,
18535c4bbdfSmrg                                 xnestBell, xnestChangeKeyboardControl);
18635c4bbdfSmrg
18735c4bbdfSmrg        XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode,
18835c4bbdfSmrg                              keySyms.maxKeyCode - keySyms.minKeyCode + 1,
18935c4bbdfSmrg                              modmap, serverClient);
19035c4bbdfSmrg
19135c4bbdfSmrg        XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
19235c4bbdfSmrg        XkbFreeKeyboard(xkb, 0, False);
19335c4bbdfSmrg        free(keymap);
19435c4bbdfSmrg        break;
19535c4bbdfSmrg    case DEVICE_ON:
19635c4bbdfSmrg        xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
19735c4bbdfSmrg        for (i = 0; i < xnestNumScreens; i++)
19835c4bbdfSmrg            XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
19935c4bbdfSmrg        break;
20035c4bbdfSmrg    case DEVICE_OFF:
20135c4bbdfSmrg        xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
20235c4bbdfSmrg        for (i = 0; i < xnestNumScreens; i++)
20335c4bbdfSmrg            XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
20435c4bbdfSmrg        break;
20535c4bbdfSmrg    case DEVICE_CLOSE:
20635c4bbdfSmrg        break;
20705b261ecSmrg    }
20835c4bbdfSmrg    return Success;
20935c4bbdfSmrg
21035c4bbdfSmrg XkbError:
21135c4bbdfSmrg    XGetKeyboardControl(xnestDisplay, &values);
21235c4bbdfSmrg    memmove((char *) defaultKeyboardControl.autoRepeats,
21335c4bbdfSmrg            (char *) values.auto_repeats, sizeof(values.auto_repeats));
21435c4bbdfSmrg
21535c4bbdfSmrg    InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl);
21635c4bbdfSmrg    free(keymap);
21735c4bbdfSmrg    return Success;
21805b261ecSmrg}
21905b261ecSmrg
22005b261ecSmrgvoid
22105b261ecSmrgxnestUpdateModifierState(unsigned int state)
22205b261ecSmrg{
22335c4bbdfSmrg    DeviceIntPtr pDev = xnestKeyboardDevice;
22435c4bbdfSmrg    KeyClassPtr keyc = pDev->key;
22535c4bbdfSmrg    int i;
22635c4bbdfSmrg    CARD8 mask;
22735c4bbdfSmrg    int xkb_state;
22835c4bbdfSmrg
22935c4bbdfSmrg    if (!pDev)
23035c4bbdfSmrg        return;
23135c4bbdfSmrg
23235c4bbdfSmrg    xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
23335c4bbdfSmrg    state = state & 0xff;
23435c4bbdfSmrg
23535c4bbdfSmrg    if (xkb_state == state)
23635c4bbdfSmrg        return;
23735c4bbdfSmrg
23835c4bbdfSmrg    for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
23935c4bbdfSmrg        int key;
24035c4bbdfSmrg
241ed6184dfSmrg        /* Modifier is down, but shouldn't be */
24235c4bbdfSmrg        if ((xkb_state & mask) && !(state & mask)) {
24335c4bbdfSmrg            int count = keyc->modifierKeyCount[i];
24435c4bbdfSmrg
24535c4bbdfSmrg            for (key = 0; key < MAP_LENGTH; key++)
24635c4bbdfSmrg                if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
24735c4bbdfSmrg                    if (mask == LockMask) {
24835c4bbdfSmrg                        xnestQueueKeyEvent(KeyPress, key);
24935c4bbdfSmrg                        xnestQueueKeyEvent(KeyRelease, key);
25035c4bbdfSmrg                    }
25135c4bbdfSmrg                    else if (key_is_down(pDev, key, KEY_PROCESSED))
25235c4bbdfSmrg                        xnestQueueKeyEvent(KeyRelease, key);
25335c4bbdfSmrg
25435c4bbdfSmrg                    if (--count == 0)
25535c4bbdfSmrg                        break;
25635c4bbdfSmrg                }
25735c4bbdfSmrg        }
25835c4bbdfSmrg
259ed6184dfSmrg        /* Modifier should be down, but isn't */
26035c4bbdfSmrg        if (!(xkb_state & mask) && (state & mask))
26135c4bbdfSmrg            for (key = 0; key < MAP_LENGTH; key++)
26235c4bbdfSmrg                if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
26335c4bbdfSmrg                    xnestQueueKeyEvent(KeyPress, key);
26435c4bbdfSmrg                    if (mask == LockMask)
26535c4bbdfSmrg                        xnestQueueKeyEvent(KeyRelease, key);
26635c4bbdfSmrg                    break;
26735c4bbdfSmrg                }
26805b261ecSmrg    }
26905b261ecSmrg}
270