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.
23 #include <xgl-config.h>
26 #include <linux/input.h>
28 #include <X11/Xproto.h>
29 #include <X11/Xpoll.h>
31 #include <X11/keysym.h>
34 #include "scrnintstr.h"
37 #define NUM_EVENTS 128
38 #define ABS_UNSET -65535
40 #define BITS_PER_LONG (sizeof(long) * 8)
41 #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
42 #define ISBITSET(x,y) ((x)[LONG(y)] & BIT(y))
43 #define OFF(x) ((x)%BITS_PER_LONG)
44 #define LONG(x) ((x)/BITS_PER_LONG)
45 #define BIT(x) (1 << OFF(x))
46 #define SETBIT(x,y) ((x)[LONG(y)] |= BIT(y))
47 #define CLRBIT(x,y) ((x)[LONG(y)] &= ~BIT(y))
48 #define ASSIGNBIT(x,y,z) ((x)[LONG(y)] = ((x)[LONG(y)] & ~BIT(y)) | (z << OFF(y)))
50 typedef struct _kevdevMouse
{
51 /* current device state */
54 int prevabs
[ABS_MAX
+ 1];
55 long key
[NBITS(KEY_MAX
+ 1)];
57 /* supported device info */
58 long relbits
[NBITS(REL_MAX
+ 1)];
59 long absbits
[NBITS(ABS_MAX
+ 1)];
60 long keybits
[NBITS(KEY_MAX
+ 1)];
61 struct input_absinfo absinfo
[ABS_MAX
+ 1];
69 EvdevMotion (KdMouseInfo
*mi
)
71 Kevdev
*ke
= mi
->driver
;
74 for (i
= 0; i
<= ke
->max_rel
; i
++)
77 KdEnqueueMouseEvent (mi
, flags
| KD_MOUSE_DELTA
, ke
->rel
[0], ke
->rel
[1]);
80 for (a
= 0; a
<= ke
->max_rel
; a
++)
82 // if (ISBITSET (ke->relbits, a))
83 // ErrorF (" %d=%d", a, ke->rel[a]);
89 for (i
= 0; i
< ke
->max_abs
; i
++)
90 if (ke
->abs
[i
] != ke
->prevabs
[i
])
92 KdEnqueueMouseEvent (mi
, flags
, ke
->abs
[0], ke
->abs
[1]);
95 for (a
= 0; a
<= ke
->max_abs
; a
++)
97 // if (ISBITSET (ke->absbits, a))
98 // ErrorF (" %d=%d", a, ke->abs[a]);
99 ke
->prevabs
[a
] = ke
->abs
[a
];
107 EvdevRead (int evdevPort
, void *closure
)
109 KdMouseInfo
*mi
= closure
;
110 Kevdev
*ke
= mi
->driver
;
112 struct input_event events
[NUM_EVENTS
];
114 n
= read (evdevPort
, &events
, NUM_EVENTS
* sizeof (struct input_event
));
117 n
/= sizeof (struct input_event
);
118 for (i
= 0; i
< n
; i
++)
120 switch (events
[i
].type
) {
125 ASSIGNBIT(ke
->key
,events
[i
].code
, events
[i
].value
);
126 if (events
[i
].code
< 0x100)
127 ErrorF ("key %d %d\n", events
[i
].code
, events
[i
].value
);
129 ErrorF ("key 0x%x %d\n", events
[i
].code
, events
[i
].value
);
131 if (events
[i
].value
==1) {
132 switch (events
[i
].code
) {
134 flags
|= KD_BUTTON_1
;
137 flags
|= KD_BUTTON_3
;
140 flags
|= KD_BUTTON_2
;
143 flags
|= KD_BUTTON_4
;
146 flags
|= KD_BUTTON_5
;
150 else if (events
[i
].value
==0) {
151 switch (events
[i
].code
) {
153 flags
&= ~KD_BUTTON_1
;
156 flags
&= ~KD_BUTTON_3
;
159 flags
&= ~KD_BUTTON_2
;
162 flags
&= ~KD_BUTTON_4
;
165 flags
&= ~KD_BUTTON_5
;
169 KdEnqueueMouseEvent (mi
, KD_MOUSE_DELTA
| flags
, 0, 0);
172 ke
->rel
[events
[i
].code
] += events
[i
].value
;
175 ke
->abs
[events
[i
].code
] = events
[i
].value
;
184 char *kdefaultEvdev
[] = {
185 // "/dev/input/event0",
187 // "/dev/input/event2",
188 // "/dev/input/event3",
189 // "/dev/input/event4",
190 // "/dev/input/event5",
193 #define NUM_DEFAULT_EVDEV (sizeof (kdefaultEvdev) / sizeof (kdefaultEvdev[0]))
200 KdMouseInfo
*mi
, *next
;
206 EvdevInputType
= KdAllocInputType ();
208 for (mi
= kdMouseInfo
; mi
; mi
= next
)
216 for (i
= 0; i
< NUM_DEFAULT_EVDEV
; i
++)
218 fd
= open (kdefaultEvdev
[i
], 2);
221 ioctl(fd
, EVIOCGRAB
, 1);
223 ioctl(fd
, EVIOCGNAME(sizeof(name
)), name
);
224 ErrorF("Name is %s\n", name
);
225 ioctl(fd
, EVIOCGPHYS(sizeof(name
)), name
);
226 ErrorF("Phys Loc is %s\n", name
);
227 ioctl(fd
, EVIOCGUNIQ(sizeof(name
)), name
);
228 ErrorF("Unique is %s\n", name
);
230 mi
->name
= KdSaveString (kdefaultEvdev
[i
]);
236 fd
= open (mi
->name
, 2);
240 unsigned long ev
[NBITS(EV_MAX
)];
243 if (ioctl (fd
, EVIOCGBIT(0 /*EV*/, sizeof (ev
)), ev
) < 0)
245 perror ("EVIOCGBIT 0");
249 ke
= xalloc (sizeof (Kevdev
));
255 memset (ke
, '\0', sizeof (Kevdev
));
256 if (ISBITSET (ev
, EV_KEY
))
258 if (ioctl (fd
, EVIOCGBIT (EV_KEY
, sizeof (ke
->keybits
)),
261 perror ("EVIOCGBIT EV_KEY");
267 if (ISBITSET (ev
, EV_REL
))
269 if (ioctl (fd
, EVIOCGBIT (EV_REL
, sizeof (ke
->relbits
)),
272 perror ("EVIOCGBIT EV_REL");
277 for (ke
->max_rel
= REL_MAX
; ke
->max_rel
>= 0; ke
->max_rel
--)
278 if (ISBITSET(ke
->relbits
, ke
->max_rel
))
281 if (ISBITSET (ev
, EV_ABS
))
285 if (ioctl (fd
, EVIOCGBIT (EV_ABS
, sizeof (ke
->absbits
)),
288 perror ("EVIOCGBIT EV_ABS");
293 for (ke
->max_abs
= ABS_MAX
; ke
->max_abs
>= 0; ke
->max_abs
--)
294 if (ISBITSET(ke
->absbits
, ke
->max_abs
))
296 for (i
= 0; i
<= ke
->max_abs
; i
++)
298 if (ISBITSET (ke
->absbits
, i
))
299 if (ioctl (fd
, EVIOCGABS(i
), &ke
->absinfo
[i
]) < 0)
301 perror ("EVIOCGABS");
304 ke
->prevabs
[i
] = ABS_UNSET
;
306 if (i
<= ke
->max_abs
)
314 mi
->inputType
= EvdevInputType
;
315 if (KdRegisterFd (EvdevInputType
, fd
, EvdevRead
, (void *) mi
))
327 KdUnregisterFds (EvdevInputType
, TRUE
);
328 for (mi
= kdMouseInfo
; mi
; mi
= mi
->next
)
330 if (mi
->inputType
== EvdevInputType
)
339 KdMouseFuncs LinuxEvdevMouseFuncs
= {
345 KeySym evdevKeymap
[(112 - 1 + 1) * 2] = {
346 /* These are directly mapped from DOS scanset 0 */
347 /* 1 8 */ XK_Escape
, NoSymbol
,
348 /* 2 9 */ XK_1
, XK_exclam
,
349 /* 3 10 */ XK_2
, XK_at
,
350 /* 4 11 */ XK_3
, XK_numbersign
,
351 /* 5 12 */ XK_4
, XK_dollar
,
352 /* 6 13 */ XK_5
, XK_percent
,
353 /* 7 14 */ XK_6
, XK_asciicircum
,
354 /* 8 15 */ XK_7
, XK_ampersand
,
355 /* 9 16 */ XK_8
, XK_asterisk
,
356 /* 10 17 */ XK_9
, XK_parenleft
,
357 /* 11 18 */ XK_0
, XK_parenright
,
358 /* 12 19 */ XK_minus
, XK_underscore
,
359 /* 13 20 */ XK_equal
, XK_plus
,
360 /* 14 21 */ XK_BackSpace
, NoSymbol
,
361 /* 15 22 */ XK_Tab
, NoSymbol
,
362 /* 16 23 */ XK_Q
, NoSymbol
,
363 /* 17 24 */ XK_W
, NoSymbol
,
364 /* 18 25 */ XK_E
, NoSymbol
,
365 /* 19 26 */ XK_R
, NoSymbol
,
366 /* 20 27 */ XK_T
, NoSymbol
,
367 /* 21 28 */ XK_Y
, NoSymbol
,
368 /* 22 29 */ XK_U
, NoSymbol
,
369 /* 23 30 */ XK_I
, NoSymbol
,
370 /* 24 31 */ XK_O
, NoSymbol
,
371 /* 25 32 */ XK_P
, NoSymbol
,
372 /* 26 33 */ XK_bracketleft
, XK_braceleft
,
373 /* 27 34 */ XK_bracketright
, XK_braceright
,
374 /* 28 35 */ XK_Return
, NoSymbol
,
375 /* 29 36 */ XK_Control_L
, NoSymbol
,
376 /* 30 37 */ XK_A
, NoSymbol
,
377 /* 31 38 */ XK_S
, NoSymbol
,
378 /* 32 39 */ XK_D
, NoSymbol
,
379 /* 33 40 */ XK_F
, NoSymbol
,
380 /* 34 41 */ XK_G
, NoSymbol
,
381 /* 35 42 */ XK_H
, NoSymbol
,
382 /* 36 43 */ XK_J
, NoSymbol
,
383 /* 37 44 */ XK_K
, NoSymbol
,
384 /* 38 45 */ XK_L
, NoSymbol
,
385 /* 39 46 */ XK_semicolon
, XK_colon
,
386 /* 40 47 */ XK_apostrophe
, XK_quotedbl
,
387 /* 41 48 */ XK_grave
, XK_asciitilde
,
388 /* 42 49 */ XK_Shift_L
, NoSymbol
,
389 /* 43 50 */ XK_backslash
, XK_bar
,
390 /* 44 51 */ XK_Z
, NoSymbol
,
391 /* 45 52 */ XK_X
, NoSymbol
,
392 /* 46 53 */ XK_C
, NoSymbol
,
393 /* 47 54 */ XK_V
, NoSymbol
,
394 /* 48 55 */ XK_B
, NoSymbol
,
395 /* 49 56 */ XK_N
, NoSymbol
,
396 /* 50 57 */ XK_M
, NoSymbol
,
397 /* 51 58 */ XK_comma
, XK_less
,
398 /* 52 59 */ XK_period
, XK_greater
,
399 /* 53 60 */ XK_slash
, XK_question
,
400 /* 54 61 */ XK_Shift_R
, NoSymbol
,
401 /* 55 62 */ XK_KP_Multiply
, NoSymbol
,
402 /* 56 63 */ XK_Alt_L
, XK_Meta_L
,
403 /* 57 64 */ XK_space
, NoSymbol
,
404 /* 58 65 */ XK_Caps_Lock
, NoSymbol
,
405 /* 59 66 */ XK_F1
, NoSymbol
,
406 /* 60 67 */ XK_F2
, NoSymbol
,
407 /* 61 68 */ XK_F3
, NoSymbol
,
408 /* 62 69 */ XK_F4
, NoSymbol
,
409 /* 63 70 */ XK_F5
, NoSymbol
,
410 /* 64 71 */ XK_F6
, NoSymbol
,
411 /* 65 72 */ XK_F7
, NoSymbol
,
412 /* 66 73 */ XK_F8
, NoSymbol
,
413 /* 67 74 */ XK_F9
, NoSymbol
,
414 /* 68 75 */ XK_F10
, NoSymbol
,
415 /* 69 76 */ XK_Break
, XK_Pause
,
416 /* 70 77 */ XK_Scroll_Lock
, NoSymbol
,
417 /* 71 78 */ XK_KP_Home
, XK_KP_7
,
418 /* 72 79 */ XK_KP_Up
, XK_KP_8
,
419 /* 73 80 */ XK_KP_Page_Up
, XK_KP_9
,
420 /* 74 81 */ XK_KP_Subtract
, NoSymbol
,
421 /* 75 82 */ XK_KP_Left
, XK_KP_4
,
422 /* 76 83 */ XK_KP_5
, NoSymbol
,
423 /* 77 84 */ XK_KP_Right
, XK_KP_6
,
424 /* 78 85 */ XK_KP_Add
, NoSymbol
,
425 /* 79 86 */ XK_KP_End
, XK_KP_1
,
426 /* 80 87 */ XK_KP_Down
, XK_KP_2
,
427 /* 81 88 */ XK_KP_Page_Down
, XK_KP_3
,
428 /* 82 89 */ XK_KP_Insert
, XK_KP_0
,
429 /* 83 90 */ XK_KP_Delete
, XK_KP_Decimal
,
430 /* 84 91 */ NoSymbol
, NoSymbol
,
431 /* 85 92 */ NoSymbol
, NoSymbol
,
432 /* 86 93 */ NoSymbol
, NoSymbol
,
433 /* 87 94 */ XK_F11
, NoSymbol
,
434 /* 88 95 */ XK_F12
, NoSymbol
,
436 /* These are remapped from the extended set (using ExtendMap) */
438 /* 89 96 */ XK_Control_R
, NoSymbol
,
439 /* 90 97 */ XK_KP_Enter
, NoSymbol
,
440 /* 91 98 */ XK_KP_Divide
, NoSymbol
,
441 /* 92 99 */ XK_Sys_Req
, XK_Print
,
442 /* 93 100 */ XK_Alt_R
, XK_Meta_R
,
443 /* 94 101 */ XK_Num_Lock
, NoSymbol
,
444 /* 95 102 */ XK_Home
, NoSymbol
,
445 /* 96 103 */ XK_Up
, NoSymbol
,
446 /* 97 104 */ XK_Page_Up
, NoSymbol
,
447 /* 98 105 */ XK_Left
, NoSymbol
,
448 /* 99 106 */ XK_Right
, NoSymbol
,
449 /* 100 107 */ XK_End
, NoSymbol
,
450 /* 101 108 */ XK_Down
, NoSymbol
,
451 /* 102 109 */ XK_Page_Down
, NoSymbol
,
452 /* 103 110 */ XK_Insert
, NoSymbol
,
453 /* 104 111 */ XK_Delete
, NoSymbol
,
454 /* 105 112 */ XK_Super_L
, NoSymbol
,
455 /* 106 113 */ XK_Super_R
, NoSymbol
,
456 /* 107 114 */ XK_Menu
, NoSymbol
,
457 /* 108 115 */ NoSymbol
, NoSymbol
,
458 /* 109 116 */ NoSymbol
, NoSymbol
,
459 /* 110 117 */ NoSymbol
, NoSymbol
,
460 /* 111 118 */ NoSymbol
, NoSymbol
,
461 /* 112 119 */ NoSymbol
, NoSymbol
,
465 EvdevRead1 (int evdevPort
, void *closure
)
468 struct input_event events
[NUM_EVENTS
];
470 n
= read (evdevPort
, &events
, NUM_EVENTS
* sizeof (struct input_event
));
473 n
/= sizeof (struct input_event
);
474 for (i
= 0; i
< n
; i
++)
476 switch (events
[i
].type
) {
481 if (events
[i
].code
< 0x100)
482 ErrorF ("key %d %d xk %d\n", events
[i
].code
, events
[i
].value
, xk
);
484 ErrorF ("key 0x%x %d xk %d\n", events
[i
].code
, events
[i
].value
, xk
);
485 if (events
[i
].value
== 2) {
486 //KdEnqueueKeyboardEvent (xk, 0);
487 KdEnqueueKeyboardEvent (xk
, 0);
489 KdEnqueueKeyboardEvent (xk
, !events
[i
].value
);
495 char *kdefaultEvdev1
[] = {
497 // "/dev/input/event1",
498 // "/dev/input/event2",
499 // "/dev/input/event3",
500 // "/dev/input/event4",
501 // "/dev/input/event5",
504 #define NUM_DEFAULT_EVDEV1 (sizeof (kdefaultEvdev1) / sizeof (kdefaultEvdev1[0]))
515 EvdevInputType
= KdAllocInputType ();
517 for (i
= 0; i
< NUM_DEFAULT_EVDEV
; i
++)
519 fd
= open (kdefaultEvdev1
[i
], 2);
522 ioctl(fd
, EVIOCGRAB
, 1);
524 ioctl(fd
, EVIOCGNAME(sizeof(name
)), name
);
525 ErrorF("Name is %s\n", name
);
526 ioctl(fd
, EVIOCGPHYS(sizeof(name
)), name
);
527 ErrorF("Phys Loc is %s\n", name
);
528 ioctl(fd
, EVIOCGUNIQ(sizeof(name
)), name
);
529 ErrorF("Unique is %s\n", name
);
535 unsigned long ev
[NBITS(EV_MAX
)];
538 if (ioctl (fd
, EVIOCGBIT(0 /*EV*/, sizeof (ev
)), ev
) < 0)
540 perror ("EVIOCGBIT 0");
544 ke
= xalloc (sizeof (Kevdev
));
550 memset (ke
, '\0', sizeof (Kevdev
));
551 if (ISBITSET (ev
, EV_KEY
))
553 if (ioctl (fd
, EVIOCGBIT (EV_KEY
, sizeof (ke
->keybits
)),
556 perror ("EVIOCGBIT EV_KEY");
562 if (ISBITSET (ev
, EV_REL
))
564 if (ioctl (fd
, EVIOCGBIT (EV_REL
, sizeof (ke
->relbits
)),
567 perror ("EVIOCGBIT EV_REL");
572 for (ke
->max_rel
= REL_MAX
; ke
->max_rel
>= 0; ke
->max_rel
--)
573 if (ISBITSET(ke
->relbits
, ke
->max_rel
))
576 if (ISBITSET (ev
, EV_ABS
))
580 if (ioctl (fd
, EVIOCGBIT (EV_ABS
, sizeof (ke
->absbits
)),
583 perror ("EVIOCGBIT EV_ABS");
588 for (ke
->max_abs
= ABS_MAX
; ke
->max_abs
>= 0; ke
->max_abs
--)
589 if (ISBITSET(ke
->absbits
, ke
->max_abs
))
591 for (i
= 0; i
<= ke
->max_abs
; i
++)
593 if (ISBITSET (ke
->absbits
, i
))
594 if (ioctl (fd
, EVIOCGABS(i
), &ke
->absinfo
[i
]) < 0)
596 perror ("EVIOCGABS");
599 ke
->prevabs
[i
] = ABS_UNSET
;
601 if (i
<= ke
->max_abs
)
608 if (KdRegisterFd (EvdevInputType
, fd
, EvdevRead1
, NULL
))
615 static void EvdevKbdLoad(void)
620 memcpy (kdKeymap
, evdevKeymap
, sizeof (evdevKeymap
));
629 EvdevKbdLeds (int leds
)
634 static void EvdevKbdBell(int volume
, int pitch
, int duration
)
639 KdKeyboardFuncs LinuxEvdevKeyboardFuncs
= {