2
* Copyright © 1999 Keith Packard
3
* Copyright © 2006 Nokia Corporation
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.
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.
25
#include <kdrive-config.h>
31
#include <X11/keysym.h>
32
#if HAVE_X11_XF86KEYSYM_H
33
#include <X11/XF86keysym.h>
38
#include <sys/file.h> /* needed for FNONBLOCK & FASYNC */
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? */
48
#include "exglobals.h"
50
#include "xserver-properties.h"
51
#include "inpututils.h"
52
#include "optionstr.h"
54
#define AtomFromName(x) MakeAtom(x, strlen(x), 1)
56
struct KdConfigDevice {
58
struct KdConfigDevice *next;
61
/* kdKeyboards and kdPointers hold all the real devices. */
62
static KdKeyboardInfo *kdKeyboards = NULL;
63
static KdPointerInfo *kdPointers = NULL;
64
static struct KdConfigDevice *kdConfigKeyboards = NULL;
65
static struct KdConfigDevice *kdConfigPointers = NULL;
67
static KdKeyboardDriver *kdKeyboardDrivers = NULL;
68
static KdPointerDriver *kdPointerDrivers = NULL;
70
static Bool kdInputEnabled;
71
static Bool kdOffScreen;
72
static unsigned long kdOffScreenTime;
74
static KdPointerMatrix kdPointerMatrix = {
79
void KdResetInputMachine(void);
81
#define KD_MAX_INPUT_FDS 8
83
typedef struct _kdInputFd {
85
void (*read) (int fd, void *closure);
86
int (*enable) (int fd, void *closure);
87
void (*disable) (int fd, void *closure);
91
static KdInputFd kdInputFds[KD_MAX_INPUT_FDS];
92
static int kdNumInputFds;
94
extern Bool kdRawPointerCoordinates;
101
for (i = 0; i < kdNumInputFds; i++)
102
(*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
108
KdAssertSigioBlocked(char *where)
113
sigprocmask(SIG_BLOCK, &set, &old);
114
if (!sigismember(&old, SIGIO)) {
115
ErrorF("SIGIO not blocked at %s\n", where);
122
#define KdAssertSigioBlocked(s)
129
#define NOBLOCK FNONBLOCK
131
#define NOBLOCK FNDELAY
135
KdResetInputMachine(void)
139
for (pi = kdPointers; pi; pi = pi->next) {
140
pi->mouseState = start;
141
pi->eventHeld = FALSE;
150
flags = fcntl(fd, F_GETFL);
151
flags |= FASYNC | NOBLOCK;
152
fcntl(fd, F_SETFL, flags);
158
struct sigaction act;
162
fcntl(fd, F_SETOWN, getpid());
164
AddEnabledDevice(fd);
165
memset(&act, '\0', sizeof act);
166
act.sa_handler = KdSigio;
167
sigemptyset(&act.sa_mask);
168
sigaddset(&act.sa_mask, SIGIO);
169
sigaddset(&act.sa_mask, SIGALRM);
170
sigaddset(&act.sa_mask, SIGVTALRM);
171
sigaction(SIGIO, &act, 0);
173
sigprocmask(SIG_SETMASK, &set, 0);
179
struct sigaction act;
183
RemoveEnabledDevice(fd);
184
flags = fcntl(fd, F_GETFL);
185
flags &= ~(FASYNC | NOBLOCK);
186
fcntl(fd, F_SETFL, flags);
188
memset(&act, '\0', sizeof act);
189
act.sa_handler = SIG_IGN;
190
sigemptyset(&act.sa_mask);
191
sigaction(SIGIO, &act, 0);
196
KdRegisterFd(int fd, void (*read) (int fd, void *closure), void *closure)
198
if (kdNumInputFds == KD_MAX_INPUT_FDS)
200
kdInputFds[kdNumInputFds].fd = fd;
201
kdInputFds[kdNumInputFds].read = read;
202
kdInputFds[kdNumInputFds].enable = 0;
203
kdInputFds[kdNumInputFds].disable = 0;
204
kdInputFds[kdNumInputFds].closure = closure;
212
KdUnregisterFd(void *closure, int fd, Bool do_close)
216
for (i = 0; i < kdNumInputFds; i++) {
217
if (kdInputFds[i].closure == closure &&
218
(fd == -1 || kdInputFds[i].fd == fd)) {
220
KdRemoveFd(kdInputFds[i].fd);
222
close(kdInputFds[i].fd);
224
for (j = i; j < (kdNumInputFds - 1); j++)
225
kdInputFds[j] = kdInputFds[j + 1];
232
KdUnregisterFds(void *closure, Bool do_close)
234
KdUnregisterFd(closure, -1, do_close);
242
int found = 0, i = 0;
246
for (ki = kdKeyboards; ki; ki = ki->next) {
247
if (ki->driver && ki->driver->Disable)
248
(*ki->driver->Disable) (ki);
251
for (pi = kdPointers; pi; pi = pi->next) {
252
if (pi->driver && pi->driver->Disable)
253
(*pi->driver->Disable) (pi);
257
ErrorF("[KdDisableInput] Buggy drivers: still %d input fds left!",
260
while (i < kdNumInputFds) {
262
for (ki = kdKeyboards; ki; ki = ki->next) {
263
if (ki == kdInputFds[i].closure) {
264
ErrorF(" fd %d belongs to keybd driver %s\n",
266
ki->driver && ki->driver->name ?
267
ki->driver->name : "(unnamed!)");
278
for (pi = kdPointers; pi; pi = pi->next) {
279
if (pi == kdInputFds[i].closure) {
280
ErrorF(" fd %d belongs to pointer driver %s\n",
282
pi->driver && pi->driver->name ?
283
pi->driver->name : "(unnamed!)");
293
ErrorF(" fd %d not claimed by any active device!\n",
295
KdUnregisterFd(kdInputFds[i].closure, kdInputFds[i].fd, TRUE);
299
kdInputEnabled = FALSE;
309
kdInputEnabled = TRUE;
311
ev.any.time = GetTimeInMillis();
313
for (ki = kdKeyboards; ki; ki = ki->next) {
314
if (ki->driver && ki->driver->Enable)
315
(*ki->driver->Enable) (ki);
316
/* reset screen saver */
317
NoticeEventTime (&ev, ki->dixdev);
320
for (pi = kdPointers; pi; pi = pi->next) {
321
if (pi->driver && pi->driver->Enable)
322
(*pi->driver->Enable) (pi);
323
/* reset screen saver */
324
NoticeEventTime (&ev, pi->dixdev);
330
static KdKeyboardDriver *
331
KdFindKeyboardDriver(const char *name)
333
KdKeyboardDriver *ret;
335
/* ask a stupid question ... */
339
for (ret = kdKeyboardDrivers; ret; ret = ret->next) {
340
if (strcmp(ret->name, name) == 0)
347
static KdPointerDriver *
348
KdFindPointerDriver(const char *name)
350
KdPointerDriver *ret;
352
/* ask a stupid question ... */
356
for (ret = kdPointerDrivers; ret; ret = ret->next) {
357
if (strcmp(ret->name, name) == 0)
365
KdPointerProc(DeviceIntPtr pDevice, int onoff)
367
DevicePtr pDev = (DevicePtr) pDevice;
374
return BadImplementation;
376
for (pi = kdPointers; pi; pi = pi->next) {
377
if (pi->dixdev && pi->dixdev->id == pDevice->id)
381
if (!pi || !pi->dixdev || pi->dixdev->id != pDevice->id) {
382
ErrorF("[KdPointerProc] Failed to find pointer for device %d!\n",
384
return BadImplementation;
390
ErrorF("initialising pointer %s ...\n", pi->name);
393
if (!pi->driverPrivate) {
394
ErrorF("no driver specified for %s\n", pi->name);
395
return BadImplementation;
398
pi->driver = KdFindPointerDriver(pi->driverPrivate);
400
ErrorF("Couldn't find pointer driver %s\n",
401
pi->driverPrivate ? (char *) pi->driverPrivate :
405
free(pi->driverPrivate);
406
pi->driverPrivate = NULL;
409
if (!pi->driver->Init) {
410
ErrorF("no init function\n");
411
return BadImplementation;
414
if ((*pi->driver->Init) (pi) != Success) {
418
btn_labels = calloc(pi->nButtons, sizeof(Atom));
421
axes_labels = calloc(pi->nAxes, sizeof(Atom));
430
btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
432
btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
434
btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
436
btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
438
btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
440
btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
442
btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
447
if (pi->nAxes >= 2) {
448
axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
449
axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
452
InitPointerDeviceStruct(pDev, pi->map, pi->nButtons, btn_labels,
453
(PtrCtrlProcPtr) NoopDDA,
454
GetMotionHistorySize(), pi->nAxes, axes_labels);
459
if (pi->inputClass == KD_TOUCHSCREEN) {
460
xiclass = AtomFromName(XI_TOUCHSCREEN);
463
xiclass = AtomFromName(XI_MOUSE);
466
AssignTypeAndName(pi->dixdev, xiclass,
467
pi->name ? pi->name : "Generic KDrive Pointer");
472
if (pDev->on == TRUE)
475
if (!pi->driver->Enable) {
476
ErrorF("no enable function\n");
477
return BadImplementation;
480
if ((*pi->driver->Enable) (pi) == Success) {
485
return BadImplementation;
491
if (pDev->on == FALSE) {
495
if (!pi->driver->Disable) {
496
return BadImplementation;
499
(*pi->driver->Disable) (pi);
508
if (!pi->driver->Disable) {
509
return BadImplementation;
511
(*pi->driver->Disable) (pi);
515
if (!pi->driver->Fini)
516
return BadImplementation;
518
(*pi->driver->Fini) (pi);
526
return BadImplementation;
530
LegalModifier(unsigned int key, DeviceIntPtr pDev)
536
KdBell(int volume, DeviceIntPtr pDev, void *arg, int something)
538
KeybdCtrl *ctrl = arg;
539
KdKeyboardInfo *ki = NULL;
541
for (ki = kdKeyboards; ki; ki = ki->next) {
542
if (ki->dixdev && ki->dixdev->id == pDev->id)
546
if (!ki || !ki->dixdev || ki->dixdev->id != pDev->id || !ki->driver)
549
KdRingBell(ki, volume, ctrl->bell_pitch, ctrl->bell_duration);
553
DDXRingBell(int volume, int pitch, int duration)
555
KdKeyboardInfo *ki = NULL;
557
if (kdOsFuncs->Bell) {
558
(*kdOsFuncs->Bell) (volume, pitch, duration);
561
for (ki = kdKeyboards; ki; ki = ki->next) {
562
if (ki->dixdev->coreEvents)
563
KdRingBell(ki, volume, pitch, duration);
569
KdRingBell(KdKeyboardInfo * ki, int volume, int pitch, int duration)
571
if (!ki || !ki->driver || !ki->driver->Bell)
575
(*ki->driver->Bell) (ki, volume, pitch, duration);
579
KdSetLeds(KdKeyboardInfo * ki, int leds)
581
if (!ki || !ki->driver)
584
if (kdInputEnabled) {
585
if (ki->driver->Leds)
586
(*ki->driver->Leds) (ki, leds);
591
KdSetLed(KdKeyboardInfo * ki, int led, Bool on)
593
if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed)
596
NoteLedState(ki->dixdev, led, on);
597
KdSetLeds(ki, ki->dixdev->kbdfeed->ctrl.leds);
601
KdSetPointerMatrix(KdPointerMatrix * matrix)
603
kdPointerMatrix = *matrix;
607
KdComputePointerMatrix(KdPointerMatrix * m, Rotation randr, int width,
610
int x_dir = 1, y_dir = 1;
616
if (randr & RR_Reflect_X)
618
if (randr & RR_Reflect_Y)
620
switch (randr & (RR_Rotate_All)) {
622
m->matrix[0][0] = x_dir;
625
m->matrix[1][1] = y_dir;
629
m->matrix[0][1] = -x_dir;
630
m->matrix[1][0] = y_dir;
634
m->matrix[0][0] = -x_dir;
637
m->matrix[1][1] = -y_dir;
641
m->matrix[0][1] = x_dir;
642
m->matrix[1][0] = -y_dir;
646
for (i = 0; i < 2; i++) {
648
for (j = 0; j < 2; j++)
649
if (m->matrix[i][j] < 0)
650
m->matrix[i][2] = size[j] - 1;
655
KdScreenToPointerCoords(int *x, int *y)
657
int (*m)[3] = kdPointerMatrix.matrix;
658
int div = m[0][1] * m[1][0] - m[1][1] * m[0][0];
662
*x = (m[0][1] * sy - m[0][1] * m[1][2] + m[1][1] * m[0][2] -
664
*y = (m[1][0] * sx + m[0][0] * m[1][2] - m[1][0] * m[0][2] -
669
KdKbdCtrl(DeviceIntPtr pDevice, KeybdCtrl * ctrl)
673
for (ki = kdKeyboards; ki; ki = ki->next) {
674
if (ki->dixdev && ki->dixdev->id == pDevice->id)
678
if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id || !ki->driver)
681
KdSetLeds(ki, ctrl->leds);
682
ki->bellPitch = ctrl->bell_pitch;
683
ki->bellDuration = ctrl->bell_duration;
687
KdKeyboardProc(DeviceIntPtr pDevice, int onoff)
690
DevicePtr pDev = (DevicePtr) pDevice;
696
return BadImplementation;
698
for (ki = kdKeyboards; ki; ki = ki->next) {
699
if (ki->dixdev && ki->dixdev->id == pDevice->id)
703
if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id) {
704
return BadImplementation;
710
ErrorF("initialising keyboard %s\n", ki->name);
713
if (!ki->driverPrivate) {
714
ErrorF("no driver specified!\n");
715
return BadImplementation;
718
ki->driver = KdFindKeyboardDriver(ki->driverPrivate);
720
ErrorF("Couldn't find keyboard driver %s\n",
721
ki->driverPrivate ? (char *) ki->driverPrivate :
725
free(ki->driverPrivate);
726
ki->driverPrivate = NULL;
729
if (!ki->driver->Init) {
730
ErrorF("Keyboard %s: no init function\n", ki->name);
731
return BadImplementation;
734
if ((*ki->driver->Init) (ki) != Success) {
738
memset(&rmlvo, 0, sizeof(rmlvo));
739
rmlvo.rules = ki->xkbRules;
740
rmlvo.model = ki->xkbModel;
741
rmlvo.layout = ki->xkbLayout;
742
rmlvo.variant = ki->xkbVariant;
743
rmlvo.options = ki->xkbOptions;
744
ret = InitKeyboardDeviceStruct(pDevice, &rmlvo, KdBell, KdKbdCtrl);
746
ErrorF("Couldn't initialise keyboard %s\n", ki->name);
747
return BadImplementation;
750
xiclass = AtomFromName(XI_KEYBOARD);
751
AssignTypeAndName(pDevice, xiclass,
752
ki->name ? ki->name : "Generic KDrive Keyboard");
754
KdResetInputMachine();
759
if (pDev->on == TRUE)
762
if (!ki->driver->Enable)
763
return BadImplementation;
765
if ((*ki->driver->Enable) (ki) != Success) {
773
if (pDev->on == FALSE)
776
if (!ki->driver->Disable)
777
return BadImplementation;
779
(*ki->driver->Disable) (ki);
788
if (!ki->driver->Disable)
789
return BadImplementation;
791
(*ki->driver->Disable) (ki);
795
if (!ki->driver->Fini)
796
return BadImplementation;
798
(*ki->driver->Fini) (ki);
800
KdRemoveKeyboard(ki);
806
return BadImplementation;
810
KdAddPointerDriver(KdPointerDriver * driver)
812
KdPointerDriver **prev;
817
for (prev = &kdPointerDrivers; *prev; prev = &(*prev)->next) {
825
KdRemovePointerDriver(KdPointerDriver * driver)
827
KdPointerDriver *tmp;
832
/* FIXME remove all pointers using this driver */
833
for (tmp = kdPointerDrivers; tmp; tmp = tmp->next) {
834
if (tmp->next == driver)
835
tmp->next = driver->next;
842
KdAddKeyboardDriver(KdKeyboardDriver * driver)
844
KdKeyboardDriver **prev;
849
for (prev = &kdKeyboardDrivers; *prev; prev = &(*prev)->next) {
857
KdRemoveKeyboardDriver(KdKeyboardDriver * driver)
859
KdKeyboardDriver *tmp;
864
/* FIXME remove all keyboards using this driver */
865
for (tmp = kdKeyboardDrivers; tmp; tmp = tmp->next) {
866
if (tmp->next == driver)
867
tmp->next = driver->next;
876
KdKeyboardInfo *ki = calloc(sizeof(KdKeyboardInfo), 1);
884
ki->bellPitch = 1000;
885
ki->bellDuration = 200;
888
ki->xkbRules = strdup(XKB_DFLT_RULES);
889
ki->xkbModel = strdup(XKB_DFLT_MODEL);
890
ki->xkbLayout = strdup(XKB_DFLT_LAYOUT);
891
ki->xkbVariant = strdup(XKB_DFLT_VARIANT);
892
ki->xkbOptions = strdup(XKB_DFLT_OPTIONS);
898
KdAddConfigKeyboard(char *keyboard)
900
struct KdConfigDevice **prev, *new;
905
new = (struct KdConfigDevice *) calloc(sizeof(struct KdConfigDevice), 1);
909
new->line = strdup(keyboard);
912
for (prev = &kdConfigKeyboards; *prev; prev = &(*prev)->next);
919
KdAddKeyboard(KdKeyboardInfo * ki)
921
KdKeyboardInfo **prev;
926
ki->dixdev = AddInputDevice(serverClient, KdKeyboardProc, TRUE);
928
ErrorF("Couldn't register keyboard device %s\n",
929
ki->name ? ki->name : "(unnamed)");
934
ErrorF("added keyboard %s with dix id %d\n", ki->name, ki->dixdev->id);
937
for (prev = &kdKeyboards; *prev; prev = &(*prev)->next);
944
KdRemoveKeyboard(KdKeyboardInfo * ki)
946
KdKeyboardInfo **prev;
951
for (prev = &kdKeyboards; *prev; prev = &(*prev)->next) {
962
KdAddConfigPointer(char *pointer)
964
struct KdConfigDevice **prev, *new;
969
new = (struct KdConfigDevice *) calloc(sizeof(struct KdConfigDevice), 1);
973
new->line = strdup(pointer);
976
for (prev = &kdConfigPointers; *prev; prev = &(*prev)->next);
983
KdAddPointer(KdPointerInfo * pi)
985
KdPointerInfo **prev;
990
pi->mouseState = start;
991
pi->eventHeld = FALSE;
993
pi->dixdev = AddInputDevice(serverClient, KdPointerProc, TRUE);
995
ErrorF("Couldn't add pointer device %s\n",
996
pi->name ? pi->name : "(unnamed)");
1000
for (prev = &kdPointers; *prev; prev = &(*prev)->next);
1007
KdRemovePointer(KdPointerInfo * pi)
1009
KdPointerInfo **prev;
1014
for (prev = &kdPointers; *prev; prev = &(*prev)->next) {
1025
* You can call your kdriver server with something like:
1026
* $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd
1027
* evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br
1030
KdGetOptions(InputOption **options, char *string)
1032
InputOption *newopt = NULL;
1033
char *key = NULL, *value = NULL;
1036
if (strchr(string, '=')) {
1037
tam_key = (strchr(string, '=') - string);
1038
key = strndup(string, tam_key);
1042
value = strdup(strchr(string, '=') + 1);
1047
key = strdup(string);
1051
newopt = input_option_new(*options, key, value);
1059
return (newopt != NULL);
1063
KdParseKbdOptions(KdKeyboardInfo * ki)
1065
InputOption *option = NULL;
1067
nt_list_for_each_entry(option, ki->options, list.next) {
1068
const char *key = input_option_get_key(option);
1069
const char *value = input_option_get_value(option);
1071
if (strcasecmp(key, "XkbRules") == 0)
1072
ki->xkbRules = strdup(value);
1073
else if (strcasecmp(key, "XkbModel") == 0)
1074
ki->xkbModel = strdup(value);
1075
else if (strcasecmp(key, "XkbLayout") == 0)
1076
ki->xkbLayout = strdup(value);
1077
else if (strcasecmp(key, "XkbVariant") == 0)
1078
ki->xkbVariant = strdup(value);
1079
else if (strcasecmp(key, "XkbOptions") == 0)
1080
ki->xkbOptions = strdup(value);
1081
else if (!strcasecmp(key, "device"))
1082
ki->path = strdup(value);
1084
ErrorF("Kbd option key (%s) of value (%s) not assigned!\n",
1090
KdParseKeyboard(const char *arg)
1094
InputOption *options = NULL;
1095
KdKeyboardInfo *ki = NULL;
1097
ki = KdNewKeyboard();
1101
ki->name = strdup("Unknown KDrive Keyboard");
1104
ki->driverPrivate = NULL;
1108
ErrorF("keybd: no arg\n");
1113
if (strlen(arg) >= sizeof(save)) {
1114
ErrorF("keybd: arg too long\n");
1119
arg = KdParseFindNext(arg, ",", save, &delim);
1121
ErrorF("keybd: failed on save[0]\n");
1126
if (strcmp(save, "auto") == 0)
1127
ki->driverPrivate = NULL;
1129
ki->driverPrivate = strdup(save);
1135
arg = KdParseFindNext(arg, ",", save, &delim);
1137
while (delim == ',') {
1138
arg = KdParseFindNext(arg, ",", save, &delim);
1140
if (!KdGetOptions(&options, save)) {
1147
ki->options = options;
1148
KdParseKbdOptions(ki);
1155
KdParsePointerOptions(KdPointerInfo * pi)
1157
InputOption *option = NULL;
1159
nt_list_for_each_entry(option, pi->options, list.next) {
1160
const char *key = input_option_get_key(option);
1161
const char *value = input_option_get_value(option);
1163
if (!strcmp(key, "emulatemiddle"))
1164
pi->emulateMiddleButton = TRUE;
1165
else if (!strcmp(key, "noemulatemiddle"))
1166
pi->emulateMiddleButton = FALSE;
1167
else if (!strcmp(key, "transformcoord"))
1168
pi->transformCoordinates = TRUE;
1169
else if (!strcmp(key, "rawcoord"))
1170
pi->transformCoordinates = FALSE;
1171
else if (!strcasecmp(key, "device"))
1172
pi->path = strdup(value);
1173
else if (!strcasecmp(key, "protocol"))
1174
pi->protocol = strdup(value);
1176
ErrorF("Pointer option key (%s) of value (%s) not assigned!\n",
1182
KdParsePointer(const char *arg)
1186
KdPointerInfo *pi = NULL;
1187
InputOption *options = NULL;
1190
pi = KdNewPointer();
1193
pi->emulateMiddleButton = kdEmulateMiddleButton;
1194
pi->transformCoordinates = !kdRawPointerCoordinates;
1195
pi->protocol = NULL;
1196
pi->nButtons = 5; /* XXX should not be hardcoded */
1197
pi->inputClass = KD_MOUSE;
1200
ErrorF("mouse: no arg\n");
1205
if (strlen(arg) >= sizeof(save)) {
1206
ErrorF("mouse: arg too long\n");
1210
arg = KdParseFindNext(arg, ",", save, &delim);
1212
ErrorF("failed on save[0]\n");
1217
if (strcmp(save, "auto") == 0)
1218
pi->driverPrivate = NULL;
1220
pi->driverPrivate = strdup(save);
1226
arg = KdParseFindNext(arg, ",", save, &delim);
1228
while (delim == ',') {
1229
arg = KdParseFindNext(arg, ",", save, &delim);
1230
if (save[0] == '{') {
1234
while (*s && *s != '}') {
1235
if ('1' <= *s && *s <= '0' + pi->nButtons)
1236
pi->map[i] = *s - '0';
1243
if (!KdGetOptions(&options, save)) {
1251
pi->options = options;
1252
KdParsePointerOptions(pi);
1263
struct KdConfigDevice *dev;
1265
kdInputEnabled = TRUE;
1267
for (dev = kdConfigPointers; dev; dev = dev->next) {
1268
pi = KdParsePointer(dev->line);
1270
ErrorF("Failed to parse pointer\n");
1271
if (KdAddPointer(pi) != Success)
1272
ErrorF("Failed to add pointer!\n");
1274
for (dev = kdConfigKeyboards; dev; dev = dev->next) {
1275
ki = KdParseKeyboard(dev->line);
1277
ErrorF("Failed to parse keyboard\n");
1278
if (KdAddKeyboard(ki) != Success)
1279
ErrorF("Failed to add keyboard!\n");
1292
* Middle button emulation state machine
1294
* Possible transitions:
1296
* Button 1 release ^1
1298
* Button 2 release ^2
1300
* Button 3 release ^3
1301
* Button other press vo
1302
* Button other release ^o
1315
* synthetic_2_down_13
1316
* synthetic_2_down_3
1317
* synthetic_2_down_1
1319
* Transition diagram
1322
* v1 -> (hold) (settimeout) button_1_pend
1323
* ^1 -> (deliver) start
1324
* v2 -> (deliver) button_2_down
1325
* ^2 -> (deliever) start
1326
* v3 -> (hold) (settimeout) button_3_pend
1327
* ^3 -> (deliver) start
1328
* vo -> (deliver) start
1329
* ^o -> (deliver) start
1330
* <> -> (deliver) start
1331
* k -> (deliver) start
1333
* button_1_pend (button 1 is down, timeout pending)
1334
* ^1 -> (release) (deliver) start
1335
* v2 -> (release) (deliver) button_1_down
1336
* ^2 -> (release) (deliver) button_1_down
1337
* v3 -> (cleartimeout) (generate v2) synthetic_2_down_13
1338
* ^3 -> (release) (deliver) button_1_down
1339
* vo -> (release) (deliver) button_1_down
1340
* ^o -> (release) (deliver) button_1_down
1341
* <-> -> (release) (deliver) button_1_down
1342
* <> -> (deliver) button_1_pend
1343
* k -> (release) (deliver) button_1_down
1344
* ... -> (release) button_1_down
1346
* button_1_down (button 1 is down)
1347
* ^1 -> (deliver) start
1348
* v2 -> (deliver) button_1_down
1349
* ^2 -> (deliver) button_1_down
1350
* v3 -> (deliver) button_1_down
1351
* ^3 -> (deliver) button_1_down
1352
* vo -> (deliver) button_1_down
1353
* ^o -> (deliver) button_1_down
1354
* <> -> (deliver) button_1_down
1355
* k -> (deliver) button_1_down
1357
* button_2_down (button 2 is down)
1358
* v1 -> (deliver) button_2_down
1359
* ^1 -> (deliver) button_2_down
1360
* ^2 -> (deliver) start
1361
* v3 -> (deliver) button_2_down
1362
* ^3 -> (deliver) button_2_down
1363
* vo -> (deliver) button_2_down
1364
* ^o -> (deliver) button_2_down
1365
* <> -> (deliver) button_2_down
1366
* k -> (deliver) button_2_down
1368
* button_3_pend (button 3 is down, timeout pending)
1369
* v1 -> (generate v2) synthetic_2_down
1370
* ^1 -> (release) (deliver) button_3_down
1371
* v2 -> (release) (deliver) button_3_down
1372
* ^2 -> (release) (deliver) button_3_down
1373
* ^3 -> (release) (deliver) start
1374
* vo -> (release) (deliver) button_3_down
1375
* ^o -> (release) (deliver) button_3_down
1376
* <-> -> (release) (deliver) button_3_down
1377
* <> -> (deliver) button_3_pend
1378
* k -> (release) (deliver) button_3_down
1379
* ... -> (release) button_3_down
1381
* button_3_down (button 3 is down)
1382
* v1 -> (deliver) button_3_down
1383
* ^1 -> (deliver) button_3_down
1384
* v2 -> (deliver) button_3_down
1385
* ^2 -> (deliver) button_3_down
1386
* ^3 -> (deliver) start
1387
* vo -> (deliver) button_3_down
1388
* ^o -> (deliver) button_3_down
1389
* <> -> (deliver) button_3_down
1390
* k -> (deliver) button_3_down
1392
* synthetic_2_down_13 (button 1 and 3 are down)
1393
* ^1 -> (generate ^2) synthetic_2_down_3
1394
* v2 -> synthetic_2_down_13
1395
* ^2 -> synthetic_2_down_13
1396
* ^3 -> (generate ^2) synthetic_2_down_1
1397
* vo -> (deliver) synthetic_2_down_13
1398
* ^o -> (deliver) synthetic_2_down_13
1399
* <> -> (deliver) synthetic_2_down_13
1400
* k -> (deliver) synthetic_2_down_13
1402
* synthetic_2_down_3 (button 3 is down)
1403
* v1 -> (deliver) synthetic_2_down_3
1404
* ^1 -> (deliver) synthetic_2_down_3
1405
* v2 -> synthetic_2_down_3
1406
* ^2 -> synthetic_2_down_3
1408
* vo -> (deliver) synthetic_2_down_3
1409
* ^o -> (deliver) synthetic_2_down_3
1410
* <> -> (deliver) synthetic_2_down_3
1411
* k -> (deliver) synthetic_2_down_3
1413
* synthetic_2_down_1 (button 1 is down)
1415
* v2 -> synthetic_2_down_1
1416
* ^2 -> synthetic_2_down_1
1417
* v3 -> (deliver) synthetic_2_down_1
1418
* ^3 -> (deliver) synthetic_2_down_1
1419
* vo -> (deliver) synthetic_2_down_1
1420
* ^o -> (deliver) synthetic_2_down_1
1421
* <> -> (deliver) synthetic_2_down_1
1422
* k -> (deliver) synthetic_2_down_1
1425
typedef enum _inputClass {
1430
motion, outside_box,
1435
typedef enum _inputAction {
1446
#define MAX_ACTIONS 2
1448
typedef struct _inputTransition {
1449
KdInputAction actions[MAX_ACTIONS];
1450
KdPointerState nextState;
1451
} KdInputTransition;
1454
KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
1457
{{hold, setto}, button_1_pend}, /* v1 */
1458
{{deliver, noop}, start}, /* ^1 */
1459
{{deliver, noop}, button_2_down}, /* v2 */
1460
{{deliver, noop}, start}, /* ^2 */
1461
{{hold, setto}, button_3_pend}, /* v3 */
1462
{{deliver, noop}, start}, /* ^3 */
1463
{{deliver, noop}, start}, /* vo */
1464
{{deliver, noop}, start}, /* ^o */
1465
{{deliver, noop}, start}, /* <> */
1466
{{deliver, noop}, start}, /* <-> */
1467
{{noop, noop}, start}, /* k */
1468
{{noop, noop}, start}, /* ... */
1472
{{noop, noop}, button_1_pend}, /* v1 */
1473
{{release, deliver}, start}, /* ^1 */
1474
{{release, deliver}, button_1_down}, /* v2 */
1475
{{release, deliver}, button_1_down}, /* ^2 */
1476
{{clearto, gen_down_2}, synth_2_down_13}, /* v3 */
1477
{{release, deliver}, button_1_down}, /* ^3 */
1478
{{release, deliver}, button_1_down}, /* vo */
1479
{{release, deliver}, button_1_down}, /* ^o */
1480
{{deliver, noop}, button_1_pend}, /* <> */
1481
{{release, deliver}, button_1_down}, /* <-> */
1482
{{noop, noop}, button_1_down}, /* k */
1483
{{release, noop}, button_1_down}, /* ... */
1487
{{noop, noop}, button_1_down}, /* v1 */
1488
{{deliver, noop}, start}, /* ^1 */
1489
{{deliver, noop}, button_1_down}, /* v2 */
1490
{{deliver, noop}, button_1_down}, /* ^2 */
1491
{{deliver, noop}, button_1_down}, /* v3 */
1492
{{deliver, noop}, button_1_down}, /* ^3 */
1493
{{deliver, noop}, button_1_down}, /* vo */
1494
{{deliver, noop}, button_1_down}, /* ^o */
1495
{{deliver, noop}, button_1_down}, /* <> */
1496
{{deliver, noop}, button_1_down}, /* <-> */
1497
{{noop, noop}, button_1_down}, /* k */
1498
{{noop, noop}, button_1_down}, /* ... */
1502
{{deliver, noop}, button_2_down}, /* v1 */
1503
{{deliver, noop}, button_2_down}, /* ^1 */
1504
{{noop, noop}, button_2_down}, /* v2 */
1505
{{deliver, noop}, start}, /* ^2 */
1506
{{deliver, noop}, button_2_down}, /* v3 */
1507
{{deliver, noop}, button_2_down}, /* ^3 */
1508
{{deliver, noop}, button_2_down}, /* vo */
1509
{{deliver, noop}, button_2_down}, /* ^o */
1510
{{deliver, noop}, button_2_down}, /* <> */
1511
{{deliver, noop}, button_2_down}, /* <-> */
1512
{{noop, noop}, button_2_down}, /* k */
1513
{{noop, noop}, button_2_down}, /* ... */
1517
{{clearto, gen_down_2}, synth_2_down_13}, /* v1 */
1518
{{release, deliver}, button_3_down}, /* ^1 */
1519
{{release, deliver}, button_3_down}, /* v2 */
1520
{{release, deliver}, button_3_down}, /* ^2 */
1521
{{release, deliver}, button_3_down}, /* v3 */
1522
{{release, deliver}, start}, /* ^3 */
1523
{{release, deliver}, button_3_down}, /* vo */
1524
{{release, deliver}, button_3_down}, /* ^o */
1525
{{deliver, noop}, button_3_pend}, /* <> */
1526
{{release, deliver}, button_3_down}, /* <-> */
1527
{{release, noop}, button_3_down}, /* k */
1528
{{release, noop}, button_3_down}, /* ... */
1532
{{deliver, noop}, button_3_down}, /* v1 */
1533
{{deliver, noop}, button_3_down}, /* ^1 */
1534
{{deliver, noop}, button_3_down}, /* v2 */
1535
{{deliver, noop}, button_3_down}, /* ^2 */
1536
{{noop, noop}, button_3_down}, /* v3 */
1537
{{deliver, noop}, start}, /* ^3 */
1538
{{deliver, noop}, button_3_down}, /* vo */
1539
{{deliver, noop}, button_3_down}, /* ^o */
1540
{{deliver, noop}, button_3_down}, /* <> */
1541
{{deliver, noop}, button_3_down}, /* <-> */
1542
{{noop, noop}, button_3_down}, /* k */
1543
{{noop, noop}, button_3_down}, /* ... */
1545
/* synthetic_2_down_13 */
1547
{{noop, noop}, synth_2_down_13}, /* v1 */
1548
{{gen_up_2, noop}, synth_2_down_3}, /* ^1 */
1549
{{noop, noop}, synth_2_down_13}, /* v2 */
1550
{{noop, noop}, synth_2_down_13}, /* ^2 */
1551
{{noop, noop}, synth_2_down_13}, /* v3 */
1552
{{gen_up_2, noop}, synth_2_down_1}, /* ^3 */
1553
{{deliver, noop}, synth_2_down_13}, /* vo */
1554
{{deliver, noop}, synth_2_down_13}, /* ^o */
1555
{{deliver, noop}, synth_2_down_13}, /* <> */
1556
{{deliver, noop}, synth_2_down_13}, /* <-> */
1557
{{noop, noop}, synth_2_down_13}, /* k */
1558
{{noop, noop}, synth_2_down_13}, /* ... */
1560
/* synthetic_2_down_3 */
1562
{{deliver, noop}, synth_2_down_3}, /* v1 */
1563
{{deliver, noop}, synth_2_down_3}, /* ^1 */
1564
{{deliver, noop}, synth_2_down_3}, /* v2 */
1565
{{deliver, noop}, synth_2_down_3}, /* ^2 */
1566
{{noop, noop}, synth_2_down_3}, /* v3 */
1567
{{noop, noop}, start}, /* ^3 */
1568
{{deliver, noop}, synth_2_down_3}, /* vo */
1569
{{deliver, noop}, synth_2_down_3}, /* ^o */
1570
{{deliver, noop}, synth_2_down_3}, /* <> */
1571
{{deliver, noop}, synth_2_down_3}, /* <-> */
1572
{{noop, noop}, synth_2_down_3}, /* k */
1573
{{noop, noop}, synth_2_down_3}, /* ... */
1575
/* synthetic_2_down_1 */
1577
{{noop, noop}, synth_2_down_1}, /* v1 */
1578
{{noop, noop}, start}, /* ^1 */
1579
{{deliver, noop}, synth_2_down_1}, /* v2 */
1580
{{deliver, noop}, synth_2_down_1}, /* ^2 */
1581
{{deliver, noop}, synth_2_down_1}, /* v3 */
1582
{{deliver, noop}, synth_2_down_1}, /* ^3 */
1583
{{deliver, noop}, synth_2_down_1}, /* vo */
1584
{{deliver, noop}, synth_2_down_1}, /* ^o */
1585
{{deliver, noop}, synth_2_down_1}, /* <> */
1586
{{deliver, noop}, synth_2_down_1}, /* <-> */
1587
{{noop, noop}, synth_2_down_1}, /* k */
1588
{{noop, noop}, synth_2_down_1}, /* ... */
1592
#define EMULATION_WINDOW 10
1593
#define EMULATION_TIMEOUT 100
1596
KdInsideEmulationWindow(KdPointerInfo * pi, int x, int y, int z)
1598
pi->emulationDx = pi->heldEvent.x - x;
1599
pi->emulationDy = pi->heldEvent.y - y;
1601
return (abs(pi->emulationDx) < EMULATION_WINDOW &&
1602
abs(pi->emulationDy) < EMULATION_WINDOW);
1606
KdClassifyInput(KdPointerInfo * pi, int type, int x, int y, int z, int b)
1634
if (pi->eventHeld && !KdInsideEmulationWindow(pi, x, y, z))
1645
char *kdStateNames[] = {
1654
"synthetic_2_down_1",
1658
char *kdClassNames[] = {
1662
"motion", "ouside_box",
1663
"keyboard", "timeout",
1667
char *kdActionNames[] = {
1679
/* We return true if we're stealing the event. */
1681
KdRunMouseMachine(KdPointerInfo * pi, KdInputClass c, int type, int x, int y,
1682
int z, int b, int absrel)
1684
const KdInputTransition *t;
1687
c = KdClassifyInput(pi, type, x, y, z, b);
1688
t = &kdInputMachine[pi->mouseState][c];
1689
for (a = 0; a < MAX_ACTIONS; a++) {
1690
switch (t->actions[a]) {
1694
pi->eventHeld = TRUE;
1695
pi->emulationDx = 0;
1696
pi->emulationDy = 0;
1697
pi->heldEvent.type = type;
1698
pi->heldEvent.x = x;
1699
pi->heldEvent.y = y;
1700
pi->heldEvent.z = z;
1701
pi->heldEvent.flags = b;
1702
pi->heldEvent.absrel = absrel;
1706
pi->emulationTimeout = GetTimeInMillis() + EMULATION_TIMEOUT;
1707
pi->timeoutPending = TRUE;
1710
_KdEnqueuePointerEvent(pi, pi->heldEvent.type, pi->heldEvent.x,
1711
pi->heldEvent.y, pi->heldEvent.z,
1712
pi->heldEvent.flags, pi->heldEvent.absrel,
1716
pi->eventHeld = FALSE;
1717
pi->timeoutPending = FALSE;
1718
_KdEnqueuePointerEvent(pi, pi->heldEvent.type, pi->heldEvent.x,
1719
pi->heldEvent.y, pi->heldEvent.z,
1720
pi->heldEvent.flags, pi->heldEvent.absrel,
1725
pi->timeoutPending = FALSE;
1728
_KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, 2, absrel, TRUE);
1729
pi->eventHeld = FALSE;
1733
_KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, 2, absrel, TRUE);
1738
pi->mouseState = t->nextState;
1743
KdHandlePointerEvent(KdPointerInfo * pi, int type, int x, int y, int z, int b,
1746
if (pi->emulateMiddleButton)
1747
return KdRunMouseMachine(pi, KdClassifyInput(pi, type, x, y, z, b),
1748
type, x, y, z, b, absrel);
1753
KdReceiveTimeout(KdPointerInfo * pi)
1755
KdRunMouseMachine(pi, timeout, 0, 0, 0, 0, 0, 0);
1759
* kdCheckTermination
1761
* This function checks for the key sequence that terminates the server. When
1762
* detected, it sets the dispatchException flag and returns. The key sequence
1765
* It's assumed that the server will be waken up by the caller when this
1769
extern int nClients;
1772
KdReleaseAllKeys(void)
1780
for (ki = kdKeyboards; ki; ki = ki->next) {
1781
for (key = ki->keySyms.minKeyCode; key < ki->keySyms.maxKeyCode; key++) {
1782
if (key_is_down(ki->dixdev, key, KEY_POSTED | KEY_PROCESSED)) {
1783
KdHandleKeyboardEvent(ki, KeyRelease, key);
1784
QueueGetKeyboardEvents(ki->dixdev, KeyRelease, key, NULL);
1796
KeyClassPtr keyc = NULL;
1797
Bool isSet = FALSE, shouldBeSet = FALSE;
1798
KdKeyboardInfo *tmp = NULL;
1800
for (tmp = kdKeyboards; tmp; tmp = tmp->next) {
1801
if (tmp->LockLed && tmp->dixdev && tmp->dixdev->key) {
1802
keyc = tmp->dixdev->key;
1803
isSet = (tmp->leds & (1 << (tmp->LockLed - 1))) != 0;
1804
/* FIXME: Just use XKB indicators! */
1806
! !(XkbStateFieldFromRec(&keyc->xkbInfo->state) & LockMask);
1807
if (isSet != shouldBeSet)
1808
KdSetLed(tmp, tmp->LockLed, shouldBeSet);
1814
KdEnqueueKeyboardEvent(KdKeyboardInfo * ki,
1815
unsigned char scan_code, unsigned char is_up)
1817
unsigned char key_code;
1820
if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key)
1823
if (scan_code >= ki->minScanCode && scan_code <= ki->maxScanCode) {
1824
key_code = scan_code + KD_MIN_KEYCODE - ki->minScanCode;
1827
* Set up this event -- the type may be modified below
1834
QueueKeyboardEvents(ki->dixdev, type, key_code, NULL);
1837
ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n",
1838
ki->name, scan_code, ki->minScanCode, ki->maxScanCode);
1843
* kdEnqueuePointerEvent
1845
* This function converts hardware mouse event information into X event
1846
* information. A mouse movement event is passed off to MI to generate
1847
* a MotionNotify event, if appropriate. Button events are created and
1848
* passed off to MI for enqueueing.
1851
/* FIXME do something a little more clever to deal with multiple axes here */
1853
KdEnqueuePointerEvent(KdPointerInfo * pi, unsigned long flags, int rx, int ry,
1856
unsigned char buttons;
1858
int (*matrix)[3] = kdPointerMatrix.matrix;
1859
unsigned long button;
1866
/* we don't need to transform z, so we don't. */
1867
if (flags & KD_MOUSE_DELTA) {
1868
if (pi->transformCoordinates) {
1869
x = matrix[0][0] * rx + matrix[0][1] * ry;
1870
y = matrix[1][0] * rx + matrix[1][1] * ry;
1878
if (pi->transformCoordinates) {
1879
x = matrix[0][0] * rx + matrix[0][1] * ry + matrix[0][2];
1880
y = matrix[1][0] * rx + matrix[1][1] * ry + matrix[1][2];
1889
if (flags & KD_MOUSE_DELTA) {
1891
dixflags = POINTER_RELATIVE | POINTER_ACCELERATE;
1892
_KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags,
1897
dixflags = POINTER_ABSOLUTE;
1898
if (flags & KD_POINTER_DESKTOP)
1899
dixflags |= POINTER_DESKTOP;
1900
if (x != pi->dixdev->last.valuators[0] ||
1901
y != pi->dixdev->last.valuators[1])
1902
_KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags,
1908
for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; button <<= 1, n++) {
1909
if (((pi->buttonState & button) ^ (buttons & button)) &&
1910
!(buttons & button)) {
1911
_KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, n,
1915
for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; button <<= 1, n++) {
1916
if (((pi->buttonState & button) ^ (buttons & button)) &&
1917
(buttons & button)) {
1918
_KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, n,
1923
pi->buttonState = buttons;
1927
_KdEnqueuePointerEvent(KdPointerInfo * pi, int type, int x, int y, int z,
1928
int b, int absrel, Bool force)
1930
int valuators[3] = { x, y, z };
1933
/* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */
1934
if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel))
1937
valuator_mask_set_range(&mask, 0, 3, valuators);
1939
QueuePointerEvents(pi->dixdev, type, b, absrel, &mask);
1943
KdBlockHandler(ScreenPtr pScreen, void *timeo, void *readmask)
1948
for (pi = kdPointers; pi; pi = pi->next) {
1949
if (pi->timeoutPending) {
1952
ms = pi->emulationTimeout - GetTimeInMillis();
1955
if (ms < myTimeout || myTimeout == 0)
1959
/* if we need to poll for events, do that */
1960
if (kdOsFuncs->pollEvents) {
1961
(*kdOsFuncs->pollEvents) ();
1965
AdjustWaitForDelay(timeo, myTimeout);
1969
KdWakeupHandler(ScreenPtr pScreen, unsigned long lresult, void *readmask)
1971
int result = (int) lresult;
1972
fd_set *pReadmask = (fd_set *) readmask;
1976
if (kdInputEnabled && result > 0) {
1977
for (i = 0; i < kdNumInputFds; i++)
1978
if (FD_ISSET(kdInputFds[i].fd, pReadmask)) {
1980
(*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
1984
for (pi = kdPointers; pi; pi = pi->next) {
1985
if (pi->timeoutPending) {
1986
if ((long) (GetTimeInMillis() - pi->emulationTimeout) >= 0) {
1987
pi->timeoutPending = FALSE;
1989
KdReceiveTimeout(pi);
1994
if (kdSwitchPending)
1998
#define KdScreenOrigin(pScreen) (&(KdGetScreenPriv(pScreen)->screen->origin))
2001
KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
2003
ScreenPtr pScreen = *ppScreen;
2004
ScreenPtr pNewScreen;
2008
int n_best_x, n_best_y;
2011
if (kdDisableZaphod || screenInfo.numScreens <= 1)
2014
if (0 <= *x && *x < pScreen->width && 0 <= *y && *y < pScreen->height)
2017
ms = GetTimeInMillis();
2018
if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000)
2021
kdOffScreenTime = ms;
2026
for (n = 0; n < screenInfo.numScreens; n++) {
2027
pNewScreen = screenInfo.screens[n];
2028
if (pNewScreen == pScreen)
2030
dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x;
2031
dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y;
2033
if (dx < 0 && -dx < best_x) {
2038
else if (*x >= pScreen->width) {
2039
if (dx > 0 && dx < best_x) {
2045
if (dy < 0 && -dy < best_y) {
2050
else if (*y >= pScreen->height) {
2051
if (dy > 0 && dy < best_y) {
2057
if (best_y < best_x)
2058
n_best_x = n_best_y;
2061
pNewScreen = screenInfo.screens[n_best_x];
2064
*x += pNewScreen->width;
2066
*y += pNewScreen->height;
2068
if (*x >= pScreen->width)
2069
*x -= pScreen->width;
2070
if (*y >= pScreen->height)
2071
*y -= pScreen->height;
2073
*ppScreen = pNewScreen;
2078
KdCrossScreen(ScreenPtr pScreen, Bool entering)
2082
int KdCurScreen; /* current event screen */
2085
KdWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
2088
KdCurScreen = pScreen->myNum;
2089
miPointerWarpCursor(pDev, pScreen, x, y);
2093
miPointerScreenFuncRec kdPointerScreenFuncs = {
2100
ProcessInputEvents(void)
2102
mieqProcessInputEvents();
2103
if (kdSwitchPending)
2108
/* At the moment, absolute/relative is up to the client. */
2110
SetDeviceMode(register ClientPtr client, DeviceIntPtr pDev, int mode)
2116
SetDeviceValuators(register ClientPtr client, DeviceIntPtr pDev,
2117
int *valuators, int first_valuator, int num_valuators)
2123
ChangeDeviceControl(register ClientPtr client, DeviceIntPtr pDev,
2124
xDeviceCtl * control)
2126
switch (control->control) {
2127
case DEVICE_RESOLUTION:
2128
/* FIXME do something more intelligent here */
2131
case DEVICE_ABS_CALIB:
2132
case DEVICE_ABS_AREA:
2143
return BadImplementation;
2147
NewInputDeviceRequest(InputOption *options, InputAttributes * attrs,
2150
InputOption *option = NULL;
2151
KdPointerInfo *pi = NULL;
2152
KdKeyboardInfo *ki = NULL;
2154
nt_list_for_each_entry(option, options, list.next) {
2155
const char *key = input_option_get_key(option);
2156
const char *value = input_option_get_value(option);
2158
if (strcmp(key, "type") == 0) {
2159
if (strcmp(value, "pointer") == 0) {
2160
pi = KdNewPointer();
2164
else if (strcmp(value, "keyboard") == 0) {
2165
ki = KdNewKeyboard();
2170
ErrorF("unrecognised device type!\n");
2175
else if (strcmp(key, "_source") == 0 &&
2176
strcmp(value, "server/hal") == 0) {
2177
ErrorF("Ignoring device from HAL.\n");
2182
else if (strcmp(key, "_source") == 0 &&
2183
strcmp(value, "server/udev") == 0) {
2184
ErrorF("Ignoring device from udev.\n");
2191
ErrorF("unrecognised device identifier!\n");
2195
/* FIXME: change this code below to use KdParseKbdOptions and
2196
* KdParsePointerOptions */
2197
nt_list_for_each_entry(option, options, list.next) {
2198
const char *key = input_option_get_key(option);
2199
const char *value = input_option_get_value(option);
2201
if (strcmp(key, "device") == 0) {
2203
pi->path = strdup(value);
2204
else if (ki && value)
2205
ki->path = strdup(value);
2207
else if (strcmp(key, "driver") == 0) {
2209
pi->driver = KdFindPointerDriver(value);
2211
ErrorF("couldn't find driver!\n");
2215
pi->options = options;
2218
ki->driver = KdFindKeyboardDriver(value);
2220
ErrorF("couldn't find driver!\n");
2224
ki->options = options;
2230
if (KdAddPointer(pi) != Success ||
2231
ActivateDevice(pi->dixdev, TRUE) != Success ||
2232
EnableDevice(pi->dixdev, TRUE) != TRUE) {
2233
ErrorF("couldn't add or enable pointer\n");
2234
return BadImplementation;
2238
if (KdAddKeyboard(ki) != Success ||
2239
ActivateDevice(ki->dixdev, TRUE) != Success ||
2240
EnableDevice(ki->dixdev, TRUE) != TRUE) {
2241
ErrorF("couldn't add or enable keyboard\n");
2242
return BadImplementation;
2257
DeleteInputDeviceRequest(DeviceIntPtr pDev)
2259
RemoveDevice(pDev, TRUE);