Bug#530264: tsclient printer redirection patch
Joseph Miller
josephcmiller2 at gmail.com
Sat May 23 14:05:32 UTC 2009
Package: tsclient
Version: 0.150-1
This patch adds printer redirection support. It uses GTK calls to
search for all printers, then adds all of them.
I am not a GTK programmer so I copied most of the code from the drive
redirection patch. I have addressed this also in
https://bugs.launchpad.net/ubuntu/+source/tsclient/+bug/233784 since
it was listed there already. I have also filed this at
https://sourceforge.net/tracker/?func=detail&aid=2795819&group_id=192483&atid=941576
for upstream support. The patch applies cleanly to 0.150-1ubuntu6 on
Jaunty and compiles cleanly for 32-bit.
I do have a concern about the use of sprintf(buffer, ...). I used it
because that's what existing code was using. Someone with too many
printers or printers with very long names may possibly cause a buffer
overrun. I did not attempt to address it because I do not know the
correct approach to take. I would like someone to enlighten me as to
why this was used instead of using GString (like I said, I'm not a
professional programmer and don't program in GTK).
I would like to do what is necessary to get this included in the next
release and how to get a new release made soon for this patch.
Printer redirection has been missing too long from this program.
--- tsclient-0.150-1ubuntu6/src/connect.c 2009-05-20 18:07:20.000000000 -0400
+++ tsclient-0.150/src/connect.c 2009-05-20 15:09:16.000000000 -0400
@@ -185,6 +185,16 @@
GtkWidget *imgDrive;
GtkWidget *vbxDrive;
+ // Printer mapping
+ GtkWidget *chkPrinterMapping;
+
+ // Printer mapping Widgets
+ GtkWidget *framePrinter;
+ GtkWidget *lblPrinterFrame;
+ GtkWidget *tblPrinter;
+ GtkWidget *imgPrinter;
+ GtkWidget *vbxPrinter;
+
// Program Tab Widgets
GtkWidget *lblProgramsTab1;
@@ -886,6 +896,35 @@
chkDiskMapping = gtk_check_button_new_with_mnemonic (_("Add my
local drive to the remote computer"));
gtk_box_pack_start (GTK_BOX (vbxDrive), chkDiskMapping, FALSE, FALSE, 0);
+
+ framePrinter = gtk_frame_new(NULL);
+ // Add the new frame to the Local ressource tab
+ gtk_box_pack_start (GTK_BOX (vbxLocalTab1), framePrinter, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (framePrinter), 3);
+ gtk_frame_set_shadow_type (GTK_FRAME (framePrinter), GTK_SHADOW_NONE);
+
+ lblPrinterFrame = gtk_label_new_with_mnemonic (_("Remotely map your
Printers"));
+ gtk_label_set_markup (GTK_LABEL (lblPrinterFrame), g_strconcat
("<span weight=\"bold\">", _("Remotely map your printers"), "</span>",
NULL));
+ gtk_frame_set_label_widget (GTK_FRAME (framePrinter), lblPrinterFrame);
+ gtk_label_set_justify (GTK_LABEL (lblPrinterFrame), GTK_JUSTIFY_LEFT);
+
+ tblPrinter = gtk_table_new (1, 2, FALSE);
+ gtk_container_add (GTK_CONTAINER (framePrinter), tblPrinter);
+ gtk_table_set_col_spacings (GTK_TABLE (tblPrinter), 6);
+
+ imgPrinter = create_pixmap (frmConnect, "printer.png");
+ gtk_misc_set_padding (GTK_MISC (imgPrinter), 3, 3);
+ gtk_table_attach (GTK_TABLE (tblPrinter), imgPrinter, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) 0, 0, 0);
+
+ vbxPrinter = gtk_vbox_new (FALSE, 0);
+ gtk_table_attach (GTK_TABLE (tblPrinter), vbxPrinter, 1, 2, 0, 2,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ chkPrinterMapping = gtk_check_button_new_with_mnemonic (_("Add my
local printers to the remote computer"));
+ gtk_box_pack_start (GTK_BOX (vbxPrinter), chkPrinterMapping, FALSE,
FALSE, 0);
/*
@@ -1138,6 +1177,9 @@
// Drive mapping
HOOKUP_OBJECT (frmConnect, chkDiskMapping, "chkDiskMapping");
+ // Printer mapping
+ HOOKUP_OBJECT (frmConnect, chkPrinterMapping, "chkPrinterMapping");
+
// Program Tab Widgets
HOOKUP_OBJECT (frmConnect, lblProgramsTab1, "lblProgramsTab1");
--- tsclient-0.150-1ubuntu6/src/rdpfile.c 2009-05-20 18:07:20.000000000 -0400
+++ tsclient-0.150/src/rdpfile.c 2009-05-20 13:29:23.000000000 -0400
@@ -41,6 +41,7 @@
rdp->audiomode = 0;
rdp->auto_connect = 0;
rdp->diskmapping = 0;
+ rdp->printermapping = 0;
rdp->bitmapcachepersistenable = 0;
rdp->client_hostname = "";
rdp->compression = 0;
@@ -198,6 +199,7 @@
buffer = g_strconcat (buffer, "audiomode:i:",
g_strdup_printf("%d",rdp->audiomode), "\r\n", NULL);
buffer = g_strconcat (buffer, "auto connect:i:",
g_strdup_printf("%d",rdp->auto_connect), "\r\n", NULL);
buffer = g_strconcat (buffer, "diskmapping:i:",
g_strdup_printf("%d",rdp->diskmapping), "\r\n", NULL);
+ buffer = g_strconcat (buffer, "printermapping:i:",
g_strdup_printf("%d",rdp->printermapping), "\r\n", NULL);
buffer = g_strconcat (buffer, "bitmapcachepersistenable:i:",
g_strdup_printf("%d",rdp->bitmapcachepersistenable), "\r\n", NULL);
buffer = g_strconcat (buffer, "client hostname:s:",
rdp->client_hostname, "\r\n", NULL);
buffer = g_strconcat (buffer, "compression:i:",
g_strdup_printf("%d",rdp->compression), "\r\n", NULL);
@@ -519,6 +521,12 @@
else
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
+ widget = lookup_widget (main_window, "chkPrinterMapping");
+ if (rdp->printermapping == 1)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
+
tsc_set_protocol_widgets (main_window, rdp->protocol);
// end if and drop out
@@ -715,6 +723,12 @@
else
rdp->diskmapping = 0;
+ widget = lookup_widget (main_window, "chkPrinterMapping");
+ if (gtk_toggle_button_get_active ((GtkToggleButton*)widget))
+ rdp->printermapping = 1;
+ else
+ rdp->printermapping = 0;
+
widget = lookup_widget (main_window, "chkBitmapCache");
if (!gtk_toggle_button_get_active ((GtkToggleButton*)widget))
rdp->bitmapcachepersistenable = 1;
@@ -832,6 +846,10 @@
rdp->diskmapping = atoi(value);
}
+ if (strcmp(key, "printermapping") == 0) {
+ rdp->printermapping = atoi(value);
+ }
+
if (strcmp(key, "bitmapcachepersistenable") == 0) {
rdp->bitmapcachepersistenable = atoi(value);
}
--- tsclient-0.150-1ubuntu6/src/rdpfile.h 2009-05-20 18:07:19.000000000 -0400
+++ tsclient-0.150/src/rdpfile.h 2009-05-20 13:30:05.000000000 -0400
@@ -24,6 +24,7 @@
int audiomode;
int auto_connect;
int diskmapping;
+ int printermapping;
int bitmapcachepersistenable;
char *client_hostname;
int compression;
--- tsclient-0.150-1ubuntu6/src/support.c 2009-05-20 18:07:19.000000000 -0400
+++ tsclient-0.150/src/support.c 2009-05-20 17:59:32.000000000 -0400
@@ -10,6 +10,7 @@
#include <stdlib.h>
#include <gtk/gtk.h>
+#include <gtk-unix-print-2.0/gtk/gtkprinter.h>
#include <gdk/gdk.h>
#include <glib.h>
#include <glib/gprintf.h>
@@ -328,6 +329,27 @@
return -1;
}
+/***************************************
+* *
+* tsc_enum_print *
+* *
+***************************************/
+
+static gboolean tsc_enum_print(GtkPrinter *printer, gpointer data)
+{
+ GList ** list;
+ GString *printer_name;
+
+ list = data;
+ printer_name = g_string_new(gtk_printer_get_name(printer));
+ if ( (*list)->data ) {
+ *list = g_list_append(*list, printer_name);
+ } else {
+ (*list)->data = printer_name;
+ }
+ return FALSE;
+}
+
/***************************************
* *
@@ -349,6 +371,8 @@
gchar *std_err;
gint exit_stat = 0;
gint retval = 0;
+ GList *printer_list, *printer_node;
+ GString *printer_string, *printer_cmd;
#ifdef TSCLIENT_DEBUG
printf ("tsc_launch_remote\n");
@@ -479,6 +503,35 @@
c_argv[c_argc++] = g_strdup (buffer);
}
+ // printer mapping
+ if (rdp->printermapping == 1) {
+ printer_list = g_list_alloc();
+ printer_list->data = NULL;
+
+ gtk_enumerate_printers(tsc_enum_print, &printer_list, NULL, TRUE);
+ if (printer_list->data) {
+ printer_cmd = g_string_new("-rprinter:");
+ int pc = 0;
+
+ for (printer_node = printer_list; printer_node != NULL;
printer_node = printer_node->next) {
+ printer_string = printer_node->data;
+ if (pc) {
+ printer_cmd = g_string_append(printer_cmd, ",");
+ printer_cmd = g_string_append(printer_cmd, printer_string->str);
+ } else {
+ printer_cmd = g_string_append(printer_cmd, printer_string->str);
+ }
+ g_string_free(printer_string, TRUE);
+ pc++;
+ }
+ sprintf(buffer, printer_cmd->str);
+ c_argv[c_argc++] = g_strdup (buffer);
+ g_string_free(printer_cmd, TRUE);
+ }
+
+ g_list_free(printer_list);
+ }
+
if (rdp->bitmapcachepersistenable == 1) {
sprintf(buffer, "-b");
c_argv[c_argc++] = g_strdup (buffer);
@@ -524,12 +577,12 @@
}
}
- // If RDP protocol is asked without disk mapping => protocol 4
- if (rdp->protocol == 0 && rdp->diskmapping == 0) {
+ // If RDP protocol is asked without disk/printer mapping => protocol 4
+ if (rdp->protocol == 0 && rdp->diskmapping == 0 &&
rdp->printermapping == 0) {
sprintf (buffer, "-4");
c_argv[c_argc++] = g_strdup (buffer);
}
- // but if disk mapping is asked => protocol 5
+ // but if disk/printer mapping is asked => protocol 5
else {
sprintf (buffer, "-5");
c_argv[c_argc++] = g_strdup (buffer);
@@ -1128,6 +1181,7 @@
gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data (G_OBJECT
(main_win), "vbxSound"), TRUE);
gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data (G_OBJECT
(main_win), "chkDiskMapping"), TRUE);
+ gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data (G_OBJECT
(main_win), "chkPrinterMapping"), TRUE);
gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data (G_OBJECT
(main_win), "chkStartProgram"), TRUE);
if (gtk_toggle_button_get_active
((GtkToggleButton*)g_object_get_data (G_OBJECT (main_win),
"chkStartProgram"))) {
@@ -1151,6 +1205,7 @@
gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data
(G_OBJECT (main_win), "txtPassword"), FALSE);
gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data
(G_OBJECT (main_win), "vbxSound"), FALSE);
gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data
(G_OBJECT (main_win), "chkDiskMapping"), FALSE);
+ gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data
(G_OBJECT (main_win), "chkPrinterMapping"), TRUE);
gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data
(G_OBJECT (main_win), "chkStartProgram"), FALSE);
gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data
(G_OBJECT (main_win), "txtProgramPath"), FALSE);
gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data
(G_OBJECT (main_win), "txtStartFolder"), FALSE);
@@ -1161,6 +1216,7 @@
gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data
(G_OBJECT (main_win), "txtProtoFile"), FALSE);
gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data
(G_OBJECT (main_win), "vbxSound"), FALSE);
+ gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data
(G_OBJECT (main_win), "chkPrinterMapping"), TRUE);
gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data
(G_OBJECT (main_win), "chkDiskMapping"), FALSE);
gtk_widget_set_sensitive ((GtkWidget*) g_object_get_data
(G_OBJECT (main_win), "chkStartProgram"), FALSE);
More information about the pkg-gnome-maintainers
mailing list