From b20582c6617a114d3469eb7205c54c1a5be02cfb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 19 Sep 2009 20:14:27 +0200 Subject: gtk: add various validity checks before using data from GdkWindow Only access the GdkWindow of realized widgets Clamp positions into range. --- src/canberra-gtk.c | 96 +++++++++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/src/canberra-gtk.c b/src/canberra-gtk.c index d6353d3..b03eba6 100644 --- a/src/canberra-gtk.c +++ b/src/canberra-gtk.c @@ -183,9 +183,6 @@ int ca_gtk_proplist_set_for_widget(ca_proplist *p, GtkWidget *widget) { GtkWindow *w; int ret; const char *t, *role; - GdkWindow *dw; - GdkScreen *screen; - gint x = 0, y = 0, width = 0, height = 0, screen_width = 0, screen_height = 0; ca_return_val_if_fail(p, CA_ERROR_INVALID); ca_return_val_if_fail(widget, CA_ERROR_INVALID); @@ -217,66 +214,77 @@ int ca_gtk_proplist_set_for_widget(ca_proplist *p, GtkWidget *widget) { if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_ICON_NAME, t)) < 0) return ret; - if ((dw = GTK_WIDGET(w)->window)) - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_XID, "%lu", (unsigned long) GDK_WINDOW_XID(dw))) < 0) - return ret; - - if ((screen = gtk_widget_get_screen(widget))) { + if (GTK_WIDGET_REALIZED(GTK_WIDGET(w))) { + GdkWindow *dw = NULL; + GdkScreen *screen = NULL; + gint x = 0, y = 0, width = 0, height = 0, screen_width = 0, screen_height = 0; - if ((t = gdk_display_get_name(gdk_screen_get_display(screen)))) - if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_X11_DISPLAY, t)) < 0) + if ((dw = gtk_widget_get_window(GTK_WIDGET(w)))) + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_XID, "%lu", (unsigned long) GDK_WINDOW_XID(dw))) < 0) return ret; - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_SCREEN, "%i", gdk_screen_get_number(screen))) < 0) - return ret; - if (dw) - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_MONITOR, "%i", gdk_screen_get_monitor_at_window(screen, dw))) < 0) + if ((screen = gtk_widget_get_screen(GTK_WIDGET(w)))) { + + if ((t = gdk_display_get_name(gdk_screen_get_display(screen)))) + if ((ret = ca_proplist_sets(p, CA_PROP_WINDOW_X11_DISPLAY, t)) < 0) + return ret; + + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_SCREEN, "%i", gdk_screen_get_number(screen))) < 0) return ret; - } - /* FIXME, this might cause a round trip */ + if (dw) + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X11_MONITOR, "%i", gdk_screen_get_monitor_at_window(screen, dw))) < 0) + return ret; + } + + /* FIXME, this might cause a round trip */ + + if (dw) { + gdk_window_get_origin(dw, &x, &y); + + if (x >= 0) + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X, "%i", x)) < 0) + return ret; + if (y >= 0) + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_Y, "%i", y)) < 0) + return ret; + } - if (dw) { - gdk_window_get_origin(dw, &x, &y); + gtk_window_get_size(w, &width, &height); - if (x >= 0) - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_X, "%i", x)) < 0) + if (width > 0) + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_WIDTH, "%i", width)) < 0) return ret; - if (y >= 0) - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_Y, "%i", y)) < 0) + if (height > 0) + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_HEIGHT, "%i", height)) < 0) return ret; - } - gtk_window_get_size(w, &width, &height); + if (x > 0 && width > 0) { + x += width/2; - if (width > 0) - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_WIDTH, "%i", width)) < 0) - return ret; - if (height > 0) - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_HEIGHT, "%i", height)) < 0) - return ret; + screen_width = gdk_screen_get_width(gtk_widget_get_screen(GTK_WIDGET(w))); - if (x > 0 && width > 0) { - x += width/2; + x = CA_CLAMP(x, 0, screen_width-1); - screen_width = gdk_screen_get_width(gtk_widget_get_screen(GTK_WIDGET(w))); + /* We use these strange format strings here to avoid that libc + * applies locale information on the formatting of floating + * numbers. */ - /* We use these strange format strings here to avoid that libc - * applies locale information on the formatting of floating - * numbers. */ + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_HPOS, "%i.%03i", (int) (x/(screen_width-1)), (int) (1000.0*x/(screen_width-1)) % 1000)) < 0) + return ret; + } - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_HPOS, "%i.%03i", (int) (x/screen_width), (int) (1000.0*x/screen_width) % 1000)) < 0) - return ret; - } + if (y > 0 && height > 0) { + y += height/2; - if (y > 0 && height > 0) { - y += height/2; + screen_height = gdk_screen_get_height(gtk_widget_get_screen(GTK_WIDGET(w))); - screen_height = gdk_screen_get_height(gtk_widget_get_screen(GTK_WIDGET(w))); + y = CA_CLAMP(y, 0, screen_height-1); - if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_VPOS, "%i.%03i", (int) (y/screen_height), (int) (1000.0*y/screen_height) % 1000)) < 0) - return ret; + if ((ret = ca_proplist_setf(p, CA_PROP_WINDOW_VPOS, "%i.%03i", (int) (y/(screen_height-1)), (int) (1000.0*y/(screen_height-1)) % 1000)) < 0) + return ret; + } } return CA_SUCCESS; -- cgit