Initial commit
[xorg_rtime.git] / xorg-server-1.4 / hw / xgl / egl / evdev.c
blobfff4524d17581846048bf2312dfa4a79f8e5874b
1 /*
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>
24 #define NEED_EVENTS
25 #include <errno.h>
26 #include <linux/input.h>
27 #include <X11/X.h>
28 #include <X11/Xproto.h>
29 #include <X11/Xpoll.h>
30 #define XK_PUBLISHING
31 #include <X11/keysym.h>
32 #include "inputstr.h"
33 #include "kkeymap.h"
34 #include "scrnintstr.h"
35 #include "xegl.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 */
52 int rel[REL_MAX + 1];
53 int abs[ABS_MAX + 1];
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];
62 int max_rel;
63 int max_abs;
64 } Kevdev;
66 static int flags = 0;
68 static void
69 EvdevMotion (KdMouseInfo *mi)
71 Kevdev *ke = mi->driver;
72 int i;
74 for (i = 0; i <= ke->max_rel; i++)
75 if (ke->rel[i])
77 KdEnqueueMouseEvent (mi, flags | KD_MOUSE_DELTA, ke->rel[0], ke->rel[1]);
78 int a;
79 // ErrorF ("rel");
80 for (a = 0; a <= ke->max_rel; a++)
82 // if (ISBITSET (ke->relbits, a))
83 // ErrorF (" %d=%d", a, ke->rel[a]);
84 ke->rel[a] = 0;
86 // ErrorF ("\n");
87 break;
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]);
93 int a;
94 // ErrorF ("abs");
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];
101 // ErrorF ("\n");
102 break;
106 static void
107 EvdevRead (int evdevPort, void *closure)
109 KdMouseInfo *mi = closure;
110 Kevdev *ke = mi->driver;
111 int i, n;
112 struct input_event events[NUM_EVENTS];
114 n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event));
115 if (n <= 0)
116 return;
117 n /= sizeof (struct input_event);
118 for (i = 0; i < n; i++)
120 switch (events[i].type) {
121 case EV_SYN:
122 break;
123 case EV_KEY:
124 EvdevMotion (mi);
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);
128 else
129 ErrorF ("key 0x%x %d\n", events[i].code, events[i].value);
131 if (events[i].value==1) {
132 switch (events[i].code) {
133 case BTN_LEFT:
134 flags |= KD_BUTTON_1;
135 break;
136 case BTN_RIGHT:
137 flags |= KD_BUTTON_3;
138 break;
139 case BTN_MIDDLE:
140 flags |= KD_BUTTON_2;
141 break;
142 case BTN_FORWARD:
143 flags |= KD_BUTTON_4;
144 break;
145 case BTN_BACK:
146 flags |= KD_BUTTON_5;
147 break;
150 else if (events[i].value==0) {
151 switch (events[i].code) {
152 case BTN_LEFT:
153 flags &= ~KD_BUTTON_1;
154 break;
155 case BTN_RIGHT:
156 flags &= ~KD_BUTTON_3;
157 break;
158 case BTN_MIDDLE:
159 flags &= ~KD_BUTTON_2;
160 break;
161 case BTN_FORWARD:
162 flags &= ~KD_BUTTON_4;
163 break;
164 case BTN_BACK:
165 flags &= ~KD_BUTTON_5;
166 break;
169 KdEnqueueMouseEvent (mi, KD_MOUSE_DELTA | flags, 0, 0);
170 break;
171 case EV_REL:
172 ke->rel[events[i].code] += events[i].value;
173 break;
174 case EV_ABS:
175 ke->abs[events[i].code] = events[i].value;
176 break;
179 EvdevMotion (mi);
182 int EvdevInputType;
184 char *kdefaultEvdev[] = {
185 // "/dev/input/event0",
186 "/dev/input/event1",
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]))
195 static Bool
196 EvdevInit (void)
198 int i;
199 int fd;
200 KdMouseInfo *mi, *next;
201 int n = 0;
202 char *prot;
203 char name[100];
205 if (!EvdevInputType)
206 EvdevInputType = KdAllocInputType ();
208 for (mi = kdMouseInfo; mi; mi = next)
210 next = mi->next;
211 prot = mi->prot;
212 if (mi->inputType)
213 continue;
214 if (!mi->name)
216 for (i = 0; i < NUM_DEFAULT_EVDEV; i++)
218 fd = open (kdefaultEvdev[i], 2);
219 if (fd >= 0)
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]);
231 break;
235 else
236 fd = open (mi->name, 2);
238 if (fd >= 0)
240 unsigned long ev[NBITS(EV_MAX)];
241 Kevdev *ke;
243 if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0)
245 perror ("EVIOCGBIT 0");
246 close (fd);
247 continue;
249 ke = xalloc (sizeof (Kevdev));
250 if (!ke)
252 close (fd);
253 continue;
255 memset (ke, '\0', sizeof (Kevdev));
256 if (ISBITSET (ev, EV_KEY))
258 if (ioctl (fd, EVIOCGBIT (EV_KEY, sizeof (ke->keybits)),
259 ke->keybits) < 0)
261 perror ("EVIOCGBIT EV_KEY");
262 xfree (ke);
263 close (fd);
264 continue;
267 if (ISBITSET (ev, EV_REL))
269 if (ioctl (fd, EVIOCGBIT (EV_REL, sizeof (ke->relbits)),
270 ke->relbits) < 0)
272 perror ("EVIOCGBIT EV_REL");
273 xfree (ke);
274 close (fd);
275 continue;
277 for (ke->max_rel = REL_MAX; ke->max_rel >= 0; ke->max_rel--)
278 if (ISBITSET(ke->relbits, ke->max_rel))
279 break;
281 if (ISBITSET (ev, EV_ABS))
283 int i;
285 if (ioctl (fd, EVIOCGBIT (EV_ABS, sizeof (ke->absbits)),
286 ke->absbits) < 0)
288 perror ("EVIOCGBIT EV_ABS");
289 xfree (ke);
290 close (fd);
291 continue;
293 for (ke->max_abs = ABS_MAX; ke->max_abs >= 0; ke->max_abs--)
294 if (ISBITSET(ke->absbits, ke->max_abs))
295 break;
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");
302 break;
304 ke->prevabs[i] = ABS_UNSET;
306 if (i <= ke->max_abs)
308 xfree (ke);
309 close (fd);
310 continue;
313 mi->driver = ke;
314 mi->inputType = EvdevInputType;
315 if (KdRegisterFd (EvdevInputType, fd, EvdevRead, (void *) mi))
316 n++;
319 return TRUE;
322 static void
323 EvdevFini (void)
325 KdMouseInfo *mi;
327 KdUnregisterFds (EvdevInputType, TRUE);
328 for (mi = kdMouseInfo; mi; mi = mi->next)
330 if (mi->inputType == EvdevInputType)
332 xfree (mi->driver);
333 mi->driver = 0;
334 mi->inputType = 0;
339 KdMouseFuncs LinuxEvdevMouseFuncs = {
340 EvdevInit,
341 EvdevFini,
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,
464 static void
465 EvdevRead1 (int evdevPort, void *closure)
467 int i, n, xk;
468 struct input_event events[NUM_EVENTS];
470 n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event));
471 if (n <= 0)
472 return;
473 n /= sizeof (struct input_event);
474 for (i = 0; i < n; i++)
476 switch (events[i].type) {
477 case EV_SYN:
478 break;
479 case EV_KEY:
480 xk = events[i].code;
481 if (events[i].code < 0x100)
482 ErrorF ("key %d %d xk %d\n", events[i].code, events[i].value, xk);
483 else
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);
488 } else
489 KdEnqueueKeyboardEvent (xk, !events[i].value);
490 break;
495 char *kdefaultEvdev1[] = {
496 "/dev/input/event0",
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]))
506 static Bool
507 EvdevKbdInit (void)
509 int i;
510 int fd;
511 int n = 0;
512 char name[100];
514 if (!EvdevInputType)
515 EvdevInputType = KdAllocInputType ();
517 for (i = 0; i < NUM_DEFAULT_EVDEV; i++)
519 fd = open (kdefaultEvdev1[i], 2);
520 if (fd >= 0)
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);
533 if (fd >= 0)
535 unsigned long ev[NBITS(EV_MAX)];
536 Kevdev *ke;
538 if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0)
540 perror ("EVIOCGBIT 0");
541 close (fd);
542 continue;
544 ke = xalloc (sizeof (Kevdev));
545 if (!ke)
547 close (fd);
548 continue;
550 memset (ke, '\0', sizeof (Kevdev));
551 if (ISBITSET (ev, EV_KEY))
553 if (ioctl (fd, EVIOCGBIT (EV_KEY, sizeof (ke->keybits)),
554 ke->keybits) < 0)
556 perror ("EVIOCGBIT EV_KEY");
557 xfree (ke);
558 close (fd);
559 continue;
562 if (ISBITSET (ev, EV_REL))
564 if (ioctl (fd, EVIOCGBIT (EV_REL, sizeof (ke->relbits)),
565 ke->relbits) < 0)
567 perror ("EVIOCGBIT EV_REL");
568 xfree (ke);
569 close (fd);
570 continue;
572 for (ke->max_rel = REL_MAX; ke->max_rel >= 0; ke->max_rel--)
573 if (ISBITSET(ke->relbits, ke->max_rel))
574 break;
576 if (ISBITSET (ev, EV_ABS))
578 int i;
580 if (ioctl (fd, EVIOCGBIT (EV_ABS, sizeof (ke->absbits)),
581 ke->absbits) < 0)
583 perror ("EVIOCGBIT EV_ABS");
584 xfree (ke);
585 close (fd);
586 continue;
588 for (ke->max_abs = ABS_MAX; ke->max_abs >= 0; ke->max_abs--)
589 if (ISBITSET(ke->absbits, ke->max_abs))
590 break;
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");
597 break;
599 ke->prevabs[i] = ABS_UNSET;
601 if (i <= ke->max_abs)
603 xfree (ke);
604 close (fd);
605 continue;
608 if (KdRegisterFd (EvdevInputType, fd, EvdevRead1, NULL))
609 n++;
612 return TRUE;
615 static void EvdevKbdLoad(void)
617 kdMinScanCode = 1;
618 kdMaxScanCode = 112;
619 kdKeymapWidth = 2;
620 memcpy (kdKeymap, evdevKeymap, sizeof (evdevKeymap));
623 static void
624 EvdevKbdFini (void)
628 static void
629 EvdevKbdLeds (int leds)
634 static void EvdevKbdBell(int volume, int pitch, int duration)
639 KdKeyboardFuncs LinuxEvdevKeyboardFuncs = {
640 EvdevKbdLoad,
641 EvdevKbdInit,
642 EvdevKbdLeds,
643 EvdevKbdBell,
644 EvdevKbdFini,