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