Changeset 15d0046 in mainline for uspace/srv/hid/input/input.c
- Timestamp:
- 2014-09-12T13:22:33Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9b20126
- Parents:
- 8db09e4 (diff), 105d8d6 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/input/input.c
r8db09e4 r15d0046 54 54 #include <io/keycode.h> 55 55 #include <loc.h> 56 #include <str_error.h> 56 57 #include "layout.h" 57 58 #include "kbd.h" … … 62 63 #include "input.h" 63 64 65 bool irc_service = false; 66 async_sess_t *irc_sess = NULL; 67 64 68 #define NUM_LAYOUTS 4 65 69 … … 71 75 }; 72 76 73 static void kbd_devs_yield(void); 74 static void kbd_devs_reclaim(void); 75 76 async_sess_t *client_sess = NULL; 77 typedef struct { 78 /** Link into the list of clients */ 79 link_t link; 80 81 /** Indicate whether the client is active */ 82 bool active; 83 84 /** Client callback session */ 85 async_sess_t *sess; 86 } client_t; 87 88 /** List of clients */ 89 static list_t clients; 90 static client_t *active_client = NULL; 77 91 78 92 /** List of keyboard devices */ … … 82 96 static list_t mouse_devs; 83 97 84 bool irc_service = false;85 async_sess_t *irc_sess = NULL;86 87 98 static FIBRIL_MUTEX_INITIALIZE(discovery_lock); 99 100 static void *client_data_create(void) 101 { 102 client_t *client = (client_t *) calloc(1, sizeof(client_t)); 103 if (client == NULL) 104 return NULL; 105 106 link_initialize(&client->link); 107 client->active = false; 108 client->sess = NULL; 109 110 list_append(&client->link, &clients); 111 112 return client; 113 } 114 115 static void client_data_destroy(void *data) 116 { 117 client_t *client = (client_t *) data; 118 119 list_remove(&client->link); 120 free(client); 121 } 88 122 89 123 void kbd_push_data(kbd_dev_t *kdev, sysarg_t data) … … 103 137 104 138 switch (key) { 105 case KC_LCTRL: mod_mask = KM_LCTRL; break; 106 case KC_RCTRL: mod_mask = KM_RCTRL; break; 107 case KC_LSHIFT: mod_mask = KM_LSHIFT; break; 108 case KC_RSHIFT: mod_mask = KM_RSHIFT; break; 109 case KC_LALT: mod_mask = KM_LALT; break; 110 case KC_RALT: mod_mask = KM_RALT; break; 111 default: mod_mask = 0; break; 139 case KC_LCTRL: 140 mod_mask = KM_LCTRL; 141 break; 142 case KC_RCTRL: 143 mod_mask = KM_RCTRL; 144 break; 145 case KC_LSHIFT: 146 mod_mask = KM_LSHIFT; 147 break; 148 case KC_RSHIFT: 149 mod_mask = KM_RSHIFT; 150 break; 151 case KC_LALT: 152 mod_mask = KM_LALT; 153 break; 154 case KC_RALT: 155 mod_mask = KM_RALT; 156 break; 157 default: 158 mod_mask = 0; 112 159 } 113 160 … … 120 167 121 168 switch (key) { 122 case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break; 123 case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break; 124 case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break; 125 default: mod_mask = 0; break; 169 case KC_CAPS_LOCK: 170 mod_mask = KM_CAPS_LOCK; 171 break; 172 case KC_NUM_LOCK: 173 mod_mask = KM_NUM_LOCK; 174 break; 175 case KC_SCROLL_LOCK: 176 mod_mask = KM_SCROLL_LOCK; 177 break; 178 default: 179 mod_mask = 0; 126 180 } 127 181 … … 143 197 } 144 198 145 if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) && 146 key == KC_F1) { 199 // TODO: More elegant layout switching 200 201 if ((type == KEY_PRESS) && (kdev->mods & KM_LCTRL) && 202 (key == KC_F1)) { 147 203 layout_destroy(kdev->active_layout); 148 204 kdev->active_layout = layout_create(layout[0]); … … 150 206 } 151 207 152 if ( type == KEY_PRESS&& (kdev->mods & KM_LCTRL) &&153 key == KC_F2) {208 if ((type == KEY_PRESS) && (kdev->mods & KM_LCTRL) && 209 (key == KC_F2)) { 154 210 layout_destroy(kdev->active_layout); 155 211 kdev->active_layout = layout_create(layout[1]); … … 157 213 } 158 214 159 if ( type == KEY_PRESS&& (kdev->mods & KM_LCTRL) &&160 key == KC_F3) {215 if ((type == KEY_PRESS) && (kdev->mods & KM_LCTRL) && 216 (key == KC_F3)) { 161 217 layout_destroy(kdev->active_layout); 162 218 kdev->active_layout = layout_create(layout[2]); … … 164 220 } 165 221 166 if ( type == KEY_PRESS&& (kdev->mods & KM_LCTRL) &&167 key == KC_F4) {222 if ((type == KEY_PRESS) && (kdev->mods & KM_LCTRL) && 223 (key == KC_F4)) { 168 224 layout_destroy(kdev->active_layout); 169 225 kdev->active_layout = layout_create(layout[3]); … … 177 233 ev.c = layout_parse_ev(kdev->active_layout, &ev); 178 234 179 async_exch_t *exch = async_exchange_begin(client_sess); 180 async_msg_4(exch, INPUT_EVENT_KEY, ev.type, ev.key, ev.mods, ev.c); 181 async_exchange_end(exch); 182 } 183 184 /** Mouse pointer has moved. */ 235 list_foreach(clients, link, client_t, client) { 236 if (client->active) { 237 async_exch_t *exch = async_exchange_begin(client->sess); 238 async_msg_4(exch, INPUT_EVENT_KEY, ev.type, ev.key, ev.mods, ev.c); 239 async_exchange_end(exch); 240 } 241 } 242 } 243 244 /** Mouse pointer has moved (relative mode). */ 185 245 void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy, int dz) 186 246 { 187 async_exch_t *exch = async_exchange_begin(client_sess); 188 if (dx || dy) 189 async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy); 190 if (dz) { 191 // TODO: Implement proper wheel support 192 keycode_t code = dz > 0 ? KC_UP : KC_DOWN; 193 for (int i = 0; i < 3; ++i) { 194 async_msg_4(exch, INPUT_EVENT_KEY, KEY_PRESS, code, 0, 0); 195 } 196 async_msg_4(exch, INPUT_EVENT_KEY, KEY_RELEASE, code, 0, 0); 197 } 198 async_exchange_end(exch); 199 } 200 201 /** Mouse pointer has moved in absolute mode. */ 247 list_foreach(clients, link, client_t, client) { 248 if (client->active) { 249 async_exch_t *exch = async_exchange_begin(client->sess); 250 251 if ((dx) || (dy)) 252 async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy); 253 254 if (dz) { 255 // TODO: Implement proper wheel support 256 keycode_t code = dz > 0 ? KC_UP : KC_DOWN; 257 258 for (unsigned int i = 0; i < 3; i++) 259 async_msg_4(exch, INPUT_EVENT_KEY, KEY_PRESS, code, 0, 0); 260 261 async_msg_4(exch, INPUT_EVENT_KEY, KEY_RELEASE, code, 0, 0); 262 } 263 264 async_exchange_end(exch); 265 } 266 } 267 } 268 269 /** Mouse pointer has moved (absolute mode). */ 202 270 void mouse_push_event_abs_move(mouse_dev_t *mdev, unsigned int x, unsigned int y, 203 271 unsigned int max_x, unsigned int max_y) 204 272 { 205 if (max_x && max_y) { 206 async_exch_t *exch = async_exchange_begin(client_sess); 207 async_msg_4(exch, INPUT_EVENT_ABS_MOVE, x, y, max_x, max_y); 208 async_exchange_end(exch); 273 list_foreach(clients, link, client_t, client) { 274 if (client->active) { 275 if ((max_x) && (max_y)) { 276 async_exch_t *exch = async_exchange_begin(client->sess); 277 async_msg_4(exch, INPUT_EVENT_ABS_MOVE, x, y, max_x, max_y); 278 async_exchange_end(exch); 279 } 280 } 209 281 } 210 282 } … … 213 285 void mouse_push_event_button(mouse_dev_t *mdev, int bnum, int press) 214 286 { 215 async_exch_t *exch = async_exchange_begin(client_sess); 216 async_msg_2(exch, INPUT_EVENT_BUTTON, bnum, press); 217 async_exchange_end(exch); 218 } 219 287 list_foreach(clients, link, client_t, client) { 288 if (client->active) { 289 async_exch_t *exch = async_exchange_begin(client->sess); 290 async_msg_2(exch, INPUT_EVENT_BUTTON, bnum, press); 291 async_exchange_end(exch); 292 } 293 } 294 } 295 296 /** Arbitrate client actiovation */ 297 static void client_arbitration(client_t *req) 298 { 299 /* Mutual exclusion of active clients */ 300 list_foreach(clients, link, client_t, client) 301 client->active = (client == req); 302 303 /* Notify clients about the arbitration */ 304 list_foreach(clients, link, client_t, client) { 305 async_exch_t *exch = async_exchange_begin(client->sess); 306 async_msg_0(exch, client->active ? 307 INPUT_EVENT_ACTIVE : INPUT_EVENT_DEACTIVE); 308 async_exchange_end(exch); 309 } 310 } 311 312 /** New client connection */ 220 313 static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 221 314 { 315 client_t *client = (client_t *) async_get_client_data(); 316 if (client == NULL) { 317 async_answer_0(iid, ENOMEM); 318 return; 319 } 320 222 321 async_answer_0(iid, EOK); 223 322 … … 227 326 228 327 if (!IPC_GET_IMETHOD(call)) { 229 if (client _sess != NULL) {230 async_hangup(client _sess);231 client _sess = NULL;328 if (client->sess != NULL) { 329 async_hangup(client->sess); 330 client->sess = NULL; 232 331 } 233 332 … … 239 338 async_callback_receive_start(EXCHANGE_SERIALIZE, &call); 240 339 if (sess != NULL) { 241 if (client _sess == NULL) {242 client _sess = sess;340 if (client->sess == NULL) { 341 client->sess = sess; 243 342 async_answer_0(callid, EOK); 244 343 } else … … 246 345 } else { 247 346 switch (IPC_GET_IMETHOD(call)) { 248 case INPUT_YIELD: 249 kbd_devs_yield(); 250 async_answer_0(callid, EOK); 251 break; 252 case INPUT_RECLAIM: 253 kbd_devs_reclaim(); 347 case INPUT_ACTIVATE: 348 active_client = client; 349 client_arbitration(client); 254 350 async_answer_0(callid, EOK); 255 351 break; … … 261 357 } 262 358 359 static void kconsole_event_handler(ipc_callid_t callid, ipc_call_t *call, 360 void *arg) 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 263 371 static kbd_dev_t *kbd_dev_new(void) 264 372 { … … 270 378 } 271 379 272 link_initialize(&kdev-> kbd_devs);380 link_initialize(&kdev->link); 273 381 274 382 kdev->mods = KM_NUM_LOCK; … … 288 396 } 289 397 290 link_initialize(&mdev-> mouse_devs);398 link_initialize(&mdev->link); 291 399 292 400 return mdev; … … 314 422 } 315 423 316 list_append(&kdev-> kbd_devs, &kbd_devs);424 list_append(&kdev->link, &kbd_devs); 317 425 return; 318 426 … … 342 450 } 343 451 344 list_append(&mdev-> mouse_devs, &mouse_devs);452 list_append(&mdev->link, &mouse_devs); 345 453 return; 346 454 … … 351 459 /** Add new kbdev device. 352 460 * 353 * @param service_id 461 * @param service_id Service ID of the keyboard device 354 462 * 355 463 */ … … 375 483 } 376 484 377 list_append(&kdev-> kbd_devs, &kbd_devs);485 list_append(&kdev->link, &kbd_devs); 378 486 *kdevp = kdev; 379 487 return EOK; … … 388 496 /** Add new mousedev device. 389 497 * 390 * @param service_id 498 * @param service_id Service ID of the mouse device 391 499 * 392 500 */ … … 412 520 } 413 521 414 list_append(&mdev-> mouse_devs, &mouse_devs);522 list_append(&mdev->link, &mouse_devs); 415 523 *mdevp = mdev; 416 524 return EOK; … … 430 538 #if defined(UARCH_arm32) && defined(MACHINE_gta02) 431 539 kbd_add_dev(&chardev_port, &stty_ctl); 432 #endif433 #if defined(UARCH_arm32) && defined(MACHINE_integratorcp)434 kbd_add_dev(&pl050_port, &pc_ctl);435 540 #endif 436 541 #if defined(MACHINE_ski) … … 467 572 } 468 573 469 static void kbd_devs_yield(void)470 {471 /* For each keyboard device */472 list_foreach(kbd_devs, kbd_devs, kbd_dev_t, kdev) {473 /* Yield port */474 if (kdev->port_ops != NULL)475 (*kdev->port_ops->yield)();476 }477 }478 479 static void kbd_devs_reclaim(void)480 {481 /* For each keyboard device */482 list_foreach(kbd_devs, kbd_devs, kbd_dev_t, kdev) {483 /* Reclaim port */484 if (kdev->port_ops != NULL)485 (*kdev->port_ops->reclaim)();486 }487 }488 489 574 static int dev_check_new_kbdevs(void) 490 575 { … … 515 600 516 601 /* Determine whether we already know this device. */ 517 list_foreach(kbd_devs, kbd_devs, kbd_dev_t, kdev) {602 list_foreach(kbd_devs, link, kbd_dev_t, kdev) { 518 603 if (kdev->svc_id == svcs[i]) { 519 604 already_known = true; … … 566 651 567 652 /* Determine whether we already know this device. */ 568 list_foreach(mouse_devs, mouse_devs, mouse_dev_t, mdev) {653 list_foreach(mouse_devs, link, mouse_dev_t, mdev) { 569 654 if (mdev->svc_id == svcs[i]) { 570 655 already_known = true; … … 620 705 static int input_start_dev_discovery(void) 621 706 { 622 int rc; 623 624 rc = loc_register_cat_change_cb(cat_change_cb); 707 int rc = loc_register_cat_change_cb(cat_change_cb); 625 708 if (rc != EOK) { 626 709 printf("%s: Failed registering callback for device discovery. " … … 628 711 return rc; 629 712 } 630 713 631 714 return dev_check_new(); 632 715 } … … 648 731 sysarg_t obio; 649 732 733 list_initialize(&clients); 650 734 list_initialize(&kbd_devs); 651 735 list_initialize(&mouse_devs); … … 667 751 668 752 /* Register driver */ 753 async_set_client_data_constructor(client_data_create); 754 async_set_client_data_destructor(client_data_destroy); 669 755 async_set_client_connection(client_connection); 756 670 757 int rc = loc_server_register(NAME); 671 758 if (rc != EOK) { … … 680 767 return rc; 681 768 } 769 770 /* Receive kernel notifications */ 771 rc = async_event_subscribe(EVENT_KCONSOLE, kconsole_event_handler, NULL); 772 if (rc != EOK) 773 printf("%s: Failed to register kconsole notifications (%s)\n", 774 NAME, str_error(rc)); 682 775 683 776 /* Start looking for new input devices */
Note:
See TracChangeset
for help on using the changeset viewer.