Hi,

Create a patch which does similar things for the image (instead of
just the label), adding a text containing a number 2, 3, etc. in case
when more than one keyboard layout is using the same XkbLayout string.
Disclaimer: I'm completely new to Glib, Gdk and Gtk+, and I've read
just enough from the manual to be able to make up the patch, so I
cannot claim the patch to be rock solid.

Regards,
Isaac
diff -ru xfce4-xkb-plugin-0.4.3.orig/panel-plugin/xkb.c xfce4-xkb-plugin-0.4.3/panel-plugin/xkb.c
--- xfce4-xkb-plugin-0.4.3.orig/panel-plugin/xkb.c	2007-01-17 18:02:57.000000000 +0000
+++ xfce4-xkb-plugin-0.4.3/panel-plugin/xkb.c	2007-07-22 10:10:45.000000000 +0100
@@ -21,8 +21,10 @@
 #include <X11/XKBlib.h>
 
 #include <gtk/gtk.h>
+#include <gdk/gdk.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <glib.h>
+#define PIXMAP_DEPTH 24
 
 Display *dsp;
 
@@ -100,10 +102,24 @@
 }
 
 static char *
-get_current_group_name(void) 
+get_current_group_name(char **diff) 
 {
+  char *ret, *start, *end;
   const char *tmp = get_symbol_name_by_res_no(current_group_xkb_no);
-  return g_utf8_strdown (tmp, -1);
+
+  ret = g_utf8_strdown (tmp, -1);
+  start = strchr(ret, '(');
+  if (start) {
+    *start = '\0';
+    if (diff)
+      *diff = start + 1;
+    end = strchr(*diff, ')');
+    if (end)
+      *end = '\0';
+  } else if (diff) {
+    *diff = NULL;
+  }
+  return ret;
 }
 
 void 
@@ -116,6 +132,28 @@
   current_group_res_no = group_xkb_to_res(current_group_xkb_no);
 }
 
+static void
+differentiate_symbol_names(void)
+{
+  GHashTable* symbol_cnt;
+  int i, cnt;
+  gchar *temp_str;
+
+  symbol_cnt = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+  for (i = 0; i < group_count; ++i) {
+    cnt = GPOINTER_TO_INT
+      (g_hash_table_lookup(symbol_cnt, symbol_names[i])) + 1;
+    g_hash_table_insert(symbol_cnt, g_strdup(symbol_names[i]),
+                        GINT_TO_POINTER(cnt));
+    if (cnt > 1) {
+      temp_str = g_strdup_printf("%s(%i)", symbol_names[i], cnt);
+      g_free(symbol_names[i]);
+      symbol_names[i] = temp_str;
+    }
+  }
+  g_hash_table_destroy(symbol_cnt);
+}
+
 int 
 do_init_xkb() 
 {
@@ -270,6 +308,7 @@
         break;
     }
   }
+  differentiate_symbol_names();
 
   XkbGetState(dsp, device_id, &xkb_state);
   current_group_xkb_no = xkb_state.group;
@@ -289,7 +328,7 @@
   char *filename;
   gboolean result = FALSE;
   GdkPixbuf *tmp = NULL;
-  char *group_name = get_current_group_name();
+  char *group_name = get_current_group_name(NULL);
   filename = g_strdup_printf("%s/%s.png", FLAGSDIR, group_name);
   DBG ("Try to load image: %s", filename);
   tmp = gdk_pixbuf_new_from_file(filename, NULL);
@@ -334,15 +373,57 @@
   return g_markup_printf_escaped ("<span font_desc=\"%d\">%s</span>", font_desc, get_symbol_name_by_res_no (current_group_xkb_no));
 }
 
