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
60struct KdConfigDevice {
61    char *line;
62    struct KdConfigDevice *next;
63};
64
65/* kdKeyboards and kdPointers hold all the real devices. */
66static KdKeyboardInfo *kdKeyboards = NULL;
67static KdPointerInfo *kdPointers = NULL;
68static struct KdConfigDevice *kdConfigKeyboards = NULL;
69static struct KdConfigDevice *kdConfigPointers = NULL;
70
71static KdKeyboardDriver *kdKeyboardDrivers = NULL;
72static KdPointerDriver *kdPointerDrivers = NULL;
73
74static Bool kdInputEnabled;
75static Bool kdOffScreen;
76static unsigned long kdOffScreenTime;
77
78static KdPointerMatrix kdPointerMatrix = {
79    {{1, 0, 0},
80     {0, 1, 0}}
81};
82
83extern Bool kdRawPointerCoordinates;
84
85extern const char *kdGlobalXkbRules;
86extern const char *kdGlobalXkbModel;
87extern const char *kdGlobalXkbLayout;
88extern const char *kdGlobalXkbVariant;
89extern const char *kdGlobalXkbOptions;
90
91#ifdef FNONBLOCK
92#define NOBLOCK FNONBLOCK
93#else
94#define NOBLOCK FNDELAY
95#endif
96
97static void
98KdResetInputMachine(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
108void
109KdDisableInput(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
129void
130KdEnableInput(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
157static KdKeyboardDriver *
158KdFindKeyboardDriver(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
174static KdPointerDriver *
175KdFindPointerDriver(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
191static int
192KdPointerProc(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
357static void
358KdRingBell(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
367static void
368KdBell(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
384void
385DDXRingBell(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
395static void
396KdSetLeds(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
407static void
408KdSetLed(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
417void
418KdSetPointerMatrix(KdPointerMatrix * matrix)
419{
420    kdPointerMatrix = *matrix;
421}
422
423void
424KdComputePointerMatrix(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
471static void
472KdKbdCtrl(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
489static int
490KdKeyboardProc(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
613void
614KdAddPointerDriver(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
628void
629KdRemovePointerDriver(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
645void
646KdAddKeyboardDriver(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
660void
661KdRemoveKeyboardDriver(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
677KdKeyboardInfo *
678KdNewKeyboard(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
703int
704KdAddConfigKeyboard(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
724int
725KdAddKeyboard(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
749void
750KdRemoveKeyboard(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
767int
768KdAddConfigPointer(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
788int
789KdAddPointer(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
812void
813KdRemovePointer(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 */
835static Bool
836KdGetOptions(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
868static void
869KdParseKbdOptions(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
931static KdKeyboardInfo *
932KdParseKeyboard(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
996static void
997KdParsePointerOptions(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
1039static KdPointerInfo *
1040KdParsePointer(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
1116void
1117KdInitInput(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
1151void
1152KdCloseInput(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
1296typedef 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
1306typedef 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
1319typedef struct _inputTransition {
1320    KdInputAction actions[MAX_ACTIONS];
1321    KdPointerState nextState;
1322} KdInputTransition;
1323
1324static const
1325KdInputTransition 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
1466static int
1467KdInsideEmulationWindow(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
1476static KdInputClass
1477KdClassifyInput(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
1515static 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. */
1519static Bool
1520KdRunMouseMachine(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
1581static int
1582KdHandlePointerEvent(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
1591static 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
1607static void
1608KdReceiveTimeout(KdPointerInfo * pi)
1609{
1610    KdRunMouseMachine(pi, timeout, 0, 0, 0, 0, 0, 0);
1611}
1612
1613extern int nClients;
1614
1615static void
1616KdCheckLock(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
1635void
1636KdEnqueueKeyboardEvent(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 */
1674void
1675KdEnqueuePointerEvent(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
1748void
1749KdBlockHandler(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
1769void
1770KdWakeupHandler(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
1788static Bool
1789KdCursorOffScreen(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
1865static void
1866KdCrossScreen(ScreenPtr pScreen, Bool entering)
1867{
1868}
1869
1870static void
1871KdWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
1872{
1873    input_lock();
1874    miPointerWarpCursor(pDev, pScreen, x, y);
1875    input_unlock();
1876}
1877
1878miPointerScreenFuncRec kdPointerScreenFuncs = {
1879    KdCursorOffScreen,
1880    KdCrossScreen,
1881    KdWarpCursor
1882};
1883
1884void
1885ProcessInputEvents(void)
1886{
1887    mieqProcessInputEvents();
1888    KdCheckLock();
1889}
1890
1891/* At the moment, absolute/relative is up to the client. */
1892int
1893SetDeviceMode(register ClientPtr client, DeviceIntPtr pDev, int mode)
1894{
1895    return BadMatch;
1896}
1897
1898int
1899SetDeviceValuators(register ClientPtr client, DeviceIntPtr pDev,
1900                   int *valuators, int first_valuator, int num_valuators)
1901{
1902    return BadMatch;
1903}
1904
1905int
1906ChangeDeviceControl(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
1929int
1930NewInputDeviceRequest(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
2073void
2074DeleteInputDeviceRequest(DeviceIntPtr pDev)
2075{
2076    RemoveDevice(pDev, TRUE);
2077}
2078
2079void
2080RemoveInputDeviceTraces(const char *config_info)
2081{
2082}
2083