Changeset c2245a3 in mainline for uspace/drv/bus/usb/usbhid/multimedia/multimedia.c
- Timestamp:
- 2011-11-10T20:03:48Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- fa76f81
- Parents:
- 27ca3a3 (diff), 747ef72 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhid/multimedia/multimedia.c
r27ca3a3 rc2245a3 67 67 /** IPC session to the console device (for sending key events). */ 68 68 async_sess_t *console_sess; 69 /** DDF function */70 ddf_fun_t *fun;71 69 } usb_multimedia_t; 72 70 73 71 74 72 /*----------------------------------------------------------------------------*/ 75 /** 73 /** 76 74 * Default handler for IPC methods not handled by DDF. 77 75 * … … 88 86 { 89 87 usb_log_debug(NAME " default_connection_handler()\n"); 90 91 usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data; 92 93 if (multim_dev == NULL) { 88 if (fun == NULL || fun->driver_data == NULL) { 94 89 async_answer_0(icallid, EINVAL); 95 90 return; 96 91 } 92 93 usb_multimedia_t *multim_dev = fun->driver_data; 97 94 98 95 async_sess_t *sess = … … 109 106 async_answer_0(icallid, EINVAL); 110 107 } 111 112 /*----------------------------------------------------------------------------*/ 113 108 /*----------------------------------------------------------------------------*/ 114 109 static ddf_dev_ops_t multimedia_ops = { 115 110 .default_handler = default_connection_handler 116 111 }; 117 118 112 /*----------------------------------------------------------------------------*/ 119 113 /** … … 127 121 * sends also these keys to application (otherwise it cannot use those 128 122 * keys at all). 129 * 130 * @param hid_dev 131 * @param lgtch_dev132 * @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: 133 127 * KEY_PRESS, KEY_RELEASE 134 128 * @param key Key code of the key according to HID Usage Tables. 135 129 */ 136 static void usb_multimedia_push_ev( usb_hid_dev_t *hid_dev,130 static void usb_multimedia_push_ev( 137 131 usb_multimedia_t *multim_dev, int type, unsigned int key) 138 132 { 139 assert(hid_dev != NULL);140 133 assert(multim_dev != NULL); 141 134 142 kbd_event_t ev;143 144 ev.type = type;145 ev.key = key;146 ev.mods = 0;147 ev.c = 0;135 const kbd_event_t ev = { 136 .type = type, 137 .key = key, 138 .mods = 0, 139 .c = 0, 140 }; 148 141 149 142 usb_log_debug2(NAME " Sending key %d to the console\n", ev.key); … … 155 148 156 149 async_exch_t *exch = async_exchange_begin(multim_dev->console_sess); 157 async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c); 158 async_exchange_end(exch); 159 } 160 161 /*----------------------------------------------------------------------------*/ 162 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 /*----------------------------------------------------------------------------*/ 163 158 int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data) 164 159 { 165 160 if (hid_dev == NULL || hid_dev->usb_dev == NULL) { 166 return EINVAL; /*! @todo Other return code? */161 return EINVAL; 167 162 } 168 163 … … 187 182 188 183 multim_dev->console_sess = NULL; 189 multim_dev->fun = fun;190 184 191 185 //todo Autorepeat? … … 199 193 } 200 194 201 usb_log_debug( "%sfunction created (handle: %" PRIun ").\n",202 NAME,fun->handle);195 usb_log_debug(NAME " function created (handle: %" PRIun ").\n", 196 fun->handle); 203 197 204 198 rc = ddf_fun_add_to_category(fun, "keyboard"); … … 207 201 "Could not add DDF function to category 'keyboard': %s.\n", 208 202 str_error(rc)); 209 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 } 210 209 return rc; 211 210 } 212 211 213 212 /* Save the KBD device structure into the HID device structure. */ 214 *data = multim_dev;213 *data = fun; 215 214 216 215 usb_log_debug(NAME " HID/multimedia structure initialized.\n"); 217 216 return EOK; 218 217 } 219 220 /*----------------------------------------------------------------------------*/ 221 218 /*----------------------------------------------------------------------------*/ 222 219 void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data) 223 220 { 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"); 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); 235 230 } else { 236 usb_log_debug2("%s unbound.\n", multim_dev->fun->name); 237 ddf_fun_destroy(multim_dev->fun); 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); 238 235 } 239 } 240 } 241 242 /*----------------------------------------------------------------------------*/ 243 236 } else { 237 usb_log_error( 238 "Failed to deinit multimedia subdriver, data missing.\n"); 239 } 240 } 241 /*----------------------------------------------------------------------------*/ 244 242 bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data) 245 243 { 246 244 // TODO: checks 247 if (hid_dev == NULL || data == NULL) { 245 ddf_fun_t *fun = data; 246 if (hid_dev == NULL || fun == NULL || fun->driver_data == NULL) { 248 247 return false; 249 248 } 250 249 251 usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;250 usb_multimedia_t *multim_dev = fun->driver_data; 252 251 253 252 usb_hid_report_path_t *path = usb_hid_report_path(); 254 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 } 255 262 256 263 usb_hid_report_path_set_report_id(path, hid_dev->report_id); … … 261 268 USB_HID_REPORT_TYPE_INPUT); 262 269 263 /*! @todo Is this iterating OK if done multiple times? 264 * @todo The parsing is not OK 265 */ 270 //FIXME Is this iterating OK if done multiple times? 271 //FIXME The parsing is not OK. (what's wrong?) 266 272 while (field != NULL) { 267 if (field->value != 0) {268 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", 269 275 field->value, field->usage); 270 unsigned int key =276 const unsigned key = 271 277 usb_multimedia_map_usage(field->usage); 272 const char *key_str = 278 const char *key_str = 273 279 usbhid_multimedia_usage_to_str(field->usage); 274 280 usb_log_info("Pressed key: %s\n", key_str); 275 usb_multimedia_push_ev(hid_dev, multim_dev, KEY_PRESS, 276 key); 281 usb_multimedia_push_ev(multim_dev, KEY_PRESS, key); 277 282 } 278 283 279 284 field = usb_hid_report_get_sibling( 280 285 &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 281 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 286 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 282 287 USB_HID_REPORT_TYPE_INPUT); 283 288 } … … 287 292 return true; 288 293 } 289 290 294 /** 291 295 * @}
Note:
See TracChangeset
for help on using the changeset viewer.