Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.4
virt-viewer
keymap.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File keymap.diff of Package virt-viewer
Index: virt-viewer-0.0.3/src/keymap.c =================================================================== --- /dev/null +++ virt-viewer-0.0.3/src/keymap.c @@ -0,0 +1,411 @@ +/* + * keymap.c: Reads keymap XML definition file populating keyComboDef + * structures + * + * Copyright (C) 2008 Novell, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Pat Campbell <plc@novell.com> + */ + +#include <config.h> + +#include <gtk/gtk.h> +#include <gdk/gdkkeysyms.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <libxml/xpath.h> + +#include "viewer.h" + +#define ITEM_PATH "//keymap/item" +#define ROOT "keymap" +#define ITEM "item" +#define TYPE "type" +#define MENU "menu" +#define SEP "separator" +#define LABEL "label" +#define KEYS "keys" +#define KEY "key" +#define DEFAULT_KEY_XML "/usr/share/virt-viewer/keymap.xml" + +static int verbose = 0; + +static int create_keyCombos(SendKeyItems * sendKeyItems, xmlXPathContextPtr ctxt) +{ + xmlXPathObjectPtr obj; + xmlNodePtr relnode; + SendKeyItems old_sendKeyItems; + + if (ctxt == NULL) { + fprintf(stderr,"Invalid parser context to %s", __func__); + goto error; + } + relnode = ctxt->node; + + /* + * Determine number of items + */ + obj = xmlXPathEval((xmlChar *)ITEM_PATH, ctxt); + if ((obj == NULL) || (obj->type != XPATH_NODESET)) { + xmlXPathFreeObject(obj); + fprintf(stderr, "Error obj NULL or type not a NODESET"); + goto error; + } + old_sendKeyItems.keyCombos = sendKeyItems->keyCombos; + old_sendKeyItems.cnt = sendKeyItems->cnt; + + sendKeyItems->cnt = xmlXPathNodeSetGetLength(obj->nodesetval); + if (sendKeyItems->cnt) { + sendKeyItems->keyCombos = calloc(sendKeyItems->cnt, sizeof(struct keyComboDef *)); + if (!sendKeyItems->keyCombos) { + sendKeyItems->keyCombos = old_sendKeyItems.keyCombos; + sendKeyItems->cnt = old_sendKeyItems.cnt; + } + else if (old_sendKeyItems.keyCombos) { + int i; + for (i = 0; i < old_sendKeyItems.cnt; i++) { + free(old_sendKeyItems.keyCombos[i]->keys); + free(old_sendKeyItems.keyCombos[i]->label); + } + free(old_sendKeyItems.keyCombos); + } + } + ctxt->node = relnode; + xmlXPathFreeObject(obj); +error: + return(sendKeyItems->cnt); +} + +static void build_keyComboDef(SendKeyItems *sendKeyItems, guint *keys, int cnt, const char * label) +{ + int i; + struct keyComboDef *kp; + + kp = (struct keyComboDef*)calloc(sizeof(guint *) + sizeof(guint) + sizeof(char *), 1); + if (!kp) + return; + + if (keys) { + kp->keys = (guint *)malloc((sizeof(guint) * cnt) ); + if (!kp->keys) { + free(kp); + return; + } + for(i=0; i<cnt; i++) { + kp->keys[i] = keys[i]; + } + } + if (label) { + kp->label = strdup(label); + } + else { + kp->label = strdup("Unknown"); + } + kp->nkeys = cnt; + + for (i = 0; i < sendKeyItems->cnt; i++) { + if ( sendKeyItems->keyCombos[i] == NULL) { + sendKeyItems->keyCombos[i] = kp; + break; + } + } +} + +static char *trim(char *str) +{ + char * p = str; + + p += strlen(str); + + /* trim trailing */ + while(p != str) { + if (*p == '\n' || *p == '\t' || *p == ' ' || *p == '\0') { + *p = '\0'; + p--; + continue; + } + break; + } + /* trim leading */ + p = str; + while(p != '\0') { + if (*p == '\n' || *p == '\t' || *p == ' ') { + p++; + continue; + } + break; + } + if (p != str) { + memcpy(str, p, strlen(p) + 1); + } + return(str); +} + +static void process_keys(SendKeyItems *sendKeyItems, xmlDocPtr xml, xmlXPathContextPtr ctxt, + xmlNode * node, char *label) +{ + xmlNode *n; + int cnt = 0; + int i = 0; + guint * keys; + xmlXPathObjectPtr obj; + char *str; + + if (!node || !node->children) return; + + /* + * get number of keys + */ + for(n=node->children; n; n=n->next) { + if (n->type != XML_ELEMENT_NODE) continue; + cnt++; + } + + if (cnt) { + keys = malloc(sizeof(guint) * cnt); + if (keys) { + for(i = 0, n=node->children; n; n=n->next) { + if (n->type != XML_ELEMENT_NODE) continue; + obj = xmlXPathEval(xmlGetNodePath(n), ctxt); + str = (char *)xmlNodeListGetString(xml, obj->nodesetval->nodeTab[0]->xmlChildrenNode, 1); + trim(str); + keys[i] = gdk_keyval_from_name(str); + if (keys[i] == 0) { + if (verbose) { + fprintf(stderr, "virt-viewer: Could not get keyval for %s:%s, ignoring\n", + str, label); + } + free(keys); + sendKeyItems->cnt--; + return; + } + i++; + } + build_keyComboDef(sendKeyItems, keys, cnt, label); + } + } +} + +static void process_item(SendKeyItems * sendKeyItems, xmlDocPtr xml, + xmlXPathContextPtr ctxt, xmlNode * node) +{ + xmlNode *n; + xmlXPathObjectPtr obj; + xmlChar *type; + char *label = NULL; + + if (!node) return; + + type = xmlGetProp(node, (xmlChar*)"type"); + if (!type) return; + + if (xmlStrncmp((const xmlChar*)MENU, type, strlen(MENU)) == 0) { + for(n=node->children; n; n=n->next) { + if (n->type != XML_ELEMENT_NODE) continue; + if (xmlStrncmp((const xmlChar*)LABEL, n->name, strlen(LABEL)) == 0) { + obj = xmlXPathEval(xmlGetNodePath(n), ctxt); + if (!obj) return; + label = (char *)xmlNodeListGetString(xml, obj->nodesetval->nodeTab[0]->xmlChildrenNode, 1); + } + else if (xmlStrncmp((const xmlChar*)KEYS, n->name, strlen(KEYS)) == 0) { + process_keys(sendKeyItems, xml, ctxt, n, label); + } + } + } + else if (xmlStrncmp((const xmlChar*)SEP, type, strlen(SEP)) == 0) { + build_keyComboDef(sendKeyItems, NULL, 0, ""); + } +} + +#define MAX_KEYS 3 +struct defaultKeyComboDef { + guint keys[MAX_KEYS]; + guint nkeys; + const char *label; +}; +static const struct defaultKeyComboDef defaultKeyCombos[] = { + { { GDK_Control_L, GDK_Alt_L, GDK_Delete }, 3, "Ctrl+Alt+_Del"}, + { { GDK_Control_L, GDK_Alt_L, GDK_BackSpace }, 3, "Ctrl+Alt+_Backspace"}, + { {}, 0, "" }, + { { GDK_Control_L, GDK_Alt_L, GDK_F1 }, 3, "Ctrl+Alt+F_1"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F2 }, 3, "Ctrl+Alt+F_2"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F3 }, 3, "Ctrl+Alt+F_3"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F4 }, 3, "Ctrl+Alt+F_4"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F5 }, 3, "Ctrl+Alt+F_5"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F6 }, 3, "Ctrl+Alt+F_6"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F7 }, 3, "Ctrl+Alt+F_7"}, + { { GDK_Control_L, GDK_Alt_L, GDK_F8 }, 3, "Ctrl+Alt+F_8"}, + { {}, 0, "" }, + { { GDK_Print }, 1, "_PrintScreen"}, +}; + +static void makeDefaultKeyCombos(SendKeyItems * sendKeyItems) +{ + int i; + guint *keys; + + sendKeyItems->cnt = (sizeof(defaultKeyCombos)/sizeof(defaultKeyCombos[0])); + sendKeyItems->keyCombos = calloc(sendKeyItems->cnt, sizeof(struct keyComboDef *)); + if (!sendKeyItems->keyCombos) { + sendKeyItems->cnt = 0; + return; + } + + for (i = 0 ; i < (sizeof(defaultKeyCombos)/sizeof(defaultKeyCombos[0])) ; i++) { + keys = (guint *)defaultKeyCombos[i].keys; + build_keyComboDef(sendKeyItems, keys, defaultKeyCombos[i].nkeys, defaultKeyCombos[i].label); + } +} + + +int build_keyCombos(SendKeyItems * sendKeyItems, const char *filename, int set_verbose) +{ + xmlDocPtr xml = NULL; + xmlParserCtxtPtr pctxt = NULL; + xmlXPathContextPtr ctxt = NULL; + xmlNode *root_element = NULL; + xmlNode *node; + struct stat sbuf; + + verbose = set_verbose; + pctxt = xmlNewParserCtxt(); + if (!pctxt || !pctxt->sax) + goto error; + + if (filename == NULL) + filename = DEFAULT_KEY_XML; + + if(stat(filename, &sbuf) != 0) { + if (verbose) + fprintf(stderr, "%s(): could not stat file:%s \n", __FUNCTION__, filename); + goto error; + } + + xml = xmlCtxtReadFile(pctxt, filename, NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + if (!xml) { + if (verbose) + fprintf(stderr, "%s(): could not read file:%s \n", __FUNCTION__, filename); + goto error; + } + + ctxt = xmlXPathNewContext(xml); + if (!ctxt) + goto error; + + root_element = xmlDocGetRootElement(xml); + if (!root_element) { + if (verbose) + fprintf(stderr, "%s(): could not locate root element\n", __FUNCTION__); + goto error; + } + + if (!create_keyCombos(sendKeyItems, ctxt)) { + if (verbose) + fprintf(stderr, "%s(): could not create XML based keyCombos structure \n", __FUNCTION__); + goto error; + } + + for (node=root_element; node; node=node->next) { + if (node->type != XML_ELEMENT_NODE) continue; + if (node->children) + { + xmlNode *n; + for(n=node->children; n; n=n->next) { + if (n->type != XML_ELEMENT_NODE) continue; + if (xmlStrncmp((const xmlChar*)ITEM, n->name, strlen(ITEM)) == 0) { + process_item(sendKeyItems, xml, ctxt, n); + } + } + } + } + + error: + if (ctxt) + xmlXPathFreeContext(ctxt); + if (xml) + xmlFreeDoc(xml); + if (pctxt) + xmlFreeParserCtxt(pctxt); + if (sendKeyItems->keyCombos == NULL) + makeDefaultKeyCombos(sendKeyItems); + return(sendKeyItems->cnt); +} + +int sendkey_xml_validate(const char * filename) +{ + xmlDocPtr doc = NULL; + xmlParserCtxtPtr pctxt = NULL; + xmlXPathContextPtr ctxt = NULL; + xmlNode *root_element = NULL; + int ret = -1; + + pctxt = xmlNewParserCtxt(); + if (!pctxt || !pctxt->sax) { + if (verbose) + fprintf(stderr, "%s(): failed to allocate parser context \n", __FUNCTION__); + goto error; + } + + doc = xmlCtxtReadFile(pctxt, filename, NULL, XML_PARSE_DTDVALID); + if (!doc) { + if (verbose) + fprintf(stderr, "%s(): could not read file:%s \n", __FUNCTION__, filename); + goto error; + } + if (pctxt->valid == 0) { + if (verbose) + fprintf(stderr, "%s(): Failed to validate :%s \n", __FUNCTION__, filename); + goto error; + } + + ctxt = xmlXPathNewContext(doc); + if (!ctxt) { + if (verbose) + fprintf(stderr, "%s(): Failed to allocate path context\n", __FUNCTION__); + goto error; + } + + root_element = xmlDocGetRootElement(doc); + if (!root_element) { + if (verbose) + fprintf(stderr, "%s(): could not locate root element\n", __FUNCTION__); + goto error; + } + + if (xmlStrncmp((const xmlChar*)ROOT, root_element->name, strlen(ROOT)) != 0) { + if (verbose) + fprintf(stderr, "%s(): Incorrect root element name:%s\n", __FUNCTION__, + root_element->name); + goto error; + } + ret = 0; + +error: + if (ctxt) + xmlXPathFreeContext(ctxt); + if (doc) + xmlFreeDoc(doc); + if (pctxt) + xmlFreeParserCtxt(pctxt); + return(ret); + +} Index: virt-viewer-0.0.3/src/keymap.xml =================================================================== --- /dev/null +++ virt-viewer-0.0.3/src/keymap.xml @@ -0,0 +1,95 @@ +<?xml version="1.0"?> + +<!DOCTYPE keymap [ +<!ELEMENT keymap (item)*> +<!ELEMENT item (label,keys)*> +<!ELEMENT label (#PCDATA)> +<!ELEMENT keys (key)+> +<!ELEMENT key (#PCDATA)> +<!ATTLIST keymap id CDATA #REQUIRED> +<!ATTLIST item type (menu|separator) #REQUIRED> +]> + +<keymap id="virt-viewer, Send Key menu keymap"> + <!-- See /usr/include/gtk2.0/gdk/gdkkeysyms.h for valid key names --> + <item type="menu"> + <label>Ctrl+Alt+_Del</label> + <keys> + <key>Control_L</key> + <key>Alt_L</key> + <key>Delete</key> + </keys> + </item> + <item type="menu"> + <label>Ctrl+Alt+_BackSpace</label> + <keys> + <key>Control_L</key> + <key>Alt_L</key> + <key>BackSpace</key> + </keys> + </item> + <item type="separator"/> + <item type="menu"> + <label>Ctrl+Alt+F1</label> + <keys> + <key>Control_L</key> + <key>Alt_L</key> + <key>F1</key> + </keys> + </item> + <item type="menu"> + <label>Ctrl+Alt+F2</label> + <keys> + <key>Control_L</key> + <key>Alt_L</key> + <key>F2</key> + </keys> + </item> + <item type="menu"> + <label>Ctrl+Alt+F3</label> + <keys> + <key>Control_L</key> + <key>Alt_L</key> + <key>F3</key> + </keys> + </item> + <item type="menu"> + <label>Ctrl+Alt+F4</label> + <keys> + <key>Control_L</key> + <key>Alt_L</key> + <key>F4</key> + </keys> + </item> + <item type="menu"> + <label>Ctrl+Alt+F5</label> + <keys> + <key>Control_L</key> + <key>Alt_L</key> + <key>F5</key> + </keys> + </item> + <item type="menu"> + <label>Ctrl+Alt+F6</label> + <keys> + <key>Control_L</key> + <key>Alt_L</key> + <key>F6</key> + </keys> + </item> + <item type="menu"> + <label>Ctrl+Alt+F7</label> + <keys> + <key>Control_L</key> + <key>Alt_L</key> + <key>F7</key> + </keys> + </item> + <item type="separator"/> + <item type="menu"> + <label>_PrintScreen</label> + <keys> + <key>Print</key> + </keys> + </item> +</keymap> Index: virt-viewer-0.0.3/src/main.c =================================================================== --- virt-viewer-0.0.3.orig/src/main.c +++ virt-viewer-0.0.3/src/main.c @@ -46,28 +46,9 @@ static char *domname = NULL; static int verbose = 0; -#define MAX_KEY_COMBO 3 -struct keyComboDef { - guint keys[MAX_KEY_COMBO]; - guint nkeys; - const char *label; -}; -static const struct keyComboDef keyCombos[] = { - { { GDK_Control_L, GDK_Alt_L, GDK_Delete }, 3, "Ctrl+Alt+_Del"}, - { { GDK_Control_L, GDK_Alt_L, GDK_BackSpace }, 3, "Ctrl+Alt+_Backspace"}, - { {}, 0, "" }, - { { GDK_Control_L, GDK_Alt_L, GDK_F1 }, 3, "Ctrl+Alt+F_1"}, - { { GDK_Control_L, GDK_Alt_L, GDK_F2 }, 3, "Ctrl+Alt+F_2"}, - { { GDK_Control_L, GDK_Alt_L, GDK_F3 }, 3, "Ctrl+Alt+F_3"}, - { { GDK_Control_L, GDK_Alt_L, GDK_F4 }, 3, "Ctrl+Alt+F_4"}, - { { GDK_Control_L, GDK_Alt_L, GDK_F5 }, 3, "Ctrl+Alt+F_5"}, - { { GDK_Control_L, GDK_Alt_L, GDK_F6 }, 3, "Ctrl+Alt+F_6"}, - { { GDK_Control_L, GDK_Alt_L, GDK_F7 }, 3, "Ctrl+Alt+F_7"}, - { { GDK_Control_L, GDK_Alt_L, GDK_F8 }, 3, "Ctrl+Alt+F_8"}, - { {}, 0, "" }, - { { GDK_Print }, 1, "_PrintScreen"}, -}; +SendKeyItems sendKeyItems; +static GtkWidget *viewer_build_sendkey_menu(VncDisplay *vnc); enum menuNums { FILE_MENU, @@ -79,18 +60,27 @@ enum menuNums { struct menuItem { guint menu; + GtkWidget *widget; GtkWidget *label; const char *ungrabbed_text; const char *grabbed_text; }; static struct menuItem menuItems[] = { - { FILE_MENU, NULL, "_File", "File" }, - { VIEW_MENU, NULL, "_View", "View" }, - { SEND_KEY_MENU, NULL, "_Send Key", "Send Key" }, - { HELP_MENU, NULL, "_Help", "Help" } + { FILE_MENU, NULL, NULL, "_File", "File" }, + { VIEW_MENU, NULL, NULL, "_View", "View" }, + { SEND_KEY_MENU, NULL, NULL, "_Send Key", "Send Key" }, + { HELP_MENU, NULL, NULL, "_Help", "Help" } }; +typedef struct { + VncDisplay *vnc; + GtkWindow *window; + GtkWidget *menubar; +}VirtViewer; + +static VirtViewer virtViewer; + static void viewer_set_title(VncDisplay *vnc G_GNUC_UNUSED, GtkWidget *window, gboolean grabbed) { char title[1024]; @@ -182,12 +172,13 @@ static void viewer_send_key(GtkWidget *m GtkWidget *label = gtk_bin_get_child(GTK_BIN(menu)); const char *text = gtk_label_get_label(GTK_LABEL(label)); - for (i = 0 ; i < (sizeof(keyCombos)/sizeof(keyCombos[0])) ; i++) { - if (!strcmp(text, keyCombos[i].label)) { + for (i = 0 ; i < sendKeyItems.cnt; i++) { + struct keyComboDef *kp = sendKeyItems.keyCombos[i]; + if (!strcmp(text, kp->label)) { DEBUG_LOG("Sending key combo %s\n", gtk_label_get_text(GTK_LABEL(label))); vnc_display_send_keys(VNC_DISPLAY(vnc), - keyCombos[i].keys, - keyCombos[i].nkeys); + kp->keys, + kp->nkeys); return; } } @@ -229,6 +220,47 @@ static void viewer_screenshot(GtkWidget gtk_widget_destroy (dialog); } +static void viewer_file_sendkey(GtkWidget *menu G_GNUC_UNUSED, VirtViewer *viewer) +{ + GtkWidget *dialog; + GtkWidget *sendkey; + + dialog = gtk_file_chooser_dialog_new ("Load SendKey", + NULL, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); +again: + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + char *filename; + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + if (sendkey_xml_validate(filename) == -1) { + GtkWidget *msg_dialog = gtk_message_dialog_new (GTK_WINDOW(dialog), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Invalid send key XML format: '%s'", + filename); + gtk_dialog_run (GTK_DIALOG (msg_dialog)); + gtk_widget_destroy (msg_dialog); + g_free (filename); + goto again; + } + else { + build_keyCombos(&sendKeyItems, filename, verbose); + gtk_widget_destroy (menuItems[SEND_KEY_MENU].widget); + sendkey = viewer_build_sendkey_menu(viewer->vnc); + gtk_menu_bar_insert(GTK_MENU_BAR(viewer->menubar), sendkey, SEND_KEY_MENU); + gtk_widget_show_all(viewer->menubar); + } + g_free (filename); + } + + gtk_widget_destroy (dialog); +} + static void viewer_credential(GtkWidget *vnc, GValueArray *credList) { @@ -386,6 +418,7 @@ static GtkWidget *menu_item_new(int whic gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(label), widget); gtk_widget_show(label); + menuItems[which_menu].widget = widget; menuItems[which_menu].label = label; return widget; @@ -397,6 +430,7 @@ static GtkWidget *viewer_build_file_menu GtkWidget *filemenu; GtkWidget *quit; GtkWidget *screenshot; + GtkWidget *sendkey; file = menu_item_new(FILE_MENU); @@ -407,6 +441,10 @@ static GtkWidget *viewer_build_file_menu gtk_menu_append(GTK_MENU(filemenu), screenshot); g_signal_connect(screenshot, "activate", GTK_SIGNAL_FUNC(viewer_screenshot), vnc); + sendkey = gtk_menu_item_new_with_mnemonic("Send _Key"); + gtk_menu_append(GTK_MENU(filemenu), sendkey); + g_signal_connect(sendkey, "activate", GTK_SIGNAL_FUNC(viewer_file_sendkey), &virtViewer); + gtk_menu_append(GTK_MENU(filemenu), gtk_separator_menu_item_new()); @@ -453,11 +491,12 @@ static GtkWidget *viewer_build_sendkey_m sendkeymenu = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(sendkey), sendkeymenu); - for (i = 0 ; i < (sizeof(keyCombos)/sizeof(keyCombos[0])) ; i++) { + for (i = 0 ; i < sendKeyItems.cnt; i++) { GtkWidget *key; + struct keyComboDef *kp = sendKeyItems.keyCombos[i]; - if (keyCombos[i].nkeys) { - key = gtk_menu_item_new_with_mnemonic(keyCombos[i].label); + if (kp->nkeys) { + key = gtk_menu_item_new_with_mnemonic(kp->label); gtk_menu_append(GTK_MENU(sendkeymenu), key); g_signal_connect(key, "activate", GTK_SIGNAL_FUNC(viewer_send_key), vnc); } else { @@ -495,6 +534,7 @@ static GtkWidget *viewer_build_menu(VncD GtkWidget *help; menubar = gtk_menu_bar_new(); + virtViewer.menubar = menubar; file = viewer_build_file_menu(vnc); view = viewer_build_view_menu(vnc, window, composited); @@ -527,6 +567,9 @@ static GtkWidget *viewer_build_window(Vn window = get_toplevel (data); gtk_window_set_resizable(GTK_WINDOW(window), TRUE); + virtViewer.vnc = vnc; + virtViewer.window = (GTK_WINDOW(window)); + if (with_menubar) { layout = gtk_vbox_new(FALSE, 3); menubar = viewer_build_menu(vnc, window, gtk_widget_is_composited(window)); @@ -886,6 +929,7 @@ static void viewer_help(FILE *out, const fprintf(out, " -d, --direct direct connection with no automatic tunnels\n"); fprintf(out, " -c URI, --connect URI connect to hypervisor URI\n"); fprintf(out, " -w, --wait wait for domain to start\n"); + fprintf(out, " -k file, --keymap file menu key definition file\n"); fprintf(out, "\n"); } @@ -894,7 +938,7 @@ int main(int argc, char **argv) char *uri = NULL; char *name = NULL; int opt_ind; - const char *sopts = "hVc:"; + const char *sopts = "hvVdc:wk:"; static const struct option lopts[] = { { "help", 0, 0, 'h' }, { "version", 0, 0, 'V' }, @@ -902,6 +946,7 @@ int main(int argc, char **argv) { "connect", 1, 0, 'c' }, { "wait", 0, 0, 'w' }, { "direct", 0, 0, 'd' }, + { "keymap", 1, 0, 'k' }, { 0, 0, 0, 0 } }; int ch; @@ -909,6 +954,7 @@ int main(int argc, char **argv) int waitvnc = 0; int set_verbose = 0; int ret; + char *keymap_file = NULL; while ((ch = getopt_long(argc, argv, sopts, lopts, &opt_ind)) != -1) { switch (ch) { @@ -930,6 +976,9 @@ int main(int argc, char **argv) case 'd': direct = 1; break; + case 'k': + keymap_file = strdup(optarg); + break; case '?': viewer_help(stderr, argv[0]); return 1; @@ -941,6 +990,8 @@ int main(int argc, char **argv) return 1; } + build_keyCombos(&sendKeyItems, keymap_file, set_verbose); + gtk_init(&argc, &argv); name = argv[optind]; Index: virt-viewer-0.0.3/src/Makefile.am =================================================================== --- virt-viewer-0.0.3.orig/src/Makefile.am +++ virt-viewer-0.0.3/src/Makefile.am @@ -1,6 +1,13 @@ bin_PROGRAMS = virt-viewer -virt_viewer_SOURCES = main.c viewer.h +virt_viewer_SOURCES = main.c keymap.c viewer.h virt_viewer_LDADD = @GTKVNC_LIBS@ @GTK2_LIBS@ @LIBXML2_LIBS@ @LIBVIRT_LIBS@ virt_viewer_CFLAGS = @GTKVNC_CFLAGS@ @GTK2_CFLAGS@ @LIBXML2_CFLAGS@ @LIBVIRT_CFLAGS@ @WARN_CFLAGS@ + +install-data-local: + mkdir -p $(DESTDIR)$(datadir)/virt-viewer + install keymap.xml $(DESTDIR)$(datadir)/virt-viewer + +install-data-am: install-data-local + Index: virt-viewer-0.0.3/src/Makefile.in =================================================================== --- virt-viewer-0.0.3.orig/src/Makefile.in +++ virt-viewer-0.0.3/src/Makefile.in @@ -46,7 +46,7 @@ CONFIG_CLEAN_FILES = am__installdirs = "$(DESTDIR)$(bindir)" binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(bin_PROGRAMS) -am_virt_viewer_OBJECTS = virt_viewer-main.$(OBJEXT) +am_virt_viewer_OBJECTS = virt_viewer-main.$(OBJEXT) virt_viewer-keymap.$(OBJEXT) virt_viewer_OBJECTS = $(am_virt_viewer_OBJECTS) virt_viewer_DEPENDENCIES = virt_viewer_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @@ -191,7 +191,7 @@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -virt_viewer_SOURCES = main.c viewer.h +virt_viewer_SOURCES = main.c keymap.c viewer.h virt_viewer_LDADD = @GTKVNC_LIBS@ @GTK2_LIBS@ @LIBXML2_LIBS@ @LIBVIRT_LIBS@ virt_viewer_CFLAGS = @GTKVNC_CFLAGS@ @GTK2_CFLAGS@ @LIBXML2_CFLAGS@ @LIBVIRT_CFLAGS@ @WARN_CFLAGS@ all: all-am @@ -266,6 +266,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virt_viewer-keymap.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -295,6 +296,13 @@ virt_viewer-main.o: main.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c +virt_viewer-keymap.o: keymap.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-keymap.o -MD -MP -MF $(DEPDIR)/virt_viewer-keymap.Tpo -c -o virt_viewer-keymap.o `test -f 'keymap.c' || echo '$(srcdir)/'`keymap.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/virt_viewer-keymap.Tpo $(DEPDIR)/virt_viewer-keymap.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keymap.c' object='virt_viewer-keymap.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -c -o virt_viewer-keymap.o `test -f 'keymap.c' || echo '$(srcdir)/'`keymap.c + virt_viewer-main.obj: main.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(virt_viewer_CFLAGS) $(CFLAGS) -MT virt_viewer-main.obj -MD -MP -MF $(DEPDIR)/virt_viewer-main.Tpo -c -o virt_viewer-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/virt_viewer-main.Tpo $(DEPDIR)/virt_viewer-main.Po @@ -433,7 +441,7 @@ info: info-am info-am: -install-data-am: +install-data-am: install-data-local install-dvi: install-dvi-am @@ -487,6 +495,10 @@ uninstall-am: uninstall-binPROGRAMS pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-binPROGRAMS +install-data-local: + mkdir -p $(DESTDIR)$(datadir)/virt-viewer + install keymap.xml $(DESTDIR)$(datadir)/virt-viewer + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: Index: virt-viewer-0.0.3/src/viewer.h =================================================================== --- virt-viewer-0.0.3.orig/src/viewer.h +++ virt-viewer-0.0.3/src/viewer.h @@ -25,4 +25,18 @@ extern int viewer_start (const char *uri, const char *name, int direct, int waitvnc, int set_verbose, GtkWidget *(*get_toplevel)(void *), void *data, int with_menubar); +typedef struct keyComboDef { + guint *keys; + guint nkeys; + char *label; +}KeyComboDef; + +typedef struct sendKeyItems { + int cnt; + struct keyComboDef **keyCombos; +}SendKeyItems; + +int build_keyCombos(SendKeyItems *, const char *, int); +int sendkey_xml_validate(const char * filename); + #endif /* VIEWER_H */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor