Hi<br><br>This patch could use a bit more comments about the file format, so here we go:<br><br>VirtViewerFile can read files in the .ini file format, with a mandatory [virt-viewer] group and "type" key:<br><br># this is a comment<br>
[virt-viewer]<br>type=spice<br>host=localhost<br>port=5900<br><br>The current list of [virt-viewer] keys is:<br>- type: string, mandatory, values: "spice" (later "vnc" etc..)<br>- host: string<br>- port: int<br>
- tls-port: int<br>- password: string<br>- disable-channels: string list<br>- tls-ciphers: string<br>- ca: currently base64 of PEM data. FIXME: I think we could use raw PEM data since it' s already base64 encoded in fact.<br>
- host-subject: string<br>- fullscreen: int (0 or 1 atm)<br>- title: string<br>- toggle-fullscreen: string in spice hotkey format<br>- release-cursor: string in spice hotkey format<br>- smartcard-insert: string in spice hotkey format<br>
- smartcard-remove: string in spice hotkey format<br>- enable-smartcard: int (0 or 1 atm)<br>- enable-usbredir: int (0 or 1 atm)<br>- color-depth: int<br>- disable-effects: string list<br>- enable-usb-autoshare: int<br>- usb-filter: string<br>
<br>(the file can be extended with extra groups or keys, which should be prefixed with x- to avoid later conflicts)<div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Nov 23, 2012 at 1:41 PM, Marc-André Lureau <span dir="ltr"><<a href="mailto:marcandre.lureau@gmail.com" target="_blank">marcandre.lureau@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">---<br>
 src/Makefile.am        |   1 +<br>
 src/virt-viewer-file.c | 775 +++++++++++++++++++++++++++++++++++++++++++++++++<br>
 src/virt-viewer-file.h | 102 +++++++<br>
 3 files changed, 878 insertions(+)<br>
 create mode 100644 src/virt-viewer-file.c<br>
 create mode 100644 src/virt-viewer-file.h<br>
<br>
diff --git a/src/Makefile.am b/src/Makefile.am<br>
index fc357d3..05e20b2 100644<br>
--- a/src/Makefile.am<br>
+++ b/src/Makefile.am<br>
@@ -39,6 +39,7 @@ COMMON_SOURCES =                                      \<br>
        virt-viewer-util.h virt-viewer-util.c           \<br>
        virt-viewer-auth.h virt-viewer-auth.c           \<br>
        virt-viewer-app.h virt-viewer-app.c             \<br>
+       virt-viewer-file.h virt-viewer-file.c           \<br>
        virt-viewer-session.h virt-viewer-session.c     \<br>
        virt-viewer-display.h virt-viewer-display.c     \<br>
        virt-viewer-notebook.h virt-viewer-notebook.c   \<br>
