Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhid/mouse/mousedev.c

    r2b621cb r5cc9eba  
    5252#include "../usbhid.h"
    5353
    54 /** Number of simulated arrow-key presses for singel wheel step. */
    55 #define ARROWS_PER_SINGLE_WHEEL 3
    56 
    5754#define NAME "mouse"
    5855
    59 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
    60 
    61 static ddf_dev_ops_t ops = { .default_handler = default_connection_handler };
    62 
    63 /*----------------------------------------------------------------------------*/
     56/*----------------------------------------------------------------------------*/
     57
    6458const usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = {
    6559        .transfer_type = USB_TRANSFER_INTERRUPT,
     
    7266
    7367const char *HID_MOUSE_FUN_NAME = "mouse";
    74 const char *HID_MOUSE_WHEEL_FUN_NAME = "mouse-wheel";
    7568const char *HID_MOUSE_CATEGORY = "mouse";
    76 const char *HID_MOUSE_WHEEL_CATEGORY = "keyboard";
    7769
    7870/** Default idle rate for mouses. */
     
    129121
    130122        usb_log_debug("%s: fun->name: %s\n", __FUNCTION__, fun->name);
    131         usb_log_debug("%s: mouse_sess: %p, wheel_sess: %p\n",
    132             __FUNCTION__, mouse_dev->mouse_sess, mouse_dev->wheel_sess);
    133 
    134         async_sess_t **sess_ptr = (fun == mouse_dev->mouse_fun) ?
    135             &mouse_dev->mouse_sess : &mouse_dev->wheel_sess;
     123        usb_log_debug("%s: mouse_sess: %p\n",
     124            __FUNCTION__, mouse_dev->mouse_sess);
    136125
    137126        async_sess_t *sess =
    138127            async_callback_receive_start(EXCHANGE_SERIALIZE, icall);
    139128        if (sess != NULL) {
    140                 if (*sess_ptr == NULL) {
    141                         *sess_ptr = sess;
     129                if (mouse_dev->mouse_sess == NULL) {
     130                        mouse_dev->mouse_sess = sess;
    142131                        usb_log_debug("Console session to %s set ok (%p).\n",
    143132                            fun->name, sess);
     
    147136                            fun->name);
    148137                        async_answer_0(icallid, ELIMIT);
     138                        async_hangup(sess);
    149139                }
    150140        } else {
     
    153143        }
    154144}
    155 
    156 /*----------------------------------------------------------------------------*/
    157 
    158 static void usb_mouse_send_wheel(const usb_mouse_t *mouse_dev, int wheel)
    159 {
    160         unsigned int key = (wheel > 0) ? KC_UP : KC_DOWN;
    161 
    162         if (mouse_dev->wheel_sess == NULL) {
    163                 usb_log_warning(
    164                     "Connection to console not ready, wheel roll discarded.\n");
    165                 return;
    166         }
    167 
    168         const unsigned count =
    169             ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL;
    170         for (unsigned i = 0; i < count; i++) {
    171                 /* Send arrow press and release. */
    172                 usb_log_debug2("Sending key %d to the console\n", key);
    173                
    174                 async_exch_t *exch = async_exchange_begin(mouse_dev->wheel_sess);
    175                
    176                 async_msg_4(exch, KBDEV_EVENT, KEY_PRESS, key, 0, 0);
    177                 async_msg_4(exch, KBDEV_EVENT, KEY_RELEASE, key, 0, 0);
    178                
    179                 async_exchange_end(exch);
    180         }
    181 }
    182 
    183 /*----------------------------------------------------------------------------*/
    184 
     145/*----------------------------------------------------------------------------*/
    185146static int get_mouse_axis_move_value(uint8_t rid, usb_hid_report_t *report,
    186147    int32_t usage)
     
    224185            &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL);
    225186
    226         if ((shift_x != 0) || (shift_y != 0)) {
     187        if (shift_x || shift_y || wheel) {
    227188                async_exch_t *exch =
    228189                    async_exchange_begin(mouse_dev->mouse_sess);
    229190                if (exch != NULL) {
    230                         async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y);
     191                        async_msg_3(exch, MOUSEEV_MOVE_EVENT,
     192                            shift_x, shift_y, wheel);
    231193                        async_exchange_end(exch);
    232194                }
    233195        }
    234 
    235         if (wheel != 0)
    236                 usb_mouse_send_wheel(mouse_dev, wheel);
    237196
    238197        /* Buttons */
     
    262221                assert(index < mouse_dev->buttons_count);
    263222
    264                 if (mouse_dev->buttons[index] != field->value) {
     223                if (mouse_dev->buttons[index] == 0 && field->value != 0) {
    265224                        async_exch_t *exch =
    266225                            async_exchange_begin(mouse_dev->mouse_sess);
    267226                        if (exch != NULL) {
    268227                                async_req_2_0(exch, MOUSEEV_BUTTON_EVENT,
    269                                     field->usage, (field->value != 0) ? 1 : 0);
     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) {
     234                        async_exch_t *exch =
     235                            async_exchange_begin(mouse_dev->mouse_sess);
     236                        if (exch != NULL) {
     237                                async_req_2_0(exch, MOUSEEV_BUTTON_EVENT,
     238                                    field->usage, 0);
    270239                                async_exchange_end(exch);
    271240                                mouse_dev->buttons[index] = field->value;
     
    310279        }
    311280
    312         fun->ops = &ops;
     281        fun->ops = &mouse->ops;
    313282        fun->driver_data = mouse;
    314283
     
    334303        mouse->mouse_fun = fun;
    335304
    336         /*
    337          * Special function for acting as keyboard (wheel)
    338          */
    339         usb_log_debug("Creating DDF function %s...\n",
    340                       HID_MOUSE_WHEEL_FUN_NAME);
    341         fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
    342             HID_MOUSE_WHEEL_FUN_NAME);
    343         if (fun == NULL) {
    344                 usb_log_error("Could not create DDF function node `%s'.\n",
    345                     HID_MOUSE_WHEEL_FUN_NAME);
    346                 FUN_UNBIND_DESTROY(mouse->mouse_fun);
    347                 mouse->mouse_fun = NULL;
    348                 return ENOMEM;
    349         }
    350 
    351         /*
    352          * Store the initialized HID device and HID ops
    353          * to the DDF function.
    354          */
    355         fun->ops = &ops;
    356         fun->driver_data = mouse;
    357 
    358         rc = ddf_fun_bind(fun);
    359         if (rc != EOK) {
    360                 usb_log_error("Could not bind DDF function `%s': %s.\n",
    361                     fun->name, str_error(rc));
    362                 FUN_UNBIND_DESTROY(mouse->mouse_fun);
    363                 mouse->mouse_fun = NULL;
    364 
    365                 fun->driver_data = NULL;
    366                 ddf_fun_destroy(fun);
    367                 return rc;
    368         }
    369 
    370         usb_log_debug("Adding DDF function to category %s...\n",
    371             HID_MOUSE_WHEEL_CATEGORY);
    372         rc = ddf_fun_add_to_category(fun, HID_MOUSE_WHEEL_CATEGORY);
    373         if (rc != EOK) {
    374                 usb_log_error(
    375                     "Could not add DDF function to category %s: %s.\n",
    376                     HID_MOUSE_WHEEL_CATEGORY, str_error(rc));
    377 
    378                 FUN_UNBIND_DESTROY(mouse->mouse_fun);
    379                 mouse->mouse_fun = NULL;
    380                 FUN_UNBIND_DESTROY(fun);
    381                 return rc;
    382         }
    383         mouse->wheel_fun = fun;
    384 
    385305        return EOK;
    386306}
    387 
    388 /*----------------------------------------------------------------------------*/
    389307
    390308/** Get highest index of a button mentioned in given report.
     
    461379        }
    462380
     381        // set handler for incoming calls
     382        mouse_dev->ops.default_handler = default_connection_handler;
     383
    463384        // TODO: how to know if the device supports the request???
    464385        usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
     
    506427        }
    507428
    508         if (mouse_dev->wheel_sess != NULL) {
    509                 const int ret = async_hangup(mouse_dev->wheel_sess);
    510                 if (ret != EOK)
    511                         usb_log_warning("Failed to hang up wheel session: "
    512                             "%p, %s.\n", mouse_dev->wheel_sess, str_error(ret));
    513         }
    514 
    515429        FUN_UNBIND_DESTROY(mouse_dev->mouse_fun);
    516         FUN_UNBIND_DESTROY(mouse_dev->wheel_fun);
    517430
    518431        free(mouse_dev->buttons);
Note: See TracChangeset for help on using the changeset viewer.