Changeset 593e023 in mainline for uspace/srv/hid/input/input.c
- Timestamp:
- 2014-08-12T17:14:32Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c3bdc92
- Parents:
- ce3efa0
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/input/input.c
rce3efa0 r593e023 54 54 #include <io/keycode.h> 55 55 #include <loc.h> 56 #include <event.h> 57 #include <str_error.h> 56 58 #include "layout.h" 57 59 #include "kbd.h" … … 62 64 #include "input.h" 63 65 66 bool irc_service = false; 67 async_sess_t *irc_sess = NULL; 68 64 69 #define NUM_LAYOUTS 4 65 70 … … 71 76 }; 72 77 73 static void kbd_devs_yield(void); 74 static void kbd_devs_reclaim(void); 75 76 async_sess_t *client_sess = NULL; 78 typedef struct { 79 /** Link into the list of clients */ 80 link_t link; 81 82 /** Indicate whether the client is active */ 83 bool active; 84 85 /** Client callback session */ 86 async_sess_t *sess; 87 } client_t; 88 89 /** List of clients */ 90 static list_t clients; 91 static client_t *active_client = NULL; 77 92 78 93 /** List of keyboard devices */ … … 82 97 static list_t mouse_devs; 83 98 84 bool irc_service = false;85 async_sess_t *irc_sess = NULL;86 87 99 static FIBRIL_MUTEX_INITIALIZE(discovery_lock); 100 101 static void *client_data_create(void) 102 { 103 client_t *client = (client_t *) calloc(1, sizeof(client_t)); 104 if (client == NULL) 105 return NULL; 106 107 link_initialize(&client->link); 108 client->active = false; 109 client->sess = NULL; 110 111 list_append(&client->link, &clients); 112 113 return client; 114 } 115 116 static void client_data_destroy(void *data) 117 { 118 client_t *client = (client_t *) data; 119 120 list_remove(&client->link); 121 free(client); 122 } 88 123 89 124 void kbd_push_data(kbd_dev_t *kdev, sysarg_t data) … … 199 234 ev.c = layout_parse_ev(kdev->active_layout, &ev); 200 235 201 async_exch_t *exch = async_exchange_begin(client_sess); 202 async_msg_4(exch, INPUT_EVENT_KEY, ev.type, ev.key, ev.mods, ev.c); 203 async_exchange_end(exch); 204 } 205 206 /** Mouse pointer has moved. */ 236 list_foreach(clients, link, client_t, client) { 237 if (client->active) { 238 async_exch_t *exch = async_exchange_begin(client->sess); 239 async_msg_4(exch, INPUT_EVENT_KEY, ev.type, ev.key, ev.mods, ev.c); 240 async_exchange_end(exch); 241 } 242 } 243 } 244 245 /** Mouse pointer has moved (relative mode). */ 207 246 void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy, int dz) 208 247 { 209 async_exch_t *exch = async_exchange_begin(client_sess); 210 if (dx || dy) 211 async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy); 212 if (dz) { 213 // TODO: Implement proper wheel support 214 keycode_t code = dz > 0 ? KC_UP : KC_DOWN; 215 for (int i = 0; i < 3; ++i) { 216 async_msg_4(exch, INPUT_EVENT_KEY, KEY_PRESS, code, 0, 0); 217 } 218 async_msg_4(exch, INPUT_EVENT_KEY, KEY_RELEASE, code, 0, 0); 219 } 220 async_exchange_end(exch); 221 } 222 223 /** Mouse pointer has moved in absolute mode. */ 248 list_foreach(clients, link, client_t, client) { 249 if (client->active) { 250 async_exch_t *exch = async_exchange_begin(client->sess); 251 252 if ((dx) || (dy)) 253 async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy); 254 255 if (dz) { 256 // TODO: Implement proper wheel support 257 keycode_t code = dz > 0 ? KC_UP : KC_DOWN; 258 259 for (unsigned int i = 0; i < 3; i++) 260 async_msg_4(exch, INPUT_EVENT_KEY, KEY_PRESS, code, 0, 0); 261 262 async_msg_4(exch, INPUT_EVENT_KEY, KEY_RELEASE, code, 0, 0); 263 } 264 265 async_exchange_end(exch); 266 } 267 } 268 } 269 270 /** Mouse pointer has moved (absolute mode). */ 224 271 void mouse_push_event_abs_move(mouse_dev_t *mdev, unsigned int x, unsigned int y, 225 272 unsigned int max_x, unsigned int max_y) 226 273 { 227 if (max_x && max_y) { 228 async_exch_t *exch = async_exchange_begin(client_sess); 229 async_msg_4(exch, INPUT_EVENT_ABS_MOVE, x, y, max_x, max_y); 230 async_exchange_end(exch); 274 list_foreach(clients, link, client_t, client) { 275 if (client->active) { 276 if ((max_x) && (max_y)) { 277 async_exch_t *exch = async_exchange_begin(client->sess); 278 async_msg_4(exch, INPUT_EVENT_ABS_MOVE, x, y, max_x, max_y); 279 async_exchange_end(exch); 280 } 281 } 231 282 } 232 283 } … … 235 286 void mouse_push_event_button(mouse_dev_t *mdev, int bnum, int press) 236 287 { 237 async_exch_t *exch = async_exchange_begin(client_sess); 238 async_msg_2(exch, INPUT_EVENT_BUTTON, bnum, press); 239 async_exchange_end(exch); 240 } 241 288 list_foreach(clients, link, client_t, client) { 289 if (client->active) { 290 async_exch_t *exch = async_exchange_begin(client->sess); 291 async_msg_2(exch, INPUT_EVENT_BUTTON, bnum, press); 292 async_exchange_end(exch); 293 } 294 } 295 } 296 297 /** Arbitrate client actiovation */ 298 static void client_arbitration(client_t *req) 299 { 300 /* Mutual exclusion of active clients */ 301 list_foreach(clients, link, client_t, client) 302 client->active = (client == req); 303 304 /* Notify clients about the arbitration */ 305 list_foreach(clients, link, client_t, client) { 306 async_exch_t *exch = async_exchange_begin(client->sess); 307 async_msg_0(exch, client->active ? 308 INPUT_EVENT_ACTIVE : INPUT_EVENT_DEACTIVE); 309 async_exchange_end(exch); 310 } 311 } 312 313 /** New client connection */ 242 314 static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 243 315 { 316 client_t *client = (client_t *) async_get_client_data(); 317 if (client == NULL) { 318 async_answer_0(iid, ENOMEM); 319 return; 320 } 321 244 322 async_answer_0(iid, EOK); 245 323 … … 249 327 250 328 if (!IPC_GET_IMETHOD(call)) { 251 if (client _sess != NULL) {252 async_hangup(client _sess);253 client _sess = NULL;329 if (client->sess != NULL) { 330 async_hangup(client->sess); 331 client->sess = NULL; 254 332 } 255 333 … … 261 339 async_callback_receive_start(EXCHANGE_SERIALIZE, &call); 262 340 if (sess != NULL) { 263 if (client _sess == NULL) {264 client _sess = sess;341 if (client->sess == NULL) { 342 client->sess = sess; 265 343 async_answer_0(callid, EOK); 266 344 } else … … 268 346 } else { 269 347 switch (IPC_GET_IMETHOD(call)) { 270 case INPUT_YIELD: 271 kbd_devs_yield(); 272 async_answer_0(callid, EOK); 273 break; 274 case INPUT_RECLAIM: 275 kbd_devs_reclaim(); 348 case INPUT_ACTIVATE: 349 active_client = client; 350 client_arbitration(client); 276 351 async_answer_0(callid, EOK); 277 352 break; … … 283 358 } 284 359 360 static void kconsole_event_received(ipc_callid_t callid, ipc_call_t *call) 361 { 362 if (IPC_GET_ARG1(*call)) { 363 /* Kernel console activated */ 364 client_arbitration(NULL); 365 } else { 366 /* Kernel console deactivated */ 367 client_arbitration(active_client); 368 } 369 } 370 285 371 static kbd_dev_t *kbd_dev_new(void) 286 372 { … … 292 378 } 293 379 294 link_initialize(&kdev-> kbd_devs);380 link_initialize(&kdev->link); 295 381 296 382 kdev->mods = KM_NUM_LOCK; … … 310 396 } 311 397 312 link_initialize(&mdev-> mouse_devs);398 link_initialize(&mdev->link); 313 399 314 400 return mdev; … … 336 422 } 337 423 338 list_append(&kdev-> kbd_devs, &kbd_devs);424 list_append(&kdev->link, &kbd_devs); 339 425 return; 340 426 … … 364 450 } 365 451 366 list_append(&mdev-> mouse_devs, &mouse_devs);452 list_append(&mdev->link, &mouse_devs); 367 453 return; 368 454 … … 373 459 /** Add new kbdev device. 374 460 * 375 * @param service_id 461 * @param service_id Service ID of the keyboard device 376 462 * 377 463 */ … … 397 483 } 398 484 399 list_append(&kdev-> kbd_devs, &kbd_devs);485 list_append(&kdev->link, &kbd_devs); 400 486 *kdevp = kdev; 401 487 return EOK; … … 410 496 /** Add new mousedev device. 411 497 * 412 * @param service_id 498 * @param service_id Service ID of the mouse device 413 499 * 414 500 */ … … 434 520 } 435 521 436 list_append(&mdev-> mouse_devs, &mouse_devs);522 list_append(&mdev->link, &mouse_devs); 437 523 *mdevp = mdev; 438 524 return EOK; … … 489 575 } 490 576 491 static void kbd_devs_yield(void)492 {493 /* For each keyboard device */494 list_foreach(kbd_devs, kbd_devs, kbd_dev_t, kdev) {495 /* Yield port */496 if (kdev->port_ops != NULL)497 (*kdev->port_ops->yield)();498 }499 }500 501 static void kbd_devs_reclaim(void)502 {503 /* For each keyboard device */504 list_foreach(kbd_devs, kbd_devs, kbd_dev_t, kdev) {505 /* Reclaim port */506 if (kdev->port_ops != NULL)507 (*kdev->port_ops->reclaim)();508 }509 }510 511 577 static int dev_check_new_kbdevs(void) 512 578 { … … 537 603 538 604 /* Determine whether we already know this device. */ 539 list_foreach(kbd_devs, kbd_devs, kbd_dev_t, kdev) {605 list_foreach(kbd_devs, link, kbd_dev_t, kdev) { 540 606 if (kdev->svc_id == svcs[i]) { 541 607 already_known = true; … … 588 654 589 655 /* Determine whether we already know this device. */ 590 list_foreach(mouse_devs, mouse_devs, mouse_dev_t, mdev) {656 list_foreach(mouse_devs, link, mouse_dev_t, mdev) { 591 657 if (mdev->svc_id == svcs[i]) { 592 658 already_known = true; … … 668 734 sysarg_t obio; 669 735 736 list_initialize(&clients); 670 737 list_initialize(&kbd_devs); 671 738 list_initialize(&mouse_devs); … … 687 754 688 755 /* Register driver */ 756 async_set_client_data_constructor(client_data_create); 757 async_set_client_data_destructor(client_data_destroy); 689 758 async_set_client_connection(client_connection); 690 759 … … 701 770 return rc; 702 771 } 772 773 /* Receive kernel notifications */ 774 async_set_interrupt_received(kconsole_event_received); 775 rc = event_subscribe(EVENT_KCONSOLE, 0); 776 if (rc != EOK) 777 printf("%s: Failed to register kconsole notifications (%s)\n", 778 NAME, str_error(rc)); 703 779 704 780 /* Start looking for new input devices */
Note:
See TracChangeset
for help on using the changeset viewer.