1/* 2 * Copyright © 2004 Keith Packard 3 * 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. 13 * 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. 21 */ 22 23#ifdef HAVE_CONFIG_H 24#include <kdrive-config.h> 25#endif 26#include <errno.h> 27#include <linux/input.h> 28#include <X11/X.h> 29#include <X11/Xproto.h> 30#include <X11/Xpoll.h> 31#include "inputstr.h" 32#include "scrnintstr.h" 33#include "kdrive.h" 34 35#define NUM_EVENTS 128 36#define ABS_UNSET -65535 37 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)) 44 45typedef struct _kevdev { 46 /* current device state */ 47 int rel[REL_MAX + 1]; 48 int abs[ABS_MAX + 1]; 49 int prevabs[ABS_MAX + 1]; 50 long key[NBITS(KEY_MAX + 1)]; 51 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]; 57 int max_rel; 58 int max_abs; 59 60 int fd; 61} Kevdev; 62 63static void 64EvdevPtrBtn (KdPointerInfo *pi, struct input_event *ev) 65{ 66 int flags = KD_MOUSE_DELTA | pi->buttonState; 67 68 if (ev->code >= BTN_MOUSE && ev->code < BTN_JOYSTICK) { 69 switch (ev->code) { 70 case BTN_LEFT: 71 if (ev->value == 1) 72 flags |= KD_BUTTON_1; 73 else 74 flags &= ~KD_BUTTON_1; 75 break; 76 case BTN_MIDDLE: 77 if (ev->value == 1) 78 flags |= KD_BUTTON_2; 79 else 80 flags &= ~KD_BUTTON_2; 81 break; 82 case BTN_RIGHT: 83 if (ev->value == 1) 84 flags |= KD_BUTTON_3; 85 else 86 flags &= ~KD_BUTTON_3; 87 break; 88 default: 89 /* Unknow button */ 90 break; 91 } 92 93 KdEnqueuePointerEvent (pi, flags, 0, 0, 0); 94 } 95} 96static void 97EvdevPtrMotion (KdPointerInfo *pi, struct input_event *ev) 98{ 99 Kevdev *ke = pi->driverPrivate; 100 int i; 101 int flags = KD_MOUSE_DELTA | pi->buttonState; 102 103 for (i = 0; i <= ke->max_rel; i++) 104 if (ke->rel[i]) 105 { 106 int a; 107 for (a = 0; a <= ke->max_rel; a++) 108 { 109 if (ISBITSET (ke->relbits, a)) 110 { 111 if (a == 0) 112 KdEnqueuePointerEvent(pi, flags, ke->rel[a], 0, 0); 113 else if (a == 1) 114 KdEnqueuePointerEvent(pi, flags, 0, ke->rel[a], 0); 115 } 116 ke->rel[a] = 0; 117 } 118 break; 119 } 120 for (i = 0; i < ke->max_abs; i++) 121 if (ke->abs[i] != ke->prevabs[i]) 122 { 123 int a; 124 ErrorF ("abs"); 125 for (a = 0; a <= ke->max_abs; a++) 126 { 127 if (ISBITSET (ke->absbits, a)) 128 ErrorF (" %d=%d", a, ke->abs[a]); 129 ke->prevabs[a] = ke->abs[a]; 130 } 131 ErrorF ("\n"); 132 break; 133 } 134 135 if (ev->code == REL_WHEEL) { 136 for (i = 0; i < abs (ev->value); i++) 137 { 138 if (ev->value > 0) 139 flags |= KD_BUTTON_4; 140 else 141 flags |= KD_BUTTON_5; 142 143 KdEnqueuePointerEvent (pi, flags, 0, 0, 0); 144 145 if (ev->value > 0) 146 flags &= ~KD_BUTTON_4; 147 else 148 flags &= ~KD_BUTTON_5; 149 150 KdEnqueuePointerEvent (pi, flags, 0, 0, 0); 151 } 152 } 153 154} 155 156static void 157EvdevPtrRead (int evdevPort, void *closure) 158{ 159 KdPointerInfo *pi = closure; 160 Kevdev *ke = pi->driverPrivate; 161 int i; 162 struct input_event events[NUM_EVENTS]; 163 int n; 164 165 n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event)); 166 if (n <= 0) { 167 if (errno == ENODEV) 168 DeleteInputDeviceRequest(pi->dixdev); 169 return; 170 } 171 172 n /= sizeof (struct input_event); 173 for (i = 0; i < n; i++) 174 { 175 switch (events[i].type) { 176 case EV_SYN: 177 break; 178 case EV_KEY: 179 EvdevPtrBtn (pi, &events[i]); 180 break; 181 case EV_REL: 182 ke->rel[events[i].code] += events[i].value; 183 EvdevPtrMotion (pi, &events[i]); 184 break; 185 case EV_ABS: 186 ke->abs[events[i].code] = events[i].value; 187 EvdevPtrMotion (pi, &events[i]); 188 break; 189 } 190 } 191} 192 193char *kdefaultEvdev[] = { 194 "/dev/input/event0", 195 "/dev/input/event1", 196 "/dev/input/event2", 197 "/dev/input/event3", 198}; 199 200#define NUM_DEFAULT_EVDEV (sizeof (kdefaultEvdev) / sizeof (kdefaultEvdev[0])) 201 202static Status 203EvdevPtrInit (KdPointerInfo *pi) 204{ 205 int i; 206 int fd; 207 208 if (!pi->path) { 209 for (i = 0; i < NUM_DEFAULT_EVDEV; i++) { 210 fd = open (kdefaultEvdev[i], 2); 211 if (fd >= 0) { 212 pi->path = strdup (kdefaultEvdev[i]); 213 break; 214 } 215 } 216 } 217 else { 218 fd = open (pi->path, O_RDWR); 219 if (fd < 0) { 220 ErrorF("Failed to open evdev device %s\n", pi->path); 221 return BadMatch; 222 } 223 } 224 225 close(fd); 226 227 pi->name = strdup("Evdev mouse"); 228 229 return Success; 230} 231 232static Status 233EvdevPtrEnable (KdPointerInfo *pi) 234{ 235 int fd; 236 unsigned long ev[NBITS(EV_MAX)]; 237 Kevdev *ke; 238 239 if (!pi || !pi->path) 240 return BadImplementation; 241 242 fd = open(pi->path, 2); 243 if (fd < 0) 244 return BadMatch; 245 246 if (ioctl (fd, EVIOCGRAB, 1) < 0) 247 perror ("Grabbing evdev mouse device failed"); 248 249 if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0) 250 { 251 perror ("EVIOCGBIT 0"); 252 close (fd); 253 return BadMatch; 254 } 255 ke = calloc(1, sizeof (Kevdev)); 256 if (!ke) 257 { 258 close (fd); 259 return BadAlloc; 260 } 261 if (ISBITSET (ev, EV_KEY)) 262 { 263 if (ioctl (fd, EVIOCGBIT (EV_KEY, sizeof (ke->keybits)), 264 ke->keybits) < 0) 265 { 266 perror ("EVIOCGBIT EV_KEY"); 267 free(ke); 268 close (fd); 269 return BadMatch; 270 } 271 } 272 if (ISBITSET (ev, EV_REL)) 273 { 274 if (ioctl (fd, EVIOCGBIT (EV_REL, sizeof (ke->relbits)), 275 ke->relbits) < 0) 276 { 277 perror ("EVIOCGBIT EV_REL"); 278 free(ke); 279 close (fd); 280 return BadMatch; 281 } 282 for (ke->max_rel = REL_MAX; ke->max_rel >= 0; ke->max_rel--) 283 if (ISBITSET(ke->relbits, ke->max_rel)) 284 break; 285 } 286 if (ISBITSET (ev, EV_ABS)) 287 { 288 int i; 289 290 if (ioctl (fd, EVIOCGBIT (EV_ABS, sizeof (ke->absbits)), 291 ke->absbits) < 0) 292 { 293 perror ("EVIOCGBIT EV_ABS"); 294 free(ke); 295 close (fd); 296 return BadMatch; 297 } 298 for (ke->max_abs = ABS_MAX; ke->max_abs >= 0; ke->max_abs--) 299 if (ISBITSET(ke->absbits, ke->max_abs)) 300 break; 301 for (i = 0; i <= ke->max_abs; i++) 302 { 303 if (ISBITSET (ke->absbits, i)) 304 if (ioctl (fd, EVIOCGABS(i), &ke->absinfo[i]) < 0) 305 { 306 perror ("EVIOCGABS"); 307 break; 308 } 309 ke->prevabs[i] = ABS_UNSET; 310 } 311 if (i <= ke->max_abs) 312 { 313 free(ke); 314 close (fd); 315 return BadValue; 316 } 317 } 318 if (!KdRegisterFd (fd, EvdevPtrRead, pi)) { 319 free(ke); 320 close (fd); 321 return BadAlloc; 322 } 323 pi->driverPrivate = ke; 324 ke->fd = fd; 325 326 return Success; 327} 328 329static void 330EvdevPtrDisable (KdPointerInfo *pi) 331{ 332 Kevdev *ke; 333 334 ke = pi->driverPrivate; 335 336 if (!pi || !pi->driverPrivate) 337 return; 338 339 KdUnregisterFd (pi, ke->fd, TRUE); 340 341 if (ioctl (ke->fd, EVIOCGRAB, 0) < 0) 342 perror ("Ungrabbing evdev mouse device failed"); 343 344 free(ke); 345 pi->driverPrivate = 0; 346} 347 348static void 349EvdevPtrFini (KdPointerInfo *pi) 350{ 351} 352 353 354/* 355 * Evdev keyboard functions 356 */ 357 358static void 359readMapping (KdKeyboardInfo *ki) 360{ 361 if (!ki) 362 return; 363 364 ki->minScanCode = 0; 365 ki->maxScanCode = 247; 366} 367 368static void 369EvdevKbdRead (int evdevPort, void *closure) 370{ 371 KdKeyboardInfo *ki = closure; 372 struct input_event events[NUM_EVENTS]; 373 int i, n; 374 375 n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event)); 376 if (n <= 0) { 377 if (errno == ENODEV) 378 DeleteInputDeviceRequest(ki->dixdev); 379 return; 380 } 381 382 n /= sizeof (struct input_event); 383 for (i = 0; i < n; i++) 384 { 385 if (events[i].type == EV_KEY) 386 KdEnqueueKeyboardEvent (ki, events[i].code, !events[i].value); 387/* FIXME: must implement other types of events 388 else 389 ErrorF("Event type (%d) not delivered\n", events[i].type); 390*/ 391 } 392} 393 394static Status 395EvdevKbdInit (KdKeyboardInfo *ki) 396{ 397 int fd; 398 399 if (!ki->path) { 400 ErrorF("Couldn't find evdev device path\n"); 401 return BadValue; 402 } 403 else { 404 fd = open (ki->path, O_RDWR); 405 if (fd < 0) { 406 ErrorF("Failed to open evdev device %s\n", ki->path); 407 return BadMatch; 408 } 409 } 410 411 close (fd); 412 413 ki->name = strdup("Evdev keyboard"); 414 415 readMapping(ki); 416 417 return Success; 418} 419 420static Status 421EvdevKbdEnable (KdKeyboardInfo *ki) 422{ 423 unsigned long ev[NBITS(EV_MAX)]; 424 Kevdev *ke; 425 int fd; 426 427 if (!ki || !ki->path) 428 return BadImplementation; 429 430 fd = open(ki->path, O_RDWR); 431 if (fd < 0) 432 return BadMatch; 433 434 if (ioctl (fd, EVIOCGRAB, 1) < 0) 435 perror ("Grabbing evdev keyboard device failed"); 436 437 if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0) { 438 perror ("EVIOCGBIT 0"); 439 close (fd); 440 return BadMatch; 441 } 442 443 ke = calloc(1, sizeof (Kevdev)); 444 if (!ke) { 445 close (fd); 446 return BadAlloc; 447 } 448 449 if (!KdRegisterFd (fd, EvdevKbdRead, ki)) { 450 free(ke); 451 close (fd); 452 return BadAlloc; 453 } 454 ki->driverPrivate = ke; 455 ke->fd = fd; 456 457 return Success; 458} 459 460static void 461EvdevKbdLeds (KdKeyboardInfo *ki, int leds) 462{ 463/* struct input_event event; 464 Kevdev *ke; 465 466 ki->driverPrivate = ke; 467 468 memset(&event, 0, sizeof(event)); 469 470 event.type = EV_LED; 471 event.code = LED_CAPSL; 472 event.value = leds & (1 << 0) ? 1 : 0; 473 write(ke->fd, (char *) &event, sizeof(event)); 474 475 event.type = EV_LED; 476 event.code = LED_NUML; 477 event.value = leds & (1 << 1) ? 1 : 0; 478 write(ke->fd, (char *) &event, sizeof(event)); 479 480 event.type = EV_LED; 481 event.code = LED_SCROLLL; 482 event.value = leds & (1 << 2) ? 1 : 0; 483 write(ke->fd, (char *) &event, sizeof(event)); 484 485 event.type = EV_LED; 486 event.code = LED_COMPOSE; 487 event.value = leds & (1 << 3) ? 1 : 0; 488 write(ke->fd, (char *) &event, sizeof(event)); 489*/ 490} 491 492static void 493EvdevKbdBell (KdKeyboardInfo *ki, int volume, int frequency, int duration) 494{ 495} 496 497static void 498EvdevKbdDisable (KdKeyboardInfo *ki) 499{ 500 Kevdev *ke; 501 502 ke = ki->driverPrivate; 503 504 if (!ki || !ki->driverPrivate) 505 return; 506 507 KdUnregisterFd (ki, ke->fd, TRUE); 508 509 if (ioctl (ke->fd, EVIOCGRAB, 0) < 0) 510 perror ("Ungrabbing evdev keyboard device failed"); 511 512 free(ke); 513 ki->driverPrivate = 0; 514} 515 516static void 517EvdevKbdFini (KdKeyboardInfo *ki) 518{ 519} 520 521KdPointerDriver LinuxEvdevMouseDriver = { 522 "evdev", 523 EvdevPtrInit, 524 EvdevPtrEnable, 525 EvdevPtrDisable, 526 EvdevPtrFini, 527 NULL, 528}; 529 530KdKeyboardDriver LinuxEvdevKeyboardDriver = { 531 "evdev", 532 EvdevKbdInit, 533 EvdevKbdEnable, 534 EvdevKbdLeds, 535 EvdevKbdBell, 536 EvdevKbdDisable, 537 EvdevKbdFini, 538 NULL, 539}; 540