diff options
author | kraxel <kraxel> | 2008-10-17 22:46:47 +0000 |
---|---|---|
committer | kraxel <kraxel> | 2008-10-17 22:46:47 +0000 |
commit | 99537ea7f5f0622656b2a85e93fadcf875216349 (patch) | |
tree | ad29fe74cc01c69f921d861de8348441225d152c /devices.c | |
parent | 3b6bd0694fa18ad018c2aff3611996097ece0acd (diff) | |
download | qemu-gtk-99537ea7f5f0622656b2a85e93fadcf875216349.tar.gz |
- usb hotplug
Diffstat (limited to 'devices.c')
-rw-r--r-- | devices.c | 235 |
1 files changed, 214 insertions, 21 deletions
@@ -14,10 +14,32 @@ static char media_xml[] = "<ui>\n" " <menubar name='MainMenu'>\n" " <menu action='DevicesMenu'>\n" +" <menu action='ChangeMediaSubMenu'>\n" +"%s" +" </menu>\n" " <menu action='EjectMediaSubMenu'>\n" "%s" " </menu>\n" -" <menu action='ChangeMediaSubMenu'>\n" +" </menu>\n" +" </menubar>\n" +"</ui>\n"; + +static char plug_usb_xml[] = +"<ui>\n" +" <menubar name='MainMenu'>\n" +" <menu action='DevicesMenu'>\n" +" <menu action='PlugUsbSubMenu'>\n" +"%s" +" </menu>\n" +" </menu>\n" +" </menubar>\n" +"</ui>\n"; + +static char unplug_usb_xml[] = +"<ui>\n" +" <menubar name='MainMenu'>\n" +" <menu action='DevicesMenu'>\n" +" <menu action='UnplugUsbSubMenu'>\n" "%s" " </menu>\n" " </menu>\n" @@ -77,12 +99,63 @@ static void menu_cb_eject_media(GtkAction *action, void *data) monitor_append(win, "info block"); } +static void menu_cb_plug_usb(GtkAction *action, void *data) +{ + struct qemu_window *win = data; + char device[32], cmd[128]; + + if (1 != sscanf(gtk_action_get_name(action), "PlugUsb_%31s", device)) + return; + if (debug) + fprintf(stderr, "%s: %s\n", __FUNCTION__, device); + + snprintf(cmd, sizeof(cmd), "usb_add %s", device); + monitor_append(win, cmd); + monitor_append(win, "info usb"); +} + +static void menu_cb_unplug_usb(GtkAction *action, void *data) +{ + struct qemu_window *win = data; + char device[32], cmd[128]; + + if (1 != sscanf(gtk_action_get_name(action), "UnplugUsb_%31s", device)) + return; + if (debug) + fprintf(stderr, "%s: %s\n", __FUNCTION__, device); + + snprintf(cmd, sizeof(cmd), "usb_del %s", device); + monitor_append(win, cmd); + monitor_append(win, "info usb"); +} + +/* ----------------------------------------------------------------- */ + +static void add_entry(struct qemu_window *win, + GtkActionGroup *ag, + void (*cb)(GtkAction *action, void *data), + char **i_xml, int *i_pos, + char *label, char *type, char *name) +{ + GtkActionEntry entry; + char action[128]; + + snprintf(action, sizeof(action), "%s_%s", type, name); + memset(&entry, 0, sizeof(entry)); + entry.callback = G_CALLBACK(cb); + entry.name = action; + entry.label = label; + gtk_action_group_add_actions(ag, &entry, 1, win); + *i_xml = realloc(*i_xml, (*i_pos) + 128); + *i_pos += snprintf((*i_xml)+(*i_pos), 128, + " <menuitem action='%s'/>\n", action); +} + void devices_parse_info_block(struct qemu_window *win, char *str) { char name[32], type[16], line[256], *file, *ptr, *xml; - char action[128], label[128]; + char label[128]; int removable, pos, len, rc, eject; - GtkActionEntry c_entry, e_entry; char *c_xml = NULL, *e_xml = NULL; int c_pos = 0, e_pos = 0; GError *err = NULL; @@ -99,10 +172,6 @@ void devices_parse_info_block(struct qemu_window *win, char *str) } /* start */ - memset(&c_entry, 0, sizeof(c_entry)); - c_entry.callback = G_CALLBACK(menu_cb_change_media); - memset(&e_entry, 0, sizeof(e_entry)); - e_entry.callback = G_CALLBACK(menu_cb_eject_media); win->mc_ag = gtk_action_group_new("MediaActions"); /* parse & build */ @@ -135,29 +204,21 @@ void devices_parse_info_block(struct qemu_window *win, char *str) fprintf(stderr, "%s: %s (%s, %s) - [%s]\n", __FUNCTION__, name, type, file, line); - snprintf(action, sizeof(action), "ChangeMedia_%s", name); snprintf(label, sizeof(label), "%s (%s, %s)", name, type, file); - c_entry.name = action; - c_entry.label = label; - gtk_action_group_add_actions(win->mc_ag, &c_entry, 1, win); - c_xml = realloc(c_xml, c_pos + 128); - c_pos += snprintf(c_xml+c_pos, 128, " <menuitem action='%s'/>\n", action); + add_entry(win, win->mc_ag, menu_cb_change_media, &c_xml, &c_pos, + label, "ChangeMedia", name); if (eject) { - snprintf(action, sizeof(action), "EjectMedia_%s", name); snprintf(label, sizeof(label), "%s (%s, %s)", name, type, file); - e_entry.name = action; - e_entry.label = label; - gtk_action_group_add_actions(win->mc_ag, &e_entry, 1, win); - e_xml = realloc(e_xml, e_pos + 128); - e_pos += snprintf(e_xml+e_pos, 128, " <menuitem action='%s'/>\n", action); + add_entry(win, win->mc_ag, menu_cb_eject_media, &e_xml, &e_pos, + label, "EjectMedia", name); } } xml = malloc(e_pos + c_pos + strlen(media_xml)); sprintf(xml, media_xml, - e_pos ? e_xml : "", - c_pos ? c_xml : ""); + c_pos ? c_xml : "", + e_pos ? e_xml : ""); /* add */ if (debug) @@ -173,3 +234,135 @@ void devices_parse_info_block(struct qemu_window *win, char *str) free(e_xml); free(xml); } + +void devices_parse_info_usb(struct qemu_window *win, char *str) +{ + char device[16], name[64], speed[16], *xml; + char label[128]; + GError *err = NULL; + int pos, len, rc; + char *i_xml = NULL; + int i_pos = 0; + + /* remove */ + if (win->usb_id) { + gtk_ui_manager_remove_ui(win->ui, win->usb_id); + win->usb_id = 0; + } + if (win->usb_ag) { + gtk_ui_manager_remove_action_group(win->ui, win->usb_ag); + g_object_unref(win->usb_ag); + win->usb_ag = NULL; + } + + /* start */ + win->usb_ag = gtk_action_group_new("UnplugUsbActions"); + + /* parse & build */ + for (pos = 0;; pos += len) { + rc = sscanf(str+pos, " Device %15[^,], Speed %15s Mb/s, Product %63[^\r\n]%n", + device, speed, name, &len); + if (rc != 3) + break; + while (str[pos+len] == '\r' || str[pos+len] == '\n') + len++; + if (debug) + fprintf(stderr, "%s: %s - %s - %s\n", + __FUNCTION__, device, speed, name); + + snprintf(label, sizeof(label), "%s (%s)", name, device); + add_entry(win, win->usb_ag, menu_cb_unplug_usb, &i_xml, &i_pos, + label, "UnplugUsb", device); + } + + xml = malloc(i_pos + strlen(unplug_usb_xml)); + sprintf(xml, unplug_usb_xml, + i_pos ? i_xml : ""); + + /* add */ + if (debug) + fprintf(stderr, "---\n%s---\n", xml); + gtk_ui_manager_insert_action_group(win->ui, win->usb_ag, 1); + win->usb_id = gtk_ui_manager_add_ui_from_string(win->ui, xml, -1, &err); + if (!win->usb_id) { + g_message("building unplug usb menu failed: %s", err->message); + g_error_free(err); + } + + free(i_xml); + free(xml); +} + +void devices_parse_info_usbhost(struct qemu_window *win, char *str) +{ + char device[16], speed[16], class[32], name[64], *xml; + char action[128], label[128]; + GError *err = NULL; + int pos, len, rc, vendor, product; + char *i_xml = NULL; + int i_pos = 0; + + /* remove */ + if (win->usbhost_id) { + gtk_ui_manager_remove_ui(win->ui, win->usbhost_id); + win->usbhost_id = 0; + } + if (win->usbhost_ag) { + gtk_ui_manager_remove_action_group(win->ui, win->usbhost_ag); + g_object_unref(win->usbhost_ag); + win->usbhost_ag = NULL; + } + + /* start */ + win->usbhost_ag = gtk_action_group_new("PlugUsbActions"); + + /* parse & build */ + for (pos = 0;; pos += len) { + rc = sscanf(str+pos, + " Device %15[^,], speed %15s Mb/s\n" + " %31[^:]: USB device %x:%x, %63[^\r\n]%n", + device, speed, class, &vendor, &product, name, &len); + if (rc != 6) + break; + while (str[pos+len] == '\r' || str[pos+len] == '\n') + len++; + if (0 == strcmp("Hub", class)) + continue; + if (1 || debug) + fprintf(stderr, "%s: %s (%04x:%04x) - %s - %s\n", + __FUNCTION__, device, vendor, product, class, name); + + snprintf(label, sizeof(label), "%s (host %s)", name, device); + snprintf(action, sizeof(action), "host:%s", device); + add_entry(win, win->usbhost_ag, menu_cb_plug_usb, &i_xml, &i_pos, + label, "PlugUsb", action); + } + + /* static */ + add_entry(win, win->usbhost_ag, menu_cb_plug_usb, &i_xml, &i_pos, + "QEMU USB Tablet (virtual)", "PlugUsb", "tablet"); + + xml = malloc(i_pos + strlen(plug_usb_xml)); + sprintf(xml, plug_usb_xml, + i_pos ? i_xml : ""); + + /* add */ + if (debug) + fprintf(stderr, "---\n%s---\n", xml); + gtk_ui_manager_insert_action_group(win->ui, win->usbhost_ag, 1); + win->usbhost_id = gtk_ui_manager_add_ui_from_string(win->ui, xml, -1, &err); + if (!win->usbhost_id) { + g_message("building host usb menu failed: %s", err->message); + g_error_free(err); + } + + free(i_xml); + free(xml); +} + +void devices_rescan(struct qemu_window *win) +{ + monitor_append(win, "info block"); + monitor_append(win, "info usb"); + monitor_append(win, "info usbhost"); +} |