X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;ds=sidebyside;f=main.c;h=390046a3a5ab45375e185b19fce5d11dab04a230;hb=0e605c0d34447f049f14dfd96ace73fb1c0cffaf;hp=cf37b318c0d0ef9c38733502b1699796a151ba2d;hpb=0b9477affd8b7978768ee76bc5631adbec3a2dcf;p=ovirt-viewer.git diff --git a/main.c b/main.c index cf37b31..390046a 100644 --- a/main.c +++ b/main.c @@ -27,6 +27,14 @@ #include #include +#ifdef HAVE_NETDB_H +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + #ifdef HAVE_SYS_SOCKET_H #include #endif @@ -60,6 +68,16 @@ static void login_to_wui (GtkWidget *, gpointer); static gboolean delete_event (GtkWidget *widget, GdkEvent *event, gpointer data); static void destroy (GtkWidget *widget, gpointer data); static void clear_connectmenu (void); +static void help_about (GtkWidget *menu); +static void viewer_shutdown (GtkWidget *src, void *dummy, GtkWidget *vnc); +#if 0 +static void viewer_quit (GtkWidget *src, GtkWidget *vnc); +#endif +static void viewer_connected (GtkWidget *vnc); +static void viewer_initialized (GtkWidget *vnc, GtkWidget *data); +static void viewer_disconnected (GtkWidget *vnc); +static void viewer_credential (GtkWidget *vnc, GValueArray *credList); +static int viewer_open_vnc_socket (const char *vnchost, int vncport); /* For any widgets accessed from multiple functions. */ static GtkWidget *window; @@ -220,6 +238,7 @@ start_ui (void) GtkWidget *windmenu; GtkWidget *help; GtkWidget *helpmenu; + GtkWidget *about; GtkWidget *ca_vbox; GtkWidget *ca_hbox; GtkWidget *ca_label; @@ -291,6 +310,10 @@ start_ui (void) helpmenu = gtk_menu_new (); gtk_menu_item_set_submenu (GTK_MENU_ITEM (help), helpmenu); + about = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, NULL); + gtk_menu_append(GTK_MENU(helpmenu), about); + g_signal_connect(about, "activate", GTK_SIGNAL_FUNC (help_about), NULL); + gtk_menu_bar_append (GTK_MENU_BAR (menubar), connectitem); gtk_menu_bar_append (GTK_MENU_BAR (menubar), view); gtk_menu_bar_append (GTK_MENU_BAR (menubar), sendkey); @@ -408,6 +431,42 @@ destroy (GtkWidget *widget, gpointer data) } static void +help_about (GtkWidget *menu) +{ + GtkWidget *about; + const char *authors[] = { + "Richard W.M. Jones ", + "Daniel P. Berrange ", + NULL + }; + + about = gtk_about_dialog_new(); + + gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(about), "oVirt Viewer"); + gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about), VERSION); + gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about), "http://ovirt.org/"); + gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(about), "oVirt website"); + gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about), authors); + gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about), + "This program is free software; you can redistribute it and/or modify\n" \ + "it under the terms of the GNU General Public License as published by\n" \ + "the Free Software Foundation; either version 2 of the License, or\n" \ + "(at your option) any later version.\n" \ + "\n" \ + "This program is distributed in the hope that it will be useful,\n" \ + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \ + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" \ + "GNU General Public License for more details.\n" \ + "\n" \ + "You should have received a copy of the GNU General Public License\n" \ + "along with this program; if not, write to the Free Software\n" \ + "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"); + + gtk_dialog_run(GTK_DIALOG(about)); + gtk_widget_destroy(about); +} + +static void connect_to_wui (GtkWidget *widget, gpointer data) { const char *hostname; @@ -447,9 +506,10 @@ connect_to_vm (GtkWidget *widget, gpointer _vm) { struct vm *vm = (struct vm *) _vm; int n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)); - int i, uuidlen, len; + int i, uuidlen, len, fd; GtkWidget *child; const char *label; + const char* hostname; char *label2; DEBUG ("searching tabs for uuid %s", vm->uuid); @@ -472,15 +532,46 @@ connect_to_vm (GtkWidget *widget, gpointer _vm) DEBUG ("not found, creating new tab"); /* This VM isn't in the notebook already, so create a new console. */ - len = strlen (vm->description) + 1 + strlen (vm->uuid) + 1; - label2 = g_alloca (len); - snprintf (label2, len, "%s %s", vm->description, vm->uuid); + hostname = gtk_entry_get_text (GTK_ENTRY (ca_hostname)); + fd = viewer_open_vnc_socket(hostname, vm->forward_vnc_port); + if (fd == -1) return; /* We've already given an error. */ + + child = vnc_display_new (); + if (! vnc_display_open_fd (VNC_DISPLAY (child), fd)) { + main_status_error (g_strdup ("internal error in Gtk-VNC widget")); + return; + } + + /* + gtk_signal_connect(GTK_OBJECT(child), "vnc-pointer-grab", + GTK_SIGNAL_FUNC(viewer_grab), window); + gtk_signal_connect(GTK_OBJECT(child), "vnc-pointer-ungrab", + GTK_SIGNAL_FUNC(viewer_ungrab), window); + */ - child = gtk_label_new (label2); /* XXX */ + gtk_signal_connect(GTK_OBJECT(child), "delete-event", + GTK_SIGNAL_FUNC(viewer_shutdown), child); + + gtk_signal_connect(GTK_OBJECT(child), "vnc-connected", + GTK_SIGNAL_FUNC(viewer_connected), NULL); + gtk_signal_connect(GTK_OBJECT(child), "vnc-initialized", + GTK_SIGNAL_FUNC(viewer_initialized), NULL); + gtk_signal_connect(GTK_OBJECT(child), "vnc-disconnected", + GTK_SIGNAL_FUNC(viewer_disconnected), NULL); + + g_signal_connect(GTK_OBJECT(child), "vnc-auth-credential", + GTK_SIGNAL_FUNC(viewer_credential), NULL); /* NB. We have to do this before adding it to the notebook. */ gtk_widget_show (child); + /* Choose a tab label, which MUST end with the uuid string, since + * we use the tab label to store uuid. + */ + len = strlen (vm->description) + 1 + strlen (vm->uuid) + 1; + label2 = g_alloca (len); + snprintf (label2, len, "%s %s", vm->description, vm->uuid); + i = gtk_notebook_append_page (GTK_NOTEBOOK (notebook), child, NULL); gtk_notebook_set_tab_label_text (GTK_NOTEBOOK (notebook), child, label2); gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), i); @@ -488,6 +579,206 @@ connect_to_vm (GtkWidget *widget, gpointer _vm) DEBUG ("finished creating new tab"); } +/* +static void viewer_grab(GtkWidget *vnc, GtkWidget *window) +{ + int i; + + viewer_set_title(VNC_DISPLAY(vnc), window, TRUE); + + for (i = 0 ; i < LAST_MENU; i++) { + gtk_label_set_text_with_mnemonic(GTK_LABEL(menuItems[i].label), menuItems[i].grabbed_text); + } +} + +static void viewer_ungrab(GtkWidget *vnc, GtkWidget *window) +{ + int i; + + viewer_set_title(VNC_DISPLAY(vnc), window, FALSE); + + for (i = 0 ; i < LAST_MENU; i++) { + gtk_label_set_text_with_mnemonic(GTK_LABEL(menuItems[i].label), menuItems[i].ungrabbed_text); + } +} +*/ + +static void +viewer_shutdown (GtkWidget *src, void *dummy, GtkWidget *vnc) +{ + vnc_display_close (VNC_DISPLAY(vnc)); + + /* Just close the notebook tab for now. XXX */ + gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), + gtk_notebook_page_num (GTK_NOTEBOOK (notebook), + vnc)); +} + +#if 0 +static void +viewer_quit (GtkWidget *src, GtkWidget *vnc) +{ + viewer_shutdown (src, NULL, vnc); +} +#endif + +static void +viewer_connected (GtkWidget *vnc) +{ + DEBUG ("Connected to server"); +} + +static void +viewer_initialized (GtkWidget *vnc, GtkWidget *data) +{ + DEBUG ("Connection initialized"); +} + +static void +viewer_disconnected (GtkWidget *vnc) +{ + DEBUG ("Disconnected from server"); +} + +static void +viewer_credential (GtkWidget *vnc, GValueArray *credList) +{ + GtkWidget *dialog = NULL; + int response; + unsigned int i, prompt = 0; + const char **data; + + DEBUG ("Got credential request for %d credential(s)", + credList->n_values); + + data = g_new0(const char *, credList->n_values); + + for (i = 0 ; i < credList->n_values ; i++) { + GValue *cred = g_value_array_get_nth(credList, i); + switch (g_value_get_enum(cred)) { + case VNC_DISPLAY_CREDENTIAL_USERNAME: + case VNC_DISPLAY_CREDENTIAL_PASSWORD: + prompt++; + break; + case VNC_DISPLAY_CREDENTIAL_CLIENTNAME: + data[i] = "libvirt"; + default: + break; + } + } + + if (prompt) { + GtkWidget **label, **entry, *box, *vbox; + int row; + dialog = gtk_dialog_new_with_buttons("Authentication required", + NULL, + 0, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, + GTK_RESPONSE_OK, + NULL); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); + + box = gtk_table_new(credList->n_values, 2, FALSE); + label = g_new(GtkWidget *, prompt); + entry = g_new(GtkWidget *, prompt); + + for (i = 0, row =0 ; i < credList->n_values ; i++) { + GValue *cred = g_value_array_get_nth(credList, i); + switch (g_value_get_enum(cred)) { + case VNC_DISPLAY_CREDENTIAL_USERNAME: + label[row] = gtk_label_new("Username:"); + break; + case VNC_DISPLAY_CREDENTIAL_PASSWORD: + label[row] = gtk_label_new("Password:"); + break; + default: + continue; + } + entry[row] = gtk_entry_new(); + if (g_value_get_enum(cred) == VNC_DISPLAY_CREDENTIAL_PASSWORD) + gtk_entry_set_visibility(GTK_ENTRY(entry[row]), FALSE); + + gtk_table_attach(GTK_TABLE(box), label[i], 0, 1, row, row+1, GTK_SHRINK, GTK_SHRINK, 3, 3); + gtk_table_attach(GTK_TABLE(box), entry[i], 1, 2, row, row+1, GTK_SHRINK, GTK_SHRINK, 3, 3); + row++; + } + + vbox = gtk_bin_get_child(GTK_BIN(dialog)); + gtk_container_add(GTK_CONTAINER(vbox), box); + + gtk_widget_show_all(dialog); + response = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_hide(GTK_WIDGET(dialog)); + + if (response == GTK_RESPONSE_OK) { + for (i = 0, row = 0 ; i < credList->n_values ; i++) { + GValue *cred = g_value_array_get_nth(credList, i); + switch (g_value_get_enum(cred)) { + case VNC_DISPLAY_CREDENTIAL_USERNAME: + case VNC_DISPLAY_CREDENTIAL_PASSWORD: + data[i] = gtk_entry_get_text(GTK_ENTRY(entry[row])); + break; + } + } + } + } + + for (i = 0 ; i < credList->n_values ; i++) { + GValue *cred = g_value_array_get_nth(credList, i); + if (data[i]) { + if (vnc_display_set_credential(VNC_DISPLAY(vnc), + g_value_get_enum(cred), + data[i])) { + DEBUG("Failed to set credential type %d", + g_value_get_enum(cred)); + vnc_display_close(VNC_DISPLAY(vnc)); + } + } else { + DEBUG("Unsupported credential type %d", + g_value_get_enum(cred)); + vnc_display_close(VNC_DISPLAY(vnc)); + } + } + + g_free(data); + if (dialog) + gtk_widget_destroy(GTK_WIDGET(dialog)); +} + +#if defined(HAVE_SOCKET) && defined(HAVE_CONNECT) && defined(HAVE_HTONS) && defined(HAVE_GETHOSTBYNAME) + +static int +viewer_open_vnc_socket(const char* vnchost, int vncport) +{ + int socketfd; + struct hostent *serv; + struct sockaddr_in serv_addr; + + socketfd = socket(PF_INET, SOCK_STREAM, 0); + if(socketfd < 0){ + return -1; + } + + serv = gethostbyname(vnchost); + if(serv == NULL){ + return -1; + } + + serv_addr.sin_family = PF_INET; + serv_addr.sin_port = htons(vncport); + serv_addr.sin_addr.s_addr = ((struct in_addr *)(serv->h_addr))->s_addr; + + if (connect(socketfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0){ + return -1; + } + + return socketfd; +} + +#endif /* defined(HAVE_SOCKET) && defined(HAVE_CONNECT) && defined(HAVE_HTONS) && defined(HAVE_GETHOSTBYNAME) */ + /* Remove all menu items from the Connect menu. */ static void remove_menu_item (GtkWidget *menu_item, gpointer data)