xserver

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

kinput.c (56265B)


      1 /*
      2  * Copyright © 1999 Keith Packard
      3  * Copyright © 2006 Nokia Corporation
      4  *
      5  * Permission to use, copy, modify, distribute, and sell this software and its
      6  * documentation for any purpose is hereby granted without fee, provided that
      7  * the above copyright notice appear in all copies and that both that
      8  * copyright notice and this permission notice appear in supporting
      9  * documentation, and that the name of the authors not be used in
     10  * advertising or publicity pertaining to distribution of the software without
     11  * specific, written prior permission.  The authors make no
     12  * representations about the suitability of this software for any purpose.  It
     13  * is provided "as is" without express or implied warranty.
     14  *
     15  * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     17  * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     21  * PERFORMANCE OF THIS SOFTWARE.
     22  */
     23 
     24 #ifdef HAVE_DIX_CONFIG_H
     25 #include <dix-config.h>
     26 #include <xkb-config.h>
     27 #endif
     28 #include "kdrive.h"
     29 #include "inputstr.h"
     30 
     31 #define XK_PUBLISHING
     32 #include <X11/keysym.h>
     33 #if HAVE_X11_XF86KEYSYM_H
     34 #include <X11/XF86keysym.h>
     35 #endif
     36 #include <stdio.h>
     37 #ifdef __sun
     38 #include <sys/file.h>           /* needed for FNONBLOCK & FASYNC */
     39 #endif
     40 
     41 #include "xkbsrv.h"
     42 
     43 #include <X11/extensions/XI.h>
     44 #include <X11/extensions/XIproto.h>
     45 #include "XIstubs.h"            /* even though we don't use stubs.  cute, no? */
     46 #include "exevents.h"
     47 #include "extinit.h"
     48 #include "exglobals.h"
     49 #include "eventstr.h"
     50 #include "xserver-properties.h"
     51 #include "inpututils.h"
     52 #include "optionstr.h"
     53 
     54 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
     55 #include <hotplug.h>
     56 #endif
     57 
     58 #define AtomFromName(x) MakeAtom(x, strlen(x), 1)
     59 
     60 struct KdConfigDevice {
     61     char *line;
     62     struct KdConfigDevice *next;
     63 };
     64 
     65 /* kdKeyboards and kdPointers hold all the real devices. */
     66 static KdKeyboardInfo *kdKeyboards = NULL;
     67 static KdPointerInfo *kdPointers = NULL;
     68 static struct KdConfigDevice *kdConfigKeyboards = NULL;
     69 static struct KdConfigDevice *kdConfigPointers = NULL;
     70 
     71 static KdKeyboardDriver *kdKeyboardDrivers = NULL;
     72 static KdPointerDriver *kdPointerDrivers = NULL;
     73 
     74 static Bool kdInputEnabled;
     75 static Bool kdOffScreen;
     76 static unsigned long kdOffScreenTime;
     77 
     78 static KdPointerMatrix kdPointerMatrix = {
     79     {{1, 0, 0},
     80      {0, 1, 0}}
     81 };
     82 
     83 extern Bool kdRawPointerCoordinates;
     84 
     85 extern const char *kdGlobalXkbRules;
     86 extern const char *kdGlobalXkbModel;
     87 extern const char *kdGlobalXkbLayout;
     88 extern const char *kdGlobalXkbVariant;
     89 extern const char *kdGlobalXkbOptions;
     90 
     91 #ifdef FNONBLOCK
     92 #define NOBLOCK FNONBLOCK
     93 #else
     94 #define NOBLOCK FNDELAY
     95 #endif
     96 
     97 static void
     98 KdResetInputMachine(void)
     99 {
    100     KdPointerInfo *pi;
    101 
    102     for (pi = kdPointers; pi; pi = pi->next) {
    103         pi->mouseState = start;
    104         pi->eventHeld = FALSE;
    105     }
    106 }
    107 
    108 void
    109 KdDisableInput(void)
    110 {
    111     KdKeyboardInfo *ki;
    112     KdPointerInfo *pi;
    113 
    114     input_lock();
    115 
    116     for (ki = kdKeyboards; ki; ki = ki->next) {
    117         if (ki->driver && ki->driver->Disable)
    118             (*ki->driver->Disable) (ki);
    119     }
    120 
    121     for (pi = kdPointers; pi; pi = pi->next) {
    122         if (pi->driver && pi->driver->Disable)
    123             (*pi->driver->Disable) (pi);
    124     }
    125 
    126     kdInputEnabled = FALSE;
    127 }
    128 
    129 void
    130 KdEnableInput(void)
    131 {
    132     InternalEvent ev;
    133     KdKeyboardInfo *ki;
    134     KdPointerInfo *pi;
    135 
    136     kdInputEnabled = TRUE;
    137 
    138     ev.any.time = GetTimeInMillis();
    139 
    140     for (ki = kdKeyboards; ki; ki = ki->next) {
    141         if (ki->driver && ki->driver->Enable)
    142             (*ki->driver->Enable) (ki);
    143         /* reset screen saver */
    144         NoticeEventTime (&ev, ki->dixdev);
    145     }
    146 
    147     for (pi = kdPointers; pi; pi = pi->next) {
    148         if (pi->driver && pi->driver->Enable)
    149             (*pi->driver->Enable) (pi);
    150         /* reset screen saver */
    151         NoticeEventTime (&ev, pi->dixdev);
    152     }
    153 
    154     input_unlock();
    155 }
    156 
    157 static KdKeyboardDriver *
    158 KdFindKeyboardDriver(const char *name)
    159 {
    160     KdKeyboardDriver *ret;
    161 
    162     /* ask a stupid question ... */
    163     if (!name)
    164         return NULL;
    165 
    166     for (ret = kdKeyboardDrivers; ret; ret = ret->next) {
    167         if (strcmp(ret->name, name) == 0)
    168             return ret;
    169     }
    170 
    171     return NULL;
    172 }
    173 
    174 static KdPointerDriver *
    175 KdFindPointerDriver(const char *name)
    176 {
    177     KdPointerDriver *ret;
    178 
    179     /* ask a stupid question ... */
    180     if (!name)
    181         return NULL;
    182 
    183     for (ret = kdPointerDrivers; ret; ret = ret->next) {
    184         if (strcmp(ret->name, name) == 0)
    185             return ret;
    186     }
    187 
    188     return NULL;
    189 }
    190 
    191 static int
    192 KdPointerProc(DeviceIntPtr pDevice, int onoff)
    193 {
    194     DevicePtr pDev = (DevicePtr) pDevice;
    195     KdPointerInfo *pi;
    196     Atom xiclass;
    197     Atom *btn_labels;
    198     Atom *axes_labels;
    199 
    200     if (!pDev)
    201         return BadImplementation;
    202 
    203     for (pi = kdPointers; pi; pi = pi->next) {
    204         if (pi->dixdev && pi->dixdev->id == pDevice->id)
    205             break;
    206     }
    207 
    208     if (!pi || !pi->dixdev || pi->dixdev->id != pDevice->id) {
    209         ErrorF("[KdPointerProc] Failed to find pointer for device %d!\n",
    210                pDevice->id);
    211         return BadImplementation;
    212     }
    213 
    214     switch (onoff) {
    215     case DEVICE_INIT:
    216 #ifdef DEBUG
    217         ErrorF("initialising pointer %s ...\n", pi->name);
    218 #endif
    219         if (!pi->driver) {
    220             if (!pi->driverPrivate) {
    221                 ErrorF("no driver specified for pointer device \"%s\" (%s)\n",
    222                        pi->name ? pi->name : "(unnamed)", pi->path);
    223                 return BadImplementation;
    224             }
    225 
    226             pi->driver = KdFindPointerDriver(pi->driverPrivate);
    227             if (!pi->driver) {
    228                 ErrorF("Couldn't find pointer driver %s\n",
    229                        pi->driverPrivate ? (char *) pi->driverPrivate :
    230                        "(unnamed)");
    231                 return !Success;
    232             }
    233             free(pi->driverPrivate);
    234             pi->driverPrivate = NULL;
    235         }
    236 
    237         if (!pi->driver->Init) {
    238             ErrorF("no init function\n");
    239             return BadImplementation;
    240         }
    241 
    242         if ((*pi->driver->Init) (pi) != Success) {
    243             return !Success;
    244         }
    245 
    246         btn_labels = calloc(pi->nButtons, sizeof(Atom));
    247         if (!btn_labels)
    248             return BadAlloc;
    249         axes_labels = calloc(pi->nAxes, sizeof(Atom));
    250         if (!axes_labels) {
    251             free(btn_labels);
    252             return BadAlloc;
    253         }
    254 
    255         switch (pi->nAxes) {
    256         default:
    257         case 7:
    258             btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
    259         case 6:
    260             btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
    261         case 5:
    262             btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
    263         case 4:
    264             btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
    265         case 3:
    266             btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
    267         case 2:
    268             btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
    269         case 1:
    270             btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
    271         case 0:
    272             break;
    273         }
    274 
    275         if (pi->nAxes >= 2) {
    276             axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
    277             axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
    278         }
    279 
    280         InitPointerDeviceStruct(pDev, pi->map, pi->nButtons, btn_labels,
    281                                 (PtrCtrlProcPtr) NoopDDA,
    282                                 GetMotionHistorySize(), pi->nAxes, axes_labels);
    283 
    284         free(btn_labels);
    285         free(axes_labels);
    286 
    287         if (pi->inputClass == KD_TOUCHSCREEN) {
    288             xiclass = AtomFromName(XI_TOUCHSCREEN);
    289         }
    290         else {
    291             xiclass = AtomFromName(XI_MOUSE);
    292         }
    293 
    294         AssignTypeAndName(pi->dixdev, xiclass,
    295                           pi->name ? pi->name : "Generic KDrive Pointer");
    296 
    297         return Success;
    298 
    299     case DEVICE_ON:
    300         if (pDev->on == TRUE)
    301             return Success;
    302 
    303         if (!pi->driver->Enable) {
    304             ErrorF("no enable function\n");
    305             return BadImplementation;
    306         }
    307 
    308         if ((*pi->driver->Enable) (pi) == Success) {
    309             pDev->on = TRUE;
    310             return Success;
    311         }
    312         else {
    313             return BadImplementation;
    314         }
    315 
    316         return Success;
    317 
    318     case DEVICE_OFF:
    319         if (pDev->on == FALSE) {
    320             return Success;
    321         }
    322 
    323         if (!pi->driver->Disable) {
    324             return BadImplementation;
    325         }
    326         else {
    327             (*pi->driver->Disable) (pi);
    328             pDev->on = FALSE;
    329             return Success;
    330         }
    331 
    332         return Success;
    333 
    334     case DEVICE_CLOSE:
    335         if (pDev->on) {
    336             if (!pi->driver->Disable) {
    337                 return BadImplementation;
    338             }
    339             (*pi->driver->Disable) (pi);
    340             pDev->on = FALSE;
    341         }
    342 
    343         if (!pi->driver->Fini)
    344             return BadImplementation;
    345 
    346         (*pi->driver->Fini) (pi);
    347 
    348         KdRemovePointer(pi);
    349 
    350         return Success;
    351     }
    352 
    353     /* NOTREACHED */
    354     return BadImplementation;
    355 }
    356 
    357 static void
    358 KdRingBell(KdKeyboardInfo * ki, int volume, int pitch, int duration)
    359 {
    360     if (!ki || !ki->driver || !ki->driver->Bell)
    361         return;
    362 
    363     if (kdInputEnabled)
    364         (*ki->driver->Bell) (ki, volume, pitch, duration);
    365 }
    366 
    367 static void
    368 KdBell(int volume, DeviceIntPtr pDev, void *arg, int something)
    369 {
    370     KeybdCtrl *ctrl = arg;
    371     KdKeyboardInfo *ki = NULL;
    372 
    373     for (ki = kdKeyboards; ki; ki = ki->next) {
    374         if (ki->dixdev && ki->dixdev->id == pDev->id)
    375             break;
    376     }
    377 
    378     if (!ki || !ki->dixdev || ki->dixdev->id != pDev->id || !ki->driver)
    379         return;
    380 
    381     KdRingBell(ki, volume, ctrl->bell_pitch, ctrl->bell_duration);
    382 }
    383 
    384 void
    385 DDXRingBell(int volume, int pitch, int duration)
    386 {
    387     KdKeyboardInfo *ki = NULL;
    388 
    389     for (ki = kdKeyboards; ki; ki = ki->next) {
    390         if (ki->dixdev->coreEvents)
    391             KdRingBell(ki, volume, pitch, duration);
    392     }
    393 }
    394 
    395 static void
    396 KdSetLeds(KdKeyboardInfo * ki, int leds)
    397 {
    398     if (!ki || !ki->driver)
    399         return;
    400 
    401     if (kdInputEnabled) {
    402         if (ki->driver->Leds)
    403             (*ki->driver->Leds) (ki, leds);
    404     }
    405 }
    406 
    407 static void
    408 KdSetLed(KdKeyboardInfo * ki, int led, Bool on)
    409 {
    410     if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed)
    411         return;
    412 
    413     NoteLedState(ki->dixdev, led, on);
    414     KdSetLeds(ki, ki->dixdev->kbdfeed->ctrl.leds);
    415 }
    416 
    417 void
    418 KdSetPointerMatrix(KdPointerMatrix * matrix)
    419 {
    420     kdPointerMatrix = *matrix;
    421 }
    422 
    423 void
    424 KdComputePointerMatrix(KdPointerMatrix * m, Rotation randr, int width,
    425                        int height)
    426 {
    427     int x_dir = 1, y_dir = 1;
    428     int i, j;
    429     int size[2];
    430 
    431     size[0] = width;
    432     size[1] = height;
    433     if (randr & RR_Reflect_X)
    434         x_dir = -1;
    435     if (randr & RR_Reflect_Y)
    436         y_dir = -1;
    437     switch (randr & (RR_Rotate_All)) {
    438     case RR_Rotate_0:
    439         m->matrix[0][0] = x_dir;
    440         m->matrix[0][1] = 0;
    441         m->matrix[1][0] = 0;
    442         m->matrix[1][1] = y_dir;
    443         break;
    444     case RR_Rotate_90:
    445         m->matrix[0][0] = 0;
    446         m->matrix[0][1] = -x_dir;
    447         m->matrix[1][0] = y_dir;
    448         m->matrix[1][1] = 0;
    449         break;
    450     case RR_Rotate_180:
    451         m->matrix[0][0] = -x_dir;
    452         m->matrix[0][1] = 0;
    453         m->matrix[1][0] = 0;
    454         m->matrix[1][1] = -y_dir;
    455         break;
    456     case RR_Rotate_270:
    457         m->matrix[0][0] = 0;
    458         m->matrix[0][1] = x_dir;
    459         m->matrix[1][0] = -y_dir;
    460         m->matrix[1][1] = 0;
    461         break;
    462     }
    463     for (i = 0; i < 2; i++) {
    464         m->matrix[i][2] = 0;
    465         for (j = 0; j < 2; j++)
    466             if (m->matrix[i][j] < 0)
    467                 m->matrix[i][2] = size[j] - 1;
    468     }
    469 }
    470 
    471 static void
    472 KdKbdCtrl(DeviceIntPtr pDevice, KeybdCtrl * ctrl)
    473 {
    474     KdKeyboardInfo *ki;
    475 
    476     for (ki = kdKeyboards; ki; ki = ki->next) {
    477         if (ki->dixdev && ki->dixdev->id == pDevice->id)
    478             break;
    479     }
    480 
    481     if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id || !ki->driver)
    482         return;
    483 
    484     KdSetLeds(ki, ctrl->leds);
    485     ki->bellPitch = ctrl->bell_pitch;
    486     ki->bellDuration = ctrl->bell_duration;
    487 }
    488 
    489 static int
    490 KdKeyboardProc(DeviceIntPtr pDevice, int onoff)
    491 {
    492     Bool ret;
    493     DevicePtr pDev = (DevicePtr) pDevice;
    494     KdKeyboardInfo *ki;
    495     Atom xiclass;
    496     XkbRMLVOSet rmlvo;
    497 
    498     if (!pDev)
    499         return BadImplementation;
    500 
    501     for (ki = kdKeyboards; ki; ki = ki->next) {
    502         if (ki->dixdev && ki->dixdev->id == pDevice->id)
    503             break;
    504     }
    505 
    506     if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id) {
    507         return BadImplementation;
    508     }
    509 
    510     switch (onoff) {
    511     case DEVICE_INIT:
    512 #ifdef DEBUG
    513         ErrorF("initialising keyboard %s\n", ki->name);
    514 #endif
    515         if (!ki->driver) {
    516             if (!ki->driverPrivate) {
    517                 ErrorF("no driver specified for keyboard device \"%s\" (%s)\n",
    518                        ki->name ? ki->name : "(unnamed)", ki->path);
    519                 return BadImplementation;
    520             }
    521 
    522             ki->driver = KdFindKeyboardDriver(ki->driverPrivate);
    523             if (!ki->driver) {
    524                 ErrorF("Couldn't find keyboard driver %s\n",
    525                        ki->driverPrivate ? (char *) ki->driverPrivate :
    526                        "(unnamed)");
    527                 return !Success;
    528             }
    529             free(ki->driverPrivate);
    530             ki->driverPrivate = NULL;
    531         }
    532 
    533         if (!ki->driver->Init) {
    534             ErrorF("Keyboard %s: no init function\n", ki->name);
    535             return BadImplementation;
    536         }
    537 
    538         memset(&rmlvo, 0, sizeof(rmlvo));
    539         rmlvo.rules = ki->xkbRules;
    540         rmlvo.model = ki->xkbModel;
    541         rmlvo.layout = ki->xkbLayout;
    542         rmlvo.variant = ki->xkbVariant;
    543         rmlvo.options = ki->xkbOptions;
    544         ret = InitKeyboardDeviceStruct(pDevice, &rmlvo, KdBell, KdKbdCtrl);
    545         if (!ret) {
    546             ErrorF("Couldn't initialise keyboard %s\n", ki->name);
    547             return BadImplementation;
    548         }
    549 
    550         if ((*ki->driver->Init) (ki) != Success) {
    551             return !Success;
    552         }
    553 
    554         xiclass = AtomFromName(XI_KEYBOARD);
    555         AssignTypeAndName(pDevice, xiclass,
    556                           ki->name ? ki->name : "Generic KDrive Keyboard");
    557 
    558         KdResetInputMachine();
    559 
    560         return Success;
    561 
    562     case DEVICE_ON:
    563         if (pDev->on == TRUE)
    564             return Success;
    565 
    566         if (!ki->driver->Enable)
    567             return BadImplementation;
    568 
    569         if ((*ki->driver->Enable) (ki) != Success) {
    570             return BadMatch;
    571         }
    572 
    573         pDev->on = TRUE;
    574         return Success;
    575 
    576     case DEVICE_OFF:
    577         if (pDev->on == FALSE)
    578             return Success;
    579 
    580         if (!ki->driver->Disable)
    581             return BadImplementation;
    582 
    583         (*ki->driver->Disable) (ki);
    584         pDev->on = FALSE;
    585 
    586         return Success;
    587 
    588         break;
    589 
    590     case DEVICE_CLOSE:
    591         if (pDev->on) {
    592             if (!ki->driver->Disable)
    593                 return BadImplementation;
    594 
    595             (*ki->driver->Disable) (ki);
    596             pDev->on = FALSE;
    597         }
    598 
    599         if (!ki->driver->Fini)
    600             return BadImplementation;
    601 
    602         (*ki->driver->Fini) (ki);
    603 
    604         KdRemoveKeyboard(ki);
    605 
    606         return Success;
    607     }
    608 
    609     /* NOTREACHED */
    610     return BadImplementation;
    611 }
    612 
    613 void
    614 KdAddPointerDriver(KdPointerDriver * driver)
    615 {
    616     KdPointerDriver **prev;
    617 
    618     if (!driver)
    619         return;
    620 
    621     for (prev = &kdPointerDrivers; *prev; prev = &(*prev)->next) {
    622         if (*prev == driver)
    623             return;
    624     }
    625     *prev = driver;
    626 }
    627 
    628 void
    629 KdRemovePointerDriver(KdPointerDriver * driver)
    630 {
    631     KdPointerDriver *tmp;
    632 
    633     if (!driver)
    634         return;
    635 
    636     /* FIXME remove all pointers using this driver */
    637     for (tmp = kdPointerDrivers; tmp; tmp = tmp->next) {
    638         if (tmp->next == driver)
    639             tmp->next = driver->next;
    640     }
    641     if (tmp == driver)
    642         tmp = NULL;
    643 }
    644 
    645 void
    646 KdAddKeyboardDriver(KdKeyboardDriver * driver)
    647 {
    648     KdKeyboardDriver **prev;
    649 
    650     if (!driver)
    651         return;
    652 
    653     for (prev = &kdKeyboardDrivers; *prev; prev = &(*prev)->next) {
    654         if (*prev == driver)
    655             return;
    656     }
    657     *prev = driver;
    658 }
    659 
    660 void
    661 KdRemoveKeyboardDriver(KdKeyboardDriver * driver)
    662 {
    663     KdKeyboardDriver *tmp;
    664 
    665     if (!driver)
    666         return;
    667 
    668     /* FIXME remove all keyboards using this driver */
    669     for (tmp = kdKeyboardDrivers; tmp; tmp = tmp->next) {
    670         if (tmp->next == driver)
    671             tmp->next = driver->next;
    672     }
    673     if (tmp == driver)
    674         tmp = NULL;
    675 }
    676 
    677 KdKeyboardInfo *
    678 KdNewKeyboard(void)
    679 {
    680     KdKeyboardInfo *ki = calloc(sizeof(KdKeyboardInfo), 1);
    681 
    682     if (!ki)
    683         return NULL;
    684 
    685     ki->minScanCode = 0;
    686     ki->maxScanCode = 0;
    687     ki->leds = 0;
    688     ki->bellPitch = 1000;
    689     ki->bellDuration = 200;
    690     ki->next = NULL;
    691     ki->options = NULL;
    692     ki->name = strdup("Generic Keyboard");
    693     ki->path = NULL;
    694     ki->xkbRules = strdup(kdGlobalXkbRules ? kdGlobalXkbRules : XKB_DFLT_RULES);
    695     ki->xkbModel = strdup(kdGlobalXkbModel ? kdGlobalXkbModel : XKB_DFLT_MODEL);
    696     ki->xkbLayout = strdup(kdGlobalXkbLayout ? kdGlobalXkbLayout : XKB_DFLT_LAYOUT);
    697     ki->xkbVariant = strdup(kdGlobalXkbVariant ? kdGlobalXkbVariant :XKB_DFLT_VARIANT);
    698     ki->xkbOptions = strdup(kdGlobalXkbOptions ? kdGlobalXkbOptions : XKB_DFLT_OPTIONS);
    699 
    700     return ki;
    701 }
    702 
    703 int
    704 KdAddConfigKeyboard(char *keyboard)
    705 {
    706     struct KdConfigDevice **prev, *new;
    707 
    708     if (!keyboard)
    709         return Success;
    710 
    711     new = (struct KdConfigDevice *) calloc(sizeof(struct KdConfigDevice), 1);
    712     if (!new)
    713         return BadAlloc;
    714 
    715     new->line = strdup(keyboard);
    716     new->next = NULL;
    717 
    718     for (prev = &kdConfigKeyboards; *prev; prev = &(*prev)->next);
    719     *prev = new;
    720 
    721     return Success;
    722 }
    723 
    724 int
    725 KdAddKeyboard(KdKeyboardInfo * ki)
    726 {
    727     KdKeyboardInfo **prev;
    728 
    729     if (!ki)
    730         return !Success;
    731 
    732     ki->dixdev = AddInputDevice(serverClient, KdKeyboardProc, TRUE);
    733     if (!ki->dixdev) {
    734         ErrorF("Couldn't register keyboard device %s\n",
    735                ki->name ? ki->name : "(unnamed)");
    736         return !Success;
    737     }
    738 
    739 #ifdef DEBUG
    740     ErrorF("added keyboard %s with dix id %d\n", ki->name, ki->dixdev->id);
    741 #endif
    742 
    743     for (prev = &kdKeyboards; *prev; prev = &(*prev)->next);
    744     *prev = ki;
    745 
    746     return Success;
    747 }
    748 
    749 void
    750 KdRemoveKeyboard(KdKeyboardInfo * ki)
    751 {
    752     KdKeyboardInfo **prev;
    753 
    754     if (!ki)
    755         return;
    756 
    757     for (prev = &kdKeyboards; *prev; prev = &(*prev)->next) {
    758         if (*prev == ki) {
    759             *prev = ki->next;
    760             break;
    761         }
    762     }
    763 
    764     KdFreeKeyboard(ki);
    765 }
    766 
    767 int
    768 KdAddConfigPointer(char *pointer)
    769 {
    770     struct KdConfigDevice **prev, *new;
    771 
    772     if (!pointer)
    773         return Success;
    774 
    775     new = (struct KdConfigDevice *) calloc(sizeof(struct KdConfigDevice), 1);
    776     if (!new)
    777         return BadAlloc;
    778 
    779     new->line = strdup(pointer);
    780     new->next = NULL;
    781 
    782     for (prev = &kdConfigPointers; *prev; prev = &(*prev)->next);
    783     *prev = new;
    784 
    785     return Success;
    786 }
    787 
    788 int
    789 KdAddPointer(KdPointerInfo * pi)
    790 {
    791     KdPointerInfo **prev;
    792 
    793     if (!pi)
    794         return Success;
    795 
    796     pi->mouseState = start;
    797     pi->eventHeld = FALSE;
    798 
    799     pi->dixdev = AddInputDevice(serverClient, KdPointerProc, TRUE);
    800     if (!pi->dixdev) {
    801         ErrorF("Couldn't add pointer device %s\n",
    802                pi->name ? pi->name : "(unnamed)");
    803         return BadDevice;
    804     }
    805 
    806     for (prev = &kdPointers; *prev; prev = &(*prev)->next);
    807     *prev = pi;
    808 
    809     return Success;
    810 }
    811 
    812 void
    813 KdRemovePointer(KdPointerInfo * pi)
    814 {
    815     KdPointerInfo **prev;
    816 
    817     if (!pi)
    818         return;
    819 
    820     for (prev = &kdPointers; *prev; prev = &(*prev)->next) {
    821         if (*prev == pi) {
    822             *prev = pi->next;
    823             break;
    824         }
    825     }
    826 
    827     KdFreePointer(pi);
    828 }
    829 
    830 /*
    831  * You can call your kdriver server with something like:
    832  * $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd
    833  * evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br
    834  */
    835 static Bool
    836 KdGetOptions(InputOption **options, char *string)
    837 {
    838     InputOption *newopt = NULL;
    839     char *key = NULL, *value = NULL;
    840     int tam_key = 0;
    841 
    842     if (strchr(string, '=')) {
    843         tam_key = (strchr(string, '=') - string);
    844         key = strndup(string, tam_key);
    845         if (!key)
    846             goto out;
    847 
    848         value = strdup(strchr(string, '=') + 1);
    849         if (!value)
    850             goto out;
    851     }
    852     else {
    853         key = strdup(string);
    854         value = NULL;
    855     }
    856 
    857     newopt = input_option_new(*options, key, value);
    858     if (newopt)
    859         *options = newopt;
    860 
    861  out:
    862     free(key);
    863     free(value);
    864 
    865     return (newopt != NULL);
    866 }
    867 
    868 static void
    869 KdParseKbdOptions(KdKeyboardInfo * ki)
    870 {
    871     InputOption *option = NULL;
    872 
    873     nt_list_for_each_entry(option, ki->options, list.next) {
    874         const char *key = input_option_get_key(option);
    875         const char *value = input_option_get_value(option);
    876 
    877         if (
    878 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
    879             strcasecmp(key, "xkb_rules") == 0 ||
    880 #endif
    881             strcasecmp(key, "XkbRules") == 0)
    882             ki->xkbRules = strdup(value);
    883         else if (
    884 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
    885                  strcasecmp(key, "xkb_model") == 0 ||
    886 #endif
    887                  strcasecmp(key, "XkbModel") == 0)
    888             ki->xkbModel = strdup(value);
    889         else if (
    890 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
    891                  strcasecmp(key, "xkb_layout") == 0 ||
    892 #endif
    893                  strcasecmp(key, "XkbLayout") == 0)
    894             ki->xkbLayout = strdup(value);
    895         else if (
    896 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
    897                  strcasecmp(key, "xkb_variant") == 0 ||
    898 #endif
    899                  strcasecmp(key, "XkbVariant") == 0)
    900             ki->xkbVariant = strdup(value);
    901         else if (
    902 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
    903                  strcasecmp(key, "xkb_options") == 0 ||
    904 #endif
    905                  strcasecmp(key, "XkbOptions") == 0)
    906             ki->xkbOptions = strdup(value);
    907         else if (!strcasecmp(key, "device")) {
    908             if (ki->path != NULL)
    909                 free(ki->path);
    910             ki->path = strdup(value);
    911         }
    912 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
    913         else if (!strcasecmp(key, "path")) {
    914             if (ki->path != NULL)
    915                 free(ki->path);
    916             ki->path = strdup(value);
    917         }
    918         else if (!strcasecmp(key, "name")) {
    919             free(ki->name);
    920             ki->name = strdup(value);
    921         }
    922 #endif
    923         else if (!strcasecmp(key, "driver"))
    924             ki->driver = KdFindKeyboardDriver(value);
    925         else
    926             ErrorF("Kbd option key (%s) of value (%s) not assigned!\n",
    927                    key, value);
    928     }
    929 }
    930 
    931 static KdKeyboardInfo *
    932 KdParseKeyboard(const char *arg)
    933 {
    934     char save[1024];
    935     char delim;
    936     InputOption *options = NULL;
    937     KdKeyboardInfo *ki = NULL;
    938 
    939     ki = KdNewKeyboard();
    940     if (!ki)
    941         return NULL;
    942 
    943     ki->name = strdup("Unknown KDrive Keyboard");
    944     ki->path = NULL;
    945     ki->driver = NULL;
    946     ki->driverPrivate = NULL;
    947     ki->next = NULL;
    948 
    949     if (!arg) {
    950         ErrorF("keybd: no arg\n");
    951         KdFreeKeyboard(ki);
    952         return NULL;
    953     }
    954 
    955     if (strlen(arg) >= sizeof(save)) {
    956         ErrorF("keybd: arg too long\n");
    957         KdFreeKeyboard(ki);
    958         return NULL;
    959     }
    960 
    961     arg = KdParseFindNext(arg, ",", save, &delim);
    962     if (!save[0]) {
    963         ErrorF("keybd: failed on save[0]\n");
    964         KdFreeKeyboard(ki);
    965         return NULL;
    966     }
    967 
    968     if (strcmp(save, "auto") == 0)
    969         ki->driverPrivate = NULL;
    970     else
    971         ki->driverPrivate = strdup(save);
    972 
    973     if (delim != ',') {
    974         return ki;
    975     }
    976 
    977     arg = KdParseFindNext(arg, ",", save, &delim);
    978 
    979     while (delim == ',') {
    980         arg = KdParseFindNext(arg, ",", save, &delim);
    981 
    982         if (!KdGetOptions(&options, save)) {
    983             KdFreeKeyboard(ki);
    984             return NULL;
    985         }
    986     }
    987 
    988     if (options) {
    989         ki->options = options;
    990         KdParseKbdOptions(ki);
    991     }
    992 
    993     return ki;
    994 }
    995 
    996 static void
    997 KdParsePointerOptions(KdPointerInfo * pi)
    998 {
    999     InputOption *option = NULL;
   1000 
   1001     nt_list_for_each_entry(option, pi->options, list.next) {
   1002         const char *key = input_option_get_key(option);
   1003         const char *value = input_option_get_value(option);
   1004 
   1005         if (!strcasecmp(key, "emulatemiddle"))
   1006             pi->emulateMiddleButton = TRUE;
   1007         else if (!strcasecmp(key, "noemulatemiddle"))
   1008             pi->emulateMiddleButton = FALSE;
   1009         else if (!strcasecmp(key, "transformcoord"))
   1010             pi->transformCoordinates = TRUE;
   1011         else if (!strcasecmp(key, "rawcoord"))
   1012             pi->transformCoordinates = FALSE;
   1013         else if (!strcasecmp(key, "device")) {
   1014             if (pi->path != NULL)
   1015                 free(pi->path);
   1016             pi->path = strdup(value);
   1017         }
   1018 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
   1019         else if (!strcasecmp(key, "path")) {
   1020             if (pi->path != NULL)
   1021                 free(pi->path);
   1022             pi->path = strdup(value);
   1023         }
   1024         else if (!strcasecmp(key, "name")) {
   1025             free(pi->name);
   1026             pi->name = strdup(value);
   1027         }
   1028 #endif
   1029         else if (!strcasecmp(key, "protocol"))
   1030             pi->protocol = strdup(value);
   1031         else if (!strcasecmp(key, "driver"))
   1032             pi->driver = KdFindPointerDriver(value);
   1033         else
   1034             ErrorF("Pointer option key (%s) of value (%s) not assigned!\n",
   1035                    key, value);
   1036     }
   1037 }
   1038 
   1039 static KdPointerInfo *
   1040 KdParsePointer(const char *arg)
   1041 {
   1042     char save[1024];
   1043     char delim;
   1044     KdPointerInfo *pi = NULL;
   1045     InputOption *options = NULL;
   1046     int i = 0;
   1047 
   1048     pi = KdNewPointer();
   1049     if (!pi)
   1050         return NULL;
   1051     pi->emulateMiddleButton = kdEmulateMiddleButton;
   1052     pi->transformCoordinates = !kdRawPointerCoordinates;
   1053     pi->protocol = NULL;
   1054     pi->nButtons = 5;           /* XXX should not be hardcoded */
   1055     pi->inputClass = KD_MOUSE;
   1056 
   1057     if (!arg) {
   1058         ErrorF("mouse: no arg\n");
   1059         KdFreePointer(pi);
   1060         return NULL;
   1061     }
   1062 
   1063     if (strlen(arg) >= sizeof(save)) {
   1064         ErrorF("mouse: arg too long\n");
   1065         KdFreePointer(pi);
   1066         return NULL;
   1067     }
   1068     arg = KdParseFindNext(arg, ",", save, &delim);
   1069     if (!save[0]) {
   1070         ErrorF("failed on save[0]\n");
   1071         KdFreePointer(pi);
   1072         return NULL;
   1073     }
   1074 
   1075     if (strcmp(save, "auto") == 0)
   1076         pi->driverPrivate = NULL;
   1077     else
   1078         pi->driverPrivate = strdup(save);
   1079 
   1080     if (delim != ',') {
   1081         return pi;
   1082     }
   1083 
   1084     arg = KdParseFindNext(arg, ",", save, &delim);
   1085 
   1086     while (delim == ',') {
   1087         arg = KdParseFindNext(arg, ",", save, &delim);
   1088         if (save[0] == '{') {
   1089             char *s = save + 1;
   1090 
   1091             i = 0;
   1092             while (*s && *s != '}') {
   1093                 if ('1' <= *s && *s <= '0' + pi->nButtons)
   1094                     pi->map[i] = *s - '0';
   1095                 else
   1096                     UseMsg();
   1097                 s++;
   1098             }
   1099         }
   1100         else {
   1101             if (!KdGetOptions(&options, save)) {
   1102                 KdFreePointer(pi);
   1103                 return NULL;
   1104             }
   1105         }
   1106     }
   1107 
   1108     if (options) {
   1109         pi->options = options;
   1110         KdParsePointerOptions(pi);
   1111     }
   1112 
   1113     return pi;
   1114 }
   1115 
   1116 void
   1117 KdInitInput(void)
   1118 {
   1119     KdPointerInfo *pi;
   1120     KdKeyboardInfo *ki;
   1121     struct KdConfigDevice *dev;
   1122 
   1123     if (kdConfigPointers || kdConfigKeyboards)
   1124         InputThreadPreInit();
   1125 
   1126     kdInputEnabled = TRUE;
   1127 
   1128     for (dev = kdConfigPointers; dev; dev = dev->next) {
   1129         pi = KdParsePointer(dev->line);
   1130         if (!pi)
   1131             ErrorF("Failed to parse pointer\n");
   1132         if (KdAddPointer(pi) != Success)
   1133             ErrorF("Failed to add pointer!\n");
   1134     }
   1135     for (dev = kdConfigKeyboards; dev; dev = dev->next) {
   1136         ki = KdParseKeyboard(dev->line);
   1137         if (!ki)
   1138             ErrorF("Failed to parse keyboard\n");
   1139         if (KdAddKeyboard(ki) != Success)
   1140             ErrorF("Failed to add keyboard!\n");
   1141     }
   1142 
   1143     mieqInit();
   1144 
   1145 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
   1146     if (SeatId) /* Enable input hot-plugging */
   1147         config_init();
   1148 #endif
   1149 }
   1150 
   1151 void
   1152 KdCloseInput(void)
   1153 {
   1154 #if defined(CONFIG_UDEV) || defined(CONFIG_HAL)
   1155     if (SeatId) /* Input hot-plugging is enabled */
   1156         config_fini();
   1157 #endif
   1158 
   1159     mieqFini();
   1160 }
   1161 
   1162 /*
   1163  * Middle button emulation state machine
   1164  *
   1165  *  Possible transitions:
   1166  *	Button 1 press	    v1
   1167  *	Button 1 release    ^1
   1168  *	Button 2 press	    v2
   1169  *	Button 2 release    ^2
   1170  *	Button 3 press	    v3
   1171  *	Button 3 release    ^3
   1172  *	Button other press  vo
   1173  *	Button other release ^o
   1174  *	Mouse motion	    <>
   1175  *	Keyboard event	    k
   1176  *	timeout		    ...
   1177  *	outside box	    <->
   1178  *
   1179  *  States:
   1180  *	start
   1181  *	button_1_pend
   1182  *	button_1_down
   1183  *	button_2_down
   1184  *	button_3_pend
   1185  *	button_3_down
   1186  *	synthetic_2_down_13
   1187  *	synthetic_2_down_3
   1188  *	synthetic_2_down_1
   1189  *
   1190  *  Transition diagram
   1191  *
   1192  *  start
   1193  *	v1  -> (hold) (settimeout) button_1_pend
   1194  *	^1  -> (deliver) start
   1195  *	v2  -> (deliver) button_2_down
   1196  *	^2  -> (deliever) start
   1197  *	v3  -> (hold) (settimeout) button_3_pend
   1198  *	^3  -> (deliver) start
   1199  *	vo  -> (deliver) start
   1200  *	^o  -> (deliver) start
   1201  *	<>  -> (deliver) start
   1202  *	k   -> (deliver) start
   1203  *
   1204  *  button_1_pend	(button 1 is down, timeout pending)
   1205  *	^1  -> (release) (deliver) start
   1206  *	v2  -> (release) (deliver) button_1_down
   1207  *	^2  -> (release) (deliver) button_1_down
   1208  *	v3  -> (cleartimeout) (generate v2) synthetic_2_down_13
   1209  *	^3  -> (release) (deliver) button_1_down
   1210  *	vo  -> (release) (deliver) button_1_down
   1211  *	^o  -> (release) (deliver) button_1_down
   1212  *	<-> -> (release) (deliver) button_1_down
   1213  *	<>  -> (deliver) button_1_pend
   1214  *	k   -> (release) (deliver) button_1_down
   1215  *	... -> (release) button_1_down
   1216  *
   1217  *  button_1_down	(button 1 is down)
   1218  *	^1  -> (deliver) start
   1219  *	v2  -> (deliver) button_1_down
   1220  *	^2  -> (deliver) button_1_down
   1221  *	v3  -> (deliver) button_1_down
   1222  *	^3  -> (deliver) button_1_down
   1223  *	vo  -> (deliver) button_1_down
   1224  *	^o  -> (deliver) button_1_down
   1225  *	<>  -> (deliver) button_1_down
   1226  *	k   -> (deliver) button_1_down
   1227  *
   1228  *  button_2_down	(button 2 is down)
   1229  *	v1  -> (deliver) button_2_down
   1230  *	^1  -> (deliver) button_2_down
   1231  *	^2  -> (deliver) start
   1232  *	v3  -> (deliver) button_2_down
   1233  *	^3  -> (deliver) button_2_down
   1234  *	vo  -> (deliver) button_2_down
   1235  *	^o  -> (deliver) button_2_down
   1236  *	<>  -> (deliver) button_2_down
   1237  *	k   -> (deliver) button_2_down
   1238  *
   1239  *  button_3_pend	(button 3 is down, timeout pending)
   1240  *	v1  -> (generate v2) synthetic_2_down
   1241  *	^1  -> (release) (deliver) button_3_down
   1242  *	v2  -> (release) (deliver) button_3_down
   1243  *	^2  -> (release) (deliver) button_3_down
   1244  *	^3  -> (release) (deliver) start
   1245  *	vo  -> (release) (deliver) button_3_down
   1246  *	^o  -> (release) (deliver) button_3_down
   1247  *	<-> -> (release) (deliver) button_3_down
   1248  *	<>  -> (deliver) button_3_pend
   1249  *	k   -> (release) (deliver) button_3_down
   1250  *	... -> (release) button_3_down
   1251  *
   1252  *  button_3_down	(button 3 is down)
   1253  *	v1  -> (deliver) button_3_down
   1254  *	^1  -> (deliver) button_3_down
   1255  *	v2  -> (deliver) button_3_down
   1256  *	^2  -> (deliver) button_3_down
   1257  *	^3  -> (deliver) start
   1258  *	vo  -> (deliver) button_3_down
   1259  *	^o  -> (deliver) button_3_down
   1260  *	<>  -> (deliver) button_3_down
   1261  *	k   -> (deliver) button_3_down
   1262  *
   1263  *  synthetic_2_down_13	(button 1 and 3 are down)
   1264  *	^1  -> (generate ^2) synthetic_2_down_3
   1265  *	v2  -> synthetic_2_down_13
   1266  *	^2  -> synthetic_2_down_13
   1267  *	^3  -> (generate ^2) synthetic_2_down_1
   1268  *	vo  -> (deliver) synthetic_2_down_13
   1269  *	^o  -> (deliver) synthetic_2_down_13
   1270  *	<>  -> (deliver) synthetic_2_down_13
   1271  *	k   -> (deliver) synthetic_2_down_13
   1272  *
   1273  *  synthetic_2_down_3 (button 3 is down)
   1274  *	v1  -> (deliver) synthetic_2_down_3
   1275  *	^1  -> (deliver) synthetic_2_down_3
   1276  *	v2  -> synthetic_2_down_3
   1277  *	^2  -> synthetic_2_down_3
   1278  *	^3  -> start
   1279  *	vo  -> (deliver) synthetic_2_down_3
   1280  *	^o  -> (deliver) synthetic_2_down_3
   1281  *	<>  -> (deliver) synthetic_2_down_3
   1282  *	k   -> (deliver) synthetic_2_down_3
   1283  *
   1284  *  synthetic_2_down_1 (button 1 is down)
   1285  *	^1  -> start
   1286  *	v2  -> synthetic_2_down_1
   1287  *	^2  -> synthetic_2_down_1
   1288  *	v3  -> (deliver) synthetic_2_down_1
   1289  *	^3  -> (deliver) synthetic_2_down_1
   1290  *	vo  -> (deliver) synthetic_2_down_1
   1291  *	^o  -> (deliver) synthetic_2_down_1
   1292  *	<>  -> (deliver) synthetic_2_down_1
   1293  *	k   -> (deliver) synthetic_2_down_1
   1294  */
   1295 
   1296 typedef enum _inputClass {
   1297     down_1, up_1,
   1298     down_2, up_2,
   1299     down_3, up_3,
   1300     down_o, up_o,
   1301     motion, outside_box,
   1302     keyboard, timeout,
   1303     num_input_class
   1304 } KdInputClass;
   1305 
   1306 typedef enum _inputAction {
   1307     noop,
   1308     hold,
   1309     setto,
   1310     deliver,
   1311     release,
   1312     clearto,
   1313     gen_down_2,
   1314     gen_up_2
   1315 } KdInputAction;
   1316 
   1317 #define MAX_ACTIONS 2
   1318 
   1319 typedef struct _inputTransition {
   1320     KdInputAction actions[MAX_ACTIONS];
   1321     KdPointerState nextState;
   1322 } KdInputTransition;
   1323 
   1324 static const
   1325 KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
   1326     /* start */
   1327     {
   1328      {{hold, setto}, button_1_pend},    /* v1 */
   1329      {{deliver, noop}, start},  /* ^1 */
   1330      {{deliver, noop}, button_2_down},  /* v2 */
   1331      {{deliver, noop}, start},  /* ^2 */
   1332      {{hold, setto}, button_3_pend},    /* v3 */
   1333      {{deliver, noop}, start},  /* ^3 */
   1334      {{deliver, noop}, start},  /* vo */
   1335      {{deliver, noop}, start},  /* ^o */
   1336      {{deliver, noop}, start},  /* <> */
   1337      {{deliver, noop}, start},  /* <-> */
   1338      {{noop, noop}, start},     /* k */
   1339      {{noop, noop}, start},     /* ... */
   1340      },
   1341     /* button_1_pend */
   1342     {
   1343      {{noop, noop}, button_1_pend},     /* v1 */
   1344      {{release, deliver}, start},       /* ^1 */
   1345      {{release, deliver}, button_1_down},       /* v2 */
   1346      {{release, deliver}, button_1_down},       /* ^2 */
   1347      {{clearto, gen_down_2}, synth_2_down_13},  /* v3 */
   1348      {{release, deliver}, button_1_down},       /* ^3 */
   1349      {{release, deliver}, button_1_down},       /* vo */
   1350      {{release, deliver}, button_1_down},       /* ^o */
   1351      {{deliver, noop}, button_1_pend},  /* <> */
   1352      {{release, deliver}, button_1_down},       /* <-> */
   1353      {{noop, noop}, button_1_down},     /* k */
   1354      {{release, noop}, button_1_down},  /* ... */
   1355      },
   1356     /* button_1_down */
   1357     {
   1358      {{noop, noop}, button_1_down},     /* v1 */
   1359      {{deliver, noop}, start},  /* ^1 */
   1360      {{deliver, noop}, button_1_down},  /* v2 */
   1361      {{deliver, noop}, button_1_down},  /* ^2 */
   1362      {{deliver, noop}, button_1_down},  /* v3 */
   1363      {{deliver, noop}, button_1_down},  /* ^3 */
   1364      {{deliver, noop}, button_1_down},  /* vo */
   1365      {{deliver, noop}, button_1_down},  /* ^o */
   1366      {{deliver, noop}, button_1_down},  /* <> */
   1367      {{deliver, noop}, button_1_down},  /* <-> */
   1368      {{noop, noop}, button_1_down},     /* k */
   1369      {{noop, noop}, button_1_down},     /* ... */
   1370      },
   1371     /* button_2_down */
   1372     {
   1373      {{deliver, noop}, button_2_down},  /* v1 */
   1374      {{deliver, noop}, button_2_down},  /* ^1 */
   1375      {{noop, noop}, button_2_down},     /* v2 */
   1376      {{deliver, noop}, start},  /* ^2 */
   1377      {{deliver, noop}, button_2_down},  /* v3 */
   1378      {{deliver, noop}, button_2_down},  /* ^3 */
   1379      {{deliver, noop}, button_2_down},  /* vo */
   1380      {{deliver, noop}, button_2_down},  /* ^o */
   1381      {{deliver, noop}, button_2_down},  /* <> */
   1382      {{deliver, noop}, button_2_down},  /* <-> */
   1383      {{noop, noop}, button_2_down},     /* k */
   1384      {{noop, noop}, button_2_down},     /* ... */
   1385      },
   1386     /* button_3_pend */
   1387     {
   1388      {{clearto, gen_down_2}, synth_2_down_13},  /* v1 */
   1389      {{release, deliver}, button_3_down},       /* ^1 */
   1390      {{release, deliver}, button_3_down},       /* v2 */
   1391      {{release, deliver}, button_3_down},       /* ^2 */
   1392      {{release, deliver}, button_3_down},       /* v3 */
   1393      {{release, deliver}, start},       /* ^3 */
   1394      {{release, deliver}, button_3_down},       /* vo */
   1395      {{release, deliver}, button_3_down},       /* ^o */
   1396      {{deliver, noop}, button_3_pend},  /* <> */
   1397      {{release, deliver}, button_3_down},       /* <-> */
   1398      {{release, noop}, button_3_down},  /* k */
   1399      {{release, noop}, button_3_down},  /* ... */
   1400      },
   1401     /* button_3_down */
   1402     {
   1403      {{deliver, noop}, button_3_down},  /* v1 */
   1404      {{deliver, noop}, button_3_down},  /* ^1 */
   1405      {{deliver, noop}, button_3_down},  /* v2 */
   1406      {{deliver, noop}, button_3_down},  /* ^2 */
   1407      {{noop, noop}, button_3_down},     /* v3 */
   1408      {{deliver, noop}, start},  /* ^3 */
   1409      {{deliver, noop}, button_3_down},  /* vo */
   1410      {{deliver, noop}, button_3_down},  /* ^o */
   1411      {{deliver, noop}, button_3_down},  /* <> */
   1412      {{deliver, noop}, button_3_down},  /* <-> */
   1413      {{noop, noop}, button_3_down},     /* k */
   1414      {{noop, noop}, button_3_down},     /* ... */
   1415      },
   1416     /* synthetic_2_down_13 */
   1417     {
   1418      {{noop, noop}, synth_2_down_13},   /* v1 */
   1419      {{gen_up_2, noop}, synth_2_down_3},        /* ^1 */
   1420      {{noop, noop}, synth_2_down_13},   /* v2 */
   1421      {{noop, noop}, synth_2_down_13},   /* ^2 */
   1422      {{noop, noop}, synth_2_down_13},   /* v3 */
   1423      {{gen_up_2, noop}, synth_2_down_1},        /* ^3 */
   1424      {{deliver, noop}, synth_2_down_13},        /* vo */
   1425      {{deliver, noop}, synth_2_down_13},        /* ^o */
   1426      {{deliver, noop}, synth_2_down_13},        /* <> */
   1427      {{deliver, noop}, synth_2_down_13},        /* <-> */
   1428      {{noop, noop}, synth_2_down_13},   /* k */
   1429      {{noop, noop}, synth_2_down_13},   /* ... */
   1430      },
   1431     /* synthetic_2_down_3 */
   1432     {
   1433      {{deliver, noop}, synth_2_down_3}, /* v1 */
   1434      {{deliver, noop}, synth_2_down_3}, /* ^1 */
   1435      {{deliver, noop}, synth_2_down_3}, /* v2 */
   1436      {{deliver, noop}, synth_2_down_3}, /* ^2 */
   1437      {{noop, noop}, synth_2_down_3},    /* v3 */
   1438      {{noop, noop}, start},     /* ^3 */
   1439      {{deliver, noop}, synth_2_down_3}, /* vo */
   1440      {{deliver, noop}, synth_2_down_3}, /* ^o */
   1441      {{deliver, noop}, synth_2_down_3}, /* <> */
   1442      {{deliver, noop}, synth_2_down_3}, /* <-> */
   1443      {{noop, noop}, synth_2_down_3},    /* k */
   1444      {{noop, noop}, synth_2_down_3},    /* ... */
   1445      },
   1446     /* synthetic_2_down_1 */
   1447     {
   1448      {{noop, noop}, synth_2_down_1},    /* v1 */
   1449      {{noop, noop}, start},     /* ^1 */
   1450      {{deliver, noop}, synth_2_down_1}, /* v2 */
   1451      {{deliver, noop}, synth_2_down_1}, /* ^2 */
   1452      {{deliver, noop}, synth_2_down_1}, /* v3 */
   1453      {{deliver, noop}, synth_2_down_1}, /* ^3 */
   1454      {{deliver, noop}, synth_2_down_1}, /* vo */
   1455      {{deliver, noop}, synth_2_down_1}, /* ^o */
   1456      {{deliver, noop}, synth_2_down_1}, /* <> */
   1457      {{deliver, noop}, synth_2_down_1}, /* <-> */
   1458      {{noop, noop}, synth_2_down_1},    /* k */
   1459      {{noop, noop}, synth_2_down_1},    /* ... */
   1460      },
   1461 };
   1462 
   1463 #define EMULATION_WINDOW    10
   1464 #define EMULATION_TIMEOUT   100
   1465 
   1466 static int
   1467 KdInsideEmulationWindow(KdPointerInfo * pi, int x, int y, int z)
   1468 {
   1469     pi->emulationDx = pi->heldEvent.x - x;
   1470     pi->emulationDy = pi->heldEvent.y - y;
   1471 
   1472     return (abs(pi->emulationDx) < EMULATION_WINDOW &&
   1473             abs(pi->emulationDy) < EMULATION_WINDOW);
   1474 }
   1475 
   1476 static KdInputClass
   1477 KdClassifyInput(KdPointerInfo * pi, int type, int x, int y, int z, int b)
   1478 {
   1479     switch (type) {
   1480     case ButtonPress:
   1481         switch (b) {
   1482         case 1:
   1483             return down_1;
   1484         case 2:
   1485             return down_2;
   1486         case 3:
   1487             return down_3;
   1488         default:
   1489             return down_o;
   1490         }
   1491         break;
   1492     case ButtonRelease:
   1493         switch (b) {
   1494         case 1:
   1495             return up_1;
   1496         case 2:
   1497             return up_2;
   1498         case 3:
   1499             return up_3;
   1500         default:
   1501             return up_o;
   1502         }
   1503         break;
   1504     case MotionNotify:
   1505         if (pi->eventHeld && !KdInsideEmulationWindow(pi, x, y, z))
   1506             return outside_box;
   1507         else
   1508             return motion;
   1509     default:
   1510         return keyboard;
   1511     }
   1512     return keyboard;
   1513 }
   1514 
   1515 static void
   1516 _KdEnqueuePointerEvent(KdPointerInfo * pi, int type, int x, int y, int z,
   1517                        int b, int absrel, Bool force);
   1518 /* We return true if we're stealing the event. */
   1519 static Bool
   1520 KdRunMouseMachine(KdPointerInfo * pi, KdInputClass c, int type, int x, int y,
   1521                   int z, int b, int absrel)
   1522 {
   1523     const KdInputTransition *t;
   1524     int a;
   1525 
   1526     c = KdClassifyInput(pi, type, x, y, z, b);
   1527     t = &kdInputMachine[pi->mouseState][c];
   1528     for (a = 0; a < MAX_ACTIONS; a++) {
   1529         switch (t->actions[a]) {
   1530         case noop:
   1531             break;
   1532         case hold:
   1533             pi->eventHeld = TRUE;
   1534             pi->emulationDx = 0;
   1535             pi->emulationDy = 0;
   1536             pi->heldEvent.type = type;
   1537             pi->heldEvent.x = x;
   1538             pi->heldEvent.y = y;
   1539             pi->heldEvent.z = z;
   1540             pi->heldEvent.flags = b;
   1541             pi->heldEvent.absrel = absrel;
   1542             return TRUE;
   1543             break;
   1544         case setto:
   1545             pi->emulationTimeout = GetTimeInMillis() + EMULATION_TIMEOUT;
   1546             pi->timeoutPending = TRUE;
   1547             break;
   1548         case deliver:
   1549             _KdEnqueuePointerEvent(pi, pi->heldEvent.type, pi->heldEvent.x,
   1550                                    pi->heldEvent.y, pi->heldEvent.z,
   1551                                    pi->heldEvent.flags, pi->heldEvent.absrel,
   1552                                    TRUE);
   1553             break;
   1554         case release:
   1555             pi->eventHeld = FALSE;
   1556             pi->timeoutPending = FALSE;
   1557             _KdEnqueuePointerEvent(pi, pi->heldEvent.type, pi->heldEvent.x,
   1558                                    pi->heldEvent.y, pi->heldEvent.z,
   1559                                    pi->heldEvent.flags, pi->heldEvent.absrel,
   1560                                    TRUE);
   1561             return TRUE;
   1562             break;
   1563         case clearto:
   1564             pi->timeoutPending = FALSE;
   1565             break;
   1566         case gen_down_2:
   1567             _KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, 2, absrel, TRUE);
   1568             pi->eventHeld = FALSE;
   1569             return TRUE;
   1570             break;
   1571         case gen_up_2:
   1572             _KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, 2, absrel, TRUE);
   1573             return TRUE;
   1574             break;
   1575         }
   1576     }
   1577     pi->mouseState = t->nextState;
   1578     return FALSE;
   1579 }
   1580 
   1581 static int
   1582 KdHandlePointerEvent(KdPointerInfo * pi, int type, int x, int y, int z, int b,
   1583                      int absrel)
   1584 {
   1585     if (pi->emulateMiddleButton)
   1586         return KdRunMouseMachine(pi, KdClassifyInput(pi, type, x, y, z, b),
   1587                                  type, x, y, z, b, absrel);
   1588     return FALSE;
   1589 }
   1590 
   1591 static void
   1592 _KdEnqueuePointerEvent(KdPointerInfo * pi, int type, int x, int y, int z,
   1593                        int b, int absrel, Bool force)
   1594 {
   1595     int valuators[3] = { x, y, z };
   1596     ValuatorMask mask;
   1597 
   1598     /* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */
   1599     if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel))
   1600         return;
   1601 
   1602     valuator_mask_set_range(&mask, 0, 3, valuators);
   1603 
   1604     QueuePointerEvents(pi->dixdev, type, b, absrel, &mask);
   1605 }
   1606 
   1607 static void
   1608 KdReceiveTimeout(KdPointerInfo * pi)
   1609 {
   1610     KdRunMouseMachine(pi, timeout, 0, 0, 0, 0, 0, 0);
   1611 }
   1612 
   1613 extern int nClients;
   1614 
   1615 static void
   1616 KdCheckLock(void)
   1617 {
   1618     KeyClassPtr keyc = NULL;
   1619     Bool isSet = FALSE, shouldBeSet = FALSE;
   1620     KdKeyboardInfo *tmp = NULL;
   1621 
   1622     for (tmp = kdKeyboards; tmp; tmp = tmp->next) {
   1623         if (tmp->LockLed && tmp->dixdev && tmp->dixdev->key) {
   1624             keyc = tmp->dixdev->key;
   1625             isSet = (tmp->leds & (1 << (tmp->LockLed - 1))) != 0;
   1626             /* FIXME: Just use XKB indicators! */
   1627             shouldBeSet =
   1628                 ! !(XkbStateFieldFromRec(&keyc->xkbInfo->state) & LockMask);
   1629             if (isSet != shouldBeSet)
   1630                 KdSetLed(tmp, tmp->LockLed, shouldBeSet);
   1631         }
   1632     }
   1633 }
   1634 
   1635 void
   1636 KdEnqueueKeyboardEvent(KdKeyboardInfo * ki,
   1637                        unsigned char scan_code, unsigned char is_up)
   1638 {
   1639     unsigned char key_code;
   1640     int type;
   1641 
   1642     if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key)
   1643         return;
   1644 
   1645     if (scan_code >= ki->minScanCode && scan_code <= ki->maxScanCode) {
   1646         key_code = scan_code + KD_MIN_KEYCODE - ki->minScanCode;
   1647 
   1648         /*
   1649          * Set up this event -- the type may be modified below
   1650          */
   1651         if (is_up)
   1652             type = KeyRelease;
   1653         else
   1654             type = KeyPress;
   1655 
   1656         QueueKeyboardEvents(ki->dixdev, type, key_code);
   1657     }
   1658     else {
   1659         ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n",
   1660                ki->name, scan_code, ki->minScanCode, ki->maxScanCode);
   1661     }
   1662 }
   1663 
   1664 /*
   1665  * kdEnqueuePointerEvent
   1666  *
   1667  * This function converts hardware mouse event information into X event
   1668  * information.  A mouse movement event is passed off to MI to generate
   1669  * a MotionNotify event, if appropriate.  Button events are created and
   1670  * passed off to MI for enqueueing.
   1671  */
   1672 
   1673 /* FIXME do something a little more clever to deal with multiple axes here */
   1674 void
   1675 KdEnqueuePointerEvent(KdPointerInfo * pi, unsigned long flags, int rx, int ry,
   1676                       int rz)
   1677 {
   1678     unsigned char buttons;
   1679     int x, y, z;
   1680     int (*matrix)[3] = kdPointerMatrix.matrix;
   1681     unsigned long button;
   1682     int n;
   1683     int dixflags = 0;
   1684 
   1685     if (!pi)
   1686         return;
   1687 
   1688     /* we don't need to transform z, so we don't. */
   1689     if (flags & KD_MOUSE_DELTA) {
   1690         if (pi->transformCoordinates) {
   1691             x = matrix[0][0] * rx + matrix[0][1] * ry;
   1692             y = matrix[1][0] * rx + matrix[1][1] * ry;
   1693         }
   1694         else {
   1695             x = rx;
   1696             y = ry;
   1697         }
   1698     }
   1699     else {
   1700         if (pi->transformCoordinates) {
   1701             x = matrix[0][0] * rx + matrix[0][1] * ry + matrix[0][2];
   1702             y = matrix[1][0] * rx + matrix[1][1] * ry + matrix[1][2];
   1703         }
   1704         else {
   1705             x = rx;
   1706             y = ry;
   1707         }
   1708     }
   1709     z = rz;
   1710 
   1711     if (flags & KD_MOUSE_DELTA) {
   1712         if (x || y || z) {
   1713             dixflags = POINTER_RELATIVE | POINTER_ACCELERATE;
   1714             _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags,
   1715                                    FALSE);
   1716         }
   1717     }
   1718     else {
   1719         dixflags = POINTER_ABSOLUTE;
   1720         if (flags & KD_POINTER_DESKTOP)
   1721             dixflags |= POINTER_DESKTOP;
   1722         if (x != pi->dixdev->last.valuators[0] ||
   1723             y != pi->dixdev->last.valuators[1])
   1724             _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags,
   1725                                    FALSE);
   1726     }
   1727 
   1728     buttons = flags;
   1729 
   1730     for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; button <<= 1, n++) {
   1731         if (((pi->buttonState & button) ^ (buttons & button)) &&
   1732             !(buttons & button)) {
   1733             _KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, n,
   1734                                    dixflags, FALSE);
   1735         }
   1736     }
   1737     for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; button <<= 1, n++) {
   1738         if (((pi->buttonState & button) ^ (buttons & button)) &&
   1739             (buttons & button)) {
   1740             _KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, n,
   1741                                    dixflags, FALSE);
   1742         }
   1743     }
   1744 
   1745     pi->buttonState = buttons;
   1746 }
   1747 
   1748 void
   1749 KdBlockHandler(ScreenPtr pScreen, void *timeo)
   1750 {
   1751     KdPointerInfo *pi;
   1752     int myTimeout = 0;
   1753 
   1754     for (pi = kdPointers; pi; pi = pi->next) {
   1755         if (pi->timeoutPending) {
   1756             int ms;
   1757 
   1758             ms = pi->emulationTimeout - GetTimeInMillis();
   1759             if (ms < 1)
   1760                 ms = 1;
   1761             if (ms < myTimeout || myTimeout == 0)
   1762                 myTimeout = ms;
   1763         }
   1764     }
   1765     if (myTimeout > 0)
   1766         AdjustWaitForDelay(timeo, myTimeout);
   1767 }
   1768 
   1769 void
   1770 KdWakeupHandler(ScreenPtr pScreen, int result)
   1771 {
   1772     KdPointerInfo *pi;
   1773 
   1774     for (pi = kdPointers; pi; pi = pi->next) {
   1775         if (pi->timeoutPending) {
   1776             if ((long) (GetTimeInMillis() - pi->emulationTimeout) >= 0) {
   1777                 pi->timeoutPending = FALSE;
   1778                 input_lock();
   1779                 KdReceiveTimeout(pi);
   1780                 input_unlock();
   1781             }
   1782         }
   1783     }
   1784 }
   1785 
   1786 #define KdScreenOrigin(pScreen) (&(KdGetScreenPriv(pScreen)->screen->origin))
   1787 
   1788 static Bool
   1789 KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
   1790 {
   1791     ScreenPtr pScreen = *ppScreen;
   1792     ScreenPtr pNewScreen;
   1793     int n;
   1794     int dx, dy;
   1795     int best_x, best_y;
   1796     int n_best_x, n_best_y;
   1797     CARD32 ms;
   1798 
   1799     if (kdDisableZaphod || screenInfo.numScreens <= 1)
   1800         return FALSE;
   1801 
   1802     if (0 <= *x && *x < pScreen->width && 0 <= *y && *y < pScreen->height)
   1803         return FALSE;
   1804 
   1805     ms = GetTimeInMillis();
   1806     if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000)
   1807         return FALSE;
   1808     kdOffScreen = TRUE;
   1809     kdOffScreenTime = ms;
   1810     n_best_x = -1;
   1811     best_x = 32767;
   1812     n_best_y = -1;
   1813     best_y = 32767;
   1814     for (n = 0; n < screenInfo.numScreens; n++) {
   1815         pNewScreen = screenInfo.screens[n];
   1816         if (pNewScreen == pScreen)
   1817             continue;
   1818         dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x;
   1819         dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y;
   1820         if (*x < 0) {
   1821             if (dx < 0 && -dx < best_x) {
   1822                 best_x = -dx;
   1823                 n_best_x = n;
   1824             }
   1825         }
   1826         else if (*x >= pScreen->width) {
   1827             if (dx > 0 && dx < best_x) {
   1828                 best_x = dx;
   1829                 n_best_x = n;
   1830             }
   1831         }
   1832         if (*y < 0) {
   1833             if (dy < 0 && -dy < best_y) {
   1834                 best_y = -dy;
   1835                 n_best_y = n;
   1836             }
   1837         }
   1838         else if (*y >= pScreen->height) {
   1839             if (dy > 0 && dy < best_y) {
   1840                 best_y = dy;
   1841                 n_best_y = n;
   1842             }
   1843         }
   1844     }
   1845     if (best_y < best_x)
   1846         n_best_x = n_best_y;
   1847     if (n_best_x == -1)
   1848         return FALSE;
   1849     pNewScreen = screenInfo.screens[n_best_x];
   1850 
   1851     if (*x < 0)
   1852         *x += pNewScreen->width;
   1853     if (*y < 0)
   1854         *y += pNewScreen->height;
   1855 
   1856     if (*x >= pScreen->width)
   1857         *x -= pScreen->width;
   1858     if (*y >= pScreen->height)
   1859         *y -= pScreen->height;
   1860 
   1861     *ppScreen = pNewScreen;
   1862     return TRUE;
   1863 }
   1864 
   1865 static void
   1866 KdCrossScreen(ScreenPtr pScreen, Bool entering)
   1867 {
   1868 }
   1869 
   1870 static void
   1871 KdWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
   1872 {
   1873     input_lock();
   1874     miPointerWarpCursor(pDev, pScreen, x, y);
   1875     input_unlock();
   1876 }
   1877 
   1878 miPointerScreenFuncRec kdPointerScreenFuncs = {
   1879     KdCursorOffScreen,
   1880     KdCrossScreen,
   1881     KdWarpCursor
   1882 };
   1883 
   1884 void
   1885 ProcessInputEvents(void)
   1886 {
   1887     mieqProcessInputEvents();
   1888     KdCheckLock();
   1889 }
   1890 
   1891 /* At the moment, absolute/relative is up to the client. */
   1892 int
   1893 SetDeviceMode(register ClientPtr client, DeviceIntPtr pDev, int mode)
   1894 {
   1895     return BadMatch;
   1896 }
   1897 
   1898 int
   1899 SetDeviceValuators(register ClientPtr client, DeviceIntPtr pDev,
   1900                    int *valuators, int first_valuator, int num_valuators)
   1901 {
   1902     return BadMatch;
   1903 }
   1904 
   1905 int
   1906 ChangeDeviceControl(register ClientPtr client, DeviceIntPtr pDev,
   1907                     xDeviceCtl * control)
   1908 {
   1909     switch (control->control) {
   1910     case DEVICE_RESOLUTION:
   1911         /* FIXME do something more intelligent here */
   1912         return BadMatch;
   1913 
   1914     case DEVICE_ABS_CALIB:
   1915     case DEVICE_ABS_AREA:
   1916     case DEVICE_CORE:
   1917         return BadMatch;
   1918     case DEVICE_ENABLE:
   1919         return Success;
   1920 
   1921     default:
   1922         return BadMatch;
   1923     }
   1924 
   1925     /* NOTREACHED */
   1926     return BadImplementation;
   1927 }
   1928 
   1929 int
   1930 NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
   1931                       DeviceIntPtr *pdev)
   1932 {
   1933     InputOption *option = NULL, *optionsdup = NULL;
   1934     KdPointerInfo *pi = NULL;
   1935     KdKeyboardInfo *ki = NULL;
   1936 
   1937     nt_list_for_each_entry(option, options, list.next) {
   1938         const char *key = input_option_get_key(option);
   1939         const char *value = input_option_get_value(option);
   1940         optionsdup = input_option_new(optionsdup, key, value);
   1941 
   1942         if (strcmp(key, "type") == 0) {
   1943             if (strcmp(value, "pointer") == 0) {
   1944                 pi = KdNewPointer();
   1945                 if (!pi) {
   1946                     input_option_free_list(&optionsdup);
   1947                     return BadAlloc;
   1948                 }
   1949             }
   1950             else if (strcmp(value, "keyboard") == 0) {
   1951                 ki = KdNewKeyboard();
   1952                 if (!ki) {
   1953                     input_option_free_list(&optionsdup);
   1954                     return BadAlloc;
   1955                 }
   1956             }
   1957             else {
   1958                 ErrorF("unrecognised device type!\n");
   1959                 return BadValue;
   1960             }
   1961         }
   1962 #ifdef CONFIG_HAL
   1963         else if (strcmp(key, "_source") == 0 &&
   1964                  strcmp(value, "server/hal") == 0) {
   1965             if (SeatId) {
   1966                 /* Input hot-plugging is enabled */
   1967                 if (attrs->flags & ATTR_POINTER) {
   1968                     pi = KdNewPointer();
   1969                     if (!pi) {
   1970                         input_option_free_list(&optionsdup);
   1971                         return BadAlloc;
   1972                     }
   1973                 }
   1974                 else if (attrs->flags & ATTR_KEYBOARD) {
   1975                     ki = KdNewKeyboard();
   1976                     if (!ki) {
   1977                         input_option_free_list(&optionsdup);
   1978                         return BadAlloc;
   1979                     }
   1980                 }
   1981             }
   1982             else {
   1983                 ErrorF("Ignoring device from HAL.\n");
   1984                 input_option_free_list(&optionsdup);
   1985                 return BadValue;
   1986             }
   1987         }
   1988 #endif
   1989 #ifdef CONFIG_UDEV
   1990         else if (strcmp(key, "_source") == 0 &&
   1991                  strcmp(value, "server/udev") == 0) {
   1992             if (SeatId) {
   1993                 /* Input hot-plugging is enabled */
   1994                 if (attrs->flags & ATTR_POINTER) {
   1995                     pi = KdNewPointer();
   1996                     if (!pi) {
   1997                         input_option_free_list(&optionsdup);
   1998                         return BadAlloc;
   1999                     }
   2000                 }
   2001                 else if (attrs->flags & ATTR_KEYBOARD) {
   2002                     ki = KdNewKeyboard();
   2003                     if (!ki) {
   2004                         input_option_free_list(&optionsdup);
   2005                         return BadAlloc;
   2006                     }
   2007                 }
   2008             }
   2009             else {
   2010                 ErrorF("Ignoring device from udev.\n");
   2011                 input_option_free_list(&optionsdup);
   2012                 return BadValue;
   2013             }
   2014         }
   2015 #endif
   2016     }
   2017 
   2018     if (pi) {
   2019         pi->options = optionsdup;
   2020         KdParsePointerOptions(pi);
   2021 
   2022         if (!pi->driver) {
   2023             ErrorF("couldn't find driver for pointer device \"%s\" (%s)\n",
   2024                    pi->name ? pi->name : "(unnamed)", pi->path);
   2025             KdFreePointer(pi);
   2026             return BadValue;
   2027         }
   2028 
   2029         if (KdAddPointer(pi) != Success ||
   2030             ActivateDevice(pi->dixdev, TRUE) != Success ||
   2031             EnableDevice(pi->dixdev, TRUE) != TRUE) {
   2032             ErrorF("couldn't add or enable pointer \"%s\" (%s)\n",
   2033                    pi->name ? pi->name : "(unnamed)", pi->path);
   2034             KdFreePointer(pi);
   2035             return BadImplementation;
   2036         }
   2037 
   2038         *pdev = pi->dixdev;
   2039     }
   2040     else if (ki) {
   2041         ki->options = optionsdup;
   2042         KdParseKbdOptions(ki);
   2043 
   2044         if (!ki->driver) {
   2045             ErrorF("couldn't find driver for keyboard device \"%s\" (%s)\n",
   2046                    ki->name ? ki->name : "(unnamed)", ki->path);
   2047             KdFreeKeyboard(ki);
   2048             return BadValue;
   2049         }
   2050 
   2051         if (KdAddKeyboard(ki) != Success ||
   2052             ActivateDevice(ki->dixdev, TRUE) != Success ||
   2053             EnableDevice(ki->dixdev, TRUE) != TRUE) {
   2054             ErrorF("couldn't add or enable keyboard \"%s\" (%s)\n",
   2055                    ki->name ? ki->name : "(unnamed)", ki->path);
   2056             KdFreeKeyboard(ki);
   2057             return BadImplementation;
   2058         }
   2059 
   2060         *pdev = ki->dixdev;
   2061     }
   2062     else {
   2063         ErrorF("unrecognised device identifier: %s\n",
   2064                input_option_get_value(input_option_find(optionsdup,
   2065                                                         "device")));
   2066         input_option_free_list(&optionsdup);
   2067         return BadValue;
   2068     }
   2069 
   2070     return Success;
   2071 }
   2072 
   2073 void
   2074 DeleteInputDeviceRequest(DeviceIntPtr pDev)
   2075 {
   2076     RemoveDevice(pDev, TRUE);
   2077 }
   2078 
   2079 void
   2080 RemoveInputDeviceTraces(const char *config_info)
   2081 {
   2082 }