File tsclient-dmxsupport.diff of Package tsclient
diff --git a/data/tsclient.glade b/data/tsclient.glade
index edf8a49..7851642 100644
--- a/data/tsclient.glade
+++ b/data/tsclient.glade
@@ -1662,4 +1662,286 @@ LAN</property>
</widget>
</child>
</widget>
+ <widget class="GtkDialog" id="dmx_edit_dialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Edit Connection</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox12">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkVBox" id="dmx_edit_dialog_content">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment11">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkTable" id="table9">
+ <property name="visible">True</property>
+ <property name="n_rows">7</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkCheckButton" id="dmx_compress_checkbox">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip" translatable="yes">Allows you to share the desktop with other clients already using it.</property>
+ <property name="label" translatable="yes">Compress</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label43">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Host:</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="dmx_host_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label42">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">User:</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="dmx_user_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="activates_default">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="dmx_viewonly_checkbox">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip" translatable="yes">Do not send mouse or keyboard actions</property>
+ <property name="label" translatable="yes">View only</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkRadioButton" id="dmx_fullscreen_radio">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Fullscreen Window</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkRadioButton" id="dmx_custom_window_radio">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Custom Window Size:</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">dmx_fullscreen_radio</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="dmx_custom_window_box">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkSpinButton" id="dmx_width_spin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">1 1 1920 1 10 10</property>
+ <property name="climb_rate">1</property>
+ <property name="numeric">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label40">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">x</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkSpinButton" id="dmx_height_spin">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">1 0 1680 1 10 10</property>
+ <property name="climb_rate">1</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label41">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="dmx_direct_checkbox">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip" translatable="yes">Connect directly to the remote X server.</property>
+ <property name="label" translatable="yes">Direct</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label44">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"><b>Details</b></property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area12">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="button13">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button14">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
</glade-interface>
diff --git a/src/plugins/default/Makefile.am b/src/plugins/default/Makefile.am
index 765391e..a95f12c 100644
--- a/src/plugins/default/Makefile.am
+++ b/src/plugins/default/Makefile.am
@@ -57,6 +57,12 @@ libtsc_default_la_SOURCES = \
tsc-web-edit-dialog.h \
tsc-web-provider.c \
tsc-web-provider.h \
+ tsc-dmx-connection.c \
+ tsc-dmx-connection.h \
+ tsc-dmx-edit-dialog.c \
+ tsc-dmx-edit-dialog.h \
+ tsc-dmx-provider.c \
+ tsc-dmx-provider.h \
tsc-vnc-connection.c \
tsc-vnc-connection.h \
tsc-vnc-edit-dialog.c \
diff --git a/src/plugins/default/tsc-default.c b/src/plugins/default/tsc-default.c
index 06ebfe7..ea5616a 100644
--- a/src/plugins/default/tsc-default.c
+++ b/src/plugins/default/tsc-default.c
@@ -7,6 +7,7 @@
#include "tsc-ica-provider.h"
#include "tsc-mainframe-provider.h"
#include "tsc-ssh-provider.h"
+#include "tsc-dmx-provider.h"
#include "tsc-xdmcp-provider.h"
#include "tsc-web-provider.h"
#include "tsc-web-connection.h"
@@ -33,6 +34,7 @@ tsc_init_plugin (TSCManager *manager)
tsc_manager_register_provider (manager, TSC_PROVIDER (tsc_web_provider_new ()));
tsc_manager_register_provider (manager, TSC_PROVIDER (tsc_ssh_provider_new ()));
+ tsc_manager_register_provider (manager, TSC_PROVIDER (tsc_dmx_provider_new ()));
tsc_manager_register_provider (manager, TSC_PROVIDER (tsc_xdmcp_provider_new ()));
tsc_manager_register_provider (manager, TSC_PROVIDER (tsc_generic_provider_new ()));
}
diff --git a/src/plugins/default/tsc-dmx-connection.c b/src/plugins/default/tsc-dmx-connection.c
new file mode 100644
index 0000000..bdafd1f
--- /dev/null
+++ b/src/plugins/default/tsc-dmx-connection.c
@@ -0,0 +1,283 @@
+
+#include <config.h>
+#include "string.h"
+#include <unistd.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <libnotify/notify.h>
+#include "tsc-dmx-connection.h"
+#include "tsc-util.h"
+#include "tsc-connection.h"
+
+#define DMX_CONFIG_GROUP "DMX"
+#define DMX_KEY_HOST "host"
+#define DMX_KEY_USER "user"
+#define DMX_KEY_COMPRESS "compress"
+#define DMX_KEY_VIEWONLY "viewonly"
+#define DMX_KEY_FULLSCREEN "fullscreen"
+#define DMX_KEY_WIDTH "width"
+#define DMX_KEY_HEIGHT "height"
+// stolen from SSH
+#define TSC_SSH_ASKPASS LIBDIR "/tsclient/tsc-ssh-askpass"
+
+#define DMX_FULLSCREEN_NOTIFY_DELAY 5000
+
+static GObjectClass *parent_class;
+
+static gboolean
+notify_fullscreen_cb (TSCDmxConnection *connection)
+{
+ NotifyNotification *n;
+ char *summary;
+ char *body;
+
+ if (!tsc_connection_is_connected (TSC_CONNECTION (connection)))
+ return FALSE;
+
+ if (!notify_is_initted ()) {
+ notify_init (PACKAGE);
+ }
+
+ summary = g_strdup_printf (_("Connected to '%s'"),
+ tsc_connection_get_name (TSC_CONNECTION (connection)));
+ body = g_strdup_printf (_("You are connected to '%s' in fullscreen mode. Use F8 to switch to and from windowed mode."), tsc_connection_get_name (TSC_CONNECTION (connection)));
+
+ n = notify_notification_new (summary, body, GTK_STOCK_DIALOG_INFO, NULL);
+ g_free (summary);
+ g_free (body);
+
+ notify_notification_show (n, NULL);
+ g_object_unref (n);
+
+ return FALSE;
+}
+
+static void
+notify_fullscreen (TSCDmxConnection *connection)
+{
+ g_timeout_add (DMX_FULLSCREEN_NOTIFY_DELAY,
+ (GSourceFunc) notify_fullscreen_cb,
+ connection);
+}
+
+static void
+tsc_dmx_connection_stopped_cb (TSCSpawn *spawn, TSCDmxConnection *connection)
+{
+ GError *error = NULL;
+
+ error = tsc_spawn_get_error (spawn);
+
+ g_object_unref (connection->spawn);
+ connection->spawn = NULL;
+
+ g_signal_emit_by_name (connection, "ended", error, NULL);
+
+ if (error) {
+ g_error_free (error);
+ }
+}
+
+static void
+tsc_dmx_connection_setup (gpointer user_data)
+{
+ TSCConnection *con = TSC_CONNECTION (user_data);
+
+ setsid ();
+
+ if (g_file_test (TSC_SSH_ASKPASS, G_FILE_TEST_EXISTS)) {
+ g_setenv ("OLD_SSH_ASKPASS", g_getenv ("SSH_ASKPASS"), TRUE);
+ g_setenv ("TSC_USER", g_get_user_name (), TRUE);
+ g_setenv ("TSC_CONNECTION_FILE", tsc_connection_get_filename (con), TRUE);
+ g_setenv ("SSH_ASKPASS", TSC_SSH_ASKPASS, TRUE);
+ }
+}
+
+
+static gboolean
+tsc_dmx_connection_start (TSCConnection *con, GError **error)
+{
+ TSCDmxConnection *connection = TSC_DMX_CONNECTION (con);
+
+ if (connection->spawn) {
+ g_object_unref (connection->spawn);
+ }
+
+ connection->spawn = tsc_spawn_new ();
+ g_signal_connect (connection->spawn, "stopped",
+ G_CALLBACK (tsc_dmx_connection_stopped_cb),
+ connection);
+
+ tsc_spawn_set_args (connection->spawn, "dmxviewer", NULL);
+
+ if (connection->compress) {
+ tsc_spawn_append_args (connection->spawn, "-compress", NULL);
+ }
+
+ if (connection->viewonly) {
+ tsc_spawn_append_args (connection->spawn, "-viewonly", NULL);
+ }
+
+ if (connection->direct) {
+ tsc_spawn_append_args (connection->spawn, "-direct", NULL);
+ }
+
+ if (connection->fullscreen) {
+ tsc_spawn_append_args (connection->spawn, "-fullscreen", NULL);
+ } else {
+#if 0
+ char *geometry = g_strdup_printf ("%dx%d", connection->width,
+ connection->height);
+
+ tsc_spawn_append_args (connection->spawn, "-geometry", geometry, NULL);
+ g_free (geometry);
+#endif
+ }
+
+ if (connection->user) {
+ tsc_spawn_append_args (connection->spawn, "-user", connection->user, NULL);
+ }
+
+ if (connection->host) {
+ tsc_spawn_append_args (connection->spawn, connection->host, NULL);
+ }
+
+ if (!tsc_spawn_start_with_setup (connection->spawn,
+ tsc_dmx_connection_setup, connection,
+ error)) {
+ return FALSE;
+ }
+
+#if 0
+ if (connection->password) {
+ char *password = g_strdup_printf ("%s\n", connection->password);
+
+ g_io_channel_write_chars (tsc_spawn_get_stdin (connection->spawn), password,
+ strlen (password), NULL, NULL);
+ g_io_channel_flush (tsc_spawn_get_stdin (connection->spawn), NULL);
+ g_free (password);
+ }
+#endif
+
+ g_signal_emit_by_name (connection, "started", NULL);
+
+ if (connection->fullscreen) {
+ notify_fullscreen (connection);
+ }
+
+ return TRUE;
+}
+
+static void
+tsc_dmx_connection_save (TSCConnection *con, GKeyFile *keys)
+{
+ TSCDmxConnection *connection = TSC_DMX_CONNECTION (con);
+
+ if (connection->host) {
+ g_key_file_set_string (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_HOST, connection->host);
+ }
+
+ if (connection->user) {
+ g_key_file_set_string (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_USER, connection->user);
+ }
+
+ g_key_file_set_boolean (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_COMPRESS, connection->compress);
+ g_key_file_set_boolean (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_VIEWONLY, connection->viewonly);
+ g_key_file_set_boolean (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_FULLSCREEN, connection->fullscreen);
+
+ if (connection->width > 0) {
+ g_key_file_set_integer (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_WIDTH, connection->width);
+ }
+
+ if (connection->height > 0) {
+ g_key_file_set_integer (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_HEIGHT, connection->height);
+ }
+}
+
+static void
+tsc_dmx_connection_restore (TSCConnection *con, GKeyFile *keys)
+{
+ TSCDmxConnection *connection = TSC_DMX_CONNECTION (con);
+ connection->host = g_key_file_get_string (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_HOST, NULL);
+ connection->user = g_key_file_get_string (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_USER, NULL);
+
+ connection->compress = g_key_file_get_boolean (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_COMPRESS, NULL);
+ connection->viewonly = g_key_file_get_boolean (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_VIEWONLY, NULL);
+ connection->fullscreen = g_key_file_get_boolean (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_FULLSCREEN, NULL);
+
+ connection->width = g_key_file_get_integer (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_WIDTH, NULL);
+ connection->height = g_key_file_get_integer (keys, DMX_CONFIG_GROUP,
+ DMX_KEY_HEIGHT, NULL);
+}
+
+static void
+tsc_dmx_connection_finalize (GObject *obj)
+{
+ TSCDmxConnection *connection = TSC_DMX_CONNECTION (obj);
+
+ g_free (connection->host);
+ g_free (connection->user);
+
+ if (parent_class->finalize) {
+ parent_class->finalize (obj);
+ }
+}
+
+static void
+tsc_dmx_connection_class_init (TSCDmxConnectionClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+ object_class->finalize = tsc_dmx_connection_finalize;
+
+ TSC_CONNECTION_CLASS (klass)->start = tsc_dmx_connection_start;
+ TSC_CONNECTION_CLASS (klass)->save_config = tsc_dmx_connection_save;
+ TSC_CONNECTION_CLASS (klass)->restore_config = tsc_dmx_connection_restore;
+}
+
+static void
+tsc_dmx_connection_init (TSCDmxConnection *connection)
+{
+ connection->compress = FALSE;
+ connection->viewonly = FALSE;
+ connection->fullscreen = TRUE;
+ connection->direct = FALSE;
+}
+
+GType
+tsc_dmx_connection_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static GTypeInfo type_info = {
+ sizeof (TSCDmxConnectionClass),
+ NULL, NULL,
+ (GClassInitFunc) tsc_dmx_connection_class_init,
+ NULL, NULL,
+ sizeof (TSCDmxConnection),
+ 0,
+ (GInstanceInitFunc) tsc_dmx_connection_init
+ };
+
+ type = g_type_register_static (TSC_TYPE_CONNECTION,
+ "TSCDmxConnection",
+ &type_info, 0);
+ }
+
+ return type;
+
+}
diff --git a/src/plugins/default/tsc-dmx-connection.h b/src/plugins/default/tsc-dmx-connection.h
new file mode 100644
index 0000000..c3e5080
--- /dev/null
+++ b/src/plugins/default/tsc-dmx-connection.h
@@ -0,0 +1,41 @@
+
+#ifndef __TSC_DMX_CONNECTION__
+#define __TSC_DMX_CONNECTION__
+
+#include <glib.h>
+#include <glib-object.h>
+#include "tsc-connection.h"
+#include "tsc-spawn.h"
+
+#define TSC_TYPE_DMX_CONNECTION (tsc_dmx_connection_get_type ())
+#define TSC_DMX_CONNECTION(connection) (G_TYPE_CHECK_INSTANCE_CAST ((connection), TSC_TYPE_DMX_CONNECTION, TSCDmxConnection))
+#define TSC_DMX_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TSC_TYPE_DMX_CONNECTION, TSCDmxConnectionClass))
+#define TSC_IS_DMX_CONNECTION(connection) (G_TYPE_CHECK_INSTANCE_TYPE ((connection), TSC_TYPE_DMX_CONNECTION))
+#define TSC_IS_DMX_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TSC_TYPE_DMX_CONNECTION))
+#define TSC_DMX_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TSC_TYPE_DMX_CONNECTION, TSCDmxConnectionClass))
+
+typedef struct _TSCDmxConnection {
+ TSCConnection parent;
+
+ char *host;
+ char *user;
+
+ gboolean compress;
+ gboolean viewonly;
+ gboolean fullscreen;
+ gboolean direct;
+
+ int width;
+ int height;
+
+ TSCSpawn *spawn;
+} TSCDmxConnection;
+
+typedef struct _TSCDmxConnectionClass {
+ TSCConnectionClass parent_class;
+} TSCDmxConnectionClass;
+
+
+GType tsc_dmx_connection_get_type (void);
+
+#endif
diff --git a/src/plugins/default/tsc-dmx-edit-dialog.c b/src/plugins/default/tsc-dmx-edit-dialog.c
new file mode 100644
index 0000000..0115df4
--- /dev/null
+++ b/src/plugins/default/tsc-dmx-edit-dialog.c
@@ -0,0 +1,222 @@
+
+#include <config.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include "tsc-dmx-edit-dialog.h"
+#include "tsc-dmx-connection.h"
+#include "tsc-util.h"
+
+static TSCEditDialogClass *parent_class;
+
+static void
+tsc_dmx_edit_dialog_finalize (GObject *obj)
+{
+ TSCDmxEditDialog *dialog = TSC_DMX_EDIT_DIALOG (obj);
+
+ if (dialog->xml) {
+ g_object_unref (dialog->xml);
+ }
+
+ if (G_OBJECT_CLASS (parent_class)->finalize) {
+ G_OBJECT_CLASS (parent_class)->finalize (obj);
+ }
+}
+
+static void
+custom_window_toggle_cb (GtkToggleButton *button,
+ TSCDmxEditDialog *dialog)
+{
+ gtk_widget_set_sensitive (glade_xml_get_widget (dialog->xml,
+ "dmx_custom_window_box"),
+ gtk_toggle_button_get_active (button));
+}
+
+static void
+tsc_dmx_edit_dialog_load (TSCEditDialog *edit_dialog)
+{
+ TSCDmxEditDialog *dialog;
+ TSCDmxConnection *connection;
+ GdkScreen *screen;
+ int width, height;
+
+ dialog = TSC_DMX_EDIT_DIALOG (edit_dialog);
+ connection = TSC_DMX_CONNECTION (edit_dialog->connection);
+
+ if (connection->host) {
+ gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget (dialog->xml, "dmx_host_entry")),
+ connection->host);
+ }
+
+ if (connection->user) {
+ gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget (dialog->xml, "dmx_user_entry")),
+ connection->user);
+ }
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (dialog->xml,
+ "dmx_compress_checkbox")),
+ connection->compress);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (dialog->xml,
+ "dmx_viewonly_checkbox")),
+ connection->viewonly);
+
+ if (connection->fullscreen ) {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (dialog->xml,
+ "dmx_fullscreen_radio")),
+ TRUE);
+ } else {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (dialog->xml,
+ "dmx_custom_window_radio")),
+ TRUE);
+ }
+
+ /* ugh, why isn't this triggered when we do _set_active above? */
+ custom_window_toggle_cb (GTK_TOGGLE_BUTTON (glade_xml_get_widget (dialog->xml,
+ "dmx_custom_window_radio")),
+ dialog);
+
+ /* setup ranges for width/height spin buttons */
+ screen = gtk_widget_get_screen (GTK_WIDGET (dialog));
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (glade_xml_get_widget (dialog->xml,
+ "dmx_width_spin")),
+ 1, gdk_screen_get_width (screen));
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (glade_xml_get_widget (dialog->xml,
+ "dmx_height_spin")),
+ 1, gdk_screen_get_height (screen));
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (glade_xml_get_widget (dialog->xml,
+ "dmx_direct_checkbox")),
+ connection->direct);
+
+
+ if (connection->width <= 0 || connection->width > gdk_screen_get_width (screen)) {
+ width = gdk_screen_get_width (screen);
+ } else {
+ width = connection->width;
+ }
+
+ if (connection->height <= 0 || connection->height > gdk_screen_get_height (screen)) {
+ height = gdk_screen_get_height (screen);
+ } else {
+ height = connection->height;
+ }
+
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (glade_xml_get_widget (dialog->xml,
+ "dmx_width_spin")),
+ (gdouble) width);
+
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (glade_xml_get_widget (dialog->xml,
+ "dmx_height_spin")),
+ (gdouble) height);
+}
+
+static void
+tsc_dmx_edit_dialog_save (TSCEditDialog *edit_dialog)
+{
+
+ TSCDmxEditDialog *dialog;
+ TSCDmxConnection *connection;
+
+ dialog = TSC_DMX_EDIT_DIALOG (edit_dialog);
+ connection = TSC_DMX_CONNECTION (edit_dialog->connection);
+
+ g_free (connection->host);
+ connection->host = g_strdup (gtk_entry_get_text (GTK_ENTRY (glade_xml_get_widget (dialog->xml,
+ "dmx_host_entry"))));
+ g_free (connection->user);
+ connection->user = g_strdup (gtk_entry_get_text (GTK_ENTRY (glade_xml_get_widget (dialog->xml,
+ "dmx_user_entry"))));
+ NULLIFY_IF_EMPTY (connection->user);
+
+ connection->compress = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
+ glade_xml_get_widget (dialog->xml,
+ "dmx_compress_checkbox")));
+ connection->viewonly = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
+ glade_xml_get_widget (dialog->xml,
+ "dmx_viewonly_checkbox")));
+ connection->fullscreen = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
+ glade_xml_get_widget (dialog->xml,
+ "dmx_fullscreen_radio")));
+ connection->width = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (
+ glade_xml_get_widget (dialog->xml,
+ "dmx_width_spin")));
+ connection->height = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (
+ glade_xml_get_widget (dialog->xml,
+ "dmx_height_spin")));
+ connection->direct = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
+ glade_xml_get_widget (dialog->xml,
+ "dmx_direct_checkbox")));
+}
+
+static gboolean
+tsc_dmx_edit_dialog_verify (TSCEditDialog *edit_dialog, gchar **reason)
+{
+ TSCDmxEditDialog *dialog = TSC_DMX_EDIT_DIALOG (edit_dialog);
+ GtkEntry *host_entry = GTK_ENTRY (glade_xml_get_widget (dialog->xml, "dmx_host_entry"));
+
+ if (!g_ascii_strcasecmp ("", gtk_entry_get_text (host_entry))) {
+ *reason = g_strdup (_("Host is a required field"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+tsc_dmx_edit_dialog_class_init (TSCDmxEditDialogClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ TSCEditDialogClass *edit_dialog_class = (TSCEditDialogClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+ object_class->finalize = tsc_dmx_edit_dialog_finalize;
+ edit_dialog_class->load = tsc_dmx_edit_dialog_load;
+ edit_dialog_class->save = tsc_dmx_edit_dialog_save;
+ edit_dialog_class->verify = tsc_dmx_edit_dialog_verify;
+}
+
+static void
+tsc_dmx_edit_dialog_init (TSCDmxEditDialog *dialog)
+{
+ GtkWidget *content;
+
+ dialog->xml = glade_xml_new (GLADEFILE,
+ "dmx_edit_dialog_content",
+ PACKAGE);
+
+ g_signal_connect (glade_xml_get_widget (dialog->xml,
+ "dmx_custom_window_radio"),
+ "toggled",
+ G_CALLBACK (custom_window_toggle_cb),
+ dialog);
+
+ content = glade_xml_get_widget (dialog->xml, "dmx_edit_dialog_content");
+ gtk_widget_show_all (content);
+
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), content);
+}
+
+GType
+tsc_dmx_edit_dialog_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static GTypeInfo type_info = {
+ sizeof (TSCDmxEditDialogClass),
+ NULL, NULL,
+ (GClassInitFunc) tsc_dmx_edit_dialog_class_init,
+ NULL, NULL,
+ sizeof (TSCDmxEditDialog),
+ 0,
+ (GInstanceInitFunc) tsc_dmx_edit_dialog_init
+ };
+
+ type = g_type_register_static (TSC_TYPE_EDIT_DIALOG,
+ "TSCDmxEditDialog",
+ &type_info, 0);
+ }
+
+ return type;
+
+}
diff --git a/src/plugins/default/tsc-dmx-edit-dialog.h b/src/plugins/default/tsc-dmx-edit-dialog.h
new file mode 100644
index 0000000..0c5ffaf
--- /dev/null
+++ b/src/plugins/default/tsc-dmx-edit-dialog.h
@@ -0,0 +1,31 @@
+
+#ifndef __TSC_DMX_EDIT_DIALOG__
+#define __TSC_DMX_EDIT_DIALOG__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+#include "tsc-edit-dialog.h"
+
+#define TSC_TYPE_DMX_EDIT_DIALOG (tsc_dmx_edit_dialog_get_type ())
+#define TSC_DMX_EDIT_DIALOG(dialog ) (G_TYPE_CHECK_INSTANCE_CAST ((dialog), TSC_TYPE_DMX_EDIT_DIALOG, TSCDmxEditDialog))
+#define TSC_DMX_EDIT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TSC_TYPE_DMX_EDIT_DIALOG, TSCDmxEditDialogClass))
+#define TSC_IS_DMX_EDIT_DIALOG(dialog) (G_TYPE_CHECK_INSTANCE_TYPE ((dialog), TSC_TYPE_DMX_EDIT_DIALOG))
+#define TSC_IS_DMX_EDIT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TSC_TYPE_DMX_EDIT_DIALOG))
+#define TSC_DMX_EDIT_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TSC_TYPE_DMX_EDIT_DIALOG, TSCDmxEditDialogClass))
+
+typedef struct _TSCDmxEditDialog {
+ TSCEditDialog parent;
+
+ GladeXML *xml;
+} TSCDmxEditDialog;
+
+typedef struct _TSCDmxEditDialogClass {
+ TSCEditDialogClass parent_class;
+} TSCDmxEditDialogClass;
+
+
+GType tsc_dmx_edit_dialog_get_type (void);
+
+#endif
diff --git a/src/plugins/default/tsc-dmx-provider.c b/src/plugins/default/tsc-dmx-provider.c
new file mode 100644
index 0000000..1749806
--- /dev/null
+++ b/src/plugins/default/tsc-dmx-provider.c
@@ -0,0 +1,100 @@
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include "tsc-util.h"
+#include "tsc-dmx-provider.h"
+#include "tsc-dmx-connection.h"
+#include "tsc-dmx-edit-dialog.h"
+
+#define TSC_DMX_URI_SCHEME "dmx://"
+
+static TSCConnection *
+tsc_dmx_provider_create_connection (TSCProvider *provider)
+{
+ return TSC_CONNECTION (g_object_new (TSC_TYPE_DMX_CONNECTION, NULL));
+}
+
+static TSCConnection *
+tsc_dmx_provider_create_from_uri (TSCProvider *provider, const char *uri)
+{
+ TSCConnection *connection = NULL;
+ char *host;
+
+ if (!tsc_util_check_uri_scheme (uri, TSC_DMX_URI_SCHEME)) {
+ return NULL;
+ }
+
+ host = tsc_util_get_uri_host (uri);
+ if (!host) {
+ return NULL;
+ }
+
+ connection = TSC_CONNECTION (g_object_new (TSC_TYPE_DMX_CONNECTION, NULL));
+ TSC_DMX_CONNECTION (connection)->host = host;
+
+ g_free (connection->name);
+ connection->name = g_strdup_printf (_("DMX on %s"),
+ TSC_DMX_CONNECTION (connection)->host);
+
+ return connection;
+}
+
+
+static TSCEditDialog *
+tsc_dmx_provider_create_edit_dialog (TSCProvider *provider,
+ TSCConnection *connection)
+{
+ return TSC_EDIT_DIALOG (g_object_new (TSC_TYPE_DMX_EDIT_DIALOG,
+ "connection", connection, NULL));
+}
+
+static void
+tsc_dmx_provider_class_init (TSCDmxProviderClass *klass)
+{
+ TSC_PROVIDER_CLASS (klass)->create_connection = tsc_dmx_provider_create_connection;
+ TSC_PROVIDER_CLASS (klass)->create_from_uri = tsc_dmx_provider_create_from_uri;
+ TSC_PROVIDER_CLASS (klass)->create_edit_dialog = tsc_dmx_provider_create_edit_dialog;
+}
+
+static void
+tsc_dmx_provider_init (TSCDmxProvider *provider)
+{
+ TSCProvider *parent = TSC_PROVIDER (provider);
+
+ parent->name = "DMX";
+ parent->display_name = _("DMX");
+ parent->description = _("Create a DMX connection");
+ parent->icon_name = "gnome-remote-desktop";
+ parent->enabled = tsc_util_program_exists ("dmxviewer");
+}
+
+GType
+tsc_dmx_provider_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static GTypeInfo type_info = {
+ sizeof (TSCDmxProviderClass),
+ NULL, NULL,
+ (GClassInitFunc) tsc_dmx_provider_class_init,
+ NULL, NULL,
+ sizeof (TSCDmxProvider),
+ 0,
+ (GInstanceInitFunc) tsc_dmx_provider_init
+ };
+
+ type = g_type_register_static (TSC_TYPE_PROVIDER,
+ "TSCDmxProvider",
+ &type_info, 0);
+ }
+
+ return type;
+
+}
+
+TSCDmxProvider *
+tsc_dmx_provider_new (void)
+{
+ return g_object_new (TSC_TYPE_DMX_PROVIDER, NULL);
+}
diff --git a/src/plugins/default/tsc-dmx-provider.h b/src/plugins/default/tsc-dmx-provider.h
new file mode 100644
index 0000000..6759f65
--- /dev/null
+++ b/src/plugins/default/tsc-dmx-provider.h
@@ -0,0 +1,28 @@
+
+#ifndef __TSC_DMX_PROVIDER__
+#define __TSC_DMX_PROVIDER__
+
+#include <glib.h>
+#include <glib-object.h>
+#include "tsc-provider.h"
+
+#define TSC_TYPE_DMX_PROVIDER (tsc_dmx_provider_get_type ())
+#define TSC_DMX_PROVIDER(generic_provider) (G_TYPE_CHECK_INSTANCE_CAST ((generic_provider), TSC_TYPE_DMX_PROVIDER, TSCDmxProvider))
+#define TSC_DMX_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TSC_TYPE_DMX_PROVIDER, TSCDmxProviderClass))
+#define TSC_IS_DMX_PROVIDER(generic_provider) (G_TYPE_CHECK_INSTANCE_TYPE ((generic_provider), TSC_TYPE_DMX_PROVIDER))
+#define TSC_IS_DMX_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TSC_TYPE_DMX_PROVIDER))
+#define TSC_DMX_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TSC_TYPE_DMX_PROVIDER, TSCDmxProviderClass))
+
+
+typedef struct _TSCDmxProvider {
+ TSCProvider parent;
+} TSCDmxProvider;
+
+typedef struct _TSCDmxProviderClass {
+ TSCProviderClass parent_class;
+} TSCDmxProviderClass;
+
+GType tsc_dmx_provider_get_type (void);
+TSCDmxProvider *tsc_dmx_provider_new (void);
+
+#endif