diff --git a/src/virt-viewer-file.c b/src/virt-viewer-file.c<br>
new file mode 100644<br>
index 0000000..6ce76a1<br>
--- /dev/null<br>
+++ b/src/virt-viewer-file.c<br>
@@ -0,0 +1,775 @@<br>
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */<br>
+/*<br>
+ * Virt Viewer: A virtual machine console viewer<br>
+ *<br>
+ * Copyright (C) 2012 Red Hat, Inc.<br>
+ *<br>
+ * This program is free software; you can redistribute it and/or modify<br>
+ * it under the terms of the GNU General Public License as published by<br>
+ * the Free Software Foundation; either version 2 of the License, or<br>
+ * (at your option) any later version.<br>
+ *<br>
+ * This program is distributed in the hope that it will be useful,<br>
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>
+ * GNU General Public License for more details.<br>
+ *<br>
+ * You should have received a copy of the GNU General Public License<br>
+ * along with this program; if not, write to the Free Software<br>
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA<br>
+ */<br>
+<br>
+#include "virt-viewer-util.h"<br>
+#include "virt-viewer-file.h"<br>
+<br>
+struct _VirtViewerFilePrivate {<br>
+    GKeyFile* keyfile;<br>
+};<br>
+<br>
+G_DEFINE_TYPE(VirtViewerFile, virt_viewer_file, G_TYPE_OBJECT);<br>
+<br>
+#define VIRT_VIEWER_FILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), VIRT_VIEWER_TYPE_FILE, VirtViewerFilePrivate))<br>
+<br>
+#define GROUP "virt-viewer"<br>
+<br>
+enum  {<br>
+    PROP_DUMMY_PROPERTY,<br>
+    PROP_TYPE,<br>
+    PROP_HOST,<br>
+    PROP_PORT,<br>
+    PROP_TLS_PORT,<br>
+    PROP_PASSWORD,<br>
+    PROP_DISABLE_CHANNELS,<br>
+    PROP_TLS_CIPHERS,<br>
+    PROP_CA,<br>
+    PROP_HOST_SUBJECT,<br>
+    PROP_FULLSCREEN,<br>
+    PROP_TITLE,<br>
+    PROP_TOGGLE_FULLSCREEN,<br>
+    PROP_RELEASE_CURSOR,<br>
+    PROP_ENABLE_SMARTCARD,<br>
+    PROP_ENABLE_USBREDIR,<br>
+    PROP_COLOR_DEPTH,<br>
+    PROP_DISABLE_EFFECTS,<br>
+    PROP_ENABLE_USB_AUTOSHARE,<br>
+    PROP_USB_FILTER<br>
+};<br>
+<br>
+VirtViewerFile*<br>
+virt_viewer_file_new(const gchar* location, GError** error)<br>
+{<br>
+    GError* inner_error = NULL;<br>
+<br>
+    g_return_val_if_fail (location != NULL, NULL);<br>
+<br>
+    VirtViewerFile* self = VIRT_VIEWER_FILE(g_object_new(VIRT_VIEWER_TYPE_FILE, NULL));<br>
+    GKeyFile* keyfile = self->priv->keyfile;<br>
+<br>
+    g_key_file_load_from_file(keyfile, location,<br>
+                              G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,<br>
+                              &inner_error);<br>
+    if (inner_error != NULL) {<br>
+        g_propagate_error(error, inner_error);<br>
+        g_object_unref(self);<br>
+        return NULL;<br>
+    }<br>
+<br>
+    if (!g_key_file_has_group (keyfile, GROUP) ||<br>
+        !virt_viewer_file_is_set(self, "type")) {<br>
+        inner_error = g_error_new_literal(G_KEY_FILE_ERROR,<br>
+                                          G_KEY_FILE_ERROR_NOT_FOUND, "Invalid file");<br>
+        g_propagate_error(error, inner_error);<br>
+        g_object_unref(self);<br>
+        return NULL;<br>
+    }<br>
+<br>
+    return self;<br>
+}<br>
+<br>
+gboolean<br>
+virt_viewer_file_is_set(VirtViewerFile* self, const gchar* key)<br>
+{<br>
+    GError *inner_error = NULL;<br>
+    gboolean set;<br>
+<br>
+    g_return_val_if_fail(VIRT_VIEWER_IS_FILE(self), FALSE);<br>
+    g_return_val_if_fail(key != NULL, FALSE);<br>
+<br>
+    set = g_key_file_has_key(self->priv->keyfile, GROUP, key, &inner_error);<br>
+    if (inner_error == NULL)<br>
+        return set;<br>
+    else {<br>
+        g_clear_error(&inner_error);<br>
+        return FALSE;<br>
+    }<br>
+}<br>
+<br>
+static void<br>
+virt_viewer_file_set_string(VirtViewerFile* self, const gchar* key, const gchar* value)<br>
+{<br>
+    g_return_if_fail(VIRT_VIEWER_IS_FILE(self));<br>
+    g_return_if_fail(key != NULL);<br>
+    g_return_if_fail(value != NULL);<br>
+<br>
+    g_key_file_set_string(self->priv->keyfile, GROUP, key, value);<br>
+}<br>
+<br>
+static gchar*<br>
+virt_viewer_file_get_string(VirtViewerFile* self, const gchar* key)<br>
+{<br>
+    GError* inner_error = NULL;<br>
+    gchar* result = NULL;<br>
+<br>
+    g_return_val_if_fail(VIRT_VIEWER_IS_FILE(self), NULL);<br>
+    g_return_val_if_fail(key != NULL, NULL);<br>
+<br>
+    result = g_key_file_get_string(self->priv->keyfile, GROUP, key, &inner_error);<br>
+    if (inner_error && inner_error->domain != G_KEY_FILE_ERROR)<br>
+        g_critical("%s", inner_error->message);<br>
+    g_clear_error(&inner_error);<br>
+<br>
+    return result;<br>
+}<br>
+<br>
+static void<br>
+virt_viewer_file_set_string_list(VirtViewerFile* self, const gchar* key, const gchar* const* value, gsize length)<br>
+{<br>
+    g_return_if_fail(VIRT_VIEWER_IS_FILE(self));<br>
+    g_return_if_fail(key != NULL);<br>
+<br>
+    g_key_file_set_string_list(self->priv->keyfile, GROUP, key, value, length);<br>
+}<br>
+<br>
+static gchar**<br>
+virt_viewer_file_get_string_list(VirtViewerFile* self, const gchar* key, gsize* length)<br>
+{<br>
+    GError* inner_error = NULL;<br>
+    gchar** result = NULL;<br>
+<br>
+    g_return_val_if_fail(VIRT_VIEWER_IS_FILE(self), NULL);<br>
+    g_return_val_if_fail(key != NULL, NULL);<br>
+<br>
+    result = g_key_file_get_string_list(self->priv->keyfile, GROUP, key, length, &inner_error);<br>
+    if (inner_error && inner_error->domain != G_KEY_FILE_ERROR)<br>
+        g_critical("%s", inner_error->message);<br>
+    g_clear_error(&inner_error);<br>
+<br>
+    return result;<br>
+}<br>
+<br>
+static void<br>
+virt_viewer_file_set_int(VirtViewerFile* self, const gchar* key, gint value)<br>
+{<br>
+    g_return_if_fail(VIRT_VIEWER_IS_FILE(self));<br>
+    g_return_if_fail(key != NULL);<br>
+<br>
+    g_key_file_set_integer(self->priv->keyfile, GROUP, key, value);<br>
+}<br>
+<br>
+static gint<br>
+virt_viewer_file_get_int(VirtViewerFile* self, const gchar* key)<br>
+{<br>
+    GError* inner_error = NULL;<br>
+    gint result;<br>
+<br>
+    g_return_val_if_fail(VIRT_VIEWER_IS_FILE(self), -1);<br>
+    g_return_val_if_fail(key != NULL, -1);<br>
+<br>
+    result = g_key_file_get_integer(self->priv->keyfile, GROUP, key, &inner_error);<br>
+    if (inner_error && inner_error->domain != G_KEY_FILE_ERROR)<br>
+        g_critical("%s", inner_error->message);<br>
+    g_clear_error(&inner_error);<br>
+<br>
+    return result;<br>
+}<br>
+<br>
+GByteArray*<br>
+virt_viewer_file_get_ca(VirtViewerFile* self)<br>
+{<br>
+    guint8* result;<br>
+    gchar* ca;<br>
+    size_t len;<br>
+<br>
+    g_return_val_if_fail(VIRT_VIEWER_IS_FILE(self), NULL);<br>
+<br>
+    ca = virt_viewer_file_get_string(self, "ca");<br>
+    result = g_base64_decode(ca, &len);<br>
+    g_free(ca);<br>
+<br>
+    return g_byte_array_new_take(result, len);<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_ca(VirtViewerFile* self, const GByteArray* array)<br>
+{<br>
+    gchar* ca;<br>
+<br>
+    g_return_if_fail(VIRT_VIEWER_IS_FILE(self));<br>
+<br>
+    ca = g_base64_encode(array->data, array->len);<br>
+    virt_viewer_file_set_string(self, "ca", ca);<br>
+    g_free(ca);<br>
+<br>
+    g_object_notify(G_OBJECT(self), "ca");<br>
+}<br>
+<br>
+gchar*<br>
+virt_viewer_file_get_host(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_string(self, "host");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_host(VirtViewerFile* self, const gchar* value)<br>
+{<br>
+    virt_viewer_file_set_string(self, "host", value);<br>
+    g_object_notify(G_OBJECT(self), "host");<br>
+}<br>
+<br>
+gchar*<br>
+virt_viewer_file_get_file_type(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_string(self, "type");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_type(VirtViewerFile* self, const gchar* value)<br>
+{<br>
+    virt_viewer_file_set_string(self, "type", value);<br>
+    g_object_notify(G_OBJECT(self), "type");<br>
+}<br>
+<br>
+gint<br>
+virt_viewer_file_get_port(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_int(self, "port");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_port(VirtViewerFile* self, gint value)<br>
+{<br>
+    virt_viewer_file_set_int(self, "port", value);<br>
+    g_object_notify(G_OBJECT(self), "port");<br>
+}<br>
+<br>
+gint<br>
+virt_viewer_file_get_tls_port(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_int(self, "tls-port");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_tls_port(VirtViewerFile* self, gint value)<br>
+{<br>
+    virt_viewer_file_set_int(self, "tls-port", value);<br>
+    g_object_notify(G_OBJECT(self), "tls-port");<br>
+}<br>
+<br>
+gchar*<br>
+virt_viewer_file_get_password(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_string(self, "password");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_password(VirtViewerFile* self, const gchar* value)<br>
+{<br>
+    virt_viewer_file_set_string(self, "password", value);<br>
+    g_object_notify(G_OBJECT(self), "password");<br>
+}<br>
+<br>
+gchar**<br>
+virt_viewer_file_get_disable_channels(VirtViewerFile* self, gsize* length)<br>
+{<br>
+    return virt_viewer_file_get_string_list(self, "disable-channels", length);<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_disable_channels(VirtViewerFile* self, const gchar* const* value, gsize length)<br>
+{<br>
+    virt_viewer_file_set_string_list(self, "disable-channels", value, length);<br>
+    g_object_notify(G_OBJECT(self), "disable-channels");<br>
+}<br>
+<br>
+gchar**<br>
+virt_viewer_file_get_disable_effects(VirtViewerFile* self, gsize* length)<br>
+{<br>
+    return virt_viewer_file_get_string_list(self, "disable-effects", length);<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_disable_effects(VirtViewerFile* self, const gchar* const* value, gsize length)<br>
+{<br>
+    virt_viewer_file_set_string_list(self, "disable-effects", value, length);<br>
+    g_object_notify(G_OBJECT(self), "disable-effects");<br>
+}<br>
+<br>
+gchar*<br>
+virt_viewer_file_get_tls_ciphers(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_string(self, "tls-ciphers");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_tls_ciphers(VirtViewerFile* self, const gchar* value)<br>
+{<br>
+    virt_viewer_file_set_string(self, "tls-ciphers", value);<br>
+    g_object_notify(G_OBJECT(self), "tls-ciphers");<br>
+}<br>
+<br>
+gchar*<br>
+virt_viewer_file_get_host_subject(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_string(self, "host-subject");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_host_subject(VirtViewerFile* self, const gchar* value)<br>
+{<br>
+    virt_viewer_file_set_string(self, "host-subject", value);<br>
+    g_object_notify(G_OBJECT(self), "host-subject");<br>
+}<br>
+<br>
+gint<br>
+virt_viewer_file_get_fullscreen(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_int(self, "fullscreen");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_fullscreen(VirtViewerFile* self, gint value)<br>
+{<br>
+    virt_viewer_file_set_int(self, "fullscreen", value);<br>
+    g_object_notify(G_OBJECT(self), "fullscreen");<br>
+}<br>
+<br>
+gchar*<br>
+virt_viewer_file_get_title(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_string(self, "title");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_title(VirtViewerFile* self, const gchar* value)<br>
+{<br>
+    virt_viewer_file_set_string(self, "title", value);<br>
+    g_object_notify(G_OBJECT(self), "title");<br>
+}<br>
+<br>
+gchar*<br>
+virt_viewer_file_get_toggle_fullscreen(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_string(self, "toggle-fullscreen");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_toggle_fullscreen(VirtViewerFile* self, const gchar* value)<br>
+{<br>
+    virt_viewer_file_set_string(self, "toggle-fullscreen", value);<br>
+    g_object_notify(G_OBJECT(self), "toggle-fullscreen");<br>
+}<br>
+<br>
+gchar*<br>
+virt_viewer_file_get_release_cursor(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_string(self, "release-cursor");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_release_cursor(VirtViewerFile* self, const gchar* value)<br>
+{<br>
+    virt_viewer_file_set_string(self, "release-cursor", value);<br>
+    g_object_notify(G_OBJECT(self), "release-cursor");<br>
+}<br>
+<br>
+gchar*<br>
+virt_viewer_file_get_smartcard_remove(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_string(self, "smartcard-remove");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_smartcard_remove(VirtViewerFile* self, const gchar* value)<br>
+{<br>
+    virt_viewer_file_set_string(self, "smartcard-remove", value);<br>
+    g_object_notify(G_OBJECT(self), "smartcard-remove");<br>
+}<br>
+<br>
+gchar*<br>
+virt_viewer_file_get_smartcard_insert(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_string(self, "smartcard-insert");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_smartcard_insert(VirtViewerFile* self, const gchar* value)<br>
+{<br>
+    virt_viewer_file_set_string(self, "smartcard-insert", value);<br>
+    g_object_notify(G_OBJECT(self), "smartcard-insert");<br>
+}<br>
+<br>
+gint<br>
+virt_viewer_file_get_enable_smartcard(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_int(self, "enable-smartcard");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_enable_smartcard(VirtViewerFile* self, gint value)<br>
+{<br>
+    virt_viewer_file_set_int(self, "enable-smartcard", value);<br>
+    g_object_notify(G_OBJECT(self), "enable-smartcard");<br>
+}<br>
+<br>
+gint<br>
+virt_viewer_file_get_enable_usbredir(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_int(self, "enable-usbredir");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_enable_usbredir(VirtViewerFile* self, gint value)<br>
+{<br>
+    virt_viewer_file_set_int(self, "enable-usbredir", value);<br>
+    g_object_notify(G_OBJECT(self), "enable-usbredir");<br>
+}<br>
+<br>
+gint<br>
+virt_viewer_file_get_color_depth(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_int(self, "color-depth");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_color_depth(VirtViewerFile* self, gint value)<br>
+{<br>
+    virt_viewer_file_set_int(self, "color-depth", value);<br>
+    g_object_notify(G_OBJECT(self), "color-depth");<br>
+}<br>
+<br>
+gint<br>
+virt_viewer_file_get_enable_usb_autoshare(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_int(self, "enable-usb-autoshare");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_enable_usb_autoshare(VirtViewerFile* self, gint value)<br>
+{<br>
+    virt_viewer_file_set_int(self, "enable-usb-autoshare", value);<br>
+    g_object_notify(G_OBJECT(self), "enable-usb-autoshare");<br>
+}<br>
+<br>
+gchar*<br>
+virt_viewer_file_get_usb_filter(VirtViewerFile* self)<br>
+{<br>
+    return virt_viewer_file_get_string(self, "usb-filter");<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_set_usb_filter(VirtViewerFile* self, const gchar* value)<br>
+{<br>
+    virt_viewer_file_set_string(self, "usb-filter", value);<br>
+    g_object_notify(G_OBJECT(self), "usb-filter");<br>
+}<br>
+<br>
+static void<br>
+spice_hotkey_set_accel(const gchar *accel_path, const gchar *key)<br>
+{<br>
+    gchar *accel;<br>
+    guint accel_key;<br>
+    GdkModifierType accel_mods;<br>
+<br>
+    accel = spice_hotkey_to_gtk_accelerator(key);<br>
+    gtk_accelerator_parse(accel, &accel_key, &accel_mods);<br>
+    g_free(accel);<br>
+<br>
+    gtk_accel_map_change_entry(accel_path, accel_key, accel_mods, TRUE);<br>
+}<br>
+<br>
+void<br>
+virt_viewer_file_fill_app(VirtViewerFile* self, VirtViewerApp *app)<br>
+{<br>
+    g_return_if_fail(VIRT_VIEWER_IS_FILE(self));<br>
+    g_return_if_fail(VIRT_VIEWER_IS_APP(app));<br>
+<br>
+    if (virt_viewer_file_is_set(self, "title"))<br>
+        virt_viewer_app_set_title(app, virt_viewer_file_get_title(self));<br>
+<br>
+    if (virt_viewer_file_is_set(self, "release-cursor")) {<br>
+        gchar *val = virt_viewer_file_get_release_cursor(self);<br>
+        spice_hotkey_set_accel("<virt-viewer>/view/release-cursor", val);<br>
+        g_free(val);<br>
+    }<br>
+<br>
+    if (virt_viewer_file_is_set(self, "toggle-fullscreen")) {<br>
+        gchar *val = virt_viewer_file_get_toggle_fullscreen(self);<br>
+        spice_hotkey_set_accel("<virt-viewer>/view/fullscreen", val);<br>
+        g_free(val);<br>
+    }<br>
+<br>
+    if (virt_viewer_file_is_set(self, "smartcard-remove")) {<br>
+        gchar *val = virt_viewer_file_get_smartcard_remove(self);<br>
+        spice_hotkey_set_accel("<virt-viewer>/view/smartcard-remove", val);<br>
+        g_free(val);<br>
+    }<br>
+<br>
+    if (virt_viewer_file_is_set(self, "smartcard-insert")) {<br>
+        gchar *val = virt_viewer_file_get_smartcard_insert(self);<br>
+        spice_hotkey_set_accel("<virt-viewer>/view/smartcard-insert", val);<br>
+        g_free(val);<br>
+    }<br>
+<br>
+    if (virt_viewer_file_is_set(self, "fullscreen"))<br>
+        g_object_set(G_OBJECT(app), "fullscreen",<br>
+            virt_viewer_file_get_fullscreen(self), NULL);<br>
+}<br>
+<br>
+static void<br>
+virt_viewer_file_set_property(GObject* object, guint property_id,<br>
+                        const GValue* value, GParamSpec* pspec)<br>
+{<br>
+    VirtViewerFile *self = VIRT_VIEWER_FILE(object);<br>
+    gchar **strv;<br>
+<br>
+    switch (property_id) {<br>
+    case PROP_TYPE:<br>
+        virt_viewer_file_set_type(self, g_value_get_string(value));<br>
+        break;<br>
+    case PROP_HOST:<br>
+        virt_viewer_file_set_host(self, g_value_get_string(value));<br>
+        break;<br>
+    case PROP_PORT:<br>
+        virt_viewer_file_set_port(self, g_value_get_int(value));<br>
+        break;<br>
+    case PROP_TLS_PORT:<br>
+        virt_viewer_file_set_tls_port(self, g_value_get_int(value));<br>
+        break;<br>
+    case PROP_PASSWORD:<br>
+        virt_viewer_file_set_password(self, g_value_get_string(value));<br>
+        break;<br>
+    case PROP_DISABLE_CHANNELS:<br>
+        strv = g_value_get_boxed(value);<br>
+        virt_viewer_file_set_disable_channels(self, (const gchar* const*)strv, g_strv_length(strv));<br>
+        break;<br>
+    case PROP_TLS_CIPHERS:<br>
+        virt_viewer_file_set_tls_ciphers(self, g_value_get_string(value));<br>
+        break;<br>
+    case PROP_CA:<br>
+        virt_viewer_file_set_ca(self, g_value_get_boxed(value));<br>
+        break;<br>
+    case PROP_HOST_SUBJECT:<br>
+        virt_viewer_file_set_host_subject(self, g_value_get_string(value));<br>
+        break;<br>
+    case PROP_FULLSCREEN:<br>
+        virt_viewer_file_set_fullscreen(self, g_value_get_int(value));<br>
+        break;<br>
+    case PROP_TITLE:<br>
+        virt_viewer_file_set_title(self, g_value_get_string(value));<br>
+        break;<br>
+    case PROP_TOGGLE_FULLSCREEN:<br>
+        virt_viewer_file_set_toggle_fullscreen(self, g_value_get_string(value));<br>
+        break;<br>
+    case PROP_RELEASE_CURSOR:<br>
+        virt_viewer_file_set_release_cursor(self, g_value_get_string(value));<br>
+        break;<br>
+    case PROP_ENABLE_SMARTCARD:<br>
+        virt_viewer_file_set_enable_smartcard(self, g_value_get_int(value));<br>
+        break;<br>
+    case PROP_ENABLE_USBREDIR:<br>
+        virt_viewer_file_set_enable_usbredir(self, g_value_get_int(value));<br>
+        break;<br>
+    case PROP_COLOR_DEPTH:<br>
+        virt_viewer_file_set_color_depth(self, g_value_get_int(value));<br>
+        break;<br>
+    case PROP_DISABLE_EFFECTS:<br>
+        strv = g_value_get_boxed(value);<br>
+        virt_viewer_file_set_disable_effects(self, (const gchar* const*)strv, g_strv_length(strv));<br>
+        break;<br>
+    case PROP_ENABLE_USB_AUTOSHARE:<br>
+        virt_viewer_file_set_enable_usb_autoshare(self, g_value_get_int(value));<br>
+        break;<br>
+    case PROP_USB_FILTER:<br>
+        virt_viewer_file_set_usb_filter(self, g_value_get_string(value));<br>
+        break;<br>
+    default:<br>
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);<br>
+        break;<br>
+    }<br>
+}<br>
+<br>
+static void<br>
+virt_viewer_file_get_property(GObject* object, guint property_id,<br>
+                        GValue* value, GParamSpec* pspec)<br>
+{<br>
+    VirtViewerFile *self = VIRT_VIEWER_FILE(object);<br>
+<br>
+    switch (property_id) {<br>
+    case PROP_TYPE:<br>
+        g_value_take_string(value, virt_viewer_file_get_file_type(self));<br>
+        break;<br>
+    case PROP_HOST:<br>
+        g_value_take_string(value, virt_viewer_file_get_host(self));<br>
+        break;<br>
+    case PROP_PORT:<br>
+        g_value_set_int(value, virt_viewer_file_get_port(self));<br>
+        break;<br>
+    case PROP_TLS_PORT:<br>
+        g_value_set_int(value, virt_viewer_file_get_tls_port(self));<br>
+        break;<br>
+    case PROP_PASSWORD:<br>
+        g_value_take_string(value, virt_viewer_file_get_password(self));<br>
+        break;<br>
+    case PROP_DISABLE_CHANNELS:<br>
+        g_value_take_boxed(value, virt_viewer_file_get_disable_channels(self, NULL));<br>
+        break;<br>
+    case PROP_TLS_CIPHERS:<br>
+        g_value_take_string(value, virt_viewer_file_get_tls_ciphers(self));<br>
+        break;<br>
+    case PROP_CA:<br>
+        g_value_take_boxed(value, virt_viewer_file_get_ca(self));<br>
+        break;<br>
+    case PROP_HOST_SUBJECT:<br>
+        g_value_take_string(value, virt_viewer_file_get_host_subject(self));<br>
+        break;<br>
+    case PROP_FULLSCREEN:<br>
+        g_value_set_int(value, virt_viewer_file_get_fullscreen(self));<br>
+        break;<br>
+    case PROP_TITLE:<br>
+        g_value_take_string(value, virt_viewer_file_get_title(self));<br>
+        break;<br>
+    case PROP_TOGGLE_FULLSCREEN:<br>
+        g_value_take_string(value, virt_viewer_file_get_toggle_fullscreen(self));<br>
+        break;<br>
+    case PROP_RELEASE_CURSOR:<br>
+        g_value_take_string(value, virt_viewer_file_get_release_cursor(self));<br>
+        break;<br>
+    case PROP_ENABLE_SMARTCARD:<br>
+        g_value_set_int(value, virt_viewer_file_get_enable_smartcard(self));<br>
+        break;<br>
+    case PROP_ENABLE_USBREDIR:<br>
+        g_value_set_int(value, virt_viewer_file_get_enable_usbredir(self));<br>
+        break;<br>
+    case PROP_COLOR_DEPTH:<br>
+        g_value_set_int(value, virt_viewer_file_get_color_depth(self));<br>
+        break;<br>
+    case PROP_DISABLE_EFFECTS:<br>
+        g_value_take_boxed(value, virt_viewer_file_get_disable_effects(self, NULL));<br>
+        break;<br>
+    case PROP_ENABLE_USB_AUTOSHARE:<br>
+        g_value_set_int(value, virt_viewer_file_get_enable_usb_autoshare(self));<br>
+        break;<br>
+    case PROP_USB_FILTER:<br>
+        g_value_take_string(value, virt_viewer_file_get_usb_filter(self));<br>
+        break;<br>
+    default:<br>
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);<br>
+        break;<br>
+    }<br>
+}<br>
+<br>
+<br>
+static void<br>
+virt_viewer_file_finalize(GObject* object)<br>
+{<br>
+    VirtViewerFile *self = VIRT_VIEWER_FILE(object);<br>
+<br>
+    g_clear_pointer(&self->priv->keyfile, g_key_file_free);<br>
+<br>
+    G_OBJECT_CLASS(virt_viewer_file_parent_class)->finalize(object);<br>
+}<br>
+<br>
+static void<br>
+virt_viewer_file_init(VirtViewerFile* self)<br>
+{<br>
+    self->priv = VIRT_VIEWER_FILE_GET_PRIVATE(self);<br>
+<br>
+    self->priv->keyfile = g_key_file_new();<br>
+}<br>
+<br>
+static void<br>
+virt_viewer_file_class_init(VirtViewerFileClass* klass)<br>
+{<br>
+    virt_viewer_file_parent_class = g_type_class_peek_parent(klass);<br>
+    g_type_class_add_private(klass, sizeof(VirtViewerFilePrivate));<br>
+<br>
+    G_OBJECT_CLASS(klass)->get_property = virt_viewer_file_get_property;<br>
+    G_OBJECT_CLASS(klass)->set_property = virt_viewer_file_set_property;<br>
+    G_OBJECT_CLASS(klass)->finalize = virt_viewer_file_finalize;<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TYPE,<br>
+        g_param_spec_string("type", "type", "type", NULL,<br>
+                            G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_HOST,<br>
+        g_param_spec_string("host", "host", "host", NULL,<br>
+                            G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_PORT,<br>
+        g_param_spec_int("port", "port", "port", -1, 65535, -1,<br>
+                         G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TLS_PORT,<br>
+        g_param_spec_int("tls-port", "tls-port", "tls-port", -1, 65535, -1,<br>
+                         G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_PASSWORD,<br>
+        g_param_spec_string("password", "password", "password", NULL,<br>
+                            G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TLS_CIPHERS,<br>
+        g_param_spec_string("tls-ciphers", "tls-ciphers", "tls-ciphers", NULL,<br>
+                            G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_CA,<br>
+         g_param_spec_boxed("ca", "ca", "ca", G_TYPE_BYTE_ARRAY,<br>
+                            G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_HOST_SUBJECT,<br>
+        g_param_spec_string("host-subject", "host-subject", "host-subject", NULL,<br>
+                            G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_FULLSCREEN,<br>
+        g_param_spec_int("fullscreen", "fullscreen", "fullscreen", 0, 1, 0,<br>
+                         G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TITLE,<br>
+        g_param_spec_string("title", "title", "title", NULL,<br>
+                            G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TOGGLE_FULLSCREEN,<br>
+        g_param_spec_string("toggle-fullscreen", "toggle-fullscreen", "toggle-fullscreen", NULL,<br>
+                            G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_RELEASE_CURSOR,<br>
+        g_param_spec_string("release-cursor", "release-cursor", "release-cursor", NULL,<br>
+                            G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_ENABLE_SMARTCARD,<br>
+        g_param_spec_int("enable-smartcard", "enable-smartcard", "enable-smartcard", 0, 1, 0,<br>
+                         G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_ENABLE_USBREDIR,<br>
+        g_param_spec_int("enable-usbredir", "enable-usbredir", "enable-usbredir", 0, 1, 0,<br>
+                         G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_COLOR_DEPTH,<br>
+        g_param_spec_int("color-depth", "color-depth", "color-depth", 0, 32, 0,<br>
+                         G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_ENABLE_USB_AUTOSHARE,<br>
+        g_param_spec_int("enable-usb-autoshare", "enable-usb-autoshare", "enable-usb-autoshare", 0, 1, 0,<br>
+                         G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_USB_FILTER,<br>
+        g_param_spec_string("usb-filter", "usb-filter", "usb-filter", NULL,<br>
+                            G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_DISABLE_CHANNELS,<br>
+        g_param_spec_boxed("disable-channels", "disable-channels", "disable-channels", G_TYPE_STRV,<br>
+                           G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+<br>
+    g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_DISABLE_EFFECTS,<br>
+        g_param_spec_boxed("disable-effects", "disable-effects", "disable-effects", G_TYPE_STRV,<br>
+                           G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));<br>
+}<br>
diff --git a/src/virt-viewer-file.h b/src/virt-viewer-file.h<br>
new file mode 100644<br>
index 0000000..71319c7<br>
--- /dev/null<br>
+++ b/src/virt-viewer-file.h<br>
@@ -0,0 +1,102 @@<br>
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */<br>
+/*<br>
+ * Virt Viewer: A virtual machine console viewer<br>
+ *<br>
+ * Copyright (C) 2012 Red Hat, Inc.<br>
+ *<br>
+ * This program is free software; you can redistribute it and/or modify<br>
+ * it under the terms of the GNU General Public License as published by<br>
+ * the Free Software Foundation; either version 2 of the License, or<br>
+ * (at your option) any later version.<br>
+ *<br>
+ * This program is distributed in the hope that it will be useful,<br>
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>
+ * GNU General Public License for more details.<br>
+ *<br>
+ * You should have received a copy of the GNU General Public License<br>
+ * along with this program; if not, write to the Free Software<br>
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA<br>
+ */<br>
+#ifndef __VIRT_VIEWER_FILE_H__<br>
+#define __VIRT_VIEWER_FILE_H__<br>
+<br>
+#include "virt-glib-compat.h"<br>
+#include "virt-viewer-app.h"<br>
+<br>
+G_BEGIN_DECLS<br>
+<br>
+#define VIRT_VIEWER_TYPE_FILE            (virt_viewer_file_get_type ())<br>
+#define VIRT_VIEWER_FILE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIRT_VIEWER_TYPE_FILE, VirtViewerFile))<br>
+#define VIRT_VIEWER_FILE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), VIRT_VIEWER_TYPE_FILE, VirtViewerFileClass))<br>
+#define VIRT_VIEWER_IS_FILE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIRT_VIEWER_TYPE_FILE))<br>
+#define VIRT_VIEWER_IS_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIRT_VIEWER_TYPE_FILE))<br>
+#define VIRT_VIEWER_FILE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), VIRT_VIEWER_TYPE_FILE, VirtViewerFileClass))<br>
+<br>
+typedef struct _VirtViewerFile VirtViewerFile;<br>
+typedef struct _VirtViewerFileClass VirtViewerFileClass;<br>
+typedef struct _VirtViewerFilePrivate VirtViewerFilePrivate;<br>
+<br>
+struct _VirtViewerFile<br>
+{<br>
+    GObject parent;<br>
+    VirtViewerFilePrivate *priv;<br>
+};<br>
+<br>
+struct _VirtViewerFileClass<br>
+{<br>
+    GObjectClass parent_class;<br>
+};<br>
+<br>
+GType virt_viewer_file_get_type(void);<br>
+<br>
+VirtViewerFile* virt_viewer_file_new(const gchar* path, GError** error);<br>
+gboolean virt_viewer_file_is_set(VirtViewerFile* self, const gchar* key);<br>
+<br>
+GByteArray* virt_viewer_file_get_ca(VirtViewerFile* self);<br>
+void virt_viewer_file_set_ca(VirtViewerFile* self, const GByteArray* array);<br>
+gchar* virt_viewer_file_get_host(VirtViewerFile* self);<br>
+void virt_viewer_file_set_host(VirtViewerFile* self, const gchar* value);<br>
+gchar* virt_viewer_file_get_file_type(VirtViewerFile* self);<br>
+void virt_viewer_file_set_type(VirtViewerFile* self, const gchar* value);<br>
+gint virt_viewer_file_get_port(VirtViewerFile* self);<br>
+void virt_viewer_file_set_port(VirtViewerFile* self, gint value);<br>
+gint virt_viewer_file_get_tls_port(VirtViewerFile* self);<br>
+void virt_viewer_file_set_tls_port(VirtViewerFile* self, gint value);<br>
+gchar* virt_viewer_file_get_password(VirtViewerFile* self);<br>
+void virt_viewer_file_set_password(VirtViewerFile* self, const gchar* value);<br>
+gchar** virt_viewer_file_get_disable_channels(VirtViewerFile* self, gsize* length);<br>
+void virt_viewer_file_set_disable_channels(VirtViewerFile* self, const gchar* const* value, gsize length);<br>
+gchar** virt_viewer_file_get_disable_effects(VirtViewerFile* self, gsize* length);<br>
+void virt_viewer_file_set_disable_effects(VirtViewerFile* self, const gchar* const* value, gsize length);<br>
+gchar* virt_viewer_file_get_tls_ciphers(VirtViewerFile* self);<br>
+void virt_viewer_file_set_tls_ciphers(VirtViewerFile* self, const gchar* value);<br>
+gchar* virt_viewer_file_get_host_subject(VirtViewerFile* self);<br>
+void virt_viewer_file_set_host_subject(VirtViewerFile* self, const gchar* value);<br>
+gint virt_viewer_file_get_fullscreen(VirtViewerFile* self);<br>
+void virt_viewer_file_set_fullscreen(VirtViewerFile* self, gint value);<br>
+gchar* virt_viewer_file_get_title(VirtViewerFile* self);<br>
+void virt_viewer_file_set_title(VirtViewerFile* self, const gchar* value);<br>
+gchar* virt_viewer_file_get_toggle_fullscreen(VirtViewerFile* self);<br>
+void virt_viewer_file_set_toggle_fullscreen(VirtViewerFile* self, const gchar* value);<br>
+gchar* virt_viewer_file_get_release_cursor(VirtViewerFile* self);<br>
+void virt_viewer_file_set_release_cursor(VirtViewerFile* self, const gchar* value);<br>
+gint virt_viewer_file_get_enable_smartcard(VirtViewerFile* self);<br>
+void virt_viewer_file_set_enable_smartcard(VirtViewerFile* self, gint value);<br>
+gint virt_viewer_file_get_enable_usbredir(VirtViewerFile* self);<br>
+void virt_viewer_file_set_enable_usbredir(VirtViewerFile* self, gint value);<br>
+gint virt_viewer_file_get_color_depth(VirtViewerFile* self);<br>
+void virt_viewer_file_set_color_depth(VirtViewerFile* self, gint value);<br>
+gint virt_viewer_file_get_enable_usb_autoshare(VirtViewerFile* self);<br>
+void virt_viewer_file_set_enable_usb_autoshare(VirtViewerFile* self, gint value);<br>
+gchar* virt_viewer_file_get_usb_filter(VirtViewerFile* self);<br>
+void virt_viewer_file_set_usb_filter(VirtViewerFile* self, const gchar* value);<br>
+void virt_viewer_file_fill_app(VirtViewerFile* self, VirtViewerApp *app);<br>
+gchar* virt_viewer_file_get_smartcard_insert(VirtViewerFile* self);<br>
+void virt_viewer_file_set_smartcard_insert(VirtViewerFile* self, const gchar* value);<br>
+gchar* virt_viewer_file_get_smartcard_remove(VirtViewerFile* self);<br>
+void virt_viewer_file_set_smartcard_remove(VirtViewerFile* self, const gchar* value);<br>
+<br>
+G_END_DECLS<br>
+<br>
+#endif /* __VIRT_VIEWER_FILE_H__ */<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.11.7<br>
<br>
</font></span></blockquote></div><br><br clear="all"><br>-- <br>Marc-André Lureau<br>
</div>