aboutsummaryrefslogtreecommitdiffstats
path: root/devices.c
diff options
context:
space:
mode:
authorkraxel <kraxel>2008-09-30 12:14:49 +0000
committerkraxel <kraxel>2008-09-30 12:14:49 +0000
commiteb91e8c3ca50b3124b40e37a5c5836734eb36000 (patch)
tree5feaecb9453ce70ed9aff3069d98602349cbacfe /devices.c
parentdefe66190b7e8b1c877b44d6cbb8a20b8eb13f24 (diff)
downloadqemu-gtk-eb91e8c3ca50b3124b40e37a5c5836734eb36000.tar.gz
- media change support.
Diffstat (limited to 'devices.c')
-rw-r--r--devices.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/devices.c b/devices.c
new file mode 100644
index 0000000..07de700
--- /dev/null
+++ b/devices.c
@@ -0,0 +1,136 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <gtk/gtk.h>
+
+#include "qemu-gtk.h"
+
+/* ----------------------------------------------------------------- */
+
+static char mc_xml_start[] =
+"<ui>\n"
+" <menubar name='MainMenu'>\n"
+" <menu action='DevicesMenu'>\n"
+" <menu action='MediaChangeSubMenu'>\n";
+
+static char mc_xml_end[] =
+" </menu>\n"
+" </menu>\n"
+" </menubar>\n"
+"</ui>\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 = "<empty>";
+ }
+ 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, " <menuitem action='%s'/>\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);
+ }
+}