Ignore:
File:
1 edited

Legend:

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

    r310c4df rf90c0d6  
    4343#include <str_error.h>
    4444#include <ipc/mouse.h>
     45#include <io/console.h>
     46
     47#include <ipc/kbd.h>
     48#include <io/keycode.h>
    4549
    4650#include "mousedev.h"
     
    6165
    6266const char *HID_MOUSE_FUN_NAME = "mouse";
     67const char *HID_MOUSE_WHEEL_FUN_NAME = "mouse-wheel";
    6368const char *HID_MOUSE_CLASS_NAME = "mouse";
     69const char *HID_MOUSE_WHEEL_CLASS_NAME = "keyboard";
    6470
    6571/** Default idle rate for mouses. */
     
    119125       
    120126        if (hid_dev == NULL || hid_dev->data == NULL) {
     127                usb_log_debug("default_connection_handler: Missing "
     128                    "parameters.\n");
    121129                async_answer_0(icallid, EINVAL);
    122130                return;
     
    127135        usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data;
    128136       
     137        int *phone = (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0)
     138                     ? &mouse_dev->mouse_phone : &mouse_dev->wheel_phone;
     139       
    129140        if (method == IPC_M_CONNECT_TO_ME) {
    130141                int callback = IPC_GET_ARG5(*icall);
    131142
    132                 if (mouse_dev->console_phone != -1) {
     143                if (*phone != -1) {
     144                        usb_log_debug("default_connection_handler: Console "
     145                            "phone to mouse already set.\n");
    133146                        async_answer_0(icallid, ELIMIT);
     147                        //async_answer_0(icallid, EOK);
    134148                        return;
    135149                }
    136150
    137                 mouse_dev->console_phone = callback;
     151                *phone = callback;
    138152                usb_log_debug("Console phone to mouse set ok (%d).\n", callback);
    139153                async_answer_0(icallid, EOK);
     
    141155        }
    142156
     157        usb_log_debug("default_connection_handler: Invalid function.\n");
    143158        async_answer_0(icallid, EINVAL);
    144159}
     
    152167                return NULL;
    153168        }
    154         mouse->console_phone = -1;
     169        mouse->mouse_phone = -1;
     170        mouse->wheel_phone = -1;
    155171       
    156172        return mouse;
     
    164180       
    165181        // hangup phone to the console
    166         if ((*mouse_dev)->console_phone >= 0) {
    167                 async_hangup((*mouse_dev)->console_phone);
     182        if ((*mouse_dev)->mouse_phone >= 0) {
     183                async_hangup((*mouse_dev)->mouse_phone);
     184        }
     185       
     186        if ((*mouse_dev)->wheel_phone >= 0) {
     187                async_hangup((*mouse_dev)->wheel_phone);
    168188        }
    169189       
     
    174194/*----------------------------------------------------------------------------*/
    175195
    176 static bool usb_mouse_process_boot_report(usb_hid_dev_t *hid_dev,
    177     uint8_t *buffer, size_t buffer_size)
     196static void usb_mouse_send_wheel(const usb_mouse_t *mouse_dev, int wheel)
     197{
     198        console_event_t ev;
     199       
     200        ev.type = KEY_PRESS;
     201        ev.key = (wheel > 0) ? KC_UP : (wheel < 0) ? KC_DOWN : 0;
     202        ev.mods = 0;
     203        ev.c = 0;
     204
     205        if (mouse_dev->wheel_phone < 0) {
     206                usb_log_warning(
     207                    "Connection to console not ready, key discarded.\n");
     208                return;
     209        }
     210       
     211        int count = (wheel < 0) ? -wheel : wheel;
     212        int i;
     213       
     214        for (i = 0; i < count * 3; ++i) {
     215                usb_log_debug2("Sending key %d to the console\n", ev.key);
     216                async_msg_4(mouse_dev->wheel_phone, KBD_EVENT, ev.type,
     217                    ev.key, ev.mods, ev.c);
     218                // send key release right away
     219                async_msg_4(mouse_dev->wheel_phone, KBD_EVENT, KEY_RELEASE,
     220                    ev.key, ev.mods, ev.c);
     221        }
     222}
     223
     224/*----------------------------------------------------------------------------*/
     225
     226static bool usb_mouse_process_report(usb_hid_dev_t *hid_dev, uint8_t *buffer,
     227    size_t buffer_size)
    178228{
    179229        usb_mouse_t *mouse_dev = (usb_mouse_t *)hid_dev->data;
     
    182232            usb_debug_str_buffer(buffer, buffer_size, 0));
    183233       
    184         if (mouse_dev->console_phone < 0) {
     234        if (mouse_dev->mouse_phone < 0) {
    185235                usb_log_error(NAME " No console phone.\n");
    186236                return false;   // ??
     
    252302       
    253303        if ((shift_x != 0) || (shift_y != 0)) {
    254                 async_req_2_0(mouse_dev->console_phone,
     304                async_req_2_0(mouse_dev->mouse_phone,
    255305                    MEVENT_MOVE, shift_x, shift_y);
    256306        }
     307       
     308        /*
     309         * Wheel
     310         */
     311        int wheel = 0;
     312       
     313        path = usb_hid_report_path();
     314        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_GENERIC_DESKTOP,
     315            USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL);
     316
     317        usb_hid_report_path_set_report_id(path, report_id);
     318       
     319        field = usb_hid_report_get_sibling(
     320            hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END,
     321            USB_HID_REPORT_TYPE_INPUT);
     322
     323        if (field != NULL) {
     324                usb_log_debug(NAME " VALUE(%X) USAGE(%X)\n", field->value,
     325                    field->usage);
     326                wheel = field->value;
     327        }
     328
     329        usb_hid_report_path_free(path);
     330       
     331        // send arrow up for positive direction and arrow down for negative
     332        // direction; three arrows for difference of 1
     333        usb_mouse_send_wheel(mouse_dev, wheel);
     334       
    257335       
    258336        /*
     
    274352                if (mouse_dev->buttons[field->usage - field->usage_minimum] == 0
    275353                    && field->value != 0) {
    276                         async_req_2_0(mouse_dev->console_phone,
     354                        async_req_2_0(mouse_dev->mouse_phone,
    277355                            MEVENT_BUTTON, field->usage, 1);
    278356                        mouse_dev->buttons[field->usage - field->usage_minimum]
     
    281359                    mouse_dev->buttons[field->usage - field->usage_minimum] != 0
    282360                    && field->value == 0) {
    283                        async_req_2_0(mouse_dev->console_phone,
     361                       async_req_2_0(mouse_dev->mouse_phone,
    284362                           MEVENT_BUTTON, field->usage, 0);
    285363                       mouse_dev->buttons[field->usage - field->usage_minimum]
     
    337415        }
    338416       
     417        /*
     418         * Special function for acting as keyboard (wheel)
     419         */
     420        usb_log_debug("Creating DDF function %s...\n",
     421                      HID_MOUSE_WHEEL_FUN_NAME);
     422        fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     423            HID_MOUSE_WHEEL_FUN_NAME);
     424        if (fun == NULL) {
     425                usb_log_error("Could not create DDF function node.\n");
     426                return ENOMEM;
     427        }
     428       
     429        /*
     430         * Store the initialized HID device and HID ops
     431         * to the DDF function.
     432         */
     433        fun->ops = &hid_dev->ops;
     434        fun->driver_data = hid_dev;   // TODO: maybe change to hid_dev->data
     435
     436        rc = ddf_fun_bind(fun);
     437        if (rc != EOK) {
     438                usb_log_error("Could not bind DDF function: %s.\n",
     439                    str_error(rc));
     440                ddf_fun_destroy(fun);
     441                return rc;
     442        }
     443       
     444        usb_log_debug("Adding DDF function to class %s...\n",
     445            HID_MOUSE_WHEEL_CLASS_NAME);
     446        rc = ddf_fun_add_to_class(fun, HID_MOUSE_WHEEL_CLASS_NAME);
     447        if (rc != EOK) {
     448                usb_log_error(
     449                    "Could not add DDF function to class %s: %s.\n",
     450                    HID_MOUSE_WHEEL_CLASS_NAME, str_error(rc));
     451                ddf_fun_destroy(fun);
     452                return rc;
     453        }
     454       
    339455        return EOK;
    340456}
     
    407523        }
    408524       
    409         return usb_mouse_process_boot_report(hid_dev, buffer, buffer_size);
     525        return usb_mouse_process_report(hid_dev, buffer, buffer_size);
    410526}
    411527
Note: See TracChangeset for help on using the changeset viewer.