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 */
45 #include <X11/extensions/XI.h>
46 #include <X11/extensions/XIproto.h>
47 #include "XIstubs.h" /* even though we don't use stubs. cute, no? */
50 #include "exglobals.h"
52 #define AtomFromName(x) MakeAtom(x, strlen(x), 1)
54 struct KdConfigDevice
{
56 struct KdConfigDevice
*next
;
59 /* kdKeyboards and kdPointers hold all the real devices. */
60 static KdKeyboardInfo
*kdKeyboards
= NULL
;
61 static KdPointerInfo
*kdPointers
= NULL
;
62 static struct KdConfigDevice
*kdConfigKeyboards
= NULL
;
63 static struct KdConfigDevice
*kdConfigPointers
= NULL
;
65 static KdKeyboardDriver
*kdKeyboardDrivers
= NULL
;
66 static KdPointerDriver
*kdPointerDrivers
= NULL
;
68 static xEvent
*kdEvents
= NULL
;
70 static Bool kdInputEnabled
;
71 static Bool kdOffScreen
;
72 static unsigned long kdOffScreenTime
;
73 static KdPointerMatrix kdPointerMatrix
= {
78 void KdResetInputMachine (void);
80 #define IsKeyDown(ki, key) ((ki->keyState[(key) >> 3] >> ((key) & 7)) & 1)
81 #define KEYMAP(ki) (ki->dixdev->key->curKeySyms)
82 #define KEYMAPDDX(ki) (ki->keySyms)
83 #define KEYCOL1(ki, k) (KEYMAP(ki).map[((k)-(KEYMAP(ki).minKeyCode))*KEYMAP(ki).mapWidth])
84 #define KEYCOL1DDX(ki, k) (KEYMAPDDX(ki).map[((k)-(KEYMAPDDX(ki).minKeyCode))*KEYMAPDDX(ki).mapWidth])
86 #define KD_MAX_INPUT_FDS 8
88 typedef struct _kdInputFd
{
90 void (*read
) (int fd
, void *closure
);
91 int (*enable
) (int fd
, void *closure
);
92 void (*disable
) (int fd
, void *closure
);
96 static KdInputFd kdInputFds
[KD_MAX_INPUT_FDS
];
97 static int kdNumInputFds
;
99 extern Bool kdRawPointerCoordinates
;
106 for (i
= 0; i
< kdNumInputFds
; i
++)
107 (*kdInputFds
[i
].read
) (kdInputFds
[i
].fd
, kdInputFds
[i
].closure
);
116 sigaddset (&set
, SIGIO
);
117 sigprocmask (SIG_BLOCK
, &set
, 0);
121 KdUnblockSigio (void)
126 sigaddset (&set
, SIGIO
);
127 sigprocmask (SIG_UNBLOCK
, &set
, 0);
133 KdAssertSigioBlocked (char *where
)
138 sigprocmask (SIG_BLOCK
, &set
, &old
);
139 if (!sigismember (&old
, SIGIO
)) {
140 ErrorF ("SIGIO not blocked at %s\n", where
);
147 #define KdAssertSigioBlocked(s)
154 #define NOBLOCK FNONBLOCK
156 #define NOBLOCK FNDELAY
160 KdResetInputMachine (void)
164 for (pi
= kdPointers
; pi
; pi
= pi
->next
) {
165 pi
->mouseState
= start
;
166 pi
->eventHeld
= FALSE
;
171 KdNonBlockFd (int fd
)
174 flags
= fcntl (fd
, F_GETFL
);
175 flags
|= FASYNC
|NOBLOCK
;
176 fcntl (fd
, F_SETFL
, flags
);
182 struct sigaction act
;
186 fcntl (fd
, F_SETOWN
, getpid());
188 AddEnabledDevice (fd
);
189 memset (&act
, '\0', sizeof act
);
190 act
.sa_handler
= KdSigio
;
191 sigemptyset (&act
.sa_mask
);
192 sigaddset (&act
.sa_mask
, SIGIO
);
193 sigaddset (&act
.sa_mask
, SIGALRM
);
194 sigaddset (&act
.sa_mask
, SIGVTALRM
);
195 sigaction (SIGIO
, &act
, 0);
197 sigprocmask (SIG_SETMASK
, &set
, 0);
203 struct sigaction act
;
207 RemoveEnabledDevice (fd
);
208 flags
= fcntl (fd
, F_GETFL
);
209 flags
&= ~(FASYNC
|NOBLOCK
);
210 fcntl (fd
, F_SETFL
, flags
);
213 memset (&act
, '\0', sizeof act
);
214 act
.sa_handler
= SIG_IGN
;
215 sigemptyset (&act
.sa_mask
);
216 sigaction (SIGIO
, &act
, 0);
221 KdRegisterFd (int fd
, void (*read
) (int fd
, void *closure
), void *closure
)
223 if (kdNumInputFds
== KD_MAX_INPUT_FDS
)
225 kdInputFds
[kdNumInputFds
].fd
= fd
;
226 kdInputFds
[kdNumInputFds
].read
= read
;
227 kdInputFds
[kdNumInputFds
].enable
= 0;
228 kdInputFds
[kdNumInputFds
].disable
= 0;
229 kdInputFds
[kdNumInputFds
].closure
= closure
;
237 KdUnregisterFd (void *closure
, int fd
, Bool do_close
)
241 for (i
= 0; i
< kdNumInputFds
; i
++) {
242 if (kdInputFds
[i
].closure
== closure
&&
243 (fd
== -1 || kdInputFds
[i
].fd
== fd
)) {
245 KdRemoveFd (kdInputFds
[i
].fd
);
247 close (kdInputFds
[i
].fd
);
249 for (j
= i
; j
< kdNumInputFds
; j
++)
250 kdInputFds
[j
] = kdInputFds
[j
+1];
257 KdUnregisterFds (void *closure
, Bool do_close
)
259 KdUnregisterFd(closure
, -1, do_close
);
263 KdDisableInput (void)
267 int found
= 0, i
= 0;
271 for (ki
= kdKeyboards
; ki
; ki
= ki
->next
) {
272 if (ki
->driver
&& ki
->driver
->Disable
)
273 (*ki
->driver
->Disable
) (ki
);
276 for (pi
= kdPointers
; pi
; pi
= pi
->next
) {
277 if (pi
->driver
&& pi
->driver
->Disable
)
278 (*pi
->driver
->Disable
) (pi
);
282 ErrorF("[KdDisableInput] Buggy drivers: still %d input fds left!",
285 while (i
< kdNumInputFds
) {
287 for (ki
= kdKeyboards
; ki
; ki
= ki
->next
) {
288 if (ki
== kdInputFds
[i
].closure
) {
289 ErrorF(" fd %d belongs to keybd driver %s\n",
291 ki
->driver
&& ki
->driver
->name
?
292 ki
->driver
->name
: "(unnamed!)");
303 for (pi
= kdPointers
; pi
; pi
= pi
->next
) {
304 if (pi
== kdInputFds
[i
].closure
) {
305 ErrorF(" fd %d belongs to pointer driver %s\n",
307 pi
->driver
&& pi
->driver
->name
?
308 pi
->driver
->name
: "(unnamed!)");
318 ErrorF(" fd %d not claimed by any active device!\n",
320 KdUnregisterFd(kdInputFds
[i
].closure
, kdInputFds
[i
].fd
, TRUE
);
324 kdInputEnabled
= FALSE
;
334 kdInputEnabled
= TRUE
;
336 for (ki
= kdKeyboards
; ki
; ki
= ki
->next
) {
337 if (ki
->driver
&& ki
->driver
->Enable
)
338 (*ki
->driver
->Enable
) (ki
);
341 for (pi
= kdPointers
; pi
; pi
= pi
->next
) {
342 if (pi
->driver
&& pi
->driver
->Enable
)
343 (*pi
->driver
->Enable
) (pi
);
346 /* reset screen saver */
347 xE
.u
.keyButtonPointer
.time
= GetTimeInMillis ();
348 NoticeEventTime (&xE
);
353 static KdKeyboardDriver
*
354 KdFindKeyboardDriver (char *name
)
356 KdKeyboardDriver
*ret
;
358 /* ask a stupid question ... */
362 for (ret
= kdKeyboardDrivers
; ret
; ret
= ret
->next
) {
363 if (strcmp(ret
->name
, name
) == 0)
370 static KdPointerDriver
*
371 KdFindPointerDriver (char *name
)
373 KdPointerDriver
*ret
;
375 /* ask a stupid question ... */
379 for (ret
= kdPointerDrivers
; ret
; ret
= ret
->next
) {
380 if (strcmp(ret
->name
, name
) == 0)
388 KdPointerProc(DeviceIntPtr pDevice
, int onoff
)
390 DevicePtr pDev
= (DevicePtr
)pDevice
;
395 return BadImplementation
;
397 for (pi
= kdPointers
; pi
; pi
= pi
->next
) {
398 if (pi
->dixdev
&& pi
->dixdev
->id
== pDevice
->id
)
402 if (!pi
|| !pi
->dixdev
|| pi
->dixdev
->id
!= pDevice
->id
) {
403 ErrorF("[KdPointerProc] Failed to find pointer for device %d!\n",
405 return BadImplementation
;
412 ErrorF("initialising pointer %s ...\n", pi
->name
);
415 if (!pi
->driverPrivate
) {
416 ErrorF("no driver specified for %s\n", pi
->name
);
417 return BadImplementation
;
420 pi
->driver
= KdFindPointerDriver(pi
->driverPrivate
);
422 ErrorF("Couldn't find pointer driver %s\n",
423 pi
->driverPrivate
? (char *) pi
->driverPrivate
:
427 xfree(pi
->driverPrivate
);
428 pi
->driverPrivate
= NULL
;
431 if (!pi
->driver
->Init
) {
432 ErrorF("no init function\n");
433 return BadImplementation
;
436 if ((*pi
->driver
->Init
) (pi
) != Success
) {
440 InitPointerDeviceStruct(pDev
, pi
->map
, pi
->nButtons
,
442 (PtrCtrlProcPtr
)NoopDDA
,
443 GetMotionHistorySize(), pi
->nAxes
);
445 if (pi
->inputClass
== KD_TOUCHSCREEN
) {
446 InitAbsoluteClassDeviceStruct(pDevice
);
447 xiclass
= AtomFromName(XI_TOUCHSCREEN
);
450 xiclass
= AtomFromName(XI_MOUSE
);
453 AssignTypeAndName(pi
->dixdev
, xiclass
,
454 pi
->name
? pi
->name
: "Generic KDrive Pointer");
459 if (pDev
->on
== TRUE
)
462 if (!pi
->driver
->Enable
) {
463 ErrorF("no enable function\n");
464 return BadImplementation
;
467 if ((*pi
->driver
->Enable
) (pi
) == Success
) {
472 return BadImplementation
;
478 if (pDev
->on
== FALSE
) {
482 if (!pi
->driver
->Disable
) {
483 return BadImplementation
;
486 (*pi
->driver
->Disable
) (pi
);
495 if (!pi
->driver
->Disable
) {
496 return BadImplementation
;
498 (*pi
->driver
->Disable
) (pi
);
502 if (!pi
->driver
->Fini
)
503 return BadImplementation
;
505 (*pi
->driver
->Fini
) (pi
);
513 return BadImplementation
;
517 LegalModifier(unsigned int key
, DeviceIntPtr pDev
)
523 KdBell (int volume
, DeviceIntPtr pDev
, pointer arg
, int something
)
525 KeybdCtrl
*ctrl
= arg
;
526 KdKeyboardInfo
*ki
= NULL
;
528 for (ki
= kdKeyboards
; ki
; ki
= ki
->next
) {
529 if (ki
->dixdev
&& ki
->dixdev
->id
== pDev
->id
)
533 if (!ki
|| !ki
->dixdev
|| ki
->dixdev
->id
!= pDev
->id
|| !ki
->driver
)
536 KdRingBell(ki
, volume
, ctrl
->bell_pitch
, ctrl
->bell_duration
);
540 DDXRingBell(int volume
, int pitch
, int duration
)
542 KdKeyboardInfo
*ki
= NULL
;
544 if (kdOsFuncs
->Bell
) {
545 (*kdOsFuncs
->Bell
)(volume
, pitch
, duration
);
548 for (ki
= kdKeyboards
; ki
; ki
= ki
->next
) {
549 if (ki
->dixdev
->coreEvents
)
550 KdRingBell(ki
, volume
, pitch
, duration
);
556 KdRingBell(KdKeyboardInfo
*ki
, int volume
, int pitch
, int duration
)
558 if (!ki
|| !ki
->driver
|| !ki
->driver
->Bell
)
562 (*ki
->driver
->Bell
) (ki
, volume
, pitch
, duration
);
567 KdSetLeds (KdKeyboardInfo
*ki
, int leds
)
569 if (!ki
|| !ki
->driver
)
572 if (kdInputEnabled
) {
573 if (ki
->driver
->Leds
)
574 (*ki
->driver
->Leds
) (ki
, leds
);
579 KdSetLed (KdKeyboardInfo
*ki
, int led
, Bool on
)
581 if (!ki
|| !ki
->dixdev
|| !ki
->dixdev
->kbdfeed
)
584 NoteLedState (ki
->dixdev
, led
, on
);
585 KdSetLeds (ki
, ki
->dixdev
->kbdfeed
->ctrl
.leds
);
589 KdSetPointerMatrix (KdPointerMatrix
*matrix
)
591 kdPointerMatrix
= *matrix
;
595 KdComputePointerMatrix (KdPointerMatrix
*m
, Rotation randr
, int width
,
598 int x_dir
= 1, y_dir
= 1;
602 size
[0] = width
; size
[1] = height
;
603 if (randr
& RR_Reflect_X
)
605 if (randr
& RR_Reflect_Y
)
607 switch (randr
& (RR_Rotate_All
)) {
609 m
->matrix
[0][0] = x_dir
; m
->matrix
[0][1] = 0;
610 m
->matrix
[1][0] = 0; m
->matrix
[1][1] = y_dir
;
613 m
->matrix
[0][0] = 0; m
->matrix
[0][1] = -x_dir
;
614 m
->matrix
[1][0] = y_dir
; m
->matrix
[1][1] = 0;
617 m
->matrix
[0][0] = -x_dir
; m
->matrix
[0][1] = 0;
618 m
->matrix
[1][0] = 0; m
->matrix
[1][1] = -y_dir
;
621 m
->matrix
[0][0] = 0; m
->matrix
[0][1] = x_dir
;
622 m
->matrix
[1][0] = -y_dir
; m
->matrix
[1][1] = 0;
625 for (i
= 0; i
< 2; i
++)
628 for (j
= 0 ; j
< 2; j
++)
629 if (m
->matrix
[i
][j
] < 0)
630 m
->matrix
[i
][2] = size
[j
] - 1;
635 KdKbdCtrl (DeviceIntPtr pDevice
, KeybdCtrl
*ctrl
)
639 for (ki
= kdKeyboards
; ki
; ki
= ki
->next
) {
640 if (ki
->dixdev
&& ki
->dixdev
->id
== pDevice
->id
)
644 if (!ki
|| !ki
->dixdev
|| ki
->dixdev
->id
!= pDevice
->id
|| !ki
->driver
)
647 KdSetLeds(ki
, ctrl
->leds
);
648 ki
->bellPitch
= ctrl
->bell_pitch
;
649 ki
->bellDuration
= ctrl
->bell_duration
;
652 extern KeybdCtrl defaultKeyboardControl
;
655 KdInitAutoRepeats (KdKeyboardInfo
*ki
)
660 unsigned char *repeats
;
662 repeats
= defaultKeyboardControl
.autoRepeats
;
663 memset (repeats
, '\0', 32);
664 for (key_code
= KD_MIN_KEYCODE
; key_code
<= KD_MAX_KEYCODE
; key_code
++)
666 if (!ki
->modmap
[key_code
])
669 mask
= 1 << (key_code
& 7);
675 const KdKeySymModsRec kdKeySymMods
[] = {
676 { XK_Control_L
, ControlMask
},
677 { XK_Control_R
, ControlMask
},
678 { XK_Shift_L
, ShiftMask
},
679 { XK_Shift_R
, ShiftMask
},
680 { XK_Caps_Lock
, LockMask
},
681 { XK_Shift_Lock
, LockMask
},
682 { XK_Alt_L
, Mod1Mask
},
683 { XK_Alt_R
, Mod1Mask
},
684 { XK_Meta_L
, Mod1Mask
},
685 { XK_Meta_R
, Mod1Mask
},
686 { XK_Num_Lock
, Mod2Mask
},
687 { XK_Super_L
, Mod3Mask
},
688 { XK_Super_R
, Mod3Mask
},
689 { XK_Hyper_L
, Mod3Mask
},
690 { XK_Hyper_R
, Mod3Mask
},
691 { XK_Mode_switch
, Mod4Mask
},
692 /* PDA specific hacks */
694 { XF86XK_Start
, ControlMask
},
696 { XK_Menu
, ShiftMask
},
697 { XK_telephone
, Mod1Mask
},
698 #ifdef XF86XK_AudioRecord
699 { XF86XK_AudioRecord
, Mod2Mask
},
701 #ifdef XF86XK_Calendar
702 { XF86XK_Calendar
, Mod3Mask
}
706 #define NUM_SYM_MODS (sizeof(kdKeySymMods) / sizeof(kdKeySymMods[0]))
709 KdInitModMap (KdKeyboardInfo
*ki
)
717 width
= ki
->keySyms
.mapWidth
;
718 for (key_code
= ki
->keySyms
.minKeyCode
; key_code
<= ki
->keySyms
.maxKeyCode
; key_code
++)
720 ki
->modmap
[key_code
] = 0;
721 syms
= ki
->keySyms
.map
+ (key_code
- ki
->keySyms
.minKeyCode
) * width
;
722 for (row
= 0; row
< width
; row
++, syms
++)
724 for (i
= 0; i
< NUM_SYM_MODS
; i
++)
726 if (*syms
== kdKeySymMods
[i
].modsym
)
727 ki
->modmap
[key_code
] |= kdKeySymMods
[i
].modbit
;
734 KdKeyboardProc(DeviceIntPtr pDevice
, int onoff
)
737 DevicePtr pDev
= (DevicePtr
)pDevice
;
741 XkbComponentNamesRec names
;
745 return BadImplementation
;
747 for (ki
= kdKeyboards
; ki
; ki
= ki
->next
) {
748 if (ki
->dixdev
&& ki
->dixdev
->id
== pDevice
->id
)
752 if (!ki
|| !ki
->dixdev
|| ki
->dixdev
->id
!= pDevice
->id
) {
753 return BadImplementation
;
760 ErrorF("initialising keyboard %s\n", ki
->name
);
763 if (!ki
->driverPrivate
) {
764 ErrorF("no driver specified!\n");
765 return BadImplementation
;
768 ki
->driver
= KdFindKeyboardDriver(ki
->driverPrivate
);
770 ErrorF("Couldn't find keyboard driver %s\n",
771 ki
->driverPrivate
? (char *) ki
->driverPrivate
:
775 xfree(ki
->driverPrivate
);
776 ki
->driverPrivate
= NULL
;
779 if (!ki
->driver
->Init
) {
780 ErrorF("Keyboard %s: no init function\n", ki
->name
);
781 return BadImplementation
;
784 if ((*ki
->driver
->Init
) (ki
) != Success
) {
789 KdInitAutoRepeats(ki
);
792 if (!noXkbExtension
) {
793 memset(&names
, 0, sizeof(XkbComponentNamesRec
));
795 XkbSetRulesDflts (ki
->xkbRules
, ki
->xkbModel
, ki
->xkbLayout
,
796 ki
->xkbVariant
, ki
->xkbOptions
);
798 ret
= XkbInitKeyboardDeviceStruct (pDevice
,
806 ret
= InitKeyboardDeviceStruct(pDev
,
811 ErrorF("Couldn't initialise keyboard %s\n", ki
->name
);
812 return BadImplementation
;
815 xiclass
= AtomFromName(XI_KEYBOARD
);
816 AssignTypeAndName(pDevice
, xiclass
,
817 ki
->name
? ki
->name
: "Generic KDrive Keyboard");
819 KdResetInputMachine();
824 if (pDev
->on
== TRUE
)
827 if (!ki
->driver
->Enable
)
828 return BadImplementation
;
830 if ((*ki
->driver
->Enable
) (ki
) != Success
) {
838 if (pDev
->on
== FALSE
)
841 if (!ki
->driver
->Disable
)
842 return BadImplementation
;
844 (*ki
->driver
->Disable
) (ki
);
853 if (!ki
->driver
->Disable
)
854 return BadImplementation
;
856 (*ki
->driver
->Disable
) (ki
);
860 if (!ki
->driver
->Fini
)
861 return BadImplementation
;
863 (*ki
->driver
->Fini
) (ki
);
865 KdRemoveKeyboard(ki
);
871 return BadImplementation
;
875 KdAddPointerDriver (KdPointerDriver
*driver
)
877 KdPointerDriver
**prev
;
882 for (prev
= &kdPointerDrivers
; *prev
; prev
= &(*prev
)->next
) {
890 KdRemovePointerDriver (KdPointerDriver
*driver
)
892 KdPointerDriver
*tmp
;
897 /* FIXME remove all pointers using this driver */
898 for (tmp
= kdPointerDrivers
; tmp
; tmp
= tmp
->next
) {
899 if (tmp
->next
== driver
)
900 tmp
->next
= driver
->next
;
907 KdAddKeyboardDriver (KdKeyboardDriver
*driver
)
909 KdKeyboardDriver
**prev
;
914 for (prev
= &kdKeyboardDrivers
; *prev
; prev
= &(*prev
)->next
) {
922 KdRemoveKeyboardDriver (KdKeyboardDriver
*driver
)
924 KdKeyboardDriver
*tmp
;
929 /* FIXME remove all keyboards using this driver */
930 for (tmp
= kdKeyboardDrivers
; tmp
; tmp
= tmp
->next
) {
931 if (tmp
->next
== driver
)
932 tmp
->next
= driver
->next
;
941 KdKeyboardInfo
*ki
= xcalloc(sizeof(KdKeyboardInfo
), 1);
946 ki
->keySyms
.map
= (KeySym
*)xcalloc(sizeof(KeySym
),
948 kdDefaultKeySyms
.mapWidth
);
949 if (!ki
->keySyms
.map
) {
954 memcpy(ki
->keySyms
.map
, kdDefaultKeySyms
.map
,
955 sizeof(KeySym
) * (KD_MAX_LENGTH
* kdDefaultKeySyms
.mapWidth
));
956 ki
->keySyms
.minKeyCode
= kdDefaultKeySyms
.minKeyCode
;
957 ki
->keySyms
.maxKeyCode
= kdDefaultKeySyms
.maxKeyCode
;
958 ki
->keySyms
.mapWidth
= kdDefaultKeySyms
.mapWidth
;
962 ki
->bellPitch
= 1000;
963 ki
->bellDuration
= 200;
967 ki
->xkbRules
= KdSaveString("base");
968 ki
->xkbModel
= KdSaveString("pc105");
969 ki
->xkbLayout
= KdSaveString("us");
970 ki
->xkbVariant
= NULL
;
971 ki
->xkbOptions
= NULL
;
978 KdAddConfigKeyboard (char *keyboard
)
980 struct KdConfigDevice
**prev
, *new;
985 new = (struct KdConfigDevice
*) xcalloc(sizeof(struct KdConfigDevice
), 1);
989 new->line
= xstrdup(keyboard
);
992 for (prev
= &kdConfigKeyboards
; *prev
; prev
= &(*prev
)->next
);
999 KdAddKeyboard (KdKeyboardInfo
*ki
)
1001 KdKeyboardInfo
**prev
;
1006 ki
->dixdev
= AddInputDevice(KdKeyboardProc
, TRUE
);
1008 ErrorF("Couldn't register keyboard device %s\n",
1009 ki
->name
? ki
->name
: "(unnamed)");
1013 RegisterOtherDevice(ki
->dixdev
);
1016 ErrorF("added keyboard %s with dix id %d\n", ki
->name
, ki
->dixdev
->id
);
1019 for (prev
= &kdKeyboards
; *prev
; prev
= &(*prev
)->next
);
1026 KdRemoveKeyboard (KdKeyboardInfo
*ki
)
1028 KdKeyboardInfo
**prev
;
1033 for (prev
= &kdKeyboards
; *prev
; prev
= &(*prev
)->next
) {
1044 KdAddConfigPointer (char *pointer
)
1046 struct KdConfigDevice
**prev
, *new;
1051 new = (struct KdConfigDevice
*) xcalloc(sizeof(struct KdConfigDevice
), 1);
1055 new->line
= xstrdup(pointer
);
1058 for (prev
= &kdConfigPointers
; *prev
; prev
= &(*prev
)->next
);
1065 KdAddPointer (KdPointerInfo
*pi
)
1067 KdPointerInfo
**prev
;
1072 pi
->mouseState
= start
;
1073 pi
->eventHeld
= FALSE
;
1075 pi
->dixdev
= AddInputDevice(KdPointerProc
, TRUE
);
1077 ErrorF("Couldn't add pointer device %s\n",
1078 pi
->name
? pi
->name
: "(unnamed)");
1082 RegisterOtherDevice(pi
->dixdev
);
1084 for (prev
= &kdPointers
; *prev
; prev
= &(*prev
)->next
);
1091 KdRemovePointer (KdPointerInfo
*pi
)
1093 KdPointerInfo
**prev
;
1098 for (prev
= &kdPointers
; *prev
; prev
= &(*prev
)->next
) {
1109 * You can call your kdriver server with something like:
1110 * $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd
1111 * evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br
1114 KdGetOptions (InputOption
**options
, char *string
)
1116 InputOption
*newopt
= NULL
, **tmpo
= NULL
;
1119 newopt
= (InputOption
*) xalloc(sizeof (InputOption
));
1123 bzero(newopt
, sizeof (InputOption
));
1125 for (tmpo
= options
; *tmpo
; tmpo
= &(*tmpo
)->next
)
1126 ; /* Hello, I'm here */
1129 if (strchr(string
, '='))
1131 tam_key
= (strchr(string
, '=') - string
);
1132 newopt
->key
= (char *)xalloc(tam_key
);
1133 strncpy(newopt
->key
, string
, tam_key
);
1134 newopt
->key
[tam_key
] = '\0';
1135 newopt
->value
= xstrdup(strchr(string
, '=') + 1);
1139 newopt
->key
= xstrdup(string
);
1140 newopt
->value
= NULL
;
1142 newopt
->next
= NULL
;
1148 KdParseKbdOptions (KdKeyboardInfo
*ki
)
1150 InputOption
*option
= NULL
;
1152 for (option
= ki
->options
; option
; option
= option
->next
)
1155 if (strcasecmp(option
->key
, "XkbRules") == 0)
1156 ki
->xkbRules
= option
->value
;
1157 else if (strcasecmp(option
->key
, "XkbModel") == 0)
1158 ki
->xkbModel
= option
->value
;
1159 else if (strcasecmp(option
->key
, "XkbLayout") == 0)
1160 ki
->xkbLayout
= option
->value
;
1161 else if (strcasecmp(option
->key
, "XkbVariant") == 0)
1162 ki
->xkbVariant
= option
->value
;
1163 else if (strcasecmp(option
->key
, "XkbOptions") == 0)
1164 ki
->xkbOptions
= option
->value
;
1165 else if (!strcasecmp (option
->key
, "device"))
1166 ki
->path
= KdSaveString(option
->value
);
1169 ErrorF("Kbd option key (%s) of value (%s) not assigned!\n",
1170 option
->key
, option
->value
);
1175 KdParseKeyboard (char *arg
)
1179 InputOption
*options
= NULL
;
1180 KdKeyboardInfo
*ki
= NULL
;
1182 ki
= KdNewKeyboard();
1186 ki
->name
= strdup("Unknown KDrive Keyboard");
1189 ki
->driverPrivate
= NULL
;
1197 ErrorF("keybd: no arg\n");
1198 KdFreeKeyboard (ki
);
1202 if (strlen (arg
) >= sizeof (save
))
1204 ErrorF("keybd: arg too long\n");
1205 KdFreeKeyboard (ki
);
1209 arg
= KdParseFindNext (arg
, ",", save
, &delim
);
1212 ErrorF("keybd: failed on save[0]\n");
1213 KdFreeKeyboard (ki
);
1217 if (strcmp (save
, "auto") == 0)
1218 ki
->driverPrivate
= NULL
;
1220 ki
->driverPrivate
= xstrdup(save
);
1227 arg
= KdParseFindNext (arg
, ",", save
, &delim
);
1229 while (delim
== ',')
1231 arg
= KdParseFindNext (arg
, ",", save
, &delim
);
1233 if (!KdGetOptions(&options
, save
))
1242 ki
->options
= options
;
1243 KdParseKbdOptions(ki
);
1250 KdParsePointerOptions (KdPointerInfo
*pi
)
1252 InputOption
*option
= NULL
;
1254 for (option
= pi
->options
; option
; option
= option
->next
)
1256 if (!strcmp (option
->key
, "emulatemiddle"))
1257 pi
->emulateMiddleButton
= TRUE
;
1258 else if (!strcmp (option
->key
, "noemulatemiddle"))
1259 pi
->emulateMiddleButton
= FALSE
;
1260 else if (!strcmp (option
->key
, "transformcoord"))
1261 pi
->transformCoordinates
= TRUE
;
1262 else if (!strcmp (option
->key
, "rawcoord"))
1263 pi
->transformCoordinates
= FALSE
;
1264 else if (!strcasecmp (option
->key
, "device"))
1265 pi
->path
= KdSaveString(option
->value
);
1267 ErrorF("Pointer option key (%s) of value (%s) not assigned!\n",
1268 option
->key
, option
->value
);
1273 KdParsePointer (char *arg
)
1277 KdPointerInfo
*pi
= NULL
;
1278 InputOption
*options
= NULL
;
1281 pi
= KdNewPointer();
1284 pi
->emulateMiddleButton
= kdEmulateMiddleButton
;
1285 pi
->transformCoordinates
= !kdRawPointerCoordinates
;
1287 pi
->inputClass
= KD_MOUSE
;
1291 ErrorF("mouse: no arg\n");
1296 if (strlen (arg
) >= sizeof (save
))
1298 ErrorF("mouse: arg too long\n");
1302 arg
= KdParseFindNext (arg
, ",", save
, &delim
);
1305 ErrorF("failed on save[0]\n");
1310 if (strcmp(save
, "auto") == 0)
1311 pi
->driverPrivate
= NULL
;
1313 pi
->driverPrivate
= xstrdup(save
);
1320 arg
= KdParseFindNext (arg
, ",", save
, &delim
);
1322 while (delim
== ',')
1324 arg
= KdParseFindNext (arg
, ",", save
, &delim
);
1329 while (*s
&& *s
!= '}')
1331 if ('1' <= *s
&& *s
<= '0' + pi
->nButtons
)
1332 pi
->map
[i
] = *s
- '0';
1340 if (!KdGetOptions(&options
, save
))
1350 pi
->options
= options
;
1351 KdParsePointerOptions(pi
);
1363 struct KdConfigDevice
*dev
;
1365 kdInputEnabled
= TRUE
;
1367 for (dev
= kdConfigPointers
; dev
; dev
= dev
->next
) {
1368 pi
= KdParsePointer(dev
->line
);
1370 ErrorF("Failed to parse pointer\n");
1371 if (KdAddPointer(pi
) != Success
)
1372 ErrorF("Failed to add pointer!\n");
1374 for (dev
= kdConfigKeyboards
; dev
; dev
= dev
->next
) {
1375 ki
= KdParseKeyboard(dev
->line
);
1377 ErrorF("Failed to parse keyboard\n");
1378 if (KdAddKeyboard(ki
) != Success
)
1379 ErrorF("Failed to add keyboard!\n");
1383 kdEvents
= (xEvent
*)xcalloc(sizeof(xEvent
), GetMaximumEventsNum());
1385 FatalError("Couldn't allocate event buffer\n");
1391 * Middle button emulation state machine
1393 * Possible transitions:
1395 * Button 1 release ^1
1397 * Button 2 release ^2
1399 * Button 3 release ^3
1400 * Button other press vo
1401 * Button other release ^o
1414 * synthetic_2_down_13
1415 * synthetic_2_down_3
1416 * synthetic_2_down_1
1418 * Transition diagram
1421 * v1 -> (hold) (settimeout) button_1_pend
1422 * ^1 -> (deliver) start
1423 * v2 -> (deliver) button_2_down
1424 * ^2 -> (deliever) start
1425 * v3 -> (hold) (settimeout) button_3_pend
1426 * ^3 -> (deliver) start
1427 * vo -> (deliver) start
1428 * ^o -> (deliver) start
1429 * <> -> (deliver) start
1430 * k -> (deliver) start
1432 * button_1_pend (button 1 is down, timeout pending)
1433 * ^1 -> (release) (deliver) start
1434 * v2 -> (release) (deliver) button_1_down
1435 * ^2 -> (release) (deliver) button_1_down
1436 * v3 -> (cleartimeout) (generate v2) synthetic_2_down_13
1437 * ^3 -> (release) (deliver) button_1_down
1438 * vo -> (release) (deliver) button_1_down
1439 * ^o -> (release) (deliver) button_1_down
1440 * <-> -> (release) (deliver) button_1_down
1441 * <> -> (deliver) button_1_pend
1442 * k -> (release) (deliver) button_1_down
1443 * ... -> (release) button_1_down
1445 * button_1_down (button 1 is down)
1446 * ^1 -> (deliver) start
1447 * v2 -> (deliver) button_1_down
1448 * ^2 -> (deliver) button_1_down
1449 * v3 -> (deliver) button_1_down
1450 * ^3 -> (deliver) button_1_down
1451 * vo -> (deliver) button_1_down
1452 * ^o -> (deliver) button_1_down
1453 * <> -> (deliver) button_1_down
1454 * k -> (deliver) button_1_down
1456 * button_2_down (button 2 is down)
1457 * v1 -> (deliver) button_2_down
1458 * ^1 -> (deliver) button_2_down
1459 * ^2 -> (deliver) start
1460 * v3 -> (deliver) button_2_down
1461 * ^3 -> (deliver) button_2_down
1462 * vo -> (deliver) button_2_down
1463 * ^o -> (deliver) button_2_down
1464 * <> -> (deliver) button_2_down
1465 * k -> (deliver) button_2_down
1467 * button_3_pend (button 3 is down, timeout pending)
1468 * v1 -> (generate v2) synthetic_2_down
1469 * ^1 -> (release) (deliver) button_3_down
1470 * v2 -> (release) (deliver) button_3_down
1471 * ^2 -> (release) (deliver) button_3_down
1472 * ^3 -> (release) (deliver) start
1473 * vo -> (release) (deliver) button_3_down
1474 * ^o -> (release) (deliver) button_3_down
1475 * <-> -> (release) (deliver) button_3_down
1476 * <> -> (deliver) button_3_pend
1477 * k -> (release) (deliver) button_3_down
1478 * ... -> (release) button_3_down
1480 * button_3_down (button 3 is down)
1481 * v1 -> (deliver) button_3_down
1482 * ^1 -> (deliver) button_3_down
1483 * v2 -> (deliver) button_3_down
1484 * ^2 -> (deliver) button_3_down
1485 * ^3 -> (deliver) start
1486 * vo -> (deliver) button_3_down
1487 * ^o -> (deliver) button_3_down
1488 * <> -> (deliver) button_3_down
1489 * k -> (deliver) button_3_down
1491 * synthetic_2_down_13 (button 1 and 3 are down)
1492 * ^1 -> (generate ^2) synthetic_2_down_3
1493 * v2 -> synthetic_2_down_13
1494 * ^2 -> synthetic_2_down_13
1495 * ^3 -> (generate ^2) synthetic_2_down_1
1496 * vo -> (deliver) synthetic_2_down_13
1497 * ^o -> (deliver) synthetic_2_down_13
1498 * <> -> (deliver) synthetic_2_down_13
1499 * k -> (deliver) synthetic_2_down_13
1501 * synthetic_2_down_3 (button 3 is down)
1502 * v1 -> (deliver) synthetic_2_down_3
1503 * ^1 -> (deliver) synthetic_2_down_3
1504 * v2 -> synthetic_2_down_3
1505 * ^2 -> synthetic_2_down_3
1507 * vo -> (deliver) synthetic_2_down_3
1508 * ^o -> (deliver) synthetic_2_down_3
1509 * <> -> (deliver) synthetic_2_down_3
1510 * k -> (deliver) synthetic_2_down_3
1512 * synthetic_2_down_1 (button 1 is down)
1514 * v2 -> synthetic_2_down_1
1515 * ^2 -> synthetic_2_down_1
1516 * v3 -> (deliver) synthetic_2_down_1
1517 * ^3 -> (deliver) synthetic_2_down_1
1518 * vo -> (deliver) synthetic_2_down_1
1519 * ^o -> (deliver) synthetic_2_down_1
1520 * <> -> (deliver) synthetic_2_down_1
1521 * k -> (deliver) synthetic_2_down_1
1524 typedef enum _inputClass
{
1529 motion
, outside_box
,
1534 typedef enum _inputAction
{
1545 #define MAX_ACTIONS 2
1547 typedef struct _inputTransition
{
1548 KdInputAction actions
[MAX_ACTIONS
];
1549 KdPointerState nextState
;
1550 } KdInputTransition
;
1553 KdInputTransition kdInputMachine
[num_input_states
][num_input_class
] = {
1556 { { hold
, setto
}, button_1_pend
}, /* v1 */
1557 { { deliver
, noop
}, start
}, /* ^1 */
1558 { { deliver
, noop
}, button_2_down
}, /* v2 */
1559 { { deliver
, noop
}, start
}, /* ^2 */
1560 { { hold
, setto
}, button_3_pend
}, /* v3 */
1561 { { deliver
, noop
}, start
}, /* ^3 */
1562 { { deliver
, noop
}, start
}, /* vo */
1563 { { deliver
, noop
}, start
}, /* ^o */
1564 { { deliver
, noop
}, start
}, /* <> */
1565 { { deliver
, noop
}, start
}, /* <-> */
1566 { { noop
, noop
}, start
}, /* k */
1567 { { noop
, noop
}, start
}, /* ... */
1571 { { noop
, noop
}, button_1_pend
}, /* v1 */
1572 { { release
, deliver
}, start
}, /* ^1 */
1573 { { release
, deliver
}, button_1_down
}, /* v2 */
1574 { { release
, deliver
}, button_1_down
}, /* ^2 */
1575 { { clearto
, gen_down_2
}, synth_2_down_13
}, /* v3 */
1576 { { release
, deliver
}, button_1_down
}, /* ^3 */
1577 { { release
, deliver
}, button_1_down
}, /* vo */
1578 { { release
, deliver
}, button_1_down
}, /* ^o */
1579 { { deliver
, noop
}, button_1_pend
}, /* <> */
1580 { { release
, deliver
}, button_1_down
}, /* <-> */
1581 { { noop
, noop
}, button_1_down
}, /* k */
1582 { { release
, noop
}, button_1_down
}, /* ... */
1586 { { noop
, noop
}, button_1_down
}, /* v1 */
1587 { { deliver
, noop
}, start
}, /* ^1 */
1588 { { deliver
, noop
}, button_1_down
}, /* v2 */
1589 { { deliver
, noop
}, button_1_down
}, /* ^2 */
1590 { { deliver
, noop
}, button_1_down
}, /* v3 */
1591 { { deliver
, noop
}, button_1_down
}, /* ^3 */
1592 { { deliver
, noop
}, button_1_down
}, /* vo */
1593 { { deliver
, noop
}, button_1_down
}, /* ^o */
1594 { { deliver
, noop
}, button_1_down
}, /* <> */
1595 { { deliver
, noop
}, button_1_down
}, /* <-> */
1596 { { noop
, noop
}, button_1_down
}, /* k */
1597 { { noop
, noop
}, button_1_down
}, /* ... */
1601 { { deliver
, noop
}, button_2_down
}, /* v1 */
1602 { { deliver
, noop
}, button_2_down
}, /* ^1 */
1603 { { noop
, noop
}, button_2_down
}, /* v2 */
1604 { { deliver
, noop
}, start
}, /* ^2 */
1605 { { deliver
, noop
}, button_2_down
}, /* v3 */
1606 { { deliver
, noop
}, button_2_down
}, /* ^3 */
1607 { { deliver
, noop
}, button_2_down
}, /* vo */
1608 { { deliver
, noop
}, button_2_down
}, /* ^o */
1609 { { deliver
, noop
}, button_2_down
}, /* <> */
1610 { { deliver
, noop
}, button_2_down
}, /* <-> */
1611 { { noop
, noop
}, button_2_down
}, /* k */
1612 { { noop
, noop
}, button_2_down
}, /* ... */
1616 { { clearto
, gen_down_2
}, synth_2_down_13
}, /* v1 */
1617 { { release
, deliver
}, button_3_down
}, /* ^1 */
1618 { { release
, deliver
}, button_3_down
}, /* v2 */
1619 { { release
, deliver
}, button_3_down
}, /* ^2 */
1620 { { release
, deliver
}, button_3_down
}, /* v3 */
1621 { { release
, deliver
}, start
}, /* ^3 */
1622 { { release
, deliver
}, button_3_down
}, /* vo */
1623 { { release
, deliver
}, button_3_down
}, /* ^o */
1624 { { deliver
, noop
}, button_3_pend
}, /* <> */
1625 { { release
, deliver
}, button_3_down
}, /* <-> */
1626 { { release
, noop
}, button_3_down
}, /* k */
1627 { { release
, noop
}, button_3_down
}, /* ... */
1631 { { deliver
, noop
}, button_3_down
}, /* v1 */
1632 { { deliver
, noop
}, button_3_down
}, /* ^1 */
1633 { { deliver
, noop
}, button_3_down
}, /* v2 */
1634 { { deliver
, noop
}, button_3_down
}, /* ^2 */
1635 { { noop
, noop
}, button_3_down
}, /* v3 */
1636 { { deliver
, noop
}, start
}, /* ^3 */
1637 { { deliver
, noop
}, button_3_down
}, /* vo */
1638 { { deliver
, noop
}, button_3_down
}, /* ^o */
1639 { { deliver
, noop
}, button_3_down
}, /* <> */
1640 { { deliver
, noop
}, button_3_down
}, /* <-> */
1641 { { noop
, noop
}, button_3_down
}, /* k */
1642 { { noop
, noop
}, button_3_down
}, /* ... */
1644 /* synthetic_2_down_13 */
1646 { { noop
, noop
}, synth_2_down_13
}, /* v1 */
1647 { { gen_up_2
, noop
}, synth_2_down_3
}, /* ^1 */
1648 { { noop
, noop
}, synth_2_down_13
}, /* v2 */
1649 { { noop
, noop
}, synth_2_down_13
}, /* ^2 */
1650 { { noop
, noop
}, synth_2_down_13
}, /* v3 */
1651 { { gen_up_2
, noop
}, synth_2_down_1
}, /* ^3 */
1652 { { deliver
, noop
}, synth_2_down_13
}, /* vo */
1653 { { deliver
, noop
}, synth_2_down_13
}, /* ^o */
1654 { { deliver
, noop
}, synth_2_down_13
}, /* <> */
1655 { { deliver
, noop
}, synth_2_down_13
}, /* <-> */
1656 { { noop
, noop
}, synth_2_down_13
}, /* k */
1657 { { noop
, noop
}, synth_2_down_13
}, /* ... */
1659 /* synthetic_2_down_3 */
1661 { { deliver
, noop
}, synth_2_down_3
}, /* v1 */
1662 { { deliver
, noop
}, synth_2_down_3
}, /* ^1 */
1663 { { deliver
, noop
}, synth_2_down_3
}, /* v2 */
1664 { { deliver
, noop
}, synth_2_down_3
}, /* ^2 */
1665 { { noop
, noop
}, synth_2_down_3
}, /* v3 */
1666 { { noop
, noop
}, start
}, /* ^3 */
1667 { { deliver
, noop
}, synth_2_down_3
}, /* vo */
1668 { { deliver
, noop
}, synth_2_down_3
}, /* ^o */
1669 { { deliver
, noop
}, synth_2_down_3
}, /* <> */
1670 { { deliver
, noop
}, synth_2_down_3
}, /* <-> */
1671 { { noop
, noop
}, synth_2_down_3
}, /* k */
1672 { { noop
, noop
}, synth_2_down_3
}, /* ... */
1674 /* synthetic_2_down_1 */
1676 { { noop
, noop
}, synth_2_down_1
}, /* v1 */
1677 { { noop
, noop
}, start
}, /* ^1 */
1678 { { deliver
, noop
}, synth_2_down_1
}, /* v2 */
1679 { { deliver
, noop
}, synth_2_down_1
}, /* ^2 */
1680 { { deliver
, noop
}, synth_2_down_1
}, /* v3 */
1681 { { deliver
, noop
}, synth_2_down_1
}, /* ^3 */
1682 { { deliver
, noop
}, synth_2_down_1
}, /* vo */
1683 { { deliver
, noop
}, synth_2_down_1
}, /* ^o */
1684 { { deliver
, noop
}, synth_2_down_1
}, /* <> */
1685 { { deliver
, noop
}, synth_2_down_1
}, /* <-> */
1686 { { noop
, noop
}, synth_2_down_1
}, /* k */
1687 { { noop
, noop
}, synth_2_down_1
}, /* ... */
1691 #define EMULATION_WINDOW 10
1692 #define EMULATION_TIMEOUT 100
1695 KdInsideEmulationWindow (KdPointerInfo
*pi
, int x
, int y
, int z
)
1697 pi
->emulationDx
= pi
->heldEvent
.x
- x
;
1698 pi
->emulationDy
= pi
->heldEvent
.y
- y
;
1700 return (abs (pi
->emulationDx
) < EMULATION_WINDOW
&&
1701 abs (pi
->emulationDy
) < EMULATION_WINDOW
);
1705 KdClassifyInput (KdPointerInfo
*pi
, int type
, int x
, int y
, int z
, int b
)
1710 case 1: return down_1
;
1711 case 2: return down_2
;
1712 case 3: return down_3
;
1713 default: return down_o
;
1718 case 1: return up_1
;
1719 case 2: return up_2
;
1720 case 3: return up_3
;
1721 default: return up_o
;
1725 if (pi
->eventHeld
&& !KdInsideEmulationWindow(pi
, x
, y
, z
))
1736 char *kdStateNames
[] = {
1745 "synthetic_2_down_1",
1749 char *kdClassNames
[] = {
1753 "motion", "ouside_box",
1754 "keyboard", "timeout",
1758 char *kdActionNames
[] = {
1771 KdQueueEvent (DeviceIntPtr pDev
, xEvent
*ev
)
1773 KdAssertSigioBlocked ("KdQueueEvent");
1774 mieqEnqueue (pDev
, ev
);
1777 /* We return true if we're stealing the event. */
1779 KdRunMouseMachine (KdPointerInfo
*pi
, KdInputClass c
, int type
, int x
, int y
,
1780 int z
, int b
, int absrel
)
1782 const KdInputTransition
*t
;
1785 c
= KdClassifyInput(pi
, type
, x
, y
, z
, b
);
1786 t
= &kdInputMachine
[pi
->mouseState
][c
];
1787 for (a
= 0; a
< MAX_ACTIONS
; a
++)
1789 switch (t
->actions
[a
]) {
1793 pi
->eventHeld
= TRUE
;
1794 pi
->emulationDx
= 0;
1795 pi
->emulationDy
= 0;
1796 pi
->heldEvent
.type
= type
;
1797 pi
->heldEvent
.x
= x
;
1798 pi
->heldEvent
.y
= y
;
1799 pi
->heldEvent
.z
= z
;
1800 pi
->heldEvent
.flags
= b
;
1801 pi
->heldEvent
.absrel
= absrel
;
1805 pi
->emulationTimeout
= GetTimeInMillis () + EMULATION_TIMEOUT
;
1806 pi
->timeoutPending
= TRUE
;
1809 _KdEnqueuePointerEvent (pi
, pi
->heldEvent
.type
, pi
->heldEvent
.x
,
1810 pi
->heldEvent
.y
, pi
->heldEvent
.z
,
1811 pi
->heldEvent
.flags
, pi
->heldEvent
.absrel
,
1815 pi
->eventHeld
= FALSE
;
1816 pi
->timeoutPending
= FALSE
;
1817 _KdEnqueuePointerEvent (pi
, pi
->heldEvent
.type
, pi
->heldEvent
.x
,
1818 pi
->heldEvent
.y
, pi
->heldEvent
.z
,
1819 pi
->heldEvent
.flags
, pi
->heldEvent
.absrel
,
1824 pi
->timeoutPending
= FALSE
;
1827 _KdEnqueuePointerEvent (pi
, ButtonPress
, x
, y
, z
, 2, absrel
,
1829 pi
->eventHeld
= FALSE
;
1833 _KdEnqueuePointerEvent (pi
, ButtonRelease
, x
, y
, z
, 2, absrel
,
1839 pi
->mouseState
= t
->nextState
;
1844 KdHandlePointerEvent (KdPointerInfo
*pi
, int type
, int x
, int y
, int z
, int b
,
1847 if (pi
->emulateMiddleButton
)
1848 return KdRunMouseMachine (pi
, KdClassifyInput(pi
, type
, x
, y
, z
, b
),
1849 type
, x
, y
, z
, b
, absrel
);
1854 KdReceiveTimeout (KdPointerInfo
*pi
)
1856 KdRunMouseMachine (pi
, timeout
, 0, 0, 0, 0, 0, 0);
1859 #define KILL_SEQUENCE ((1L << KK_CONTROL)|(1L << KK_ALT)|(1L << KK_F8)|(1L << KK_F10))
1860 #define SPECIAL_SEQUENCE ((1L << KK_CONTROL) | (1L << KK_ALT))
1861 #define SETKILLKEY(b) (KdSpecialKeys |= (1L << (b)))
1862 #define CLEARKILLKEY(b) (KdSpecialKeys &= ~(1L << (b)))
1864 CARD32 KdSpecialKeys
= 0;
1867 * kdCheckTermination
1869 * This function checks for the key sequence that terminates the server. When
1870 * detected, it sets the dispatchException flag and returns. The key sequence
1873 * It's assumed that the server will be waken up by the caller when this
1877 extern int nClients
;
1880 KdCheckSpecialKeys(KdKeyboardInfo
*ki
, int type
, int sym
)
1886 * Ignore key releases
1889 if (type
== KeyRelease
)
1892 /* Some iPaq keyboard -> mouse button mapping used to be here, but I
1893 * refuse to perpetuate this madness. -daniels */
1896 * Check for control/alt pressed
1898 if ((ki
->dixdev
->key
->state
& (ControlMask
|Mod1Mask
)) !=
1899 (ControlMask
|Mod1Mask
))
1903 * Let OS function see keysym first
1906 if (kdOsFuncs
->SpecialKey
)
1907 if ((*kdOsFuncs
->SpecialKey
) (sym
))
1911 * Now check for backspace or delete; these signal the
1912 * X server to terminate
1914 * I can't believe it's not XKB. -daniels
1921 * Set the dispatch exception flag so the server will terminate the
1922 * next time through the dispatch loop.
1924 if (kdDontZap
== FALSE
)
1925 dispatchException
|= DE_TERMINATE
;
1931 * kdEnqueueKeyboardEvent
1933 * This function converts hardware keyboard event information into an X event
1934 * and enqueues it using MI. It wakes up the server before returning so that
1935 * the event will be processed normally.
1940 KdHandleKeyboardEvent (KdKeyboardInfo
*ki
, int type
, int key
)
1947 bit
= 1 << (key
& 7);
1951 ki
->keyState
[byte
] |= bit
;
1954 ki
->keyState
[byte
] &= ~bit
;
1958 for (pi
= kdPointers
; pi
; pi
= pi
->next
)
1959 KdRunMouseMachine (pi
, keyboard
, 0, 0, 0, 0, 0, 0);
1963 KdReleaseAllKeys (void)
1965 int key
, nEvents
, i
;
1970 for (ki
= kdKeyboards
; ki
; ki
= ki
->next
) {
1971 for (key
= ki
->keySyms
.minKeyCode
; key
< ki
->keySyms
.maxKeyCode
;
1973 if (IsKeyDown(ki
, key
)) {
1974 KdHandleKeyboardEvent(ki
, KeyRelease
, key
);
1975 nEvents
= GetKeyboardEvents(kdEvents
, ki
->dixdev
, KeyRelease
, key
);
1976 for (i
= 0; i
< nEvents
; i
++)
1977 KdQueueEvent (ki
->dixdev
, kdEvents
+ i
);
1988 KeyClassPtr keyc
= NULL
;
1989 Bool isSet
= FALSE
, shouldBeSet
= FALSE
;
1990 KdKeyboardInfo
*tmp
= NULL
;
1992 for (tmp
= kdKeyboards
; tmp
; tmp
= tmp
->next
) {
1993 if (tmp
->LockLed
&& tmp
->dixdev
&& tmp
->dixdev
->key
) {
1994 keyc
= tmp
->dixdev
->key
;
1995 isSet
= (tmp
->leds
& (1 << (tmp
->LockLed
-1))) != 0;
1996 shouldBeSet
= (keyc
->state
& LockMask
) != 0;
1997 if (isSet
!= shouldBeSet
)
1998 KdSetLed (tmp
, tmp
->LockLed
, shouldBeSet
);
2004 KdEnqueueKeyboardEvent(KdKeyboardInfo
*ki
,
2005 unsigned char scan_code
,
2006 unsigned char is_up
)
2008 unsigned char key_code
;
2009 KeyClassPtr keyc
= NULL
;
2010 KeybdCtrl
*ctrl
= NULL
;
2011 int type
, nEvents
, i
;
2013 if (!ki
|| !ki
->dixdev
|| !ki
->dixdev
->kbdfeed
|| !ki
->dixdev
->key
)
2016 keyc
= ki
->dixdev
->key
;
2017 ctrl
= &ki
->dixdev
->kbdfeed
->ctrl
;
2019 if (scan_code
>= ki
->minScanCode
&& scan_code
<= ki
->maxScanCode
)
2021 key_code
= scan_code
+ KD_MIN_KEYCODE
- ki
->minScanCode
;
2024 * Set up this event -- the type may be modified below
2035 KdCheckSpecialKeys(ki
, type
, key_code
);
2036 KdHandleKeyboardEvent(ki
, type
, key_code
);
2039 nEvents
= GetKeyboardEvents(kdEvents
, ki
->dixdev
, type
, key_code
);
2040 for (i
= 0; i
< nEvents
; i
++)
2041 KdQueueEvent(ki
->dixdev
, kdEvents
+ i
);
2044 ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n",
2045 ki
->name
, scan_code
, ki
->minScanCode
, ki
->maxScanCode
);
2050 * kdEnqueuePointerEvent
2052 * This function converts hardware mouse event information into X event
2053 * information. A mouse movement event is passed off to MI to generate
2054 * a MotionNotify event, if appropriate. Button events are created and
2055 * passed off to MI for enqueueing.
2058 /* FIXME do something a little more clever to deal with multiple axes here */
2060 KdEnqueuePointerEvent(KdPointerInfo
*pi
, unsigned long flags
, int rx
, int ry
,
2064 unsigned char buttons
;
2066 int (*matrix
)[3] = kdPointerMatrix
.matrix
;
2067 unsigned long button
;
2074 ms
= GetTimeInMillis();
2076 /* we don't need to transform z, so we don't. */
2077 if (flags
& KD_MOUSE_DELTA
) {
2078 if (pi
->transformCoordinates
) {
2079 x
= matrix
[0][0] * rx
+ matrix
[0][1] * ry
;
2080 y
= matrix
[1][0] * rx
+ matrix
[1][1] * ry
;
2088 if (pi
->transformCoordinates
) {
2089 x
= matrix
[0][0] * rx
+ matrix
[0][1] * ry
;
2090 y
= matrix
[1][0] * rx
+ matrix
[1][1] * ry
;
2099 if (flags
& KD_MOUSE_DELTA
)
2100 dixflags
= POINTER_RELATIVE
& POINTER_ACCELERATE
;
2102 dixflags
= POINTER_ABSOLUTE
;
2104 _KdEnqueuePointerEvent(pi
, MotionNotify
, x
, y
, z
, 0, dixflags
, FALSE
);
2108 for (button
= KD_BUTTON_1
, n
= 1; n
<= pi
->nButtons
;
2109 button
<<= 1, n
++) {
2110 if (((pi
->buttonState
& button
) ^ (buttons
& button
)) &&
2111 !(buttons
& button
)) {
2112 _KdEnqueuePointerEvent(pi
, ButtonRelease
, x
, y
, z
, n
,
2116 for (button
= KD_BUTTON_1
, n
= 1; n
<= pi
->nButtons
;
2117 button
<<= 1, n
++) {
2118 if (((pi
->buttonState
& button
) ^ (buttons
& button
)) &&
2119 (buttons
& button
)) {
2120 _KdEnqueuePointerEvent(pi
, ButtonPress
, x
, y
, z
, n
,
2125 pi
->buttonState
= buttons
;
2129 _KdEnqueuePointerEvent (KdPointerInfo
*pi
, int type
, int x
, int y
, int z
,
2130 int b
, int absrel
, Bool force
)
2132 int nEvents
= 0, i
= 0;
2133 int valuators
[3] = { x
, y
, z
};
2135 /* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */
2136 if (!force
&& KdHandlePointerEvent(pi
, type
, x
, y
, z
, b
, absrel
))
2139 nEvents
= GetPointerEvents(kdEvents
, pi
->dixdev
, type
, b
, absrel
, 0, 3,
2141 for (i
= 0; i
< nEvents
; i
++)
2142 KdQueueEvent(pi
->dixdev
, kdEvents
+ i
);
2146 KdBlockHandler (int screen
,
2154 for (pi
= kdPointers
; pi
; pi
= pi
->next
)
2156 if (pi
->timeoutPending
)
2160 ms
= pi
->emulationTimeout
- GetTimeInMillis ();
2163 if(ms
<myTimeout
|| myTimeout
==0)
2167 /* if we need to poll for events, do that */
2168 if(kdOsFuncs
->pollEvents
)
2170 (*kdOsFuncs
->pollEvents
)();
2174 AdjustWaitForDelay (timeout
, myTimeout
);
2178 KdWakeupHandler (int screen
,
2180 unsigned long lresult
,
2183 int result
= (int) lresult
;
2184 fd_set
*pReadmask
= (fd_set
*) readmask
;
2188 if (kdInputEnabled
&& result
> 0)
2190 for (i
= 0; i
< kdNumInputFds
; i
++)
2191 if (FD_ISSET (kdInputFds
[i
].fd
, pReadmask
))
2194 (*kdInputFds
[i
].read
) (kdInputFds
[i
].fd
, kdInputFds
[i
].closure
);
2198 for (pi
= kdPointers
; pi
; pi
= pi
->next
)
2200 if (pi
->timeoutPending
)
2202 if ((long) (GetTimeInMillis () - pi
->emulationTimeout
) >= 0)
2204 pi
->timeoutPending
= FALSE
;
2206 KdReceiveTimeout (pi
);
2211 if (kdSwitchPending
)
2215 #define KdScreenOrigin(pScreen) (&(KdGetScreenPriv(pScreen)->screen->origin))
2218 KdCursorOffScreen(ScreenPtr
*ppScreen
, int *x
, int *y
)
2220 ScreenPtr pScreen
= *ppScreen
;
2221 ScreenPtr pNewScreen
;
2225 int n_best_x
, n_best_y
;
2228 if (kdDisableZaphod
|| screenInfo
.numScreens
<= 1)
2231 if (0 <= *x
&& *x
< pScreen
->width
&& 0 <= *y
&& *y
< pScreen
->height
)
2234 ms
= GetTimeInMillis ();
2235 if (kdOffScreen
&& (int) (ms
- kdOffScreenTime
) < 1000)
2238 kdOffScreenTime
= ms
;
2243 for (n
= 0; n
< screenInfo
.numScreens
; n
++)
2245 pNewScreen
= screenInfo
.screens
[n
];
2246 if (pNewScreen
== pScreen
)
2248 dx
= KdScreenOrigin(pNewScreen
)->x
- KdScreenOrigin(pScreen
)->x
;
2249 dy
= KdScreenOrigin(pNewScreen
)->y
- KdScreenOrigin(pScreen
)->y
;
2252 if (dx
<= 0 && -dx
< best_x
)
2258 else if (*x
>= pScreen
->width
)
2260 if (dx
>= 0 && dx
< best_x
)
2268 if (dy
<= 0 && -dy
< best_y
)
2274 else if (*y
>= pScreen
->height
)
2276 if (dy
>= 0 && dy
< best_y
)
2283 if (best_y
< best_x
)
2284 n_best_x
= n_best_y
;
2287 pNewScreen
= screenInfo
.screens
[n_best_x
];
2290 *x
+= pNewScreen
->width
;
2292 *y
+= pNewScreen
->height
;
2294 if (*x
>= pScreen
->width
)
2295 *x
-= pScreen
->width
;
2296 if (*y
>= pScreen
->height
)
2297 *y
-= pScreen
->height
;
2299 *ppScreen
= pNewScreen
;
2304 KdCrossScreen(ScreenPtr pScreen
, Bool entering
)
2308 KdEnableScreen (pScreen
);
2310 KdDisableScreen (pScreen
);
2314 int KdCurScreen
; /* current event screen */
2317 KdWarpCursor (ScreenPtr pScreen
, int x
, int y
)
2320 KdCurScreen
= pScreen
->myNum
;
2321 miPointerWarpCursor (pScreen
, x
, y
);
2325 miPointerScreenFuncRec kdPointerScreenFuncs
=
2333 ProcessInputEvents ()
2335 mieqProcessInputEvents();
2337 if (kdSwitchPending
)
2342 /* FIXME use XSECURITY to work out whether the client should be allowed to
2343 * open and close. */
2345 OpenInputDevice(DeviceIntPtr pDev
, ClientPtr client
, int *status
)
2348 *status
= BadDevice
;
2354 CloseInputDevice(DeviceIntPtr pDev
, ClientPtr client
)
2359 /* We initialise all input devices at startup. */
2361 AddOtherInputDevices(void)
2366 /* At the moment, absolute/relative is up to the client. */
2368 SetDeviceMode(register ClientPtr client
, DeviceIntPtr pDev
, int mode
)
2374 SetDeviceValuators(register ClientPtr client
, DeviceIntPtr pDev
,
2375 int *valuators
, int first_valuator
, int num_valuators
)
2381 ChangeDeviceControl(register ClientPtr client
, DeviceIntPtr pDev
,
2382 xDeviceCtl
*control
)
2384 switch (control
->control
) {
2385 case DEVICE_RESOLUTION
:
2386 /* FIXME do something more intelligent here */
2389 case DEVICE_ABS_CALIB
:
2390 case DEVICE_ABS_AREA
:
2402 return BadImplementation
;
2406 NewInputDeviceRequest(InputOption
*options
, DeviceIntPtr
*pdev
)
2408 InputOption
*option
= NULL
;
2409 KdPointerInfo
*pi
= NULL
;
2410 KdKeyboardInfo
*ki
= NULL
;
2412 for (option
= options
; option
; option
= option
->next
) {
2413 if (strcmp(option
->key
, "type") == 0) {
2414 if (strcmp(option
->value
, "pointer") == 0) {
2415 pi
= KdNewPointer();
2419 else if (strcmp(option
->value
, "keyboard") == 0) {
2420 ki
= KdNewKeyboard();
2425 ErrorF("unrecognised device type!\n");
2432 ErrorF("unrecognised device identifier!\n");
2436 /* FIXME: change this code below to use KdParseKbdOptions and
2437 * KdParsePointerOptions */
2438 for (option
= options
; option
; option
= option
->next
) {
2439 if (strcmp(option
->key
, "device") == 0) {
2440 if (pi
&& option
->value
)
2441 pi
->path
= KdSaveString(option
->value
);
2442 else if (ki
&& option
->value
)
2443 ki
->path
= KdSaveString(option
->value
);
2445 else if (strcmp(option
->key
, "driver") == 0) {
2447 pi
->driver
= KdFindPointerDriver(option
->value
);
2449 ErrorF("couldn't find driver!\n");
2453 pi
->options
= options
;
2456 ki
->driver
= KdFindKeyboardDriver(option
->value
);
2458 ErrorF("couldn't find driver!\n");
2462 ki
->options
= options
;
2468 if (KdAddPointer(pi
) != Success
||
2469 ActivateDevice(pi
->dixdev
) != Success
||
2470 EnableDevice(pi
->dixdev
) != TRUE
) {
2471 ErrorF("couldn't add or enable pointer\n");
2472 return BadImplementation
;
2476 if (KdAddKeyboard(ki
) != Success
||
2477 ActivateDevice(ki
->dixdev
) != Success
||
2478 EnableDevice(ki
->dixdev
) != TRUE
) {
2479 ErrorF("couldn't add or enable keyboard\n");
2480 return BadImplementation
;
2494 DeleteInputDeviceRequest(DeviceIntPtr pDev
)