]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkicontheme.c
Correctly select default printer when there is more than one (CUPS)
[~andy/gtk] / gtk / gtkicontheme.c
index 7fe4fb2815a9c8060c123c87caa892dce54b26c7..db183310d7f057f19228eb49cc0f98932768093d 100644 (file)
@@ -110,13 +110,14 @@ struct _GtkIconInfo
   /* Information about the source
    */
   gchar *filename;
-#ifdef G_OS_WIN32
+#if defined (G_OS_WIN32) && !defined (_WIN64)
   /* System codepage version of filename, for DLL ABI backward
    * compatibility functions.
    */
   gchar *cp_filename;
 #endif
   GLoadableIcon *loadable;
+  GSList *emblem_infos;
 
   /* Cache pixbuf (if there is any) */
   GdkPixbuf *cache_pixbuf;
@@ -1321,7 +1322,7 @@ choose_icon (GtkIconTheme       *icon_theme,
        icon_info->filename = g_strdup (unthemed_icon->svg_filename);
       else if (unthemed_icon->no_svg_filename)
        icon_info->filename = g_strdup (unthemed_icon->no_svg_filename);
-#ifdef G_OS_WIN32
+#if defined (G_OS_WIN32) && !defined (_WIN64)
       icon_info->cp_filename = g_locale_from_utf8 (icon_info->filename,
                                                   -1, NULL, NULL, NULL);
 #endif
@@ -1570,7 +1571,8 @@ gtk_icon_theme_has_icon (GtkIconTheme *icon_theme,
   GList *l;
 
   g_return_val_if_fail (GTK_IS_ICON_THEME (icon_theme), FALSE);
-  
+  g_return_val_if_fail (icon_name != NULL, FALSE);
+
   priv = icon_theme->priv;
   
   ensure_valid_themes (icon_theme);
@@ -2207,7 +2209,7 @@ theme_lookup_icon (IconTheme          *theme,
           file = g_strconcat (icon_name, string_from_suffix (suffix), NULL);
           icon_info->filename = g_build_filename (min_dir->dir, file, NULL);
           g_free (file);
-#ifdef G_OS_WIN32
+#if defined (G_OS_WIN32) && !defined (_WIN64)
           icon_info->cp_filename = g_locale_from_utf8 (icon_info->filename,
                                                   -1, NULL, NULL, NULL);
 #endif
@@ -2215,7 +2217,7 @@ theme_lookup_icon (IconTheme          *theme,
       else
         {
           icon_info->filename = NULL;
-#ifdef G_OS_WIN32
+#if defined (G_OS_WIN32) && !defined (_WIN64)
           icon_info->cp_filename = NULL;
 #endif
         }
@@ -2673,11 +2675,13 @@ gtk_icon_info_free (GtkIconInfo *icon_info)
     return;
  
   g_free (icon_info->filename);
-#ifdef G_OS_WIN32
+#if defined (G_OS_WIN32) && !defined (_WIN64)
   g_free (icon_info->cp_filename);
 #endif
   if (icon_info->loadable)
     g_object_unref (icon_info->loadable);
+  g_slist_foreach (icon_info->emblem_infos, (GFunc)gtk_icon_info_free, NULL);
+  g_slist_free (icon_info->emblem_infos);
   if (icon_info->pixbuf)
     g_object_unref (icon_info->pixbuf);
   if (icon_info->cache_pixbuf)
@@ -2764,6 +2768,86 @@ gtk_icon_info_get_builtin_pixbuf (GtkIconInfo *icon_info)
   return icon_info->cache_pixbuf;
 }
 
+static gboolean icon_info_ensure_scale_and_pixbuf (GtkIconInfo*, gboolean);
+
+/* Combine the icon with all emblems, the first emblem is placed 
+ * in the southeast corner. Scale emblems to be at most 3/4 of the
+ * size of the icon itself.
+ */
+static void 
+apply_emblems (GtkIconInfo *info)
+{
+  GdkPixbuf *icon = NULL;
+  gint w, h, pos;
+  GSList *l;
+
+  if (info->emblem_infos == NULL)
+    return;
+
+  w = gdk_pixbuf_get_width (info->pixbuf);
+  h = gdk_pixbuf_get_height (info->pixbuf);
+
+  for (l = info->emblem_infos, pos = 0; l; l = l->next, pos++)
+    {
+      GtkIconInfo *emblem_info = l->data;
+
+      if (icon_info_ensure_scale_and_pixbuf (emblem_info, FALSE))
+        {
+          GdkPixbuf *emblem = emblem_info->pixbuf;
+          gint ew, eh;
+          gint x = 0, y = 0; /* silence compiler */
+          gdouble scale;
+
+          ew = gdk_pixbuf_get_width (emblem);
+          eh = gdk_pixbuf_get_height (emblem);
+          if (ew >= w)
+            {
+              scale = 0.75;
+              ew = ew * 0.75;
+              eh = eh * 0.75;
+            }
+          else
+            scale = 1.0;
+
+          switch (pos % 4)
+            {
+            case 0:
+              x = w - ew;
+              y = h - eh;
+              break;
+            case 1:
+              x = w - ew;
+              y = 0;
+              break;
+            case 2:
+              x = 0;
+              y = h - eh;
+              break;
+            case 3:
+              x = 0;
+              y = 0;
+              break;
+            }
+
+          if (icon == NULL)
+            {
+              icon = gdk_pixbuf_copy (info->pixbuf);
+              if (icon == NULL)
+                break;
+            }
+
+          gdk_pixbuf_composite (emblem, icon, x, y, ew, eh, x, y,
+                                scale, scale, GDK_INTERP_BILINEAR, 255);
+       }
+   }
+
+  if (icon)
+    {
+      g_object_unref (info->pixbuf);
+      info->pixbuf = icon;
+    }
+}
+
 /* This function contains the complicated logic for deciding
  * on the size at which to load the icon and loading it at
  * that size.
@@ -2847,7 +2931,12 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo  *icon_info,
           g_object_unref (stream);
         }
 
-      return icon_info->pixbuf != NULL;
+      if (!icon_info->pixbuf)
+        return FALSE;
+
+      apply_emblems (icon_info);
+        
+      return TRUE;
     }
 
   /* In many cases, the scale can be determined without actual access
@@ -2938,6 +3027,8 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo  *icon_info,
       g_object_unref (source_pixbuf);
     }
 
+  apply_emblems (icon_info);
+
   return TRUE;
 }
 
@@ -3334,6 +3425,7 @@ _gtk_icon_theme_check_reload (GdkDisplay *display)
     }
 }
 
+
 /**
  * gtk_icon_theme_lookup_by_gicon:
  * @icon_theme: a #GtkIconTheme
@@ -3385,6 +3477,28 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme       *icon_theme,
 
       return info;
     }
+  else if (G_IS_EMBLEMED_ICON (icon))
+    {
+      GIcon *base, *emblem;
+      GList *list, *l;
+      GtkIconInfo *emblem_info;
+
+      base = g_emblemed_icon_get_icon (G_EMBLEMED_ICON (icon));
+      info = gtk_icon_theme_lookup_by_gicon (icon_theme, base, size, flags);
+      if (info)
+        {
+          list = g_emblemed_icon_get_emblems (G_EMBLEMED_ICON (icon));
+          for (l = list; l; l = l->next)
+            {
+              emblem = g_emblem_get_icon (G_EMBLEM (l->data));
+              emblem_info = gtk_icon_theme_lookup_by_gicon (icon_theme, emblem, size / 2, flags);
+              if (emblem_info)
+                info->emblem_infos = g_slist_prepend (info->emblem_infos, emblem_info);
+            }
+        }
+
+      return info;
+    }
 
   return NULL;
 }
@@ -3394,7 +3508,7 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme       *icon_theme,
  * @icon_theme: a #GtkIconTheme
  * @pixbuf: the pixbuf to wrap in a #GtkIconInfo
  *
- * Creates a #GtkIconInfo for a #GtkPixbuf. 
+ * Creates a #GtkIconInfo for a #GdkPixbuf.
  *
  * Returns: a #GtkIconInfo
  *
@@ -3417,7 +3531,7 @@ gtk_icon_info_new_for_pixbuf (GtkIconTheme *icon_theme,
   return info;
 }
 
-#ifdef G_OS_WIN32
+#if defined (G_OS_WIN32) && !defined (_WIN64)
 
 /* DLL ABI stability backward compatibility versions */