2 * Copyright © 2004 Keith Packard
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Keith Packard makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
24 #include <kdrive-config.h>
27 #include <linux/input.h>
29 #include <X11/Xproto.h>
30 #include <X11/Xpoll.h>
32 #include "scrnintstr.h"
35 #define NUM_EVENTS 128
36 #define ABS_UNSET -65535
38 #define BITS_PER_LONG (sizeof(long) * 8)
39 #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
40 #define ISBITSET(x,y) ((x)[LONG(y)] & BIT(y))
41 #define OFF(x) ((x)%BITS_PER_LONG)
42 #define LONG(x) ((x)/BITS_PER_LONG)
43 #define BIT(x) (1 << OFF(x))
45 typedef struct _kevdev
{
46 /* current device state */
49 int prevabs
[ABS_MAX
+ 1];
50 long key
[NBITS(KEY_MAX
+ 1)];
52 /* supported device info */
53 long relbits
[NBITS(REL_MAX
+ 1)];
54 long absbits
[NBITS(ABS_MAX
+ 1)];
55 long keybits
[NBITS(KEY_MAX
+ 1)];
56 struct input_absinfo absinfo
[ABS_MAX
+ 1];
64 EvdevPtrBtn(KdPointerInfo
* pi
, struct input_event
*ev
)
66 int flags
= KD_MOUSE_DELTA
| pi
->buttonState
;
68 if (ev
->code
>= BTN_MOUSE
&& ev
->code
< BTN_JOYSTICK
) {
74 flags
&= ~KD_BUTTON_1
;
80 flags
&= ~KD_BUTTON_2
;
86 flags
&= ~KD_BUTTON_3
;
93 KdEnqueuePointerEvent(pi
, flags
, 0, 0, 0);
98 EvdevPtrMotion(KdPointerInfo
* pi
, struct input_event
*ev
)
100 Kevdev
*ke
= pi
->driverPrivate
;
102 int flags
= KD_MOUSE_DELTA
| pi
->buttonState
;
104 for (i
= 0; i
<= ke
->max_rel
; i
++)
108 for (a
= 0; a
<= ke
->max_rel
; a
++) {
109 if (ISBITSET(ke
->relbits
, a
)) {
111 KdEnqueuePointerEvent(pi
, flags
, ke
->rel
[a
], 0, 0);
113 KdEnqueuePointerEvent(pi
, flags
, 0, ke
->rel
[a
], 0);
119 for (i
= 0; i
< ke
->max_abs
; i
++)
120 if (ke
->abs
[i
] != ke
->prevabs
[i
]) {
124 for (a
= 0; a
<= ke
->max_abs
; a
++) {
125 if (ISBITSET(ke
->absbits
, a
))
126 ErrorF(" %d=%d", a
, ke
->abs
[a
]);
127 ke
->prevabs
[a
] = ke
->abs
[a
];
133 if (ev
->code
== REL_WHEEL
) {
134 for (i
= 0; i
< abs(ev
->value
); i
++) {
136 flags
|= KD_BUTTON_4
;
138 flags
|= KD_BUTTON_5
;
140 KdEnqueuePointerEvent(pi
, flags
, 0, 0, 0);
143 flags
&= ~KD_BUTTON_4
;
145 flags
&= ~KD_BUTTON_5
;
147 KdEnqueuePointerEvent(pi
, flags
, 0, 0, 0);
154 EvdevPtrRead(int evdevPort
, void *closure
)
156 KdPointerInfo
*pi
= closure
;
157 Kevdev
*ke
= pi
->driverPrivate
;
159 struct input_event events
[NUM_EVENTS
];
162 n
= read(evdevPort
, &events
, NUM_EVENTS
* sizeof(struct input_event
));
165 DeleteInputDeviceRequest(pi
->dixdev
);
169 n
/= sizeof(struct input_event
);
170 for (i
= 0; i
< n
; i
++) {
171 switch (events
[i
].type
) {
175 EvdevPtrBtn(pi
, &events
[i
]);
178 ke
->rel
[events
[i
].code
] += events
[i
].value
;
179 EvdevPtrMotion(pi
, &events
[i
]);
182 ke
->abs
[events
[i
].code
] = events
[i
].value
;
183 EvdevPtrMotion(pi
, &events
[i
]);
189 const char *kdefaultEvdev
[] = {
196 #define NUM_DEFAULT_EVDEV (sizeof (kdefaultEvdev) / sizeof (kdefaultEvdev[0]))
199 EvdevPtrInit(KdPointerInfo
* pi
)
205 for (i
= 0; i
< NUM_DEFAULT_EVDEV
; i
++) {
206 fd
= open(kdefaultEvdev
[i
], 2);
208 pi
->path
= strdup(kdefaultEvdev
[i
]);
214 fd
= open(pi
->path
, O_RDWR
);
216 ErrorF("Failed to open evdev device %s\n", pi
->path
);
223 pi
->name
= strdup("Evdev mouse");
229 EvdevPtrEnable(KdPointerInfo
* pi
)
232 unsigned long ev
[NBITS(EV_MAX
)];
235 if (!pi
|| !pi
->path
)
236 return BadImplementation
;
238 fd
= open(pi
->path
, 2);
242 if (ioctl(fd
, EVIOCGRAB
, 1) < 0)
243 perror("Grabbing evdev mouse device failed");
245 if (ioctl(fd
, EVIOCGBIT(0 /*EV*/, sizeof(ev
)), ev
) < 0) {
246 perror("EVIOCGBIT 0");
250 ke
= calloc(1, sizeof(Kevdev
));
255 if (ISBITSET(ev
, EV_KEY
)) {
256 if (ioctl(fd
, EVIOCGBIT(EV_KEY
, sizeof(ke
->keybits
)), ke
->keybits
) < 0) {
257 perror("EVIOCGBIT EV_KEY");
263 if (ISBITSET(ev
, EV_REL
)) {
264 if (ioctl(fd
, EVIOCGBIT(EV_REL
, sizeof(ke
->relbits
)), ke
->relbits
) < 0) {
265 perror("EVIOCGBIT EV_REL");
270 for (ke
->max_rel
= REL_MAX
; ke
->max_rel
>= 0; ke
->max_rel
--)
271 if (ISBITSET(ke
->relbits
, ke
->max_rel
))
274 if (ISBITSET(ev
, EV_ABS
)) {
277 if (ioctl(fd
, EVIOCGBIT(EV_ABS
, sizeof(ke
->absbits
)), ke
->absbits
) < 0) {
278 perror("EVIOCGBIT EV_ABS");
283 for (ke
->max_abs
= ABS_MAX
; ke
->max_abs
>= 0; ke
->max_abs
--)
284 if (ISBITSET(ke
->absbits
, ke
->max_abs
))
286 for (i
= 0; i
<= ke
->max_abs
; i
++) {
287 if (ISBITSET(ke
->absbits
, i
))
288 if (ioctl(fd
, EVIOCGABS(i
), &ke
->absinfo
[i
]) < 0) {
292 ke
->prevabs
[i
] = ABS_UNSET
;
294 if (i
<= ke
->max_abs
) {
300 if (!KdRegisterFd(fd
, EvdevPtrRead
, pi
)) {
305 pi
->driverPrivate
= ke
;
312 EvdevPtrDisable(KdPointerInfo
* pi
)
316 ke
= pi
->driverPrivate
;
318 if (!pi
|| !pi
->driverPrivate
)
321 KdUnregisterFd(pi
, ke
->fd
, TRUE
);
323 if (ioctl(ke
->fd
, EVIOCGRAB
, 0) < 0)
324 perror("Ungrabbing evdev mouse device failed");
327 pi
->driverPrivate
= 0;
331 EvdevPtrFini(KdPointerInfo
* pi
)
336 * Evdev keyboard functions
340 readMapping(KdKeyboardInfo
* ki
)
346 ki
->maxScanCode
= 247;
350 EvdevKbdRead(int evdevPort
, void *closure
)
352 KdKeyboardInfo
*ki
= closure
;
353 struct input_event events
[NUM_EVENTS
];
356 n
= read(evdevPort
, &events
, NUM_EVENTS
* sizeof(struct input_event
));
359 DeleteInputDeviceRequest(ki
->dixdev
);
363 n
/= sizeof(struct input_event
);
364 for (i
= 0; i
< n
; i
++) {
365 if (events
[i
].type
== EV_KEY
)
366 KdEnqueueKeyboardEvent(ki
, events
[i
].code
, !events
[i
].value
);
367 /* FIXME: must implement other types of events
369 ErrorF("Event type (%d) not delivered\n", events[i].type);
375 EvdevKbdInit(KdKeyboardInfo
* ki
)
380 ErrorF("Couldn't find evdev device path\n");
384 fd
= open(ki
->path
, O_RDWR
);
386 ErrorF("Failed to open evdev device %s\n", ki
->path
);
393 ki
->name
= strdup("Evdev keyboard");
401 EvdevKbdEnable(KdKeyboardInfo
* ki
)
403 unsigned long ev
[NBITS(EV_MAX
)];
407 if (!ki
|| !ki
->path
)
408 return BadImplementation
;
410 fd
= open(ki
->path
, O_RDWR
);
414 if (ioctl(fd
, EVIOCGRAB
, 1) < 0)
415 perror("Grabbing evdev keyboard device failed");
417 if (ioctl(fd
, EVIOCGBIT(0 /*EV*/, sizeof(ev
)), ev
) < 0) {
418 perror("EVIOCGBIT 0");
423 ke
= calloc(1, sizeof(Kevdev
));
429 if (!KdRegisterFd(fd
, EvdevKbdRead
, ki
)) {
434 ki
->driverPrivate
= ke
;
441 EvdevKbdLeds(KdKeyboardInfo
* ki
, int leds
)
443 /* struct input_event event;
446 ki->driverPrivate = ke;
448 memset(&event, 0, sizeof(event));
451 event.code = LED_CAPSL;
452 event.value = leds & (1 << 0) ? 1 : 0;
453 write(ke->fd, (char *) &event, sizeof(event));
456 event.code = LED_NUML;
457 event.value = leds & (1 << 1) ? 1 : 0;
458 write(ke->fd, (char *) &event, sizeof(event));
461 event.code = LED_SCROLLL;
462 event.value = leds & (1 << 2) ? 1 : 0;
463 write(ke->fd, (char *) &event, sizeof(event));
466 event.code = LED_COMPOSE;
467 event.value = leds & (1 << 3) ? 1 : 0;
468 write(ke->fd, (char *) &event, sizeof(event));
473 EvdevKbdBell(KdKeyboardInfo
* ki
, int volume
, int frequency
, int duration
)
478 EvdevKbdDisable(KdKeyboardInfo
* ki
)
482 ke
= ki
->driverPrivate
;
484 if (!ki
|| !ki
->driverPrivate
)
487 KdUnregisterFd(ki
, ke
->fd
, TRUE
);
489 if (ioctl(ke
->fd
, EVIOCGRAB
, 0) < 0)
490 perror("Ungrabbing evdev keyboard device failed");
493 ki
->driverPrivate
= 0;
497 EvdevKbdFini(KdKeyboardInfo
* ki
)
501 KdPointerDriver LinuxEvdevMouseDriver
= {
510 KdKeyboardDriver LinuxEvdevKeyboardDriver
= {