Ignore:
File:
1 edited

Legend:

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

    ra0c05e7 r5da7199  
    6464        //int32_t *keys;
    6565        /** Count of stored keys (i.e. number of keys in the report). */
    66         //size_t key_count;
     66        //size_t key_count;     
    6767        /** IPC session to the console device (for sending key events). */
    6868        async_sess_t *console_sess;
     
    7171
    7272/*----------------------------------------------------------------------------*/
    73 /**
     73/** 
    7474 * Default handler for IPC methods not handled by DDF.
    7575 *
     
    8686{
    8787        usb_log_debug(NAME " default_connection_handler()\n");
    88         if (fun == NULL || fun->driver_data == NULL) {
     88       
     89        usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data;
     90       
     91        if (multim_dev == NULL) {
    8992                async_answer_0(icallid, EINVAL);
    9093                return;
    9194        }
    92 
    93         usb_multimedia_t *multim_dev = fun->driver_data;
    94 
     95       
    9596        async_sess_t *sess =
    9697            async_callback_receive_start(EXCHANGE_SERIALIZE, icall);
     
    106107                async_answer_0(icallid, EINVAL);
    107108}
    108 /*----------------------------------------------------------------------------*/
     109
     110/*----------------------------------------------------------------------------*/
     111
    109112static ddf_dev_ops_t multimedia_ops = {
    110113        .default_handler = default_connection_handler
    111114};
     115
    112116/*----------------------------------------------------------------------------*/
    113117/**
     
    121125 *       sends also these keys to application (otherwise it cannot use those
    122126 *       keys at all).
    123  *
    124  * @param hid_dev
    125  * @param multim_dev
    126  * @param type Type of the event (press / release). Recognized values:
     127 * 
     128 * @param hid_dev 
     129 * @param lgtch_dev
     130 * @param type Type of the event (press / release). Recognized values: 
    127131 *             KEY_PRESS, KEY_RELEASE
    128132 * @param key Key code of the key according to HID Usage Tables.
    129133 */
    130 static void usb_multimedia_push_ev(
     134static void usb_multimedia_push_ev(usb_hid_dev_t *hid_dev,
    131135    usb_multimedia_t *multim_dev, int type, unsigned int key)
    132136{
     137        assert(hid_dev != NULL);
    133138        assert(multim_dev != NULL);
    134 
    135         const kbd_event_t ev = {
    136                 .type = type,
    137                 .key = key,
    138                 .mods = 0,
    139                 .c = 0,
    140         };
     139       
     140        kbd_event_t ev;
     141       
     142        ev.type = type;
     143        ev.key = key;
     144        ev.mods = 0;
     145        ev.c = 0;
    141146
    142147        usb_log_debug2(NAME " Sending key %d to the console\n", ev.key);
     
    146151                return;
    147152        }
    148 
     153       
    149154        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 /*----------------------------------------------------------------------------*/
    158 int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data)
    159 {
    160         if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
    161                 return EINVAL;
    162         }
    163 
    164         usb_log_debug(NAME " Initializing HID/multimedia structure...\n");
    165 
     155        async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c);
     156        async_exchange_end(exch);
     157}
     158
     159/*----------------------------------------------------------------------------*/
     160
     161static int usb_multimedia_create_function(usb_hid_dev_t *hid_dev,
     162    usb_multimedia_t *multim_dev)
     163{
    166164        /* Create the exposed function. */
    167         ddf_fun_t *fun = ddf_fun_create(
    168             hid_dev->usb_dev->ddf_dev, fun_exposed, NAME);
     165        ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
     166            NAME);
    169167        if (fun == NULL) {
    170168                usb_log_error("Could not create DDF function node.\n");
    171169                return ENOMEM;
    172170        }
    173 
     171       
    174172        fun->ops = &multimedia_ops;
    175 
    176         usb_multimedia_t *multim_dev =
    177             ddf_fun_data_alloc(fun, sizeof(usb_multimedia_t));
    178         if (multim_dev == NULL) {
    179                 ddf_fun_destroy(fun);
    180                 return ENOMEM;
    181         }
    182 
    183         multim_dev->console_sess = NULL;
    184 
    185         //todo Autorepeat?
    186 
     173        fun->driver_data = multim_dev;   // TODO: maybe change to hid_dev->data
     174       
    187175        int rc = ddf_fun_bind(fun);
    188176        if (rc != EOK) {
    189177                usb_log_error("Could not bind DDF function: %s.\n",
    190178                    str_error(rc));
     179                // TODO: Can / should I destroy the DDF function?
    191180                ddf_fun_destroy(fun);
    192181                return rc;
    193182        }
    194 
    195         usb_log_debug(NAME " function created (handle: %" PRIun ").\n",
    196             fun->handle);
    197 
     183       
     184        usb_log_debug("%s function created (handle: %" PRIun ").\n",
     185            NAME, fun->handle);
     186       
    198187        rc = ddf_fun_add_to_category(fun, "keyboard");
    199188        if (rc != EOK) {
     
    201190                    "Could not add DDF function to category 'keyboard': %s.\n",
    202191                    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                 }
     192                // TODO: Can / should I destroy the DDF function?
     193                ddf_fun_destroy(fun);
    209194                return rc;
    210195        }
    211 
    212         /* Save the KBD device structure into the HID device structure. */
    213         *data = fun;
    214 
     196       
     197        return EOK;
     198}
     199
     200/*----------------------------------------------------------------------------*/
     201
     202int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data)
     203{
     204        if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
     205                return EINVAL; /*! @todo Other return code? */
     206        }
     207       
     208        usb_log_debug(NAME " Initializing HID/multimedia structure...\n");
     209       
     210        usb_multimedia_t *multim_dev = (usb_multimedia_t *)malloc(
     211            sizeof(usb_multimedia_t));
     212        if (multim_dev == NULL) {
     213                return ENOMEM;
     214        }
     215       
     216        multim_dev->console_sess = NULL;
     217       
     218        /*! @todo Autorepeat */
     219       
     220        // save the KBD device structure into the HID device structure
     221        *data = multim_dev;
     222       
     223        usb_log_debug(NAME " HID/multimedia device structure initialized.\n");
     224       
     225        int rc = usb_multimedia_create_function(hid_dev, multim_dev);
     226        if (rc != EOK)
     227                return rc;
     228       
    215229        usb_log_debug(NAME " HID/multimedia structure initialized.\n");
     230       
    216231        return EOK;
    217232}
    218 /*----------------------------------------------------------------------------*/
     233
     234/*----------------------------------------------------------------------------*/
     235
    219236void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data)
    220237{
    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);
    230                 } 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);
    235                 }
    236         } else {
    237                 usb_log_error(
    238                     "Failed to deinit multimedia subdriver, data missing.\n");
    239         }
    240 }
    241 /*----------------------------------------------------------------------------*/
     238        if (hid_dev == NULL) {
     239                return;
     240        }
     241       
     242        if (data != NULL) {
     243                usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
     244                // hangup session to the console
     245                async_hangup(multim_dev->console_sess);
     246        }
     247}
     248
     249/*----------------------------------------------------------------------------*/
     250
    242251bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data)
    243252{
    244253        // TODO: checks
    245         ddf_fun_t *fun = data;
    246         if (hid_dev == NULL || fun == NULL || fun->driver_data == NULL) {
     254        if (hid_dev == NULL || data == NULL) {
    247255                return false;
    248256        }
    249257
    250         usb_multimedia_t *multim_dev = fun->driver_data;
    251 
     258        usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
     259       
    252260        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         }
     261        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
    262262
    263263        usb_hid_report_path_set_report_id(path, hid_dev->report_id);
    264264
    265265        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    266             &hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END
    267             | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     266            hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END
     267            | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
    268268            USB_HID_REPORT_TYPE_INPUT);
    269269
    270         //FIXME Is this iterating OK if done multiple times?
    271         //FIXME The parsing is not OK. (what's wrong?)
     270        /*! @todo Is this iterating OK if done multiple times?
     271         *  @todo The parsing is not OK
     272         */
    272273        while (field != NULL) {
    273                 if (field->value != 0) {
    274                         usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n",
     274                if(field->value != 0) {
     275                        usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", 
    275276                            field->value, field->usage);
    276                         const unsigned key =
     277                        unsigned int key =
    277278                            usb_multimedia_map_usage(field->usage);
    278                         const char *key_str =
     279                        const char *key_str = 
    279280                            usbhid_multimedia_usage_to_str(field->usage);
    280281                        usb_log_info("Pressed key: %s\n", key_str);
    281                         usb_multimedia_push_ev(multim_dev, KEY_PRESS, key);
     282                        usb_multimedia_push_ev(hid_dev, multim_dev, KEY_PRESS,
     283                                               key);
    282284                }
    283 
     285               
    284286                field = usb_hid_report_get_sibling(
    285                     &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
    286                     | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     287                    hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
     288                    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
    287289                    USB_HID_REPORT_TYPE_INPUT);
    288         }
     290        }       
    289291
    290292        usb_hid_report_path_free(path);
    291 
     293       
    292294        return true;
    293295}
     296
    294297/**
    295298 * @}
Note: See TracChangeset for help on using the changeset viewer.