diff options
Diffstat (limited to 'src/dumm/main.c')
-rw-r--r-- | src/dumm/main.c | 953 |
1 files changed, 471 insertions, 482 deletions
diff --git a/src/dumm/main.c b/src/dumm/main.c index d6e142e24..d4f2c5176 100644 --- a/src/dumm/main.c +++ b/src/dumm/main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Martin Willi + * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -13,539 +13,452 @@ * for more details. */ -#define _GNU_SOURCE +#include "dumm.h" + +#include <utils/linked_list.h> -#include <stdio.h> +#include <sys/types.h> #include <unistd.h> -#include <getopt.h> -#include <library.h> -#include <readline/readline.h> -#include <readline/history.h> -#include <dlfcn.h> -#include <dirent.h> -#include "dumm.h" +#include <glib.h> +#include <gtk/gtk.h> +#include <vte/vte.h> +#include <vte/reaper.h> /** - * global set of UMLs guests + * notebook page with vte and guest */ -dumm_t *dumm; +typedef struct { + gint num; + GtkWidget *vte; + guest_t *guest; +} page_t; /** - * show usage information (program arguments) + * Main window */ -static void usage() -{ - printf("Usage:\n"); - printf(" --dir|-d <path> set working dir to <path>\n"); - printf(" --help|-h show this help\n"); -} +GtkWidget *window; /** - * readline() wrapper + * notebook with guests, vtes */ -static char* get_line(char *format, ...) -{ - char *line = NULL; - char *prompt = ""; - va_list args; - - va_start(args, format); - vasprintf(&prompt, format, args); - va_end(args); - - while (TRUE) - { - line = readline(prompt); - if (line == NULL) - { - printf("quit\n"); - dumm->destroy(dumm); - clear_history(); - exit(0); - } - if (*line == '\0') - { - free(line); - continue; - } - add_history(line); - break; - } - free(prompt); - return line; -} +GtkWidget *notebook; + +/** + * dumm context + */ +dumm_t *dumm; + +/** + * pages in notebook, page_t + */ +linked_list_t *pages; /** - * get a guest by name + * handle guest termination, SIGCHILD */ -static guest_t* get_guest(char *name) +static void child_exited(VteReaper *vtereaper, gint pid, gint status) { - iterator_t *iterator; - guest_t *guest = NULL; + enumerator_t *enumerator; + page_t *page; - iterator = dumm->create_guest_iterator(dumm); - while (iterator->iterate(iterator, (void**)&guest)) + enumerator = pages->create_enumerator(pages); + while (enumerator->enumerate(enumerator, (void**)&page)) { - if (streq(guest->get_name(guest), name)) + if (page->guest->get_pid(page->guest) == pid) { + page->guest->sigchild(page->guest); + vte_terminal_feed(VTE_TERMINAL(page->vte), + "\n\r--- guest terminated ---\n\r", -1); break; } - guest = NULL; } - iterator->destroy(iterator); - return guest; + enumerator->destroy(enumerator); } -/** - * get a bridge by name - */ -static bridge_t* get_bridge(char *name) +static page_t* get_page(int num) { - iterator_t *iterator; - bridge_t *bridge = NULL; + enumerator_t *enumerator; + page_t *page, *found = NULL; - iterator = dumm->create_bridge_iterator(dumm); - while (iterator->iterate(iterator, (void**)&bridge)) + enumerator = pages->create_enumerator(pages); + while (enumerator->enumerate(enumerator, (void**)&page)) { - if (streq(bridge->get_name(bridge), name)) + if (page->num == num) { + found = page; break; } - bridge = NULL; } - iterator->destroy(iterator); - return bridge; + enumerator->destroy(enumerator); + return found; } /** - * get an interface by guest name + * Guest invocation callback */ -static iface_t* get_iface(char *name, char *ifname) +static pid_t invoke(void *vte, guest_t *guest, + char *args[], int argc) { - iterator_t *guests, *ifaces; - guest_t *guest; - iface_t *iface; - - guests = dumm->create_guest_iterator(dumm); - while (guests->iterate(guests, (void**)&guest)) - { - if (streq(guest->get_name(guest), name)) - { - iface = NULL; - ifaces = guest->create_iface_iterator(guest); - while (ifaces->iterate(ifaces, (void**)&iface)) - { - if (streq(iface->get_guestif(iface), ifname)) - { - break; - } - iface = NULL; - } - ifaces->destroy(ifaces); - if (iface) - { - break; - } - } - } - guests->destroy(guests); - return iface; + args[argc] = "con0=fd:0,fd:1"; + return vte_terminal_fork_command(VTE_TERMINAL(vte), args[0], args, NULL, + NULL, FALSE, FALSE, FALSE); } -static void guest_addif_menu(guest_t *guest) +void idle(void) { - char *name; - - name = get_line("interface name: "); + gtk_main_iteration_do(FALSE); + sched_yield(); +} + +static void start_guest() +{ + page_t *page; - if (!guest->create_iface(guest, name)) + page = get_page(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))); + if (page && page->guest->get_state(page->guest) == GUEST_STOPPED) { - printf("creating interface failed\n"); + vte_terminal_feed(VTE_TERMINAL(page->vte), + "--- starting guest ---\n\r", -1); + page->guest->start(page->guest, invoke, VTE_TERMINAL(page->vte), idle); } - free(name); } -static void guest_delif_menu(guest_t *guest) +static void start_all_guests() { - char *name; - iface_t *iface; - iterator_t *iterator; - bool found = FALSE; - - name = get_line("interface name: "); + enumerator_t *enumerator; + page_t *page; - iterator = guest->create_iface_iterator(guest); - while (iterator->iterate(iterator, (void**)&iface)) + enumerator = pages->create_enumerator(pages); + while (enumerator->enumerate(enumerator, (void**)&page)) { - if (streq(iface->get_guestif(iface), name)) + if (page->guest->get_state(page->guest) == GUEST_STOPPED) { - iterator->remove(iterator); - iface->destroy(iface); - found = TRUE; - break; + vte_terminal_feed(VTE_TERMINAL(page->vte), + "--- starting all guests ---\n\r", -1); + page->guest->start(page->guest, invoke, + VTE_TERMINAL(page->vte), idle); } } - iterator->destroy(iterator); - - if (!found) - { - printf("interface '%s' not found\n"); - } - free(name); + enumerator->destroy(enumerator); } -static void guest_console(guest_t *guest) +static void stop_guest() { - int con; + page_t *page; - for (con = 1; con <= 6; con++) + page = get_page(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))); + if (page && page->guest->get_state(page->guest) == GUEST_RUNNING) { - char *pts = guest->get_console(guest, con); - if (pts) - { - printf("%d: %s\n", con, pts); - free(pts); - } + page->guest->stop(page->guest, idle); } } -static void guest_menu(guest_t *guest) +/** + * quit signal handler + */ +static void quit() { - while (TRUE) + enumerator_t *enumerator; + page_t *page; + + dumm->load_template(dumm, NULL); + + enumerator = pages->create_enumerator(pages); + while (enumerator->enumerate(enumerator, &page)) { - char *line = get_line("guest/%s# ", guest->get_name(guest)); - - if (streq(line, "back")) - { - free(line); - break; + if (page->guest->get_state(page->guest) != GUEST_STOPPED) + { + page->guest->stop(page->guest, idle); } - else if (streq(line, "start")) - { - if (guest->start(guest)) - { - printf("guest '%s' is running\n", guest->get_name(guest)); - } - else - { - printf("failed to start guest '%s'\n", guest->get_name(guest)); - } - } - else if (streq(line, "stop")) - { - printf("stopping guest '%s'...\n", guest->get_name(guest)); - guest->stop(guest); - printf("guest '%s' is down\n", guest->get_name(guest)); - } - else if (streq(line, "addif")) - { - guest_addif_menu(guest); - } - else if (streq(line, "delif")) - { - guest_delif_menu(guest); - } - else if (streq(line, "console")) - { - guest_console(guest); - } - else - { - printf("back|start|stop|addif|delif|console\n"); - } - free(line); } + enumerator->destroy(enumerator); + gtk_main_quit(); } -static void guest_create_menu() +static void error_dialog(char *msg) { - char *name, *kernel, *master, *mem; - guest_t *guest; - - name = get_line("guest name: "); - kernel = get_line("kernel image: "); - master = get_line("master filesystem: "); - mem = get_line("amount of memory in MB: "); - - guest = dumm->create_guest(dumm, name, kernel, master, atoi(mem)); - if (guest) - { - printf("guest '%s' created\n", guest->get_name(guest)); - guest_menu(guest); - } - else - { - printf("failed to create guest '%s'\n", name); - } - free(name); - free(kernel); - free(master); - free(mem); + GtkWidget *error; + + error = gtk_message_dialog_new(GTK_WINDOW(window), + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, msg); + gtk_dialog_run(GTK_DIALOG(error)); + gtk_widget_destroy(error); } -static void guest_list_menu() +static void create_switch() { + GtkWidget *dialog, *table, *label, *name; + bridge_t *bridge; + + dialog = gtk_dialog_new_with_buttons("Create new switch", GTK_WINDOW(window), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + GTK_STOCK_NEW, GTK_RESPONSE_ACCEPT, NULL); + + table = gtk_table_new(1, 2, TRUE); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table); + + label = gtk_label_new("Switch name"); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, 0, 0, 0, 0); + gtk_widget_show(label); + + name = gtk_entry_new(); + gtk_table_attach(GTK_TABLE(table), name, 1, 2, 0, 1, + GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0); + gtk_widget_show(name); + + gtk_widget_show(table); + while (TRUE) { - iterator_t *iterator; - guest_t *guest; - char *line = get_line("guest# "); - - if (streq(line, "back")) - { - free(line); - break; - } - else if (streq(line, "list")) - { - iterator = dumm->create_guest_iterator(dumm); - while (iterator->iterate(iterator, (void**)&guest)) - { - printf("%s\n", guest->get_name(guest)); - } - iterator->destroy(iterator); - } - else if (streq(line, "create")) - { - guest_create_menu(); - } - else + switch (gtk_dialog_run(GTK_DIALOG(dialog))) { - guest = get_guest(line); - if (guest) - { - guest_menu(guest); - } - else - { - printf("back|list|create|<guest>\n"); + case GTK_RESPONSE_ACCEPT: + { + if (streq(gtk_entry_get_text(GTK_ENTRY(name)), "")) + { + continue; + } + bridge = dumm->create_bridge(dumm, + (char*)gtk_entry_get_text(GTK_ENTRY(name))); + if (!bridge) + { + error_dialog("creating bridge failed!"); + continue; + } + break; } + default: + break; } - free(line); + break; } + gtk_widget_destroy(dialog); } -static void bridge_addif_menu(bridge_t *bridge) +static void delete_switch() { - char *name, *ifname; - iface_t *iface; - - name = get_line("guest name: "); - ifname = get_line("interface name: "); - - iface = get_iface(name, ifname); - if (!iface) - { - printf("guest '%s' has no interface named '%s'\n", name, ifname); - } - else if (!bridge->connect_iface(bridge, iface)) - { - printf("failed to add interface '%s' to bridge '%s'\n", ifname, - bridge->get_name(bridge)); - } - free(name); - free(ifname); + } -static void bridge_delif_menu(bridge_t *bridge) +static void connect_guest() { - char *name, *ifname; + page_t *page; + GtkWidget *dialog, *table, *label, *name, *box; + bridge_t *bridge; iface_t *iface; + enumerator_t *enumerator; - name = get_line("guest name: "); - ifname = get_line("interface name: "); - - iface = get_iface(name, ifname); - if (!iface) + page = get_page(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))); + if (!page || page->guest->get_state(page->guest) != GUEST_RUNNING) { - printf("guest '%s' has no interface named '%s'\n", name, ifname); + return; } - else if (!bridge->disconnect_iface(bridge, iface)) + + dialog = gtk_dialog_new_with_buttons("Connect guest", GTK_WINDOW(window), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + GTK_STOCK_NEW, GTK_RESPONSE_ACCEPT, NULL); + + table = gtk_table_new(2, 2, TRUE); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table); + + label = gtk_label_new("Interface name"); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, 0, 0, 0, 0); + gtk_widget_show(label); + + name = gtk_entry_new(); + gtk_table_attach(GTK_TABLE(table), name, 1, 2, 0, 1, + GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0); + gtk_widget_show(name); + + label = gtk_label_new("Connected switch"); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, 0, 0, 0, 0); + gtk_widget_show(label); + + box = gtk_combo_box_new_text(); + gtk_table_attach(GTK_TABLE(table), box, 1, 2, 1, 2, + GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0); + enumerator = dumm->create_bridge_enumerator(dumm); + while (enumerator->enumerate(enumerator, &bridge)) { - printf("failed to remove interface '%s' from bridge '%s'\n", ifname, - bridge->get_name(bridge)); + gtk_combo_box_append_text(GTK_COMBO_BOX(box), bridge->get_name(bridge)); } - free(name); - free(ifname); -} - -static void bridge_menu(bridge_t *bridge) -{ + enumerator->destroy(enumerator); + gtk_widget_show(box); + + gtk_widget_show(table); + while (TRUE) { - char *line = get_line("bridge/%s# ", bridge->get_name(bridge)); - - if (streq(line, "back")) - { - free(line); - break; - } - else if (streq(line, "list")) + switch (gtk_dialog_run(GTK_DIALOG(dialog))) { - iterator_t *iterator; - iface_t *iface; - - iterator = bridge->create_iface_iterator(bridge); - while (iterator->iterate(iterator, (void**)&iface)) - { - printf("%s (%s)\n", iface->get_guestif(iface), iface->get_hostif(iface)); + case GTK_RESPONSE_ACCEPT: + { + if (streq(gtk_entry_get_text(GTK_ENTRY(name)), "")) + { + continue; + } + + iface = page->guest->create_iface(page->guest, + (char*)gtk_entry_get_text(GTK_ENTRY(name))); + if (!iface) + { + error_dialog("creating interface failed!"); + continue; + } + enumerator = dumm->create_bridge_enumerator(dumm); + while (enumerator->enumerate(enumerator, &bridge)) + { + if (!bridge->connect_iface(bridge, iface)) + { + error_dialog("connecting interface failed!"); + } + break; + } + enumerator->destroy(enumerator); + break; } - iterator->destroy(iterator); - } - else if (streq(line, "addif")) - { - bridge_addif_menu(bridge); - } - else if (streq(line, "delif")) - { - bridge_delif_menu(bridge); - } - else - { - printf("back|list|addif|delif\n"); + default: + break; } - free(line); + break; } + gtk_widget_destroy(dialog); } -static void bridge_create_menu() +static void disconnect_guest() { - char *name; - bridge_t *bridge; - - name = get_line("bridge name: "); - - bridge = dumm->create_bridge(dumm, name); - if (bridge) - { - printf("bridge '%s' created\n", bridge->get_name(bridge)); - bridge_menu(bridge); - } - else - { - printf("failed to create bridge '%s'\n", name); - } - free(name); + } -static void bridge_list_menu() +static void delete_guest() { - while (TRUE) + page_t *page; + + page = get_page(gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))); + if (page) { - iterator_t *iterator; - bridge_t *bridge; - char *line = get_line("bridge# "); - - if (streq(line, "back")) - { - free(line); - break; - } - else if (streq(line, "list")) - { - iterator = dumm->create_bridge_iterator(dumm); - while (iterator->iterate(iterator, (void**)&bridge)) - { - printf("%s\n", bridge->get_name(bridge)); - } - iterator->destroy(iterator); - } - else if (streq(line, "create")) - { - bridge_create_menu(); - } - else - { - bridge = get_bridge(line); - if (bridge) - { - bridge_menu(bridge); - } - else - { - printf("back|list|create|<bridge>\n"); - } - } - free(line); + page->guest->stop(page->guest, idle); + dumm->delete_guest(dumm, page->guest); + gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), page->num); + pages->remove(pages, page, NULL); + g_free(page); } } -static void template_menu() +/** + * create a new page for a guest + */ +static page_t* create_page(guest_t *guest) { - char *name; - - name = get_line("template name (or 'none'): "); + GtkWidget *label; + page_t *page; - dumm->load_template(dumm, streq(name, "none") ? NULL : name); - - free(name); + page = g_new(page_t, 1); + page->guest = guest; + page->vte = vte_terminal_new(); + label = gtk_label_new(guest->get_name(guest)); + page->num = gtk_notebook_append_page(GTK_NOTEBOOK(notebook), + page->vte, label); + gtk_widget_show(page->vte); + pages->insert_last(pages, page); + return page; } -typedef bool (*uml_test_t)(dumm_t *dumm); - -static void test_menu() +/** + * create a new guest + */ +static void create_guest() { - char *name; - void *handle; - struct dirent *ent; - DIR *dir; - uml_test_t test; + guest_t *guest; + GtkWidget *dialog, *table, *label, *name, *kernel, *master, *memory; + + dialog = gtk_dialog_new_with_buttons("Create new guest", GTK_WINDOW(window), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + GTK_STOCK_NEW, GTK_RESPONSE_ACCEPT, NULL); + + table = gtk_table_new(4, 2, TRUE); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table); + + label = gtk_label_new("Guest name"); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, 0, 0, 0, 0); + gtk_widget_show(label); + + label = gtk_label_new("UML kernel"); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, 0, 0, 0, 0); + gtk_widget_show(label); + + label = gtk_label_new("Master filesystem"); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, 0, 0, 0, 0); + gtk_widget_show(label); + + label = gtk_label_new("Memory (MB)"); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, 0, 0, 0, 0); + gtk_widget_show(label); + + name = gtk_entry_new(); + gtk_table_attach(GTK_TABLE(table), name, 1, 2, 0, 1, + GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0); + gtk_widget_show(name); + + kernel = gtk_file_chooser_button_new("Select UML kernel image", + GTK_FILE_CHOOSER_ACTION_OPEN); + gtk_table_attach(GTK_TABLE(table), kernel, 1, 2, 1, 2, + GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0); + gtk_widget_show(kernel); + + master = gtk_file_chooser_button_new("Select master filesystem", + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); + gtk_table_attach(GTK_TABLE(table), master, 1, 2, 2, 3, + GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0); + gtk_widget_show(master); - name = get_line("test name: "); + memory = gtk_spin_button_new_with_range(1, 4096, 1); + gtk_spin_button_set_digits(GTK_SPIN_BUTTON(memory), 0); + gtk_table_attach(GTK_TABLE(table), memory, 1, 2, 3, 4, + GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0, 0); + gtk_widget_show(memory); - dir = opendir("tests"); - if (dir) + gtk_widget_show(table); + + while (TRUE) { - while ((ent = readdir(dir))) + switch (gtk_dialog_run(GTK_DIALOG(dialog))) { - char buf[PATH_MAX]; - size_t len; - - len = strlen(ent->d_name); - if (strlen(ent->d_name) < 4 || !streq(ent->d_name + len - 3, ".so")) + case GTK_RESPONSE_ACCEPT: { - continue; - } + char *sname, *skernel, *smaster; + page_t *page; + + sname = (char*)gtk_entry_get_text(GTK_ENTRY(name)); + skernel = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(kernel)); + smaster = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(master)); - snprintf(buf, sizeof(buf), "%s/%s", "tests", ent->d_name); - handle = dlopen(buf, RTLD_LAZY); - if (!handle) - { - printf("failed to open test %s\n", ent->d_name); - continue; - } - test = dlsym(handle, "test"); - if (test && dumm->load_template(dumm, ent->d_name)) - { - printf("running test %s: ", ent->d_name); - if (test(dumm)) + if (!sname[0] || !skernel || !smaster) { - printf("success\n"); + continue; } - else + guest = dumm->create_guest(dumm, sname, skernel, smaster, + gtk_spin_button_get_value(GTK_SPIN_BUTTON(memory))); + if (!guest) { - printf("failed\n"); + error_dialog("creating guest failed!"); + continue; } + page = create_page(guest); + gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), page->num); + break; } - else - { - printf("failed to open test %s\n", ent->d_name); - } - dlclose(handle); + default: + break; } + break; } - free(name); -} - -/** - * Signal handler - */ -void signal_action(int sig, siginfo_t *info, void *ucontext) -{ - dumm->destroy(dumm); - clear_history(); - exit(0); + gtk_widget_destroy(dialog); } /** @@ -553,80 +466,156 @@ void signal_action(int sig, siginfo_t *info, void *ucontext) */ int main(int argc, char *argv[]) { - struct sigaction action; - char *dir = "."; + GtkWidget *menubar, *menu, *menuitem, *vbox; + GtkWidget *dummMenu, *guestMenu, *switchMenu; + enumerator_t *enumerator; + guest_t *guest; + + library_init(NULL); + gtk_init(&argc, &argv); + + pages = linked_list_create(); + dumm = dumm_create(NULL); - while (TRUE) - { - struct option options[] = { - {"dir", 1, 0, 0}, - {"help", 0, 0, 0}, - {0, 0, 0, 0} - }; - - switch (getopt_long(argc, argv, "d:h", options, NULL)) - { - case -1: - break; - case 'd': - dir = optarg; - continue; - case 'h': - usage(); - return 0; - default: - usage(); - return 1; - } - break; - } + /* setup window */ + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(quit), NULL); + gtk_window_set_title(GTK_WINDOW (window), "Dumm"); + gtk_window_set_default_size(GTK_WINDOW (window), 1000, 500); + g_signal_connect(G_OBJECT(vte_reaper_get()), "child-exited", + G_CALLBACK(child_exited), NULL); - memset(&action, 0, sizeof(action)); - action.sa_sigaction = signal_action; - action.sa_flags = SA_SIGINFO; - if (sigaction(SIGINT, &action, NULL) != 0 || - sigaction(SIGQUIT, &action, NULL) != 0 || - sigaction(SIGTERM, &action, NULL) != 0) - { - printf("signal handler setup failed: %m.\n"); - return 1; - } + /* add vbox with menubar, notebook */ + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(window), vbox); + menubar = gtk_menu_bar_new(); + gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0); + notebook = gtk_notebook_new(); + g_object_set(G_OBJECT(notebook), "homogeneous", TRUE, NULL); + gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_BOTTOM); + gtk_container_add(GTK_CONTAINER(vbox), notebook); + + /* Dumm menu */ + menu = gtk_menu_new(); + dummMenu = gtk_menu_item_new_with_mnemonic("_Dumm"); + gtk_menu_bar_append(GTK_MENU_BAR(menubar), dummMenu); + gtk_widget_show(dummMenu); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(dummMenu), menu); - dumm = dumm_create(dir); - while (TRUE) + /* Dumm -> exit */ + menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(quit), NULL); + gtk_menu_append(GTK_MENU(menu), menuitem); + gtk_widget_show(menuitem); + + /* Guest menu */ + menu = gtk_menu_new(); + guestMenu = gtk_menu_item_new_with_mnemonic("_Guest"); + gtk_menu_bar_append(GTK_MENU_BAR(menubar), guestMenu); + gtk_widget_show(guestMenu); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(guestMenu), menu); + + /* Guest -> new */ + menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_NEW, NULL); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(create_guest), NULL); + gtk_menu_append(GTK_MENU(menu), menuitem); + gtk_widget_show(menuitem); + + /* Guest -> delete */ + menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_DELETE, NULL); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(delete_guest), NULL); + gtk_menu_append(GTK_MENU(menu), menuitem); + gtk_widget_show(menuitem); + + menuitem = gtk_separator_menu_item_new(); + gtk_menu_append(GTK_MENU(menu), menuitem); + gtk_widget_show(menuitem); + + /* Guest -> start */ + menuitem = gtk_menu_item_new_with_mnemonic("_Start"); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(start_guest), NULL); + gtk_menu_append(GTK_MENU(menu), menuitem); + gtk_widget_show(menuitem); + + /* Guest -> startall */ + menuitem = gtk_menu_item_new_with_mnemonic("Start _all"); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(start_all_guests), NULL); + gtk_menu_append(GTK_MENU(menu), menuitem); + gtk_widget_show(menuitem); + + /* Guest -> stop */ + menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_STOP, NULL); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(stop_guest), NULL); + gtk_menu_append(GTK_MENU(menu), menuitem); + gtk_widget_show(menuitem); + + menuitem = gtk_separator_menu_item_new(); + gtk_menu_append(GTK_MENU(menu), menuitem); + gtk_widget_show(menuitem); + + /* Guest -> connect */ + menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_CONNECT, NULL); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(connect_guest), NULL); + gtk_menu_append(GTK_MENU(menu), menuitem); + gtk_widget_show(menuitem); + + /* Guest -> disconnect */ + menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_DISCONNECT, NULL); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(disconnect_guest), NULL); + gtk_menu_append(GTK_MENU(menu), menuitem); + gtk_widget_set_sensitive(menuitem, FALSE); + gtk_widget_show(menuitem); + + /* Switch menu */ + menu = gtk_menu_new(); + switchMenu = gtk_menu_item_new_with_mnemonic("_Switch"); + gtk_menu_bar_append(GTK_MENU_BAR(menubar), switchMenu); + gtk_widget_show(switchMenu); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(switchMenu), menu); + + /* Switch -> new */ + menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_NEW, NULL); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(create_switch), NULL); + gtk_menu_append(GTK_MENU(menu), menuitem); + gtk_widget_show(menuitem); + + /* Switch -> delete */ + menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_DELETE, NULL); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(delete_switch), NULL); + gtk_menu_append(GTK_MENU(menu), menuitem); + gtk_widget_set_sensitive(menuitem, FALSE); + gtk_widget_show(menuitem); + + /* show widgets */ + gtk_widget_show(menubar); + gtk_widget_show(notebook); + gtk_widget_show(vbox); + gtk_widget_show(window); + + /* fill notebook with guests */ + enumerator = dumm->create_guest_enumerator(dumm); + while (enumerator->enumerate(enumerator, (void**)&guest)) { - char *line = get_line("# "); - - if (streq(line, "quit")) - { - free(line); - break; - } - else if (streq(line, "guest")) - { - guest_list_menu(); - } - else if (streq(line, "bridge")) - { - bridge_list_menu(); - } - else if (streq(line, "template")) - { - template_menu(); - } - else if (streq(line, "test")) - { - test_menu(); - } - else - { - printf("quit|guest|bridge|template|test\n"); - } - free(line); + create_page(guest); } - dumm->load_template(dumm, NULL); + enumerator->destroy(enumerator); + + gtk_main(); + dumm->destroy(dumm); - clear_history(); + pages->destroy_function(pages, g_free); + + library_deinit(); return 0; } |