Changes in uspace/srv/hid/input/generic/input.c [b72efe8:5da7199] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/input/generic/input.c
rb72efe8 r5da7199 38 38 39 39 #include <adt/list.h> 40 #include <bool.h> 40 41 #include <ipc/services.h> 41 42 #include <ipc/input.h> … … 46 47 #include <stdio.h> 47 48 #include <ns.h> 48 #include <ns_obsolete.h>49 49 #include <async.h> 50 #include <async_obsolete.h>51 50 #include <errno.h> 52 51 #include <adt/fifo.h> 53 52 #include <io/console.h> 54 53 #include <io/keycode.h> 55 #include < devmap.h>54 #include <loc.h> 56 55 #include <input.h> 57 56 #include <kbd.h> 58 57 #include <kbd_port.h> 59 58 #include <kbd_ctl.h> 59 #include <mouse_proto.h> 60 60 #include <layout.h> 61 61 #include <mouse.h> 62 62 63 // FIXME: remove this header 64 #include <kernel/ipc/ipc_methods.h> 65 66 /* In microseconds */ 67 #define DISCOVERY_POLL_INTERVAL (10*1000*1000) 68 69 static void kbd_devs_yield(void); 70 static void kbd_devs_reclaim(void); 71 72 static void input_event_key(int, unsigned int, unsigned, wchar_t); 73 74 int client_phone = -1; 75 76 /** List of keyboard devices */ 77 static list_t kbd_devs; 78 79 /** List of mouse devices */ 80 list_t mouse_devs; 81 82 bool irc_service = false; 83 int irc_phone = -1; 84 85 #define NUM_LAYOUTS 3 63 #define NUM_LAYOUTS 3 86 64 87 65 static layout_ops_t *layout[NUM_LAYOUTS] = { … … 91 69 }; 92 70 93 void kbd_push_scancode(kbd_dev_t *kdev, int scancode) 94 { 95 /* printf("scancode: 0x%x\n", scancode);*/ 96 (*kdev->ctl_ops->parse_scancode)(scancode); 97 } 98 99 void kbd_push_ev(kbd_dev_t *kdev, int type, unsigned int key) 71 static void kbd_devs_yield(void); 72 static void kbd_devs_reclaim(void); 73 74 async_sess_t *client_sess = NULL; 75 76 /** List of keyboard devices */ 77 static list_t kbd_devs; 78 79 /** List of mouse devices */ 80 static list_t mouse_devs; 81 82 bool irc_service = false; 83 async_sess_t *irc_sess = NULL; 84 85 void kbd_push_data(kbd_dev_t *kdev, sysarg_t data) 86 { 87 (*kdev->ctl_ops->parse)(data); 88 } 89 90 void mouse_push_data(mouse_dev_t *mdev, sysarg_t data) 91 { 92 (*mdev->proto_ops->parse)(data); 93 } 94 95 void kbd_push_event(kbd_dev_t *kdev, int type, unsigned int key) 100 96 { 101 97 kbd_event_t ev; 102 unsigned mod_mask;103 98 unsigned int mod_mask; 99 104 100 switch (key) { 105 101 case KC_LCTRL: mod_mask = KM_LCTRL; break; … … 111 107 default: mod_mask = 0; break; 112 108 } 113 109 114 110 if (mod_mask != 0) { 115 111 if (type == KEY_PRESS) … … 118 114 kdev->mods = kdev->mods & ~mod_mask; 119 115 } 120 116 121 117 switch (key) { 122 118 case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break; … … 125 121 default: mod_mask = 0; break; 126 122 } 127 123 128 124 if (mod_mask != 0) { 129 125 if (type == KEY_PRESS) { … … 135 131 kdev->mods = kdev->mods ^ (mod_mask & ~kdev->lock_keys); 136 132 kdev->lock_keys = kdev->lock_keys | mod_mask; 137 133 138 134 /* Update keyboard lock indicator lights. */ 139 135 (*kdev->ctl_ops->set_ind)(kdev, kdev->mods); … … 142 138 } 143 139 } 144 /* 145 printf("type: %d\n", type); 146 printf("mods: 0x%x\n", mods); 147 printf("keycode: %u\n", key); 148 */ 140 149 141 if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) && 150 142 key == KC_F1) { 151 143 layout_destroy(kdev->active_layout); 152 144 kdev->active_layout = layout_create(layout[0]); 153 145 return; 154 146 } 155 147 156 148 if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) && 157 149 key == KC_F2) { 158 150 layout_destroy(kdev->active_layout); 159 151 kdev->active_layout = layout_create(layout[1]); 160 152 return; 161 153 } 162 154 163 155 if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) && 164 156 key == KC_F3) { 165 157 layout_destroy(kdev->active_layout); 166 158 kdev->active_layout = layout_create(layout[2]); 167 159 return; 168 160 } 169 161 170 162 ev.type = type; 171 163 ev.key = key; 172 164 ev.mods = kdev->mods; 173 165 174 166 ev.c = layout_parse_ev(kdev->active_layout, &ev); 175 input_event_key(ev.type, ev.key, ev.mods, ev.c); 176 } 177 178 /** Key has been pressed or released. */ 179 static void input_event_key(int type, unsigned int key, unsigned mods, 180 wchar_t c) 181 { 182 async_obsolete_msg_4(client_phone, INPUT_EVENT_KEY, type, key, 183 mods, c); 167 168 async_exch_t *exch = async_exchange_begin(client_sess); 169 async_msg_4(exch, INPUT_EVENT_KEY, ev.type, ev.key, ev.mods, ev.c); 170 async_exchange_end(exch); 184 171 } 185 172 186 173 /** Mouse pointer has moved. */ 187 void input_event_move(int dx, int dy) 188 { 189 async_obsolete_msg_2(client_phone, INPUT_EVENT_MOVE, dx, dy); 174 void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy) 175 { 176 async_exch_t *exch = async_exchange_begin(client_sess); 177 async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy); 178 async_exchange_end(exch); 190 179 } 191 180 192 181 /** Mouse button has been pressed. */ 193 void input_event_button(int bnum, int press) 194 { 195 async_obsolete_msg_2(client_phone, INPUT_EVENT_BUTTON, bnum, press); 182 void mouse_push_event_button(mouse_dev_t *mdev, int bnum, int press) 183 { 184 async_exch_t *exch = async_exchange_begin(client_sess); 185 async_msg_2(exch, INPUT_EVENT_BUTTON, bnum, press); 186 async_exchange_end(exch); 196 187 } 197 188 198 189 static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 199 190 { 200 ipc_callid_t callid;201 ipc_call_t call;202 int retval;203 204 191 async_answer_0(iid, EOK); 205 192 206 193 while (true) { 207 callid = async_get_call(&call); 194 ipc_call_t call; 195 ipc_callid_t callid = async_get_call(&call); 208 196 209 197 if (!IPC_GET_IMETHOD(call)) { 210 if (client_ phone != -1) {211 async_ obsolete_hangup(client_phone);212 client_ phone = -1;198 if (client_sess != NULL) { 199 async_hangup(client_sess); 200 client_sess = NULL; 213 201 } 214 202 … … 217 205 } 218 206 219 switch (IPC_GET_IMETHOD(call)) { 220 case IPC_M_CONNECT_TO_ME: 221 if (client_phone != -1) { 222 retval = ELIMIT; 207 async_sess_t *sess = 208 async_callback_receive_start(EXCHANGE_SERIALIZE, &call); 209 if (sess != NULL) { 210 if (client_sess == NULL) { 211 client_sess = sess; 212 async_answer_0(callid, EOK); 213 } else 214 async_answer_0(callid, ELIMIT); 215 } else { 216 switch (IPC_GET_IMETHOD(call)) { 217 case INPUT_YIELD: 218 kbd_devs_yield(); 219 async_answer_0(callid, EOK); 223 220 break; 221 case INPUT_RECLAIM: 222 kbd_devs_reclaim(); 223 async_answer_0(callid, EOK); 224 break; 225 default: 226 async_answer_0(callid, EINVAL); 224 227 } 225 client_phone = IPC_GET_ARG5(call);226 retval = 0;227 break;228 case INPUT_YIELD:229 kbd_devs_yield();230 retval = 0;231 break;232 case INPUT_RECLAIM:233 kbd_devs_reclaim();234 retval = 0;235 break;236 default:237 retval = EINVAL;238 228 } 239 async_answer_0(callid, retval); 240 } 229 } 241 230 } 242 231 243 232 static kbd_dev_t *kbd_dev_new(void) 244 233 { 245 kbd_dev_t *kdev; 246 247 kdev = calloc(1, sizeof(kbd_dev_t)); 234 kbd_dev_t *kdev = calloc(1, sizeof(kbd_dev_t)); 248 235 if (kdev == NULL) { 249 printf( NAME ": Error allocating keyboard device. "250 "Out of memory.\n" );236 printf("%s: Error allocating keyboard device. " 237 "Out of memory.\n", NAME); 251 238 return NULL; 252 239 } 253 240 254 241 link_initialize(&kdev->kbd_devs); 255 242 256 243 kdev->mods = KM_NUM_LOCK; 257 244 kdev->lock_keys = 0; 258 245 kdev->active_layout = layout_create(layout[0]); 259 246 260 247 return kdev; 248 } 249 250 static mouse_dev_t *mouse_dev_new(void) 251 { 252 mouse_dev_t *mdev = calloc(1, sizeof(mouse_dev_t)); 253 if (mdev == NULL) { 254 printf("%s: Error allocating keyboard device. " 255 "Out of memory.\n", NAME); 256 return NULL; 257 } 258 259 link_initialize(&mdev->mouse_devs); 260 261 return mdev; 261 262 } 262 263 … … 264 265 static void kbd_add_dev(kbd_port_ops_t *port, kbd_ctl_ops_t *ctl) 265 266 { 266 kbd_dev_t *kdev; 267 268 kdev = kbd_dev_new(); 267 kbd_dev_t *kdev = kbd_dev_new(); 269 268 if (kdev == NULL) 270 269 return; 271 270 272 271 kdev->port_ops = port; 273 272 kdev->ctl_ops = ctl; 274 kdev-> dev_path = NULL;275 273 kdev->svc_id = 0; 274 276 275 /* Initialize port driver. */ 277 276 if ((*kdev->port_ops->init)(kdev) != 0) 278 277 goto fail; 279 278 280 279 /* Initialize controller driver. */ 281 280 if ((*kdev->ctl_ops->init)(kdev) != 0) { … … 283 282 goto fail; 284 283 } 285 284 286 285 list_append(&kdev->kbd_devs, &kbd_devs); 287 286 return; 287 288 288 fail: 289 289 free(kdev); 290 290 } 291 291 292 /** Add new legacy mouse device. */ 293 static void mouse_add_dev(mouse_port_ops_t *port, mouse_proto_ops_t *proto) 294 { 295 mouse_dev_t *mdev = mouse_dev_new(); 296 if (mdev == NULL) 297 return; 298 299 mdev->port_ops = port; 300 mdev->proto_ops = proto; 301 mdev->svc_id = 0; 302 303 /* Initialize port driver. */ 304 if ((*mdev->port_ops->init)(mdev) != 0) 305 goto fail; 306 307 /* Initialize protocol driver. */ 308 if ((*mdev->proto_ops->init)(mdev) != 0) { 309 /* XXX Uninit port */ 310 goto fail; 311 } 312 313 list_append(&mdev->mouse_devs, &mouse_devs); 314 return; 315 316 fail: 317 free(mdev); 318 } 319 292 320 /** Add new kbdev device. 293 321 * 294 * @param dev_path Filesystem path to the device (/dev/class/...) 322 * @param service_id Service ID of the keyboard device 323 * 295 324 */ 296 static int kbd_add_kbdev(const char *dev_path) 297 { 298 kbd_dev_t *kdev; 299 300 kdev = kbd_dev_new(); 325 static int kbd_add_kbdev(service_id_t service_id, kbd_dev_t **kdevp) 326 { 327 kbd_dev_t *kdev = kbd_dev_new(); 301 328 if (kdev == NULL) 302 329 return -1; 303 304 kdev-> dev_path = dev_path;330 331 kdev->svc_id = service_id; 305 332 kdev->port_ops = NULL; 306 333 kdev->ctl_ops = &kbdev_ctl; 307 334 335 int rc = loc_service_get_name(service_id, &kdev->svc_name); 336 if (rc != EOK) { 337 kdev->svc_name = NULL; 338 goto fail; 339 } 340 308 341 /* Initialize controller driver. */ 309 342 if ((*kdev->ctl_ops->init)(kdev) != 0) { 310 343 goto fail; 311 344 } 312 345 313 346 list_append(&kdev->kbd_devs, &kbd_devs); 347 *kdevp = kdev; 314 348 return EOK; 349 315 350 fail: 351 if (kdev->svc_name != NULL) 352 free(kdev->svc_name); 316 353 free(kdev); 354 return -1; 355 } 356 357 /** Add new mousedev device. 358 * 359 * @param service_id Service ID of the mouse device 360 * 361 */ 362 static int mouse_add_mousedev(service_id_t service_id, mouse_dev_t **mdevp) 363 { 364 mouse_dev_t *mdev = mouse_dev_new(); 365 if (mdev == NULL) 366 return -1; 367 368 mdev->svc_id = service_id; 369 mdev->port_ops = NULL; 370 mdev->proto_ops = &mousedev_proto; 371 372 int rc = loc_service_get_name(service_id, &mdev->svc_name); 373 if (rc != EOK) { 374 mdev->svc_name = NULL; 375 goto fail; 376 } 377 378 /* Initialize controller driver. */ 379 if ((*mdev->proto_ops->init)(mdev) != 0) { 380 goto fail; 381 } 382 383 list_append(&mdev->mouse_devs, &mouse_devs); 384 *mdevp = mdev; 385 return EOK; 386 387 fail: 388 free(mdev); 317 389 return -1; 318 390 } … … 350 422 #endif 351 423 #if defined(MACHINE_msim) 352 kbd_add_dev(&msim_port, & pc_ctl);424 kbd_add_dev(&msim_port, &stty_ctl); 353 425 #endif 354 426 #if (defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)) && defined(CONFIG_FB) … … 364 436 kbd_add_dev(&niagara_port, &stty_ctl); 365 437 #endif 366 #if defined(UARCH_sparc64) && defined(MACHINE_serengeti)367 kbd_add_dev(&sgcn_port, &stty_ctl);368 #endif369 438 #if defined(UARCH_sparc64) && defined(MACHINE_generic) 370 kbd_add_dev(&z8530_port, &sun_ctl);371 439 kbd_add_dev(&ns16550_port, &sun_ctl); 372 440 #endif 373 441 /* Silence warning on abs32le about kbd_add_dev() being unused */ 374 442 (void) kbd_add_dev; 443 } 444 445 /** Add legacy drivers/devices. */ 446 static void mouse_add_legacy_devs(void) 447 { 448 /* 449 * Need to add these drivers based on config unless we can probe 450 * them automatically. 451 */ 452 #if defined(UARCH_amd64) 453 mouse_add_dev(&chardev_mouse_port, &ps2_proto); 454 #endif 455 #if defined(UARCH_ia32) 456 mouse_add_dev(&chardev_mouse_port, &ps2_proto); 457 #endif 458 #if defined(MACHINE_i460GX) 459 mouse_add_dev(&chardev_mouse_port, &ps2_proto); 460 #endif 461 #if defined(UARCH_ppc32) 462 mouse_add_dev(&adb_mouse_port, &adb_proto); 463 #endif 464 /* Silence warning on abs32le about mouse_add_dev() being unused */ 465 (void) mouse_add_dev; 375 466 } 376 467 … … 381 472 kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t, 382 473 kbd_devs); 383 474 384 475 /* Yield port */ 385 476 if (kdev->port_ops != NULL) … … 394 485 kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t, 395 486 kbd_devs); 396 487 397 488 /* Reclaim port */ 398 489 if (kdev->port_ops != NULL) … … 401 492 } 402 493 403 /** Periodically check for new input devices. 404 * 405 * Looks under /dev/class/keyboard and /dev/class/mouse. 406 * 407 * @param arg Ignored 408 */ 409 static int dev_discovery_fibril(void *arg) 410 { 411 char *dev_path; 412 size_t kbd_id = 1; 413 size_t mouse_id = 1; 494 static int dev_check_new_kbdevs(void) 495 { 496 category_id_t keyboard_cat; 497 service_id_t *svcs; 498 size_t count, i; 499 bool already_known; 414 500 int rc; 415 416 while (true) { 417 async_usleep(DISCOVERY_POLL_INTERVAL); 418 419 /* 420 * Check for new keyboard device 421 */ 422 rc = asprintf(&dev_path, "/dev/class/keyboard\\%zu", kbd_id); 423 if (rc < 0) 424 continue; 425 426 if (kbd_add_kbdev(dev_path) == EOK) { 427 printf(NAME ": Connected keyboard device '%s'\n", 428 dev_path); 429 430 /* XXX Handle device removal */ 431 ++kbd_id; 501 502 rc = loc_category_get_id("keyboard", &keyboard_cat, IPC_FLAG_BLOCKING); 503 if (rc != EOK) { 504 printf("%s: Failed resolving category 'keyboard'.\n", NAME); 505 return ENOENT; 506 } 507 508 /* 509 * Check for new keyboard devices 510 */ 511 rc = loc_category_get_svcs(keyboard_cat, &svcs, &count); 512 if (rc != EOK) { 513 printf("%s: Failed getting list of keyboard devices.\n", 514 NAME); 515 return EIO; 516 } 517 518 for (i = 0; i < count; i++) { 519 already_known = false; 520 521 /* Determine whether we already know this device. */ 522 list_foreach(kbd_devs, kdev_link) { 523 kbd_dev_t *kdev = list_get_instance(kdev_link, 524 kbd_dev_t, kbd_devs); 525 if (kdev->svc_id == svcs[i]) { 526 already_known = true; 527 break; 528 } 432 529 } 433 434 free(dev_path); 435 436 /* 437 * Check for new mouse device 438 */ 439 rc = asprintf(&dev_path, "/dev/class/mouse\\%zu", mouse_id); 440 if (rc < 0) 441 continue; 442 443 if (mouse_add_dev(dev_path) == EOK) { 444 printf(NAME ": Connected mouse device '%s'\n", 445 dev_path); 446 447 /* XXX Handle device removal */ 448 ++mouse_id; 530 531 if (!already_known) { 532 kbd_dev_t *kdev; 533 if (kbd_add_kbdev(svcs[i], &kdev) == EOK) { 534 printf("%s: Connected keyboard device '%s'\n", 535 NAME, kdev->svc_name); 536 } 449 537 } 450 451 free(dev_path); 452 } 453 538 } 539 540 free(svcs); 541 542 /* XXX Handle device removal */ 543 454 544 return EOK; 455 545 } 456 546 457 /** Start a fibril for discovering new devices. */ 458 static void input_start_dev_discovery(void) 459 { 460 fid_t fid; 461 462 fid = fibril_create(dev_discovery_fibril, NULL); 463 if (!fid) { 464 printf(NAME ": Failed to create device discovery fibril.\n"); 465 return; 466 } 467 468 fibril_add_ready(fid); 547 static int dev_check_new_mousedevs(void) 548 { 549 category_id_t mouse_cat; 550 service_id_t *svcs; 551 size_t count, i; 552 bool already_known; 553 int rc; 554 555 rc = loc_category_get_id("mouse", &mouse_cat, IPC_FLAG_BLOCKING); 556 if (rc != EOK) { 557 printf("%s: Failed resolving category 'mouse'.\n", NAME); 558 return ENOENT; 559 } 560 561 /* 562 * Check for new mouse devices 563 */ 564 rc = loc_category_get_svcs(mouse_cat, &svcs, &count); 565 if (rc != EOK) { 566 printf("%s: Failed getting list of mouse devices.\n", 567 NAME); 568 return EIO; 569 } 570 571 for (i = 0; i < count; i++) { 572 already_known = false; 573 574 /* Determine whether we already know this device. */ 575 list_foreach(mouse_devs, mdev_link) { 576 mouse_dev_t *mdev = list_get_instance(mdev_link, 577 mouse_dev_t, mouse_devs); 578 if (mdev->svc_id == svcs[i]) { 579 already_known = true; 580 break; 581 } 582 } 583 584 if (!already_known) { 585 mouse_dev_t *mdev; 586 if (mouse_add_mousedev(svcs[i], &mdev) == EOK) { 587 printf("%s: Connected mouse device '%s'\n", 588 NAME, mdev->svc_name); 589 } 590 } 591 } 592 593 free(svcs); 594 595 /* XXX Handle device removal */ 596 597 return EOK; 598 } 599 600 static int dev_check_new(void) 601 { 602 int rc; 603 604 rc = dev_check_new_kbdevs(); 605 if (rc != EOK) 606 return rc; 607 608 rc = dev_check_new_mousedevs(); 609 if (rc != EOK) 610 return rc; 611 612 return EOK; 613 } 614 615 static void cat_change_cb(void) 616 { 617 dev_check_new(); 618 } 619 620 /** Start listening for new devices. */ 621 static int input_start_dev_discovery(void) 622 { 623 int rc; 624 625 rc = loc_register_cat_change_cb(cat_change_cb); 626 if (rc != EOK) { 627 printf("%s: Failed registering callback for device discovery. " 628 "(%d)\n", NAME, rc); 629 return rc; 630 } 631 632 return dev_check_new(); 469 633 } 470 634 … … 473 637 printf("%s: HelenOS input service\n", NAME); 474 638 475 sysarg_t fhc;476 639 sysarg_t obio; 477 640 … … 479 642 list_initialize(&mouse_devs); 480 643 481 if (((sysinfo_get_value("kbd.cir.fhc", &fhc) == EOK) && (fhc)) 482 || ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio))) 644 if ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio)) 483 645 irc_service = true; 484 646 485 647 if (irc_service) { 486 while (irc_phone < 0) 487 irc_phone = service_obsolete_connect_blocking(SERVICE_IRC, 0, 0); 648 while (irc_sess == NULL) 649 irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE, 650 SERVICE_IRC, 0, 0); 488 651 } 489 652 490 653 /* Add legacy keyboard devices. */ 491 654 kbd_add_legacy_devs(); 492 493 /* Add legacy (devmap-style) mouse device. */494 (void) mouse_add_dev("/dev/hid_in/mouse");655 656 /* Add legacy mouse devices. */ 657 mouse_add_legacy_devs(); 495 658 496 659 /* Register driver */ 497 int rc = devmap_driver_register(NAME, client_connection);660 int rc = loc_server_register(NAME, client_connection); 498 661 if (rc < 0) { 499 printf("%s: Unable to register driver (%d)\n", NAME, rc);662 printf("%s: Unable to register server (%d)\n", NAME, rc); 500 663 return -1; 501 664 } 502 665 503 char kbd[ DEVMAP_NAME_MAXLEN + 1];504 snprintf(kbd, DEVMAP_NAME_MAXLEN, "%s/%s", NAMESPACE, NAME);505 506 devmap_handle_t devmap_handle;507 if ( devmap_device_register(kbd, &devmap_handle) != EOK) {508 printf("%s: Unable to register device %s\n", NAME, kbd);666 char kbd[LOC_NAME_MAXLEN + 1]; 667 snprintf(kbd, LOC_NAME_MAXLEN, "%s/%s", NAMESPACE, NAME); 668 669 service_id_t service_id; 670 if (loc_service_register(kbd, &service_id) != EOK) { 671 printf("%s: Unable to register service %s\n", NAME, kbd); 509 672 return -1; 510 673 } 511 674 512 675 /* Start looking for new input devices */ 513 676 input_start_dev_discovery(); 514 515 printf( NAME ": Accepting connections\n");677 678 printf("%s: Accepting connections\n", NAME); 516 679 async_manager(); 517 680 518 681 /* Not reached. */ 519 682 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.