Bug Summary

File:hw/kdrive/src/kinput.c
Location:line 2185, column 17
Description:Potential leak of memory pointed to by 'ki'

Annotated Source Code

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