+static void
+render_differentiation_to_pixbuf(GdkPixbuf *buf, PangoContext *pc, char *diff) {
+  GdkPixmap *pixmap;
+  GdkGC *gc;
+  int width = gdk_pixbuf_get_width(buf);
+  int height = gdk_pixbuf_get_height(buf);
+  PangoLayout *layout;
+
+  pixmap = gdk_pixmap_new(NULL, width, height, PIXMAP_DEPTH);
+  gc = gdk_gc_new((GdkDrawable *) pixmap);
+  gdk_draw_pixbuf((GdkDrawable *) pixmap, gc, buf, 0, 0, 0, 0, -1, -1,
+                  GDK_RGB_DITHER_NORMAL, 0, 0);
+  layout = pango_layout_new(pc);
+  pango_layout_set_text(layout, diff, g_utf8_strlen(diff, -1));
+  gdk_draw_layout((GdkDrawable *) pixmap, gc, 0, 0, layout);
+  gdk_pixbuf_get_from_drawable(buf, (GdkDrawable *) pixmap, NULL,
+                               0, 0, 0, 0, width, height);
+  g_object_unref(G_OBJECT(layout));
+  g_object_unref(G_OBJECT(gc));
+  g_object_unref(G_OBJECT(pixmap));
+}
+
+static GdkPixbuf *
+get_current_group_image(PangoContext *pc, int size)
+{
+  GdkPixbuf *buf;
+  char *group_name, *filename, *diff;
+  group_name = get_current_group_name(&diff);
+  filename = g_strdup_printf("%s/%s.png", FLAGSDIR, group_name);
+  DBG ("Try to load image: %s", filename);
+  buf = gdk_pixbuf_new_from_file(filename, NULL);
+  if (buf) {
+    GdkPixbuf *newbuf
+      = gdk_pixbuf_scale_simple(buf, size, size - (int) (size / 3),
+                                GDK_INTERP_BILINEAR);
+    g_object_unref(G_OBJECT(buf));
+    buf = newbuf;
+    if (diff)
+      render_differentiation_to_pixbuf(buf, pc, diff);
+  }
+  g_free(filename);
+  g_free(group_name);
+  return buf;
+}
+
 void 
 set_new_locale(t_xkb *ctrl) 
 {
   t_xkb *plugin = (t_xkb *) ctrl;
-  char *filename;
   char *label_markup;
-  char *group_name;
-  int size;
-  GdkPixbuf *pixbuf = NULL, *tmp = NULL;
+  GdkPixbuf *pixbuf = NULL;
   NetkWindow* win;
   gint pid;
 
@@ -352,14 +433,9 @@
   g_free(label_markup);
   
   /* Set the image */
-  size = 0.9 * plugin->size;
-  group_name = get_current_group_name();
-  filename = g_strdup_printf("%s/%s.png", FLAGSDIR, group_name);
-  DBG ("Try to load image: %s", filename);
-  tmp = gdk_pixbuf_new_from_file(filename, NULL);
-  g_free(filename);
-  g_free(group_name);
-  if (tmp == NULL) { /* could not be loaded for some reason */
+  pixbuf = get_current_group_image(gtk_widget_get_pango_context(plugin->image),
+                                   0.9 * plugin->size);
+  if (pixbuf == NULL) { /* could not be loaded for some reason */
     if (plugin->display_type == IMAGE) {
       temporary_changed_display_type = TRUE;
       gtk_widget_hide(plugin->image);
@@ -367,14 +443,8 @@
     }
   } else { /* loaded successfully */
     temporary_changed_display_type = TRUE;
-    pixbuf = gdk_pixbuf_scale_simple(tmp, size, size - (int) (size / 3), GDK_INTERP_BILINEAR);
     gtk_image_set_from_pixbuf((GtkImage *) plugin->image, pixbuf);
-    if (tmp)
-      g_object_unref(G_OBJECT(tmp));
-      
-    if (pixbuf)
-      g_object_unref(G_OBJECT(pixbuf));
-
+    g_object_unref(G_OBJECT(pixbuf));
     if (plugin->display_type == IMAGE) { 
       /* the image for the previous active layout could not be loaded */
       gtk_widget_hide(plugin->label);
_______________________________________________
Pkg-xfce-devel mailing list
[email protected]
http://lists.alioth.debian.org/mailman/listinfo/pkg-xfce-devel

Reply via email to