Changes in uspace/drv/bus/usb/usbhid/multimedia/multimedia.c [5da7199:a0c05e7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhid/multimedia/multimedia.c
r5da7199 ra0c05e7 64 64 //int32_t *keys; 65 65 /** Count of stored keys (i.e. number of keys in the report). */ 66 //size_t key_count; 66 //size_t key_count; 67 67 /** IPC session to the console device (for sending key events). */ 68 68 async_sess_t *console_sess; … … 71 71 72 72 /*----------------------------------------------------------------------------*/ 73 /** 73 /** 74 74 * Default handler for IPC methods not handled by DDF. 75 75 * … … 86 86 { 87 87 usb_log_debug(NAME " default_connection_handler()\n"); 88 89 usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data; 90 91 if (multim_dev == NULL) { 88 if (fun == NULL || fun->driver_data == NULL) { 92 89 async_answer_0(icallid, EINVAL); 93 90 return; 94 91 } 95 92 93 usb_multimedia_t *multim_dev = fun->driver_data; 94 96 95 async_sess_t *sess = 97 96 async_callback_receive_start(EXCHANGE_SERIALIZE, icall); … … 107 106 async_answer_0(icallid, EINVAL); 108 107 } 109 110 /*----------------------------------------------------------------------------*/ 111 108 /*----------------------------------------------------------------------------*/ 112 109 static ddf_dev_ops_t multimedia_ops = { 113 110 .default_handler = default_connection_handler 114 111 }; 115 116 112 /*----------------------------------------------------------------------------*/ 117 113 /** … … 125 121 * sends also these keys to application (otherwise it cannot use those 126 122 * keys at all). 127 * 128 * @param hid_dev 129 * @param lgtch_dev130 * @param type Type of the event (press / release). Recognized values: 123 * 124 * @param hid_dev 125 * @param multim_dev 126 * @param type Type of the event (press / release). Recognized values: 131 127 * KEY_PRESS, KEY_RELEASE 132 128 * @param key Key code of the key according to HID Usage Tables. 133 129 */ 134 static void usb_multimedia_push_ev( usb_hid_dev_t *hid_dev,130 static void usb_multimedia_push_ev( 135 131 usb_multimedia_t *multim_dev, int type, unsigned int key) 136 132 { 137 assert(hid_dev != NULL);138 133 assert(multim_dev != NULL); 139 140 kbd_event_t ev;141 142 ev.type = type;143 ev.key = key;144 ev.mods = 0;145 ev.c = 0;134 135 const kbd_event_t ev = { 136 .type = type, 137 .key = key, 138 .mods = 0, 139 .c = 0, 140 }; 146 141 147 142 usb_log_debug2(NAME " Sending key %d to the console\n", ev.key); … … 151 146 return; 152 147 } 153 148 154 149 async_exch_t *exch = async_exchange_begin(multim_dev->console_sess); 155 async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c); 156 async_exchange_end(exch); 157 } 158 159 /*----------------------------------------------------------------------------*/ 160 161 static int usb_multimedia_create_function(usb_hid_dev_t *hid_dev, 162 usb_multimedia_t *multim_dev) 163 { 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 164 166 /* Create the exposed function. */ 165 ddf_fun_t *fun = ddf_fun_create( hid_dev->usb_dev->ddf_dev, fun_exposed,166 NAME);167 ddf_fun_t *fun = ddf_fun_create( 168 hid_dev->usb_dev->ddf_dev, fun_exposed, NAME); 167 169 if (fun == NULL) { 168 170 usb_log_error("Could not create DDF function node.\n"); 169 171 return ENOMEM; 170 172 } 171 173 172 174 fun->ops = &multimedia_ops; 173 fun->driver_data = multim_dev; // TODO: maybe change to hid_dev->data 174 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 175 187 int rc = ddf_fun_bind(fun); 176 188 if (rc != EOK) { 177 189 usb_log_error("Could not bind DDF function: %s.\n", 178 190 str_error(rc)); 179 // TODO: Can / should I destroy the DDF function?180 191 ddf_fun_destroy(fun); 181 192 return rc; 182 193 } 183 184 usb_log_debug( "%sfunction created (handle: %" PRIun ").\n",185 NAME,fun->handle);186 194 195 usb_log_debug(NAME " function created (handle: %" PRIun ").\n", 196 fun->handle); 197 187 198 rc = ddf_fun_add_to_category(fun, "keyboard"); 188 199 if (rc != EOK) { … … 190 201 "Could not add DDF function to category 'keyboard': %s.\n", 191 202 str_error(rc)); 192 // TODO: Can / should I destroy the DDF function? 193 ddf_fun_destroy(fun); 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 } 194 209 return rc; 195 210 } 196 211 212 /* Save the KBD device structure into the HID device structure. */ 213 *data = fun; 214 215 usb_log_debug(NAME " HID/multimedia structure initialized.\n"); 197 216 return EOK; 198 217 } 199 200 /*----------------------------------------------------------------------------*/ 201 202 int 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 229 usb_log_debug(NAME " HID/multimedia structure initialized.\n"); 230 231 return EOK; 232 } 233 234 /*----------------------------------------------------------------------------*/ 235 218 /*----------------------------------------------------------------------------*/ 236 219 void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data) 237 220 { 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 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 /*----------------------------------------------------------------------------*/ 251 242 bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data) 252 243 { 253 244 // TODO: checks 254 if (hid_dev == NULL || data == NULL) { 245 ddf_fun_t *fun = data; 246 if (hid_dev == NULL || fun == NULL || fun->driver_data == NULL) { 255 247 return false; 256 248 } 257 249 258 usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;259 250 usb_multimedia_t *multim_dev = fun->driver_data; 251 260 252 usb_hid_report_path_t *path = usb_hid_report_path(); 261 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); 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 } 262 262 263 263 usb_hid_report_path_set_report_id(path, hid_dev->report_id); 264 264 265 265 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 266 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END267 | 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, 268 268 USB_HID_REPORT_TYPE_INPUT); 269 269 270 /*! @todo Is this iterating OK if done multiple times? 271 * @todo The parsing is not OK 272 */ 270 //FIXME Is this iterating OK if done multiple times? 271 //FIXME The parsing is not OK. (what's wrong?) 273 272 while (field != NULL) { 274 if (field->value != 0) {275 usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", 273 if (field->value != 0) { 274 usb_log_debug(NAME " KEY VALUE(%X) USAGE(%X)\n", 276 275 field->value, field->usage); 277 unsigned int key =276 const unsigned key = 278 277 usb_multimedia_map_usage(field->usage); 279 const char *key_str = 278 const char *key_str = 280 279 usbhid_multimedia_usage_to_str(field->usage); 281 280 usb_log_info("Pressed key: %s\n", key_str); 282 usb_multimedia_push_ev(hid_dev, multim_dev, KEY_PRESS, 283 key); 281 usb_multimedia_push_ev(multim_dev, KEY_PRESS, key); 284 282 } 285 283 286 284 field = usb_hid_report_get_sibling( 287 hid_dev->report, field, path, USB_HID_PATH_COMPARE_END288 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 285 &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 286 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 289 287 USB_HID_REPORT_TYPE_INPUT); 290 } 288 } 291 289 292 290 usb_hid_report_path_free(path); 293 291 294 292 return true; 295 293 } 296 297 294 /** 298 295 * @}
Note:
See TracChangeset
for help on using the changeset viewer.