Ignore:
File:
1 edited

Legend:

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

    r5f6e25e r4093b14  
    4242#include <errno.h>
    4343#include <async.h>
    44 #include <async_obsolete.h>
    4544#include <str_error.h>
    4645#include <ipc/mouseev.h>
     
    5655#define ARROWS_PER_SINGLE_WHEEL 3
    5756
    58 // FIXME: remove this header
    59 #include <abi/ipc/methods.h>
    60 
    61 #define NAME "mouse"
     57#define NAME  "mouse"
    6258
    6359/*----------------------------------------------------------------------------*/
     
    7975/** Default idle rate for mouses. */
    8076static const uint8_t IDLE_RATE = 0;
    81 static const size_t USB_MOUSE_BUTTON_COUNT = 3;
    8277
    8378/*----------------------------------------------------------------------------*/
     
    128123    ipc_callid_t icallid, ipc_call_t *icall)
    129124{
    130         sysarg_t method = IPC_GET_IMETHOD(*icall);
    131        
    132         usb_mouse_t *mouse_dev = (usb_mouse_t *)fun->driver_data;
     125        usb_mouse_t *mouse_dev = (usb_mouse_t *) fun->driver_data;
    133126       
    134127        if (mouse_dev == NULL) {
     
    141134        usb_log_debug("default_connection_handler: fun->name: %s\n",
    142135                      fun->name);
    143         usb_log_debug("default_connection_handler: mouse_phone: %d, wheel "
    144             "phone: %d\n", mouse_dev->mouse_phone, mouse_dev->wheel_phone);
    145        
    146         int *phone = (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0)
    147                      ? &mouse_dev->mouse_phone : &mouse_dev->wheel_phone;
    148        
    149         if (method == IPC_M_CONNECT_TO_ME) {
    150                 int callback = IPC_GET_ARG5(*icall);
    151 
    152                 if (*phone != -1) {
     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;
     142       
     143        async_sess_t *sess =
     144            async_callback_receive_start(EXCHANGE_SERIALIZE, icall);
     145        if (sess != NULL) {
     146                if (*sess_ptr == NULL) {
     147                        *sess_ptr = sess;
     148                        usb_log_debug("Console session to mouse set ok (%p).\n",
     149                            sess);
     150                        async_answer_0(icallid, EOK);
     151                } else {
    153152                        usb_log_debug("default_connection_handler: Console "
    154                             "phone to mouse already set.\n");
     153                            "session to mouse already set.\n");
    155154                        async_answer_0(icallid, ELIMIT);
    156                         return;
    157155                }
    158 
    159                 *phone = callback;
    160                 usb_log_debug("Console phone to mouse set ok (%d).\n", *phone);
    161                 async_answer_0(icallid, EOK);
    162                 return;
    163         }
    164 
    165         usb_log_debug("default_connection_handler: Invalid function.\n");
    166         async_answer_0(icallid, EINVAL);
     156        } else {
     157                usb_log_debug("default_connection_handler: Invalid function.\n");
     158                async_answer_0(icallid, EINVAL);
     159        }
    167160}
    168161
     
    175168                return NULL;
    176169        }
    177         mouse->mouse_phone = -1;
    178         mouse->wheel_phone = -1;
     170        mouse->mouse_sess = NULL;
     171        mouse->wheel_sess = NULL;
    179172       
    180173        return mouse;
     
    187180        assert(mouse_dev != NULL);
    188181       
    189         // hangup phone to the console
    190         if (mouse_dev->mouse_phone >= 0) {
    191                 async_obsolete_hangup(mouse_dev->mouse_phone);
    192         }
    193        
    194         if (mouse_dev->wheel_phone >= 0) {
    195                 async_obsolete_hangup(mouse_dev->wheel_phone);
    196         }
     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);
    197188}
    198189
     
    203194        unsigned int key = (wheel > 0) ? KC_UP : KC_DOWN;
    204195
    205         if (mouse_dev->wheel_phone < 0) {
     196        if (mouse_dev->wheel_sess == NULL) {
    206197                usb_log_warning(
    207198                    "Connection to console not ready, wheel roll discarded.\n");
     
    215206                /* Send arrow press and release. */
    216207                usb_log_debug2("Sending key %d to the console\n", key);
    217                 async_obsolete_msg_4(mouse_dev->wheel_phone, KBDEV_EVENT,
    218                     KEY_PRESS, key, 0, 0);
    219                 async_obsolete_msg_4(mouse_dev->wheel_phone, KBDEV_EVENT,
    220                     KEY_RELEASE, key, 0, 0);
     208               
     209                async_exch_t *exch = async_exchange_begin(mouse_dev->wheel_sess);
     210               
     211                async_msg_4(exch, KBDEV_EVENT, KEY_PRESS, key, 0, 0);
     212                async_msg_4(exch, KBDEV_EVENT, KEY_RELEASE, key, 0, 0);
     213               
     214                async_exchange_end(exch);
    221215        }
    222216}
     
    253247        assert(mouse_dev != NULL);
    254248       
    255         if (mouse_dev->mouse_phone < 0) {
    256                 usb_log_warning(NAME " No console phone.\n");
     249        if (mouse_dev->mouse_sess == NULL) {
     250                usb_log_warning(NAME " No console session.\n");
    257251                return true;
    258252        }
     
    266260
    267261        if ((shift_x != 0) || (shift_y != 0)) {
    268                 async_obsolete_req_2_0(mouse_dev->mouse_phone,
    269                     MOUSEEV_MOVE_EVENT, shift_x, shift_y);
    270         }
    271 
    272         if (wheel != 0) {
     262                async_exch_t *exch = async_exchange_begin(mouse_dev->mouse_sess);
     263                async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y);
     264                async_exchange_end(exch);
     265        }
     266       
     267        if (wheel != 0)
    273268                usb_mouse_send_wheel(mouse_dev, wheel);
    274         }
    275269       
    276270        /*
     
    292286                if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0
    293287                    && field->value != 0) {
    294                         async_obsolete_req_2_0(mouse_dev->mouse_phone,
    295                             MOUSEEV_BUTTON_EVENT, field->usage, 1);
     288                        async_exch_t *exch =
     289                            async_exchange_begin(mouse_dev->mouse_sess);
     290                        async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 1);
     291                        async_exchange_end(exch);
     292                       
    296293                        mouse_dev->buttons[field->usage - field->usage_minimum]
    297294                            = field->value;
    298295                } else if (mouse_dev->buttons[field->usage - field->usage_minimum] != 0
    299296                    && field->value == 0) {
    300                         async_obsolete_req_2_0(mouse_dev->mouse_phone,
    301                            MOUSEEV_BUTTON_EVENT, field->usage, 0);
     297                        async_exch_t *exch =
     298                            async_exchange_begin(mouse_dev->mouse_sess);
     299                        async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 0);
     300                        async_exchange_end(exch);
     301                       
    302302                        mouse_dev->buttons[field->usage - field->usage_minimum] =
    303303                           field->value;
     
    396396/*----------------------------------------------------------------------------*/
    397397
     398/** Get highest index of a button mentioned in given report.
     399 *
     400 * @param report HID report.
     401 * @param report_id Report id we are interested in.
     402 * @return Highest button mentioned in the report.
     403 * @retval 1 No button was mentioned.
     404 *
     405 */
     406static size_t usb_mouse_get_highest_button(usb_hid_report_t *report, uint8_t report_id)
     407{
     408        size_t highest_button = 0;
     409
     410        usb_hid_report_path_t *path = usb_hid_report_path();
     411        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0);
     412        usb_hid_report_path_set_report_id(path, report_id);
     413
     414        usb_hid_report_field_t *field = NULL;
     415
     416        /* Break from within. */
     417        while (1) {
     418                field = usb_hid_report_get_sibling(
     419                    report, field, path,
     420                    USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     421                    USB_HID_REPORT_TYPE_INPUT);
     422                /* No more buttons? */
     423                if (field == NULL) {
     424                        break;
     425                }
     426
     427                size_t current_button = field->usage - field->usage_minimum;
     428                if (current_button > highest_button) {
     429                        highest_button = current_button;
     430                }
     431        }
     432
     433        usb_hid_report_path_free(path);
     434
     435        return highest_button;
     436}
     437
     438/*----------------------------------------------------------------------------*/
     439
    398440int usb_mouse_init(usb_hid_dev_t *hid_dev, void **data)
    399441{
     
    413455        }
    414456       
    415         mouse_dev->buttons = (int32_t *)calloc(USB_MOUSE_BUTTON_COUNT,
    416             sizeof(int32_t));
     457        // FIXME: This may not be optimal since stupid hardware vendor may
     458        // use buttons 1, 2, 3 and 6000 and we would allocate array of
     459        // 6001*4B and use only 4 items in it.
     460        // Since I doubt that hardware producers would do that, I think
     461        // that the current solution is good enough.
     462        /* Adding 1 because we will be accessing buttons[highest]. */
     463        mouse_dev->buttons_count = usb_mouse_get_highest_button(hid_dev->report,
     464            hid_dev->report_id) + 1;
     465        mouse_dev->buttons = calloc(mouse_dev->buttons_count, sizeof(int32_t));
    417466       
    418467        if (mouse_dev->buttons == NULL) {
    419                 usb_log_fatal("No memory!\n");
     468                usb_log_error(NAME ": out of memory, giving up on device!\n");
    420469                free(mouse_dev);
    421470                return ENOMEM;
    422471        }
    423        
     472
     473
    424474        // save the Mouse device structure into the HID device structure
    425475        *data = mouse_dev;
Note: See TracChangeset for help on using the changeset viewer.