Changes in uspace/srv/hid/input/input.c [c9d011e4:380e23a3] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/input/input.c
rc9d011e4 r380e23a3 38 38 39 39 #include <adt/list.h> 40 #include < bool.h>40 #include <stdbool.h> 41 41 #include <fibril_synch.h> 42 42 #include <ipc/services.h> … … 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 64 #define NUM_LAYOUTS 3 65 bool irc_service = false; 66 async_sess_t *irc_sess = NULL; 67 68 #define NUM_LAYOUTS 4 65 69 66 70 static layout_ops_t *layout[NUM_LAYOUTS] = { 67 71 &us_qwerty_ops, 68 72 &us_dvorak_ops, 69 &cz_ops 73 &cz_ops, 74 &ar_ops 70 75 }; 71 76 72 static void kbd_devs_yield(void); 73 static void kbd_devs_reclaim(void); 74 75 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; 91 92 /** Kernel override */ 93 static bool active = true; 76 94 77 95 /** List of keyboard devices */ … … 81 99 static list_t mouse_devs; 82 100 83 bool irc_service = false;84 async_sess_t *irc_sess = NULL;85 86 101 static FIBRIL_MUTEX_INITIALIZE(discovery_lock); 102 103 static void *client_data_create(void) 104 { 105 client_t *client = (client_t *) calloc(1, sizeof(client_t)); 106 if (client == NULL) 107 return NULL; 108 109 link_initialize(&client->link); 110 client->active = false; 111 client->sess = NULL; 112 113 list_append(&client->link, &clients); 114 115 return client; 116 } 117 118 static void client_data_destroy(void *data) 119 { 120 client_t *client = (client_t *) data; 121 122 list_remove(&client->link); 123 free(client); 124 } 87 125 88 126 void kbd_push_data(kbd_dev_t *kdev, sysarg_t data) … … 102 140 103 141 switch (key) { 104 case KC_LCTRL: mod_mask = KM_LCTRL; break; 105 case KC_RCTRL: mod_mask = KM_RCTRL; break; 106 case KC_LSHIFT: mod_mask = KM_LSHIFT; break; 107 case KC_RSHIFT: mod_mask = KM_RSHIFT; break; 108 case KC_LALT: mod_mask = KM_LALT; break; 109 case KC_RALT: mod_mask = KM_RALT; break; 110 default: mod_mask = 0; break; 142 case KC_LCTRL: 143 mod_mask = KM_LCTRL; 144 break; 145 case KC_RCTRL: 146 mod_mask = KM_RCTRL; 147 break; 148 case KC_LSHIFT: 149 mod_mask = KM_LSHIFT; 150 break; 151 case KC_RSHIFT: 152 mod_mask = KM_RSHIFT; 153 break; 154 case KC_LALT: 155 mod_mask = KM_LALT; 156 break; 157 case KC_RALT: 158 mod_mask = KM_RALT; 159 break; 160 default: 161 mod_mask = 0; 111 162 } 112 163 … … 119 170 120 171 switch (key) { 121 case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break; 122 case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break; 123 case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break; 124 default: mod_mask = 0; break; 172 case KC_CAPS_LOCK: 173 mod_mask = KM_CAPS_LOCK; 174 break; 175 case KC_NUM_LOCK: 176 mod_mask = KM_NUM_LOCK; 177 break; 178 case KC_SCROLL_LOCK: 179 mod_mask = KM_SCROLL_LOCK; 180 break; 181 default: 182 mod_mask = 0; 125 183 } 126 184 … … 142 200 } 143 201 144 if (type == KEY_PRESS && (kdev->mods & KM_LCTRL) && 145 key == KC_F1) { 202 // TODO: More elegant layout switching 203 204 if ((type == KEY_PRESS) && (kdev->mods & KM_LCTRL) && 205 (key == KC_F1)) { 146 206 layout_destroy(kdev->active_layout); 147 207 kdev->active_layout = layout_create(layout[0]); … … 149 209 } 150 210 151 if ( type == KEY_PRESS&& (kdev->mods & KM_LCTRL) &&152 key == KC_F2) {211 if ((type == KEY_PRESS) && (kdev->mods & KM_LCTRL) && 212 (key == KC_F2)) { 153 213 layout_destroy(kdev->active_layout); 154 214 kdev->active_layout = layout_create(layout[1]); … … 156 216 } 157 217 158 if ( type == KEY_PRESS&& (kdev->mods & KM_LCTRL) &&159 key == KC_F3) {218 if ((type == KEY_PRESS) && (kdev->mods & KM_LCTRL) && 219 (key == KC_F3)) { 160 220 layout_destroy(kdev->active_layout); 161 221 kdev->active_layout = layout_create(layout[2]); … … 163 223 } 164 224 225 if ((type == KEY_PRESS) && (kdev->mods & KM_LCTRL) && 226 (key == KC_F4)) { 227 layout_destroy(kdev->active_layout); 228 kdev->active_layout = layout_create(layout[3]); 229 return; 230 } 231 165 232 ev.type = type; 166 233 ev.key = key; … … 169 236 ev.c = layout_parse_ev(kdev->active_layout, &ev); 170 237 171 async_exch_t *exch = async_exchange_begin(client_sess); 172 async_msg_4(exch, INPUT_EVENT_KEY, ev.type, ev.key, ev.mods, ev.c); 173 async_exchange_end(exch); 174 } 175 176 /** Mouse pointer has moved. */ 238 list_foreach(clients, link, client_t, client) { 239 if (client->active) { 240 async_exch_t *exch = async_exchange_begin(client->sess); 241 async_msg_4(exch, INPUT_EVENT_KEY, ev.type, ev.key, ev.mods, ev.c); 242 async_exchange_end(exch); 243 } 244 } 245 } 246 247 /** Mouse pointer has moved (relative mode). */ 177 248 void mouse_push_event_move(mouse_dev_t *mdev, int dx, int dy, int dz) 178 249 { 179 async_exch_t *exch = async_exchange_begin(client_sess); 180 if (dx || dy) 181 async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy); 182 if (dz) { 183 // TODO: Implement proper wheel support 184 keycode_t code = dz > 0 ? KC_UP : KC_DOWN; 185 for (int i = 0; i < 3; ++i) { 186 async_msg_4(exch, INPUT_EVENT_KEY, KEY_PRESS, code, 0, 0); 187 } 188 async_msg_4(exch, INPUT_EVENT_KEY, KEY_RELEASE, code, 0, 0); 189 } 190 async_exchange_end(exch); 191 } 192 193 /** Mouse pointer has moved in absolute mode. */ 250 list_foreach(clients, link, client_t, client) { 251 if (client->active) { 252 async_exch_t *exch = async_exchange_begin(client->sess); 253 254 if ((dx) || (dy)) 255 async_msg_2(exch, INPUT_EVENT_MOVE, dx, dy); 256 257 if (dz) { 258 // TODO: Implement proper wheel support 259 keycode_t code = dz > 0 ? KC_UP : KC_DOWN; 260 261 for (unsigned int i = 0; i < 3; i++) 262 async_msg_4(exch, INPUT_EVENT_KEY, KEY_PRESS, code, 0, 0); 263 264 async_msg_4(exch, INPUT_EVENT_KEY, KEY_RELEASE, code, 0, 0); 265 } 266 267 async_exchange_end(exch); 268 } 269 } 270 } 271 272 /** Mouse pointer has moved (absolute mode). */ 194 273 void mouse_push_event_abs_move(mouse_dev_t *mdev, unsigned int x, unsigned int y, 195 274 unsigned int max_x, unsigned int max_y) 196 275 { 197 if (max_x && max_y) { 198 async_exch_t *exch = async_exchange_begin(client_sess); 199 async_msg_4(exch, INPUT_EVENT_ABS_MOVE, x, y, max_x, max_y); 200 async_exchange_end(exch); 276 list_foreach(clients, link, client_t, client) { 277 if (client->active) { 278 if ((max_x) && (max_y)) { 279 async_exch_t *exch = async_exchange_begin(client->sess); 280 async_msg_4(exch, INPUT_EVENT_ABS_MOVE, x, y, max_x, max_y); 281 async_exchange_end(exch); 282 } 283 } 201 284 } 202 285 } … … 205 288 void mouse_push_event_button(mouse_dev_t *mdev, int bnum, int press) 206 289 { 207 async_exch_t *exch = async_exchange_begin(client_sess); 208 async_msg_2(exch, INPUT_EVENT_BUTTON, bnum, press); 209 async_exchange_end(exch); 210 } 211 290 list_foreach(clients, link, client_t, client) { 291 if (client->active) { 292 async_exch_t *exch = async_exchange_begin(client->sess); 293 async_msg_2(exch, INPUT_EVENT_BUTTON, bnum, press); 294 async_exchange_end(exch); 295 } 296 } 297 } 298 299 /** Arbitrate client actiovation */ 300 static void client_arbitration(void) 301 { 302 /* Mutual exclusion of active clients */ 303 list_foreach(clients, link, client_t, client) 304 client->active = ((active) && (client == active_client)); 305 306 /* Notify clients about the arbitration */ 307 list_foreach(clients, link, client_t, client) { 308 async_exch_t *exch = async_exchange_begin(client->sess); 309 async_msg_0(exch, client->active ? 310 INPUT_EVENT_ACTIVE : INPUT_EVENT_DEACTIVE); 311 async_exchange_end(exch); 312 } 313 } 314 315 /** New client connection */ 212 316 static void client_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 213 317 { 318 client_t *client = (client_t *) async_get_client_data(); 319 if (client == NULL) { 320 async_answer_0(iid, ENOMEM); 321 return; 322 } 323 214 324 async_answer_0(iid, EOK); 215 325 … … 219 329 220 330 if (!IPC_GET_IMETHOD(call)) { 221 if (client _sess != NULL) {222 async_hangup(client _sess);223 client _sess = NULL;331 if (client->sess != NULL) { 332 async_hangup(client->sess); 333 client->sess = NULL; 224 334 } 225 335 … … 231 341 async_callback_receive_start(EXCHANGE_SERIALIZE, &call); 232 342 if (sess != NULL) { 233 if (client _sess == NULL) {234 client _sess = sess;343 if (client->sess == NULL) { 344 client->sess = sess; 235 345 async_answer_0(callid, EOK); 236 346 } else … … 238 348 } else { 239 349 switch (IPC_GET_IMETHOD(call)) { 240 case INPUT_YIELD: 241 kbd_devs_yield(); 242 async_answer_0(callid, EOK); 243 break; 244 case INPUT_RECLAIM: 245 kbd_devs_reclaim(); 350 case INPUT_ACTIVATE: 351 active_client = client; 352 client_arbitration(); 246 353 async_answer_0(callid, EOK); 247 354 break; … … 253 360 } 254 361 362 static void kconsole_event_handler(ipc_callid_t callid, ipc_call_t *call, 363 void *arg) 364 { 365 if (IPC_GET_ARG1(*call)) { 366 /* Kernel console activated */ 367 active = false; 368 } else { 369 /* Kernel console deactivated */ 370 active = true; 371 } 372 373 client_arbitration(); 374 } 375 255 376 static kbd_dev_t *kbd_dev_new(void) 256 377 { … … 262 383 } 263 384 264 link_initialize(&kdev-> kbd_devs);385 link_initialize(&kdev->link); 265 386 266 387 kdev->mods = KM_NUM_LOCK; … … 280 401 } 281 402 282 link_initialize(&mdev-> mouse_devs);403 link_initialize(&mdev->link); 283 404 284 405 return mdev; … … 306 427 } 307 428 308 list_append(&kdev-> kbd_devs, &kbd_devs);429 list_append(&kdev->link, &kbd_devs); 309 430 return; 310 431 … … 334 455 } 335 456 336 list_append(&mdev-> mouse_devs, &mouse_devs);457 list_append(&mdev->link, &mouse_devs); 337 458 return; 338 459 … … 343 464 /** Add new kbdev device. 344 465 * 345 * @param service_id 466 * @param service_id Service ID of the keyboard device 346 467 * 347 468 */ … … 367 488 } 368 489 369 list_append(&kdev-> kbd_devs, &kbd_devs);490 list_append(&kdev->link, &kbd_devs); 370 491 *kdevp = kdev; 371 492 return EOK; … … 380 501 /** Add new mousedev device. 381 502 * 382 * @param service_id 503 * @param service_id Service ID of the mouse device 383 504 * 384 505 */ … … 404 525 } 405 526 406 list_append(&mdev-> mouse_devs, &mouse_devs);527 list_append(&mdev->link, &mouse_devs); 407 528 *mdevp = mdev; 408 529 return EOK; … … 423 544 kbd_add_dev(&chardev_port, &stty_ctl); 424 545 #endif 425 #if defined(UARCH_arm32) && defined(MACHINE_testarm) && defined(CONFIG_FB)426 kbd_add_dev(&gxemul_port, &gxe_fb_ctl);427 #endif428 #if defined(UARCH_arm32) && defined(MACHINE_testarm) && !defined(CONFIG_FB)429 kbd_add_dev(&gxemul_port, &stty_ctl);430 #endif431 #if defined(UARCH_arm32) && defined(MACHINE_integratorcp)432 kbd_add_dev(&pl050_port, &pc_ctl);433 #endif434 546 #if defined(MACHINE_ski) 435 547 kbd_add_dev(&ski_port, &stty_ctl); … … 437 549 #if defined(MACHINE_msim) 438 550 kbd_add_dev(&msim_port, &stty_ctl); 439 #endif440 #if (defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)) && defined(CONFIG_FB)441 kbd_add_dev(&gxemul_port, &gxe_fb_ctl);442 #endif443 #if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul) && !defined(CONFIG_FB)444 kbd_add_dev(&gxemul_port, &stty_ctl);445 551 #endif 446 552 #if defined(UARCH_ppc32) … … 471 577 } 472 578 473 static void kbd_devs_yield(void)474 {475 /* For each keyboard device */476 list_foreach(kbd_devs, kdev_link) {477 kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,478 kbd_devs);479 480 /* Yield port */481 if (kdev->port_ops != NULL)482 (*kdev->port_ops->yield)();483 }484 }485 486 static void kbd_devs_reclaim(void)487 {488 /* For each keyboard device */489 list_foreach(kbd_devs, kdev_link) {490 kbd_dev_t *kdev = list_get_instance(kdev_link, kbd_dev_t,491 kbd_devs);492 493 /* Reclaim port */494 if (kdev->port_ops != NULL)495 (*kdev->port_ops->reclaim)();496 }497 }498 499 579 static int dev_check_new_kbdevs(void) 500 580 { … … 525 605 526 606 /* Determine whether we already know this device. */ 527 list_foreach(kbd_devs, kdev_link) { 528 kbd_dev_t *kdev = list_get_instance(kdev_link, 529 kbd_dev_t, kbd_devs); 607 list_foreach(kbd_devs, link, kbd_dev_t, kdev) { 530 608 if (kdev->svc_id == svcs[i]) { 531 609 already_known = true; … … 578 656 579 657 /* Determine whether we already know this device. */ 580 list_foreach(mouse_devs, mdev_link) { 581 mouse_dev_t *mdev = list_get_instance(mdev_link, 582 mouse_dev_t, mouse_devs); 658 list_foreach(mouse_devs, link, mouse_dev_t, mdev) { 583 659 if (mdev->svc_id == svcs[i]) { 584 660 already_known = true; … … 634 710 static int input_start_dev_discovery(void) 635 711 { 636 int rc; 637 638 rc = loc_register_cat_change_cb(cat_change_cb); 712 int rc = loc_register_cat_change_cb(cat_change_cb); 639 713 if (rc != EOK) { 640 714 printf("%s: Failed registering callback for device discovery. " … … 642 716 return rc; 643 717 } 644 718 645 719 return dev_check_new(); 646 720 } … … 662 736 sysarg_t obio; 663 737 738 list_initialize(&clients); 664 739 list_initialize(&kbd_devs); 665 740 list_initialize(&mouse_devs); … … 681 756 682 757 /* Register driver */ 758 async_set_client_data_constructor(client_data_create); 759 async_set_client_data_destructor(client_data_destroy); 683 760 async_set_client_connection(client_connection); 761 684 762 int rc = loc_server_register(NAME); 685 763 if (rc != EOK) { … … 694 772 return rc; 695 773 } 774 775 /* Receive kernel notifications */ 776 rc = async_event_subscribe(EVENT_KCONSOLE, kconsole_event_handler, NULL); 777 if (rc != EOK) 778 printf("%s: Failed to register kconsole notifications (%s)\n", 779 NAME, str_error(rc)); 696 780 697 781 /* Start looking for new input devices */
Note:
See TracChangeset
for help on using the changeset viewer.