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
, pointer 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
, pointer timeout
, pointer 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(timeout
, myTimeout
);
1969 KdWakeupHandler(ScreenPtr pScreen
, unsigned long lresult
, pointer 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
);