Changes in uspace/srv/hid/input/generic/input.c [5da7199:b72efe8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/input/generic/input.c
r5da7199 rb72efe8 38 38 39 39 #include <adt/list.h> 40 #include <bool.h>41 40 #include <ipc/services.h> 42 41 #include <ipc/input.h> … … 47 46 #include <stdio.h> 48 47 #include <ns.h> 48 #include <ns_obsolete.h> 49 49 #include <async.h> 50 #include <async_obsolete.h> 50 51 #include <errno.h> 51 52 #include <adt/fifo.h> 52 53 #include <io/console.h> 53 54 #include <io/keycode.h> 54 #include < loc.h>55 #include <devmap.h> 55 56 #include <input.h> 56 57 #include <kbd.h> 57 58 #include <kbd_port.h> 58 59 #include <kbd_ctl.h> 59 #include <mouse_proto.h>60 60 #include <layout.h> 61 61 #include <mouse.h> 62 62 63 #define NUM_LAYOUTS 3 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 64 86 65 87 static layout_ops_t *layout[NUM_LAYOUTS] = { … … 69 91 }; 70 92 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) 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) 96 100 { 97 101 kbd_event_t ev; 98 unsigned intmod_mask;99 102 unsigned mod_mask; 103 100 104 switch (key) { 101 105 case KC_LCTRL: mod_mask = KM_LCTRL; break; … … 107 111 default: mod_mask = 0; break; 108 112 } 109 113 110 114 if (mod_mask != 0) { 111 115 if (type == KEY_PRESS) … … 114 118 kdev->mods = kdev->mods & ~mod_mask; 115 119 } 116 120 117 121 switch (key) { 118 122 case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break; … … 121 125 default: mod_mask = 0; break; 122 126 } 123 127 124 128 if (mod_mask != 0) { 125 129 if (type == KEY_PRESS) { … … 131 135 kdev->mods = kdev->mods ^ (mod_mask & ~kdev->lock_keys); 132 136 kdev->lock_keys = kdev->lock_keys | mod_mask; 133 137 134 138 /* Update keyboard lock indicator lights. */ 135 139 (*kdev->ctl_ops->set_ind)(kdev, kdev->mods); … … 138 142 } 139 143 } 140 144 /* 145 printf("type: %d\n", type); 146 printf("mods: 0x%x\n", mods); 147 printf("keycode: %u\n", key); 148 */ 141 149 if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) && 142 150 key == KC_F1) { 143 151 layout_destroy(kdev->active_layout); 144 152 kdev->active_layout = layout_create(layout[0]); 145 153 return; 146 154 } 147 155 148 156 if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) && 149 157 key == KC_F2) { 150 158 layout_destroy(kdev->active_layout); 151 159 kdev->active_layout = layout_create(layout[1]); 152 160 return; 153 161 } 154 162 155 163 if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) && 156 164 key == KC_F3) { 157 165 layout_destroy(kdev->active_layout); 158 166 kdev->active_layout = layout_create(layout[2]); 159 167 return; 160 168 } 161 169 162 170 ev.type = type; 163 171 ev.key = key; 164 172 ev.mods = kdev->mods; 165 173 166 174 ev.c = layout_parse_ev(kdev->active_layout, &ev); 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); 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); 171 184 } 172 185 173 186 /** Mouse pointer has moved. */ 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); 187 void input_event_move(int dx, int dy) 188 { 189 async_obsolete_msg_2(client_phone, INPUT_EVENT_MOVE, dx, dy); 179 190 } 180 191 181 192 /** Mouse button has been pressed. */ 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); 193 void input_event_button(int bnum, int press) 194 { 195 async_obsolete_msg_2(client_phone, INPUT_EVENT_BUTTON, bnum, press); 187 196 } 188 197 189 198 static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 190 199 { 200 ipc_callid_t callid; 201 ipc_call_t call; 202 int retval; 203 191 204 async_answer_0(iid, EOK); 192 205 193 206 while (true) { 194 ipc_call_t call; 195 ipc_callid_t callid = async_get_call(&call); 207 callid = async_get_call(&call); 196 208 197 209 if (!IPC_GET_IMETHOD(call)) { 198 if (client_ sess != NULL) {199 async_ hangup(client_sess);200 client_ sess = NULL;210 if (client_phone != -1) { 211 async_obsolete_hangup(client_phone); 212 client_phone = -1; 201 213 } 202 214 … … 205 217 } 206 218 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); 219 switch (IPC_GET_IMETHOD(call)) { 220 case IPC_M_CONNECT_TO_ME: 221 if (client_phone != -1) { 222 retval = ELIMIT; 220 223 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);227 224 } 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; 228 238 } 229 } 239 async_answer_0(callid, retval); 240 } 230 241 } 231 242 232 243 static kbd_dev_t *kbd_dev_new(void) 233 244 { 234 kbd_dev_t *kdev = calloc(1, sizeof(kbd_dev_t)); 245 kbd_dev_t *kdev; 246 247 kdev = calloc(1, sizeof(kbd_dev_t)); 235 248 if (kdev == NULL) { 236 printf( "%s: Error allocating keyboard device. "237 "Out of memory.\n" , NAME);249 printf(NAME ": Error allocating keyboard device. " 250 "Out of memory.\n"); 238 251 return NULL; 239 252 } 240 253 241 254 link_initialize(&kdev->kbd_devs); 242 255 243 256 kdev->mods = KM_NUM_LOCK; 244 257 kdev->lock_keys = 0; 245 258 kdev->active_layout = layout_create(layout[0]); 246 259 247 260 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;262 261 } 263 262 … … 265 264 static void kbd_add_dev(kbd_port_ops_t *port, kbd_ctl_ops_t *ctl) 266 265 { 267 kbd_dev_t *kdev = kbd_dev_new(); 266 kbd_dev_t *kdev; 267 268 kdev = kbd_dev_new(); 268 269 if (kdev == NULL) 269 270 return; 270 271 271 272 kdev->port_ops = port; 272 273 kdev->ctl_ops = ctl; 273 kdev-> svc_id = 0;274 274 kdev->dev_path = NULL; 275 275 276 /* Initialize port driver. */ 276 277 if ((*kdev->port_ops->init)(kdev) != 0) 277 278 goto fail; 278 279 279 280 /* Initialize controller driver. */ 280 281 if ((*kdev->ctl_ops->init)(kdev) != 0) { … … 282 283 goto fail; 283 284 } 284 285 285 286 list_append(&kdev->kbd_devs, &kbd_devs); 286 287 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 320 292 /** Add new kbdev device. 321 293 * 322 * @param service_id Service ID of the keyboard device 323 * 294 * @param dev_path Filesystem path to the device (/dev/class/...) 324 295 */ 325 static int kbd_add_kbdev(service_id_t service_id, kbd_dev_t **kdevp) 326 { 327 kbd_dev_t *kdev = kbd_dev_new(); 296 static int kbd_add_kbdev(const char *dev_path) 297 { 298 kbd_dev_t *kdev; 299 300 kdev = kbd_dev_new(); 328 301 if (kdev == NULL) 329 302 return -1; 330 331 kdev-> svc_id = service_id;303 304 kdev->dev_path = dev_path; 332 305 kdev->port_ops = NULL; 333 306 kdev->ctl_ops = &kbdev_ctl; 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 307 341 308 /* Initialize controller driver. */ 342 309 if ((*kdev->ctl_ops->init)(kdev) != 0) { 343 310 goto fail; 344 311 } 345 312 346 313 list_append(&kdev->kbd_devs, &kbd_devs); 347 *kdevp = kdev;348 314 return EOK; 349 350 315 fail: 351 if (kdev->svc_name != NULL)352 free(kdev->svc_name);353 316 free(kdev); 354 return -1;355 }356 357 /** Add new mousedev device.358 *359 * @param service_id Service ID of the mouse device360 *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);389 317 return -1; 390 318 } … … 422 350 #endif 423 351 #if defined(MACHINE_msim) 424 kbd_add_dev(&msim_port, & stty_ctl);352 kbd_add_dev(&msim_port, &pc_ctl); 425 353 #endif 426 354 #if (defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)) && defined(CONFIG_FB) … … 436 364 kbd_add_dev(&niagara_port, &stty_ctl); 437 365 #endif 366 #if defined(UARCH_sparc64) && defined(MACHINE_serengeti) 367 kbd_add_dev(&sgcn_port, &stty_ctl); 368 #endif 438 369 #if defined(UARCH_sparc64) && defined(MACHINE_generic) 370 kbd_add_dev(&z8530_port, &sun_ctl); 439 371 kbd_add_dev(&ns16550_port, &sun_ctl); 440 372 #endif 441 373 /* Silence warning on abs32le about kbd_add_dev() being unused */ 442 374 (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 probe450 * them automatically.451 */452 #if defined(UARCH_amd64)453 mouse_add_dev(&chardev_mouse_port, &ps2_proto);454 #endif455 #if defined(UARCH_ia32)456 mouse_add_dev(&chardev_mouse_port, &ps2_proto);457 #endif458 #if defined(MACHINE_i460GX)459 mouse_add_dev(&chardev_mouse_port, &ps2_proto);460 #endif461 #if defined(UARCH_ppc32)462 mouse_add_dev(&adb_mouse_port, &adb_proto);463 #endif464 /* Silence warning on abs32le about mouse_add_dev() being unused */465 (void) mouse_add_dev;466 375 } 467 376 … … 472 381 kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t, 473 382 kbd_devs); 474 383 475 384 /* Yield port */ 476 385 if (kdev->port_ops != NULL) … … 485 394 kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t, 486 395 kbd_devs); 487 396 488 397 /* Reclaim port */ 489 398 if (kdev->port_ops != NULL) … … 492 401 } 493 402 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; 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; 500 414 int rc; 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 } 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; 529 432 } 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 } 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; 537 449 } 538 } 539 540 free(svcs); 541 542 /* XXX Handle device removal */ 543 450 451 free(dev_path); 452 } 453 544 454 return EOK; 545 455 } 546 456 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(); 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); 633 469 } 634 470 … … 637 473 printf("%s: HelenOS input service\n", NAME); 638 474 475 sysarg_t fhc; 639 476 sysarg_t obio; 640 477 … … 642 479 list_initialize(&mouse_devs); 643 480 644 if ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio)) 481 if (((sysinfo_get_value("kbd.cir.fhc", &fhc) == EOK) && (fhc)) 482 || ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio))) 645 483 irc_service = true; 646 484 647 485 if (irc_service) { 648 while (irc_sess == NULL) 649 irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE, 650 SERVICE_IRC, 0, 0); 486 while (irc_phone < 0) 487 irc_phone = service_obsolete_connect_blocking(SERVICE_IRC, 0, 0); 651 488 } 652 489 653 490 /* Add legacy keyboard devices. */ 654 491 kbd_add_legacy_devs(); 655 656 /* Add legacy mouse devices. */657 mouse_add_legacy_devs();492 493 /* Add legacy (devmap-style) mouse device. */ 494 (void) mouse_add_dev("/dev/hid_in/mouse"); 658 495 659 496 /* Register driver */ 660 int rc = loc_server_register(NAME, client_connection);497 int rc = devmap_driver_register(NAME, client_connection); 661 498 if (rc < 0) { 662 printf("%s: Unable to register server (%d)\n", NAME, rc);499 printf("%s: Unable to register driver (%d)\n", NAME, rc); 663 500 return -1; 664 501 } 665 502 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);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); 672 509 return -1; 673 510 } 674 511 675 512 /* Start looking for new input devices */ 676 513 input_start_dev_discovery(); 677 678 printf( "%s: Accepting connections\n", NAME);514 515 printf(NAME ": Accepting connections\n"); 679 516 async_manager(); 680 517 681 518 /* Not reached. */ 682 519 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.