Ignore:
File:
1 edited

Legend:

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

    r9d58539 rce2a1c2  
    6767        /** IPC session to the console device (for sending key events). */
    6868        async_sess_t *console_sess;
     69        /** DDF function */
     70        ddf_fun_t *fun;
    6971} usb_multimedia_t;
    7072
    7173
    7274/*----------------------------------------------------------------------------*/
    73 /**
     75/** 
    7476 * Default handler for IPC methods not handled by DDF.
    7577 *
     
    8688{
    8789        usb_log_debug(NAME " default_connection_handler()\n");
    88         if (fun == NULL || fun->driver_data == NULL) {
     90
     91        usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data;
     92
     93        if (multim_dev == NULL) {
    8994                async_answer_0(icallid, EINVAL);
    9095                return;
    9196        }
    92 
    93         usb_multimedia_t *multim_dev = fun->driver_data;
    9497
    9598        async_sess_t *sess =
     
    106109                async_answer_0(icallid, EINVAL);
    107110}
    108 /*----------------------------------------------------------------------------*/
     111
     112/*----------------------------------------------------------------------------*/
     113
    109114static ddf_dev_ops_t multimedia_ops = {
    110115        .default_handler = default_connection_handler
    111116};
     117
    112118/*----------------------------------------------------------------------------*/
    113119/**
     
    121127 *       sends also these keys to application (otherwise it cannot use those
    122128 *       keys at all).
    123  *
    124  * @param hid_dev
    125  * @param multim_dev
    126  * @param type Type of the event (press / release). Recognized values:
     129 * 
     130 * @param hid_dev 
     131 * @param lgtch_dev
     132 * @param type Type of the event (press / release). Recognized values: 
    127133 *             KEY_PRESS, KEY_RELEASE
    128134 * @param key Key code of the key according to HID Usage Tables.
    129135 */
    130 static void usb_multimedia_push_ev(
     136static void usb_multimedia_push_ev(usb_hid_dev_t *hid_dev,
    131137    usb_multimedia_t *multim_dev, int type, unsigned int key)
    132138{
     139        assert(hid_dev != NULL);
    133140        assert(multim_dev != NULL);
    134141
    135         const kbd_event_t ev = {
    136                 .type = type,
    137                 .key = key,
    138                 .mods = 0,
    139                 .c = 0,
    140         };
     142        kbd_event_t ev;
     143
     144        ev.type = type;
     145        ev.key = key;
     146        ev.mods = 0;
     147        ev.c = 0;
    141148
    142149        usb_log_debug2(NAME " Sending key %d to the console\n", ev.key);
     
    148155
    149156        async_exch_t *exch = async_exchange_begin(multim_dev->console_sess);
    150         if (exch != NULL) {
    151                 async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c);
    152                 async_exchange_end(exch);
    153         } else {
    154                 usb_log_warning("Failed to send multimedia key.\n");
    155         }
    156 }
    157 /*----------------------------------------------------------------------------*/
     157        async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c);
     158        async_exchange_end(exch);
     159}
     160
     161/*----------------------------------------------------------------------------*/
     162
    158163int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data)
    159164{
    160165        if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
    161                 return EINVAL;
     166                return EINVAL; /*! @todo Other return code? */
    162167        }
    163168
     
    182187
    183188        multim_dev->console_sess = NULL;
     189        multim_dev->fun = fun;
    184190
    185191        //todo Autorepeat?
     
    193199        }
    194200
    195         usb_log_debug(NAME " function created (handle: %" PRIun ").\n",
    196             fun->handle);
     201        usb_log_debug("%s function created (handle: %" PRIun ").\n",
     202            NAME, fun->handle);
    197203
    198204        rc = ddf_fun_add_to_category(fun, "keyboard");
     
    201207                    "Could not add DDF function to category 'keyboard': %s.\n",
    202208                    str_error(rc));
    203                 if (ddf_fun_unbind(fun) != EOK) {
    204                         usb_log_error("Failed to unbind %s, won't destroy.\n",
    205                             fun->name);
    206                 } else {
    207                         ddf_fun_destroy(fun);
    208                 }
     209                ddf_fun_destroy(fun);
    209210                return rc;
    210211        }
    211212
    212213        /* Save the KBD device structure into the HID device structure. */
    213         *data = fun;
     214        *data = multim_dev;
    214215
    215216        usb_log_debug(NAME " HID/multimedia structure initialized.\n");
    216217        return EOK;
    217218}
    218 /*----------------------------------------------------------------------------*/
     219
     220/*----------------------------------------------------------------------------*/
     221
    219222void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data)
    220223{
    221         ddf_fun_t *fun = data;
    222         if (fun != NULL && fun->driver_data != NULL) {
    223                 usb_multimedia_t *multim_dev = fun->driver_data;
    224                 /* Hangup session to the console */
    225                 if (multim_dev->console_sess)
    226                         async_hangup(multim_dev->console_sess);
    227                 if (ddf_fun_unbind(fun) != EOK) {
    228                         usb_log_error("Failed to unbind %s, won't destroy.\n",
    229                             fun->name);
     224        if (hid_dev == NULL) {
     225                return;
     226        }
     227
     228        if (data != NULL) {
     229                usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
     230                // hangup session to the console
     231                async_hangup(multim_dev->console_sess);
     232                const int ret = ddf_fun_unbind(multim_dev->fun);
     233                if (ret != EOK) {
     234                        usb_log_error("Failed to unbind multim function.\n");
    230235                } else {
    231                         usb_log_debug2("%s unbound.\n", fun->name);
    232                         /* This frees multim_dev too as it was stored in
    233                          * fun->data */
    234                         ddf_fun_destroy(fun);
     236                        usb_log_debug2("%s unbound.\n", multim_dev->fun->name);
     237                        ddf_fun_destroy(multim_dev->fun);
    235238                }
    236         } else {
    237                 usb_log_error(
    238                     "Failed to deinit multimedia subdriver, data missing.\n");
    239         }
    240 }
    241 /*----------------------------------------------------------------------------*/
     239        }
     240}
     241
     242/*----------------------------------------------------------------------------*/
     243
    242244bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data)
    243245{
    244246        // TODO: checks
    245         ddf_fun_t *fun = data;
    246         if (hid_dev == NULL || fun == NULL || fun->driver_data == NULL) {
     247        if (hid_dev == NULL || data == NULL) {
    247248                return false;
    248249        }
    249250
    250         usb_multimedia_t *multim_dev = fun->driver_data;
     251        usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
    251252
    252253        usb_hid_report_path_t *path = usb_hid_report_path();
    253         if (path == NULL)
    254                 return true; /* This might be a temporary failure. */
    255 
    256         int ret =
    257             usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
    258         if (ret != EOK) {
    259                 usb_hid_report_path_free(path);
    260                 return true; /* This might be a temporary failure. */
    261         }
     254        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
    262255
    263256        usb_hid_report_path_set_report_id(path, hid_dev->report_id);
     
    268261            USB_HID_REPORT_TYPE_INPUT);
    269262
    270         //FIXME Is this iterating OK if done multiple times?
    271         //FIXME The parsing is not OK. (what's wrong?)
     263        /*! @todo Is this iterating OK if done multiple times?
     264         *  @todo The parsing is not OK
     265         */
    272266        while (field != NULL) {
    273                 if (field->value != 0) {
    274                         usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n",
     267                if(field->value != 0) {
     268                        usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", 
    275269                            field->value, field->usage);
    276                         const unsigned key =
     270                        unsigned int key =
    277271                            usb_multimedia_map_usage(field->usage);
    278                         const char *key_str =
     272                        const char *key_str = 
    279273                            usbhid_multimedia_usage_to_str(field->usage);
    280274                        usb_log_info("Pressed key: %s\n", key_str);
    281                         usb_multimedia_push_ev(multim_dev, KEY_PRESS, key);
     275                        usb_multimedia_push_ev(hid_dev, multim_dev, KEY_PRESS,
     276                                               key);
    282277                }
    283278
    284279                field = usb_hid_report_get_sibling(
    285280                    &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
    286                     | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     281                    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
    287282                    USB_HID_REPORT_TYPE_INPUT);
    288283        }
     
    292287        return true;
    293288}
     289
    294290/**
    295291 * @}
Note: See TracChangeset for help on using the changeset viewer.