[gtk+] GtkWindow/GdkWindow: Finish converting icons to surfaces
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GtkWindow/GdkWindow: Finish converting icons to surfaces
- Date: Mon, 23 Oct 2017 11:48:50 +0000 (UTC)
commit d3fc937b4ddad6462bfca6402ce0a186f98d4908
Author: Alexander Larsson <alexl redhat com>
Date: Mon Oct 23 13:43:50 2017 +0200
GtkWindow/GdkWindow: Finish converting icons to surfaces
There were some parts left, for instance gdk_window_set_icon_list.
gdk/broadway/gdkwindow-broadway.c | 2 +-
gdk/gdkwindow.c | 8 +-
gdk/gdkwindow.h | 2 +-
gdk/mir/gdkmirwindowimpl.c | 2 +-
gdk/quartz/gdkwindow-quartz.c | 2 +-
gdk/wayland/gdkwindow-wayland.c | 2 +-
gdk/win32/gdkwindow-win32.c | 47 +++++++++------
gdk/x11/gdkwindow-x11.c | 115 +++++++++++++++++++-----------------
gtk/gtkwindow.c | 6 +-
tests/testgtk.c | 8 ++-
10 files changed, 107 insertions(+), 87 deletions(-)
---
diff --git a/gdk/broadway/gdkwindow-broadway.c b/gdk/broadway/gdkwindow-broadway.c
index 44bc9ec..d66dd47 100644
--- a/gdk/broadway/gdkwindow-broadway.c
+++ b/gdk/broadway/gdkwindow-broadway.c
@@ -791,7 +791,7 @@ gdk_broadway_window_set_focus_on_map (GdkWindow *window,
static void
gdk_broadway_window_set_icon_list (GdkWindow *window,
- GList *pixbufs)
+ GList *surfaces)
{
}
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 6aad9e8..7e1a079 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -6643,8 +6643,8 @@ gdk_window_get_event_compression (GdkWindow *window)
/**
* gdk_window_set_icon_list:
* @window: The #GdkWindow toplevel window to set the icon of.
- * @pixbufs: (transfer none) (element-type GdkPixbuf):
- * A list of pixbufs, of different sizes.
+ * @surfaces: (transfer none) (element-type cairo_surface_t):
+ * A list of image surfaces, of different sizes.
*
* Sets a list of icons for the window. One of these will be used
* to represent the window when it has been iconified. The icon is
@@ -6658,9 +6658,9 @@ gdk_window_get_event_compression (GdkWindow *window)
*/
void
gdk_window_set_icon_list (GdkWindow *window,
- GList *pixbufs)
+ GList *surfaces)
{
- GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_icon_list (window, pixbufs);
+ GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_icon_list (window, surfaces);
}
/**
diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h
index 261762f..72156e1 100644
--- a/gdk/gdkwindow.h
+++ b/gdk/gdkwindow.h
@@ -728,7 +728,7 @@ GdkEventMask gdk_window_get_source_events (GdkWindow *window,
GDK_AVAILABLE_IN_ALL
void gdk_window_set_icon_list (GdkWindow *window,
- GList *pixbufs);
+ GList *surfaces);
GDK_AVAILABLE_IN_ALL
void gdk_window_set_icon_name (GdkWindow *window,
const gchar *name);
diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
index e92c85e..2e5669f 100644
--- a/gdk/mir/gdkmirwindowimpl.c
+++ b/gdk/mir/gdkmirwindowimpl.c
@@ -1528,7 +1528,7 @@ gdk_mir_window_impl_set_focus_on_map (GdkWindow *window,
static void
gdk_mir_window_impl_set_icon_list (GdkWindow *window,
- GList *pixbufs)
+ GList *surface)
{
// ??
}
diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c
index d7b2f04..387b38c 100644
--- a/gdk/quartz/gdkwindow-quartz.c
+++ b/gdk/quartz/gdkwindow-quartz.c
@@ -2126,7 +2126,7 @@ gdk_quartz_window_begin_move_drag (GdkWindow *window,
static void
gdk_quartz_window_set_icon_list (GdkWindow *window,
- GList *pixbufs)
+ GList *surfaces)
{
/* FIXME: Implement */
}
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c
index 1697dcd..bb15eb1 100644
--- a/gdk/wayland/gdkwindow-wayland.c
+++ b/gdk/wayland/gdkwindow-wayland.c
@@ -3215,7 +3215,7 @@ gdk_wayland_window_set_focus_on_map (GdkWindow *window,
static void
gdk_wayland_window_set_icon_list (GdkWindow *window,
- GList *pixbufs)
+ GList *surfaces)
{
}
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index 6d8f078..f0ba27f 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -2315,9 +2315,10 @@ gdk_win32_window_set_focus_on_map (GdkWindow *window,
static void
gdk_win32_window_set_icon_list (GdkWindow *window,
- GList *pixbufs)
+ GList *surfaces)
{
- GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
+ cairo_surface_t *surface, *big_surface, *small_surface;
+ GdkPixbuf *big_pixbuf, *small_pixbuf;
gint big_diff, small_diff;
gint big_w, big_h, small_w, small_h;
gint w, h;
@@ -2339,40 +2340,48 @@ gdk_win32_window_set_icon_list (GdkWindow *window,
small_h = GetSystemMetrics (SM_CYSMICON);
/* find closest sized icons in the list */
- big_pixbuf = NULL;
- small_pixbuf = NULL;
+ big_surface = NULL;
+ small_surface = NULL;
big_diff = 0;
small_diff = 0;
- while (pixbufs)
+ while (surfaces)
{
- pixbuf = (GdkPixbuf*) pixbufs->data;
- w = gdk_pixbuf_get_width (pixbuf);
- h = gdk_pixbuf_get_height (pixbuf);
+ surface = (GdkPixbuf*) surfaces->data;
+ w = cairo_image_surface_get_width (surface);
+ h = cairo_image_surface_get_height (surface);
dw = ABS (w - big_w);
dh = ABS (h - big_h);
diff = dw*dw + dh*dh;
- if (big_pixbuf == NULL || diff < big_diff)
- {
- big_pixbuf = pixbuf;
- big_diff = diff;
- }
+ if (big_surface == NULL || diff < big_diff)
+ {
+ big_surface = surface;
+ big_diff = diff;
+ }
dw = ABS (w - small_w);
dh = ABS (h - small_h);
diff = dw*dw + dh*dh;
- if (small_pixbuf == NULL || diff < small_diff)
- {
- small_pixbuf = pixbuf;
- small_diff = diff;
- }
+ if (small_surface == NULL || diff < small_diff)
+ {
+ small_surface = surface;
+ small_diff = diff;
+ }
- pixbufs = pixbufs->next;
+ surfaces = surfaces->next;
}
/* Create the icons */
+ big_pixbuf = gdk_pixbuf_get_from_surface (big_surface, 0, 0,
+ cairo_image_surface_get_width (big_surface)
+ cairo_image_surface_get_height (big_surface));
big_hicon = _gdk_win32_pixbuf_to_hicon (big_pixbuf);
+ g_object_unref (big_pixbuf);
+ small_pixbuf = gdk_pixbuf_get_from_surface (small_surface, 0, 0,
+ cairo_image_surface_get_width (small_surface)
+ cairo_image_surface_get_height (small_surface));
small_hicon = _gdk_win32_pixbuf_to_hicon (small_pixbuf);
+ g_object_unref (small_pixbuf);
/* Set the icons */
SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index 3d3d305..ad27a45 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -3145,10 +3145,10 @@ gdk_window_update_icon (GdkWindow *window,
GList *icon_list)
{
GdkToplevelX11 *toplevel;
- GdkPixbuf *best_icon;
+ cairo_surface_t *best_icon;
GList *tmp_list;
int best_size;
-
+
toplevel = _gdk_x11_window_get_toplevel (window);
if (toplevel->icon_pixmap != NULL)
@@ -3156,31 +3156,31 @@ gdk_window_update_icon (GdkWindow *window,
cairo_surface_destroy (toplevel->icon_pixmap);
toplevel->icon_pixmap = NULL;
}
-
+
if (toplevel->icon_mask != NULL)
{
cairo_surface_destroy (toplevel->icon_mask);
toplevel->icon_mask = NULL;
}
-
+
#define IDEAL_SIZE 48
-
+
best_size = G_MAXINT;
best_icon = NULL;
for (tmp_list = icon_list; tmp_list; tmp_list = tmp_list->next)
{
- GdkPixbuf *pixbuf = tmp_list->data;
+ cairo_surface_t *surface = tmp_list->data;
int this;
-
+
/* average width and height - if someone passes in a rectangular
* icon they deserve what they get.
*/
- this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
+ this = cairo_image_surface_get_width (surface) + cairo_image_surface_get_height (surface);
this /= 2;
-
+
if (best_icon == NULL)
{
- best_icon = pixbuf;
+ best_icon = surface;
best_size = this;
}
else
@@ -3192,7 +3192,7 @@ gdk_window_update_icon (GdkWindow *window,
(ABS (best_size - IDEAL_SIZE) <
ABS (this - IDEAL_SIZE)))
{
- best_icon = pixbuf;
+ best_icon = surface;
best_size = this;
}
}
@@ -3200,8 +3200,8 @@ gdk_window_update_icon (GdkWindow *window,
if (best_icon)
{
- int width = gdk_pixbuf_get_width (best_icon);
- int height = gdk_pixbuf_get_height (best_icon);
+ int width = cairo_image_surface_get_width (best_icon);
+ int height = cairo_image_surface_get_height (best_icon);
cairo_t *cr;
toplevel->icon_pixmap = gdk_x11_window_create_pixmap_surface (window,
@@ -3210,8 +3210,8 @@ gdk_window_update_icon (GdkWindow *window,
cr = cairo_create (toplevel->icon_pixmap);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- gdk_cairo_set_source_pixbuf (cr, best_icon, 0, 0);
- if (gdk_pixbuf_get_has_alpha (best_icon))
+ cairo_set_source_surface (cr, best_icon, 0, 0);
+ if (cairo_surface_get_content (best_icon) == CAIRO_CONTENT_COLOR_ALPHA)
{
/* Saturate the image, so it has bilevel alpha */
cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
@@ -3223,14 +3223,14 @@ gdk_window_update_icon (GdkWindow *window,
cairo_paint (cr);
cairo_destroy (cr);
- if (gdk_pixbuf_get_has_alpha (best_icon))
+ if (cairo_surface_get_content (best_icon) == CAIRO_CONTENT_COLOR_ALPHA)
{
toplevel->icon_mask = _gdk_x11_window_create_bitmap_surface (window,
width,
height);
cr = cairo_create (toplevel->icon_mask);
- gdk_cairo_set_source_pixbuf (cr, best_icon, 0, 0);
+ cairo_set_source_surface (cr, best_icon, 0, 0);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
cairo_destroy (cr);
@@ -3242,84 +3242,91 @@ gdk_window_update_icon (GdkWindow *window,
static void
gdk_x11_window_set_icon_list (GdkWindow *window,
- GList *pixbufs)
+ GList *surfaces)
{
gulong *data;
guchar *pixels;
gulong *p;
gint size;
GList *l;
- GdkPixbuf *pixbuf;
+ cairo_surface_t *surface;
gint width, height, stride;
gint x, y;
- gint n_channels;
GdkDisplay *display;
gint n;
-
+ cairo_format_t format;
+
if (GDK_WINDOW_DESTROYED (window) ||
!WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
return;
display = gdk_window_get_display (window);
-
- l = pixbufs;
+
size = 0;
n = 0;
- while (l)
+ for (l = surfaces; l != NULL; l = l->next)
{
- pixbuf = l->data;
- g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
+ surface = l->data;
+
+ width = cairo_image_surface_get_width (surface);
+ height = cairo_image_surface_get_height (surface);
+ format = cairo_image_surface_get_format (surface);
+
+ if (format != CAIRO_FORMAT_ARGB32 && format != CAIRO_FORMAT_RGB24)
+ continue;
- width = gdk_pixbuf_get_width (pixbuf);
- height = gdk_pixbuf_get_height (pixbuf);
-
/* silently ignore overlarge icons */
if (size + 2 + width * height > GDK_SELECTION_MAX_SIZE(display))
- break;
-
+ break;
+
n++;
size += 2 + width * height;
-
- l = l->next;
}
data = g_malloc (size * sizeof (gulong));
- l = pixbufs;
p = data;
- while (l && n > 0)
+ for (l = surfaces; l != NULL && n > 0; l = l->next)
{
- pixbuf = l->data;
-
- width = gdk_pixbuf_get_width (pixbuf);
- height = gdk_pixbuf_get_height (pixbuf);
- stride = gdk_pixbuf_get_rowstride (pixbuf);
- n_channels = gdk_pixbuf_get_n_channels (pixbuf);
-
+ surface = l->data;
+
+ width = cairo_image_surface_get_width (surface);
+ height = cairo_image_surface_get_height (surface);
+ stride = cairo_image_surface_get_stride (surface);
+ format = cairo_image_surface_get_format (surface);
+
+ if (format != CAIRO_FORMAT_ARGB32 && format != CAIRO_FORMAT_RGB24)
+ continue;
+
*p++ = width;
*p++ = height;
- pixels = gdk_pixbuf_get_pixels (pixbuf);
+ pixels = cairo_image_surface_get_data (surface);
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
guchar r, g, b, a;
-
- r = pixels[y*stride + x*n_channels + 0];
- g = pixels[y*stride + x*n_channels + 1];
- b = pixels[y*stride + x*n_channels + 2];
- if (n_channels >= 4)
- a = pixels[y*stride + x*n_channels + 3];
- else
- a = 255;
-
+ a = 255;
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ if (format == CAIRO_FORMAT_ARGB32)
+ a = pixels[y*stride + x*4 + 3];
+ r = pixels[y*stride + x*4 + 2];
+ g = pixels[y*stride + x*4 + 1];
+ b = pixels[y*stride + x*4 + 0];
+#else
+ if (format == CAIRO_FORMAT_ARGB32)
+ a = pixels[y*stride + x*4 + 0];
+ r = pixels[y*stride + x*4 + 1];
+ g = pixels[y*stride + x*4 + 2];
+ b = pixels[y*stride + x*4 + 3];
+#endif
+
*p++ = a << 24 | r << 16 | g << 8 | b ;
}
}
- l = l->next;
n--;
}
@@ -3341,7 +3348,7 @@ gdk_x11_window_set_icon_list (GdkWindow *window,
g_free (data);
- gdk_window_update_icon (window, pixbufs);
+ gdk_window_update_icon (window, surfaces);
}
static gboolean
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 31d1444..d0d1e45 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -4588,7 +4588,7 @@ icon_from_list (GtkWindow *window,
surface =
gdk_window_create_similar_image_surface (_gtk_widget_get_window (GTK_WIDGET(window)),
CAIRO_FORMAT_ARGB32,
- size, size, scale);
+ size * scale, size * scale, scale);
cr = cairo_create (surface);
cairo_set_source_surface (cr, best, 0, 0);
cairo_scale (cr,
@@ -4710,9 +4710,9 @@ gtk_window_set_icon_list (GtkWindow *window,
return;
g_list_foreach (list,
- (GFunc) g_object_ref, NULL);
+ (GFunc) cairo_surface_reference, NULL);
- g_list_free_full (info->icon_list, g_object_unref);
+ g_list_free_full (info->icon_list, (GDestroyNotify)cairo_surface_destroy);
info->icon_list = g_list_copy (list);
diff --git a/tests/testgtk.c b/tests/testgtk.c
index 86effa2..4bcc9ac 100644
--- a/tests/testgtk.c
+++ b/tests/testgtk.c
@@ -5721,6 +5721,7 @@ create_wmhints (GtkWidget *widget)
GtkWidget *box2;
GdkWindow *gdk_window;
GdkPixbuf *pixbuf;
+ cairo_surface_t *surface;
GList *list;
if (!window)
@@ -5741,11 +5742,14 @@ create_wmhints (GtkWidget *widget)
gdk_window = gtk_widget_get_window (window);
pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) openfile);
- list = g_list_prepend (NULL, pixbuf);
+ surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL);
- gdk_window_set_icon_list (gdk_window, list);
+ list = g_list_prepend (NULL, surface);
+
+ gtk_window_set_icon_list (GTK_WINDOW (window), list);
g_list_free (list);
+ cairo_surface_destroy (surface);
g_object_unref (pixbuf);
gdk_window_set_icon_name (gdk_window, "WMHints Test Icon");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]