mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-28 14:31:10 +00:00
GtkWindow/GdkWindow: Finish converting icons to surfaces
There were some parts left, for instance gdk_window_set_icon_list.
This commit is contained in:
parent
6f8644ad25
commit
d3fc937b4d
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
// ??
|
||||
}
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -3145,7 +3145,7 @@ 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;
|
||||
|
||||
@ -3169,18 +3169,18 @@ gdk_window_update_icon (GdkWindow *window,
|
||||
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,19 +3242,19 @@ 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))
|
||||
@ -3262,64 +3262,71 @@ gdk_x11_window_set_icon_list (GdkWindow *window,
|
||||
|
||||
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 = gdk_pixbuf_get_width (pixbuf);
|
||||
height = gdk_pixbuf_get_height (pixbuf);
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
surface = 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);
|
||||
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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user