#include #include #include #include #include #include #include "qemu-gtk.h" /* ----------------------------------------------------------------- */ static char mc_xml_start[] = "\n" " \n" " \n" " \n"; static char mc_xml_end[] = " \n" " \n" " \n" "\n"; /* ----------------------------------------------------------------- */ static void menu_cb_change_media(GtkAction *action, void *data) { struct qemu_window *win = data; GtkWidget *dialog; char *filename; char name[32], title[128], cmd[128]; if (1 != sscanf(gtk_action_get_name(action), "ChangeMedia_%31s", name)) return; if (debug) fprintf(stderr, "%s: %s\n", __FUNCTION__, name); snprintf(title, sizeof(title), "Pick image file for %s", name); dialog = gtk_file_chooser_dialog_new (title, GTK_WINDOW(win->toplevel), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); if (debug) fprintf(stderr, "%s: %s\n", __FUNCTION__, filename); #if 0 /* not required it seems */ snprintf(cmd, sizeof(cmd), "eject %s", name); monitor_append(win, cmd); #endif snprintf(cmd, sizeof(cmd), "change %s %s", name, filename); monitor_append(win, cmd); monitor_append(win, "info block"); g_free (filename); } gtk_widget_destroy(dialog); } void devices_parse_info_block(struct qemu_window *win, char *str) { char name[32], type[16], line[256], *file, *ptr; char action[128], label[128]; int removable, pos, xpos, len, rc; GtkActionEntry entry; GError *err = NULL; char *xml; /* remove */ if (win->mc_id) { gtk_ui_manager_remove_ui(win->ui, win->mc_id); win->mc_id = 0; } if (win->mc_ag) { gtk_ui_manager_remove_action_group(win->ui, win->mc_ag); g_object_unref(win->mc_ag); win->mc_ag = NULL; } /* start */ memset(&entry, 0, sizeof(entry)); entry.callback = G_CALLBACK(menu_cb_change_media); win->mc_ag = gtk_action_group_new("ChangeMediaActions"); xpos = 0; xml = malloc(strlen(mc_xml_start)+1); xpos += sprintf(xml+xpos, "%s", mc_xml_start); /* parse & build */ for (pos = 0;; pos += len) { rc = sscanf(str+pos, "%31[^:]: type=%15s removable=%d %255[^\r\n]%n", name, type, &removable, line, &len); if (rc != 4) break; while (str[pos+len] == '\r' || str[pos+len] == '\n') len++; if (!removable) continue; file = strstr(line, "file="); if (file) { file += 5; ptr = strchr(file, ' '); if (ptr) *ptr = 0; } else { file = ""; } if (debug) 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); xml = realloc(xml, xpos + 128); xpos += snprintf(xml+xpos, 128, " \n", action); entry.name = action; entry.label = label; gtk_action_group_add_actions(win->mc_ag, &entry, 1, win); } /* finish */ xml = realloc(xml, xpos + strlen(mc_xml_end)+1); xpos += sprintf(xml+xpos, "%s", mc_xml_end); /* add */ if (debug) fprintf(stderr, "---\n%s---\n", xml); gtk_ui_manager_insert_action_group(win->ui, win->mc_ag, 1); win->mc_id = gtk_ui_manager_add_ui_from_string(win->ui, xml, -1, &err); if (!win->mc_id) { g_message("building media change menu failed: %s", err->message); g_error_free(err); } }