Changes in uspace/drv/bus/usb/usbhid/mouse/mousedev.c [b803845:9d58539] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhid/mouse/mousedev.c
rb803845 r9d58539 52 52 #include "../usbhid.h" 53 53 54 /** Number of simulated arrow-key presses for singel wheel step. */ 55 #define ARROWS_PER_SINGLE_WHEEL 3 56 57 #define NAME "mouse" 54 #define NAME "mouse" 58 55 59 56 /*----------------------------------------------------------------------------*/ … … 69 66 70 67 const char *HID_MOUSE_FUN_NAME = "mouse"; 71 const char *HID_MOUSE_WHEEL_FUN_NAME = "mouse-wheel";72 68 const char *HID_MOUSE_CATEGORY = "mouse"; 73 const char *HID_MOUSE_WHEEL_CATEGORY = "keyboard";74 69 75 70 /** Default idle rate for mouses. */ … … 77 72 78 73 /*----------------------------------------------------------------------------*/ 79 80 enum { 81 USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE = 63 82 }; 83 84 static const uint8_t USB_MOUSE_BOOT_REPORT_DESCRIPTOR[ 85 USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE] = { 74 static const uint8_t USB_MOUSE_BOOT_REPORT_DESCRIPTOR[] = { 86 75 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 87 76 0x09, 0x02, // USAGE (Mouse) … … 123 112 ipc_callid_t icallid, ipc_call_t *icall) 124 113 { 125 usb_mouse_t *mouse_dev = (usb_mouse_t *)fun->driver_data;114 usb_mouse_t *mouse_dev = fun->driver_data; 126 115 127 116 if (mouse_dev == NULL) { 128 usb_log_debug("default_connection_handler: Missing " 129 "parameters.\n"); 117 usb_log_debug("%s: Missing parameters.\n", __FUNCTION__); 130 118 async_answer_0(icallid, EINVAL); 131 119 return; 132 120 } 133 121 134 usb_log_debug("default_connection_handler: fun->name: %s\n", 135 fun->name); 136 usb_log_debug("default_connection_handler: mouse_sess: %p, " 137 "wheel_sess: %p\n", mouse_dev->mouse_sess, mouse_dev->wheel_sess); 138 139 async_sess_t **sess_ptr = 140 (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0) ? 141 &mouse_dev->mouse_sess : &mouse_dev->wheel_sess; 122 usb_log_debug("%s: fun->name: %s\n", __FUNCTION__, fun->name); 123 usb_log_debug("%s: mouse_sess: %p\n", 124 __FUNCTION__, mouse_dev->mouse_sess); 142 125 143 126 async_sess_t *sess = 144 127 async_callback_receive_start(EXCHANGE_SERIALIZE, icall); 145 128 if (sess != NULL) { 146 if ( *sess_ptr== NULL) {147 *sess_ptr= sess;148 usb_log_debug("Console session to mouseset ok (%p).\n",149 sess);129 if (mouse_dev->mouse_sess == NULL) { 130 mouse_dev->mouse_sess = sess; 131 usb_log_debug("Console session to %s set ok (%p).\n", 132 fun->name, sess); 150 133 async_answer_0(icallid, EOK); 151 134 } else { 152 usb_log_ debug("default_connection_handler: Console "153 "session to mouse already set.\n");135 usb_log_error("Console session to %s already set.\n", 136 fun->name); 154 137 async_answer_0(icallid, ELIMIT); 138 async_hangup(sess); 155 139 } 156 140 } else { 157 usb_log_debug(" default_connection_handler: Invalid function.\n");141 usb_log_debug("%s: Invalid function.\n", __FUNCTION__); 158 142 async_answer_0(icallid, EINVAL); 159 143 } 160 144 } 161 162 /*----------------------------------------------------------------------------*/ 163 164 static usb_mouse_t *usb_mouse_new(void) 165 { 166 usb_mouse_t *mouse = calloc(1, sizeof(usb_mouse_t)); 167 if (mouse == NULL) { 168 return NULL; 169 } 170 mouse->mouse_sess = NULL; 171 mouse->wheel_sess = NULL; 172 173 return mouse; 174 } 175 176 /*----------------------------------------------------------------------------*/ 177 178 static void usb_mouse_destroy(usb_mouse_t *mouse_dev) 179 { 180 assert(mouse_dev != NULL); 181 182 // hangup session to the console 183 if (mouse_dev->mouse_sess != NULL) 184 async_hangup(mouse_dev->mouse_sess); 185 186 if (mouse_dev->wheel_sess != NULL) 187 async_hangup(mouse_dev->wheel_sess); 188 int ret = ddf_fun_unbind(mouse_dev->mouse_fun); 189 if (ret != EOK) { 190 usb_log_error("Failed to unbind mouse function.\n"); 191 } else { 192 ddf_fun_destroy(mouse_dev->mouse_fun); 193 /* Prevent double free */ 194 mouse_dev->wheel_fun->driver_data = NULL; 195 } 196 197 ret = ddf_fun_unbind(mouse_dev->wheel_fun); 198 if (ret != EOK) { 199 usb_log_error("Failed to unbind wheel function.\n"); 200 } else { 201 ddf_fun_destroy(mouse_dev->wheel_fun); 202 } 203 } 204 205 /*----------------------------------------------------------------------------*/ 206 207 static void usb_mouse_send_wheel(const usb_mouse_t *mouse_dev, int wheel) 208 { 209 unsigned int key = (wheel > 0) ? KC_UP : KC_DOWN; 210 211 if (mouse_dev->wheel_sess == NULL) { 212 usb_log_warning( 213 "Connection to console not ready, wheel roll discarded.\n"); 214 return; 215 } 216 217 int count = ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL; 218 int i; 219 220 for (i = 0; i < count; i++) { 221 /* Send arrow press and release. */ 222 usb_log_debug2("Sending key %d to the console\n", key); 223 224 async_exch_t *exch = async_exchange_begin(mouse_dev->wheel_sess); 225 226 async_msg_4(exch, KBDEV_EVENT, KEY_PRESS, key, 0, 0); 227 async_msg_4(exch, KBDEV_EVENT, KEY_RELEASE, key, 0, 0); 228 229 async_exchange_end(exch); 230 } 231 } 232 233 /*----------------------------------------------------------------------------*/ 234 145 /*----------------------------------------------------------------------------*/ 235 146 static int get_mouse_axis_move_value(uint8_t rid, usb_hid_report_t *report, 236 147 int32_t usage) … … 267 178 } 268 179 269 int shift_x = get_mouse_axis_move_value(hid_dev->report_id,180 const int shift_x = get_mouse_axis_move_value(hid_dev->report_id, 270 181 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_X); 271 int shift_y = get_mouse_axis_move_value(hid_dev->report_id,182 const int shift_y = get_mouse_axis_move_value(hid_dev->report_id, 272 183 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_Y); 273 int wheel = get_mouse_axis_move_value(hid_dev->report_id,184 const int wheel = get_mouse_axis_move_value(hid_dev->report_id, 274 185 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL); 275 186 276 if ( (shift_x != 0) || (shift_y != 0)) {187 if (shift_x || shift_y || wheel) { 277 188 async_exch_t *exch = 278 189 async_exchange_begin(mouse_dev->mouse_sess); 279 async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y); 280 async_exchange_end(exch); 281 } 282 283 if (wheel != 0) 284 usb_mouse_send_wheel(mouse_dev, wheel); 285 286 /* 287 * Buttons 288 */ 190 if (exch != NULL) { 191 async_msg_3(exch, MOUSEEV_MOVE_EVENT, 192 shift_x, shift_y, wheel); 193 async_exchange_end(exch); 194 } 195 } 196 197 /* Buttons */ 289 198 usb_hid_report_path_t *path = usb_hid_report_path(); 290 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0); 199 if (path == NULL) { 200 usb_log_warning("Failed to create USB HID report path.\n"); 201 return true; 202 } 203 int ret = 204 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0); 205 if (ret != EOK) { 206 usb_hid_report_path_free(path); 207 usb_log_warning("Failed to add buttons to report path.\n"); 208 return true; 209 } 291 210 usb_hid_report_path_set_report_id(path, hid_dev->report_id); 292 211 … … 298 217 usb_log_debug2(NAME " VALUE(%X) USAGE(%X)\n", field->value, 299 218 field->usage); 300 301 if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0 302 && field->value != 0) { 219 assert(field->usage > field->usage_minimum); 220 const unsigned index = field->usage - field->usage_minimum; 221 assert(index < mouse_dev->buttons_count); 222 223 if (mouse_dev->buttons[index] == 0 && field->value != 0) { 303 224 async_exch_t *exch = 304 225 async_exchange_begin(mouse_dev->mouse_sess); 305 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 1); 306 async_exchange_end(exch); 307 308 mouse_dev->buttons[field->usage - field->usage_minimum] 309 = field->value; 310 } else if (mouse_dev->buttons[field->usage - field->usage_minimum] != 0 311 && field->value == 0) { 226 if (exch != NULL) { 227 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, 228 field->usage, 1); 229 async_exchange_end(exch); 230 mouse_dev->buttons[index] = field->value; 231 } 232 233 } else if (mouse_dev->buttons[index] != 0 && field->value == 0) { 312 234 async_exch_t *exch = 313 235 async_exchange_begin(mouse_dev->mouse_sess); 314 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 0); 315 async_exchange_end(exch); 316 317 mouse_dev->buttons[field->usage - field->usage_minimum] = 318 field->value; 236 if (exch != NULL) { 237 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, 238 field->usage, 0); 239 async_exchange_end(exch); 240 mouse_dev->buttons[index] = field->value; 241 } 319 242 } 320 243 … … 329 252 return true; 330 253 } 331 332 /*----------------------------------------------------------------------------*/ 333 254 /*----------------------------------------------------------------------------*/ 255 #define FUN_UNBIND_DESTROY(fun) \ 256 if (fun) { \ 257 if (ddf_fun_unbind((fun)) == EOK) { \ 258 (fun)->driver_data = NULL; \ 259 ddf_fun_destroy((fun)); \ 260 } else { \ 261 usb_log_error("Could not unbind function `%s', it " \ 262 "will not be destroyed.\n", (fun)->name); \ 263 } \ 264 } else (void)0 265 /*----------------------------------------------------------------------------*/ 334 266 static int usb_mouse_create_function(usb_hid_dev_t *hid_dev, usb_mouse_t *mouse) 335 267 { … … 339 271 /* Create the exposed function. */ 340 272 usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME); 341 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 273 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 342 274 HID_MOUSE_FUN_NAME); 343 275 if (fun == NULL) { 344 usb_log_error("Could not create DDF function node.\n"); 276 usb_log_error("Could not create DDF function node `%s'.\n", 277 HID_MOUSE_FUN_NAME); 345 278 return ENOMEM; 346 279 } … … 351 284 int rc = ddf_fun_bind(fun); 352 285 if (rc != EOK) { 353 usb_log_error("Could not bind DDF function: %s.\n", 354 str_error(rc)); 286 usb_log_error("Could not bind DDF function `%s': %s.\n", 287 fun->name, str_error(rc)); 288 fun->driver_data = NULL; 289 ddf_fun_destroy(fun); 355 290 return rc; 356 291 } 357 292 358 usb_log_debug("Adding DDF function to category %s...\n",359 HID_MOUSE_CATEGORY);293 usb_log_debug("Adding DDF function `%s' to category %s...\n", 294 fun->name, HID_MOUSE_CATEGORY); 360 295 rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY); 361 296 if (rc != EOK) { … … 363 298 "Could not add DDF function to category %s: %s.\n", 364 299 HID_MOUSE_CATEGORY, str_error(rc)); 300 FUN_UNBIND_DESTROY(fun); 365 301 return rc; 366 302 } 367 303 mouse->mouse_fun = fun; 368 304 369 /*370 * Special function for acting as keyboard (wheel)371 */372 usb_log_debug("Creating DDF function %s...\n",373 HID_MOUSE_WHEEL_FUN_NAME);374 fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,375 HID_MOUSE_WHEEL_FUN_NAME);376 if (fun == NULL) {377 usb_log_error("Could not create DDF function node.\n");378 return ENOMEM;379 }380 381 /*382 * Store the initialized HID device and HID ops383 * to the DDF function.384 */385 fun->ops = &mouse->ops;386 fun->driver_data = mouse;387 388 rc = ddf_fun_bind(fun);389 if (rc != EOK) {390 usb_log_error("Could not bind DDF function: %s.\n",391 str_error(rc));392 return rc;393 }394 395 usb_log_debug("Adding DDF function to category %s...\n",396 HID_MOUSE_WHEEL_CATEGORY);397 rc = ddf_fun_add_to_category(fun, HID_MOUSE_WHEEL_CATEGORY);398 if (rc != EOK) {399 usb_log_error(400 "Could not add DDF function to category %s: %s.\n",401 HID_MOUSE_WHEEL_CATEGORY, str_error(rc));402 return rc;403 }404 mouse->wheel_fun = fun;405 406 305 return EOK; 407 306 } 408 409 /*----------------------------------------------------------------------------*/410 307 411 308 /** Get highest index of a button mentioned in given report. … … 448 345 return highest_button; 449 346 } 450 451 /*----------------------------------------------------------------------------*/ 452 347 /*----------------------------------------------------------------------------*/ 453 348 int usb_mouse_init(usb_hid_dev_t *hid_dev, void **data) 454 349 { … … 461 356 } 462 357 463 usb_mouse_t *mouse_dev = usb_mouse_new();358 usb_mouse_t *mouse_dev = calloc(1, sizeof(usb_mouse_t)); 464 359 if (mouse_dev == NULL) { 465 360 usb_log_error("Error while creating USB/HID Mouse device " … … 484 379 } 485 380 486 487 // save the Mouse device structure into the HID device structure488 *data = mouse_dev;489 490 381 // set handler for incoming calls 491 382 mouse_dev->ops.default_handler = default_connection_handler; 492 383 493 384 // TODO: how to know if the device supports the request??? 494 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 385 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 495 386 hid_dev->usb_dev->interface_no, IDLE_RATE); 496 387 497 388 int rc = usb_mouse_create_function(hid_dev, mouse_dev); 498 389 if (rc != EOK) { 499 usb_mouse_destroy(mouse_dev); 390 free(mouse_dev->buttons); 391 free(mouse_dev); 500 392 return rc; 501 393 } 502 394 395 /* Save the Mouse device structure into the HID device structure. */ 396 *data = mouse_dev; 397 503 398 return EOK; 504 399 } 505 506 /*----------------------------------------------------------------------------*/ 507 400 /*----------------------------------------------------------------------------*/ 508 401 bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data) 509 402 { 510 403 if (hid_dev == NULL || data == NULL) { 511 usb_log_error( "Missing argument to the mouse polling callback."512 " \n");404 usb_log_error( 405 "Missing argument to the mouse polling callback.\n"); 513 406 return false; 514 407 } 515 408 516 usb_mouse_t *mouse_dev = (usb_mouse_t *)data;517 409 usb_mouse_t *mouse_dev = data; 410 518 411 return usb_mouse_process_report(hid_dev, mouse_dev); 519 412 } 520 521 /*----------------------------------------------------------------------------*/ 522 413 /*----------------------------------------------------------------------------*/ 523 414 void usb_mouse_deinit(usb_hid_dev_t *hid_dev, void *data) 524 415 { 525 if (data != NULL) { 526 usb_mouse_destroy(data); 527 } 528 } 529 530 /*----------------------------------------------------------------------------*/ 531 416 if (data == NULL) 417 return; 418 419 usb_mouse_t *mouse_dev = data; 420 421 /* Hangup session to the console */ 422 if (mouse_dev->mouse_sess != NULL) { 423 const int ret = async_hangup(mouse_dev->mouse_sess); 424 if (ret != EOK) 425 usb_log_warning("Failed to hang up mouse session: " 426 "%p, %s.\n", mouse_dev->mouse_sess, str_error(ret)); 427 } 428 429 FUN_UNBIND_DESTROY(mouse_dev->mouse_fun); 430 431 free(mouse_dev->buttons); 432 free(mouse_dev); 433 } 434 /*----------------------------------------------------------------------------*/ 532 435 int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev) 533 436 { 534 437 int rc = usb_hid_parse_report_descriptor( 535 438 &hid_dev->report, USB_MOUSE_BOOT_REPORT_DESCRIPTOR, 536 USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE);439 sizeof(USB_MOUSE_BOOT_REPORT_DESCRIPTOR)); 537 440 538 441 if (rc != EOK) {
Note:
See TracChangeset
for help on using the changeset viewer.