* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
-#include <X11/extensions/shape.h>
#include <netinet/in.h>
#include "gdk.h"
-#include "../config.h"
+#include "config.h"
#include "gdkinput.h"
#include "gdkprivate.h"
#include "MwmUtil.h"
-#include <stdlib.h>
-#include <stdio.h>
-int nevent_masks = 17;
-int event_mask_table[19] =
+#if HAVE_CONFIG_H
+# include <config.h>
+# if STDC_HEADERS
+# include <stdlib.h>
+# include <stdio.h>
+# include <string.h>
+# endif
+#else
+# include <stdlib.h>
+# include <stdio.h>
+#endif
+
+
+#ifdef HAVE_SHAPE_EXT
+#include <X11/extensions/shape.h>
+#endif
+
+const int gdk_event_mask_table[20] =
{
ExposureMask,
PointerMotionMask,
PropertyChangeMask,
VisibilityChangeMask,
0, /* PROXIMITY_IN */
- 0 /* PROXIMTY_OUT */
+ 0, /* PROXIMTY_OUT */
+ SubstructureNotifyMask
};
+const int gdk_nevent_masks = sizeof(gdk_event_mask_table)/sizeof(int);
+static gboolean gdk_window_have_shape_ext (void);
/* internal function created for and used by gdk_window_xid_at_coords */
Window
-gdk_window_xid_at(Window base, gint bx, gint by, gint x, gint y,
- GList *excludes, gboolean excl_child)
+gdk_window_xid_at (Window base,
+ gint bx,
+ gint by,
+ gint x,
+ gint y,
+ GList *excludes,
+ gboolean excl_child)
{
GdkWindow *window;
GdkWindowPrivate *private;
Display *disp;
- Window *list=NULL;
- Window child=0,parent_win=0,root_win=0;
- int num,i,ww,wh,wb,wd;
- int wx,wy;
+ Window *list = NULL;
+ Window child = 0, parent_win = 0, root_win = 0;
+ int i;
+ unsigned int ww, wh, wb, wd, num;
+ int wx, wy;
- window=(GdkWindow*)&gdk_root_parent;
- private=(GdkWindowPrivate*)window;
- disp=private->xdisplay;
- if (!XGetGeometry(disp,base,&root_win,&wx,&wy,&ww,&wh,&wb,&wd))
+ window = (GdkWindow*) &gdk_root_parent;
+ private = (GdkWindowPrivate*) window;
+ disp = private->xdisplay;
+ if (!XGetGeometry (disp, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
return 0;
- wx+=bx;wy+=by;
- if (!((x>=wx)&&(y>=wy)&&(x<(wx+ww))&&(y<(wy+wh))))
+ wx += bx;
+ wy += by;
+
+ if (!((x >= wx) &&
+ (y >= wy) &&
+ (x < (int) (wx + ww)) &&
+ (y < (int) (wy + wh))))
return 0;
- if (!XQueryTree(disp,base,&root_win,&parent_win,&list,&num))
+
+ if (!XQueryTree (disp, base, &root_win, &parent_win, &list, &num))
return base;
+
if (list)
{
- for (i=num-1;;i--)
+ for (i = num - 1; ; i--)
{
- if ((!excl_child)||(!g_list_find(excludes,(gpointer *)list[i])))
+ if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
{
- if ((child=gdk_window_xid_at(list[i],wx,wy,x,y,excludes,excl_child))!=0)
+ if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
{
- XFree(list);
+ XFree (list);
return child;
}
}
- if (!i) break;
+ if (!i)
+ break;
}
- XFree(list);
+ XFree (list);
}
return base;
}
* those X,Y co-ordinates.
*/
Window
-gdk_window_xid_at_coords(gint x, gint y, GList *excludes, gboolean excl_child)
+gdk_window_xid_at_coords (gint x,
+ gint y,
+ GList *excludes,
+ gboolean excl_child)
{
GdkWindow *window;
GdkWindowPrivate *private;
Display *disp;
- Window *list=NULL;
- Window root,child=0,parent_win=0,root_win=0;
+ Window *list = NULL;
+ Window root, child = 0, parent_win = 0, root_win = 0;
unsigned int num;
int i;
- window=(GdkWindow*)&gdk_root_parent;
- private=(GdkWindowPrivate*)window;
- disp=private->xdisplay;
- root=private->xwindow;
- XGrabServer(disp);
- num=g_list_length(excludes);
- if (!XQueryTree(disp,root,&root_win,&parent_win,&list,&num))
- return root;
+ window = (GdkWindow*) &gdk_root_parent;
+ private = (GdkWindowPrivate*) window;
+ disp = private->xdisplay;
+ root = private->xwindow;
+ num = g_list_length (excludes);
+
+ XGrabServer (disp);
+ if (!XQueryTree (disp, root, &root_win, &parent_win, &list, &num))
+ {
+ XUngrabServer(disp);
+ return root;
+ }
if (list)
{
i = num - 1;
if (xwa.map_state != IsViewable)
continue;
- if (excl_child && g_list_find(excludes,(gpointer *)list[i]))
+ if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
continue;
if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
if (excludes)
{
- if (!g_list_find(excludes,(gpointer *)child))
+ if (!g_list_find (excludes, (gpointer *) child))
{
- XFree(list);
- XUngrabServer(disp);
+ XFree (list);
+ XUngrabServer (disp);
return child;
}
}
else
{
- XFree(list);
- XUngrabServer(disp);
+ XFree (list);
+ XUngrabServer (disp);
return child;
}
} while (--i > 0);
- XFree(list);
+ XFree (list);
}
- XUngrabServer(disp);
+ XUngrabServer (disp);
return root;
}
void
-gdk_window_init ()
+gdk_window_init (void)
{
XWindowAttributes xattributes;
unsigned int width;
&x, &y, &width, &height, &border_width, &depth);
XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
- gdk_root_parent.xdisplay = gdk_display;
gdk_root_parent.xwindow = gdk_root_window;
+ gdk_root_parent.xdisplay = gdk_display;
gdk_root_parent.window_type = GDK_WINDOW_ROOT;
gdk_root_parent.window.user_data = NULL;
gdk_root_parent.width = width;
gdk_root_parent.height = height;
+ gdk_root_parent.children = NULL;
+ gdk_root_parent.colormap = NULL;
+ gdk_root_parent.ref_count = 1;
+
+ gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
}
GdkWindow*
GdkWindowPrivate *private;
GdkWindowPrivate *parent_private;
GdkVisual *visual;
- GdkColormap *colormap;
Display *parent_display;
Window xparent;
Visual *xvisual;
window = (GdkWindow*) private;
private->parent = parent;
+
+ if (parent_private)
+ parent_private->children = g_list_prepend (parent_private->children, window);
+
private->xdisplay = parent_display;
private->destroyed = FALSE;
+ private->mapped = FALSE;
private->resize_count = 0;
private->ref_count = 1;
xattributes_mask = 0;
private->height = (attributes->height > 1) ? (attributes->height) : (1);
private->window_type = attributes->window_type;
private->extension_events = FALSE;
- private->dnd_drag_data_type = None;
- private->dnd_drag_data_typesavail =
- private->dnd_drop_data_typesavail = NULL;
- private->dnd_drop_enabled = private->dnd_drag_enabled =
- private->dnd_drag_accepted = private->dnd_drag_datashow =
- private->dnd_drop_data_numtypesavail =
- private->dnd_drag_data_numtypesavail = 0;
- private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
private->filters = NULL;
+ private->children = NULL;
window->user_data = NULL;
xvisual = ((GdkVisualPrivate*) visual)->xvisual;
xattributes.event_mask = StructureNotifyMask;
- for (i = 0; i < nevent_masks; i++)
+ for (i = 0; i < gdk_nevent_masks; i++)
{
if (attributes->event_mask & (1 << (i + 1)))
- xattributes.event_mask |= event_mask_table[i];
+ xattributes.event_mask |= gdk_event_mask_table[i];
}
if (xattributes.event_mask)
depth = visual->depth;
if (attributes_mask & GDK_WA_COLORMAP)
- colormap = attributes->colormap;
+ private->colormap = attributes->colormap;
else
- colormap = gdk_colormap_get_system ();
+ {
+ if ((((GdkVisualPrivate*)gdk_visual_get_system())->xvisual) == xvisual)
+ private->colormap = gdk_colormap_get_system ();
+ else
+ private->colormap = gdk_colormap_new (visual, False);
+ }
xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
switch (private->window_type)
{
case GDK_WINDOW_TOPLEVEL:
- xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
+ xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
xattributes_mask |= CWColormap;
xparent = gdk_root_window;
break;
case GDK_WINDOW_CHILD:
- xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
+ xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
xattributes_mask |= CWColormap;
break;
case GDK_WINDOW_DIALOG:
- xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
+ xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
xattributes_mask |= CWColormap;
xparent = gdk_root_window;
break;
case GDK_WINDOW_TEMP:
- xattributes.colormap = ((GdkColormapPrivate*) colormap)->xcolormap;
+ xattributes.colormap = ((GdkColormapPrivate*) private->colormap)->xcolormap;
xattributes_mask |= CWColormap;
xparent = gdk_root_window;
{
depth = 0;
class = InputOnly;
- colormap = NULL;
+ private->colormap = NULL;
}
private->xwindow = XCreateWindow (private->xdisplay, xparent,
gdk_window_ref (window);
gdk_xid_table_insert (&private->xwindow, window);
+ if (private->colormap)
+ gdk_colormap_ref (private->colormap);
+
gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
(attributes->cursor) :
NULL));
break;
case GDK_WINDOW_CHILD:
if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
- (colormap != gdk_colormap_get_system ()) &&
- (colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
+ (private->colormap != gdk_colormap_get_system ()) &&
+ (private->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
{
- GDK_NOTE (MISC, g_print ("adding colormap window\n"));
+ GDK_NOTE (MISC, g_message ("adding colormap window\n"));
gdk_window_add_colormap_windows (window);
}
if (attributes_mask & GDK_WA_TITLE)
title = attributes->title;
else
- title = gdk_progname;
+ title = g_get_prgname ();
XmbSetWMProperties (private->xdisplay, private->xwindow,
title, title,
{
GdkWindow *window;
GdkWindowPrivate *private;
+ GdkWindowPrivate *parent_private;
XWindowAttributes attrs;
Window root, parent;
- Window *children;
+ Window *children = NULL;
guint nchildren;
+ if(!XGetWindowAttributes (gdk_display, anid, &attrs)) {
+ g_warning("XGetWindowAttributes failed on window ID %d\n", anid);
+ return NULL;
+ }
+
private = g_new (GdkWindowPrivate, 1);
window = (GdkWindow*) private;
- XGetWindowAttributes (gdk_display, anid, &attrs);
-
/* FIXME: This is pretty expensive. Maybe the caller should supply
* the parent */
XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
- XFree (children);
+
+ if (children)
+ XFree (children);
private->parent = gdk_xid_table_lookup (parent);
+ parent_private = (GdkWindowPrivate *)private->parent;
+
+ if (parent_private)
+ parent_private->children = g_list_prepend (parent_private->children, window);
+
private->xwindow = anid;
private->xdisplay = gdk_display;
private->x = attrs.x;
private->ref_count = 1;
private->window_type = GDK_WINDOW_FOREIGN;
private->destroyed = FALSE;
+ private->mapped = (attrs.map_state != IsUnmapped);
private->extension_events = 0;
-
- private->dnd_drag_data_type = None;
- private->dnd_drag_data_typesavail =
- private->dnd_drop_data_typesavail = NULL;
- private->dnd_drop_enabled = private->dnd_drag_enabled =
- private->dnd_drag_accepted = private->dnd_drag_datashow =
- private->dnd_drop_data_numtypesavail =
- private->dnd_drag_data_numtypesavail = 0;
- private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
+ private->colormap = NULL;
private->filters = NULL;
+ private->children = NULL;
window->user_data = NULL;
case GDK_WINDOW_FOREIGN:
if (!private->destroyed)
{
+ if (private->parent)
+ {
+ GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
+ if (parent_private->children)
+ parent_private->children = g_list_remove (parent_private->children, window);
+ }
+
if (private->window_type != GDK_WINDOW_FOREIGN)
{
- children = gdk_window_get_children (window);
- tmp = children;
+ children = tmp = private->children;
+ private->children = NULL;
while (tmp)
{
gdk_window_internal_destroy (temp_window, FALSE,
our_destroy);
}
-
+
g_list_free (children);
}
if (private->extension_events != 0)
gdk_input_window_destroy (window);
- if(private->dnd_drag_data_numtypesavail > 0)
- {
- g_free (private->dnd_drag_data_typesavail);
- private->dnd_drag_data_typesavail = NULL;
- }
- if(private->dnd_drop_data_numtypesavail > 0)
- {
- g_free (private->dnd_drop_data_typesavail);
- private->dnd_drop_data_typesavail = NULL;
- }
-
if (private->filters)
{
tmp = private->filters;
else if (xdestroy)
XDestroyWindow (private->xdisplay, private->xwindow);
+ if (private->colormap)
+ gdk_colormap_unref (private->colormap);
+
private->destroyed = TRUE;
}
break;
if (private->ref_count == 0)
{
if (!private->destroyed)
- g_warning ("losing last reference to undestroyed window\n");
+ {
+ if (private->window_type == GDK_WINDOW_FOREIGN)
+ gdk_xid_table_remove (private->xwindow);
+ else
+ g_warning ("losing last reference to undestroyed window\n");
+ }
+ g_dataset_destroy (window);
g_free (window);
}
}
private = (GdkWindowPrivate*) window;
if (!private->destroyed)
{
+ private->mapped = TRUE;
XRaiseWindow (private->xdisplay, private->xwindow);
XMapWindow (private->xdisplay, private->xwindow);
}
private = (GdkWindowPrivate*) window;
if (!private->destroyed)
- XUnmapWindow (private->xdisplay, private->xwindow);
+ {
+ private->mapped = FALSE;
+ XUnmapWindow (private->xdisplay, private->xwindow);
+ }
}
void
{
GdkWindowPrivate *window_private;
GdkWindowPrivate *parent_private;
+ GdkWindowPrivate *old_parent_private;
g_return_if_fail (window != NULL);
new_parent = (GdkWindow*) &gdk_root_parent;
window_private = (GdkWindowPrivate*) window;
+ old_parent_private = (GdkWindowPrivate*)window_private->parent;
parent_private = (GdkWindowPrivate*) new_parent;
if (!window_private->destroyed && !parent_private->destroyed)
window_private->xwindow,
parent_private->xwindow,
x, y);
+
+ window_private->parent = new_parent;
+
+ if (old_parent_private)
+ old_parent_private->children = g_list_remove (old_parent_private->children, window);
+ parent_private->children = g_list_prepend (parent_private->children, window);
+
}
void
XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
}
+void
+gdk_window_set_geometry_hints (GdkWindow *window,
+ GdkGeometry *geometry,
+ GdkWindowHints geom_mask)
+{
+ GdkWindowPrivate *private;
+ XSizeHints size_hints;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (private->destroyed)
+ return;
+
+ size_hints.flags = 0;
+
+ if (geom_mask & GDK_HINT_POS)
+ size_hints.flags |= PPosition;
+
+ if (geom_mask & GDK_HINT_MIN_SIZE)
+ {
+ size_hints.flags |= PMinSize;
+ size_hints.min_width = geometry->min_width;
+ size_hints.min_height = geometry->min_height;
+ }
+
+ if (geom_mask & GDK_HINT_MAX_SIZE)
+ {
+ size_hints.flags |= PMaxSize;
+ size_hints.max_width = geometry->max_width;
+ size_hints.max_height = geometry->max_height;
+ }
+
+ if (geom_mask & GDK_HINT_BASE_SIZE)
+ {
+ size_hints.flags |= PBaseSize;
+ size_hints.base_width = geometry->base_width;
+ size_hints.base_height = geometry->base_height;
+ }
+
+ if (geom_mask & GDK_HINT_RESIZE_INC)
+ {
+ size_hints.flags |= PResizeInc;
+ size_hints.width_inc = geometry->width_inc;
+ size_hints.height_inc = geometry->height_inc;
+ }
+
+ if (geom_mask & GDK_HINT_ASPECT)
+ {
+ size_hints.flags |= PAspect;
+ if (geometry->min_aspect <= 1)
+ {
+ size_hints.min_aspect.x = G_MAXINT * geometry->min_aspect;
+ size_hints.min_aspect.y = G_MAXINT;
+ }
+ else
+ {
+ size_hints.min_aspect.x = G_MAXINT;
+ size_hints.min_aspect.y = G_MAXINT / geometry->min_aspect;;
+ }
+ if (geometry->max_aspect <= 1)
+ {
+ size_hints.max_aspect.x = G_MAXINT * geometry->max_aspect;
+ size_hints.max_aspect.y = G_MAXINT;
+ }
+ else
+ {
+ size_hints.max_aspect.x = G_MAXINT;
+ size_hints.max_aspect.y = G_MAXINT / geometry->max_aspect;;
+ }
+ }
+
+ if (geom_mask)
+ XSetWMNormalHints (private->xdisplay, private->xwindow, &size_hints);
+}
+
void
gdk_window_set_title (GdkWindow *window,
const gchar *title)
title, title, NULL, 0, NULL, NULL, NULL);
}
+void
+gdk_window_set_role (GdkWindow *window,
+ const gchar *role)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+
+ if (role)
+ XChangeProperty (private->xdisplay, private->xwindow,
+ gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
+ 8, PropModeReplace, role, strlen(role));
+ else
+ XDeleteProperty (private->xdisplay, private->xwindow,
+ gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
+}
+
+void
+gdk_window_set_transient_for (GdkWindow *window,
+ GdkWindow *parent)
+{
+ GdkWindowPrivate *private;
+ GdkWindowPrivate *parent_private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ parent_private = (GdkWindowPrivate*) parent;
+
+ if (!private->destroyed && !parent_private->destroyed)
+ XSetTransientForHint (private->xdisplay,
+ private->xwindow, parent_private->xwindow);
+}
+
void
gdk_window_set_background (GdkWindow *window,
GdkColor *color)
XSetWindowColormap (window_private->xdisplay,
window_private->xwindow,
colormap_private->xcolormap);
+
+ if (window_private->colormap)
+ gdk_colormap_unref (window_private->colormap);
+ window_private->colormap = colormap;
+ gdk_colormap_ref (window_private->colormap);
if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
gdk_window_add_colormap_windows (window);
{
GdkWindowPrivate *window_private;
XWindowAttributes window_attributes;
-
+
g_return_val_if_fail (window != NULL, NULL);
-
+
window_private = (GdkWindowPrivate*) window;
+ /* Huh? ->parent is never set for a pixmap. We should just return
+ * null immeditately
+ */
while (window_private && (window_private->window_type == GDK_WINDOW_PIXMAP))
window_private = (GdkWindowPrivate*) window_private->parent;
if (window_private && !window_private->destroyed)
{
- XGetWindowAttributes (window_private->xdisplay,
- window_private->xwindow,
- &window_attributes);
-
- return gdk_visual_lookup (window_attributes.visual);
+ if (window_private->colormap == NULL)
+ {
+ XGetWindowAttributes (window_private->xdisplay,
+ window_private->xwindow,
+ &window_attributes);
+ return gdk_visual_lookup (window_attributes.visual);
+ }
+ else
+ return ((GdkColormapPrivate *)window_private->colormap)->visual;
}
return NULL;
XWindowAttributes window_attributes;
g_return_val_if_fail (window != NULL, NULL);
-
window_private = (GdkWindowPrivate*) window;
-
+
+ g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
if (!window_private->destroyed)
{
- XGetWindowAttributes (window_private->xdisplay,
- window_private->xwindow,
- &window_attributes);
-
- return gdk_colormap_lookup (window_attributes.colormap);
+ if (window_private->colormap == NULL)
+ {
+ XGetWindowAttributes (window_private->xdisplay,
+ window_private->xwindow,
+ &window_attributes);
+ return gdk_colormap_lookup (window_attributes.colormap);
+ }
+ else
+ return window_private->colormap;
}
return NULL;
GdkWindowPrivate *private;
gint return_val;
Window child;
- gint tx, ty;
+ gint tx = 0;
+ gint ty = 0;
g_return_val_if_fail (window != NULL, 0);
0, 0, &tx, &ty,
&child);
+ }
+ else
+ return_val = 0;
+
+ if (x)
+ *x = tx;
+ if (y)
+ *y = ty;
+
+ return return_val;
+}
+
+gboolean
+gdk_window_get_deskrelative_origin (GdkWindow *window,
+ gint *x,
+ gint *y)
+{
+ GdkWindowPrivate *private;
+ gboolean return_val = FALSE;
+ gint num_children, format_return;
+ Window win, *child, parent, root;
+ gint tx = 0;
+ gint ty = 0;
+ Atom type_return;
+ static Atom atom = 0;
+ gulong number_return, bytes_after_return;
+ guchar *data_return;
+
+ g_return_val_if_fail (window != NULL, 0);
+
+ private = (GdkWindowPrivate*) window;
+
+ if (!private->destroyed)
+ {
+ if (!atom)
+ atom = XInternAtom(private->xdisplay, "ENLIGHTENMENT_DESKTOP", False);
+ win = private->xwindow;
+
+ while (XQueryTree(private->xdisplay, win, &root, &parent,
+ &child, (unsigned int *)&num_children))
+ {
+ if ((child) && (num_children > 0))
+ XFree(child);
+
+ if (!parent)
+ break;
+ else
+ win = parent;
+
+ if (win == root)
+ break;
+
+ data_return = NULL;
+ XGetWindowProperty(private->xdisplay, win, atom, 0, 0,
+ False, XA_CARDINAL, &type_return, &format_return,
+ &number_return, &bytes_after_return, &data_return);
+ if (type_return == XA_CARDINAL)
+ {
+ XFree(data_return);
+ break;
+ }
+ }
+
+ return_val = XTranslateCoordinates (private->xdisplay,
+ private->xwindow,
+ win,
+ 0, 0, &tx, &ty,
+ &root);
if (x)
*x = tx;
if (y)
*y = ty;
}
- else
- return_val = 0;
+
return return_val;
}
+void
+gdk_window_get_root_origin (GdkWindow *window,
+ gint *x,
+ gint *y)
+{
+ GdkWindowPrivate *private;
+ Window xwindow;
+ Window xparent;
+ Window root;
+ Window *children;
+ unsigned int nchildren;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowPrivate*) window;
+ if (x)
+ *x = 0;
+ if (y)
+ *y = 0;
+ if (private->destroyed)
+ return;
+
+ while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
+ private = (GdkWindowPrivate*) private->parent;
+ if (private->destroyed)
+ return;
+
+ xparent = private->xwindow;
+ do
+ {
+ xwindow = xparent;
+ if (!XQueryTree (private->xdisplay, xwindow,
+ &root, &xparent,
+ &children, &nchildren))
+ return;
+
+ if (children)
+ XFree (children);
+ }
+ while (xparent != root);
+
+ if (xparent == root)
+ {
+ unsigned int ww, wh, wb, wd;
+ int wx, wy;
+
+ if (XGetGeometry (private->xdisplay, xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
+ {
+ if (x)
+ *x = wx;
+ if (y)
+ *y = wy;
+ }
+ }
+}
+
GdkWindow*
gdk_window_get_pointer (GdkWindow *window,
gint *x,
Window root;
Window child;
int rootx, rooty;
- int winx, winy;
- unsigned int xmask;
+ int winx = 0;
+ int winy = 0;
+ unsigned int xmask = 0;
if (!window)
window = (GdkWindow*) &gdk_root_parent;
XQueryPointer (private->xdisplay, private->xwindow, &root, &child,
&rootx, &rooty, &winx, &winy, &xmask))
{
- if (x) *x = winx;
- if (y) *y = winy;
- if (mask) *mask = xmask;
-
if (child)
return_val = gdk_window_lookup (child);
}
+ if (x)
+ *x = winx;
+ if (y)
+ *y = winy;
+ if (mask)
+ *mask = xmask;
+
return return_val;
}
+GdkWindow*
+gdk_window_at_pointer (gint *win_x,
+ gint *win_y)
+{
+ GdkWindowPrivate *private;
+ GdkWindow *window;
+ Window root;
+ Window xwindow;
+ Window xwindow_last = 0;
+ int rootx = -1, rooty = -1;
+ int winx, winy;
+ unsigned int xmask;
+
+ private = &gdk_root_parent;
+
+ xwindow = private->xwindow;
+
+ XGrabServer (private->xdisplay);
+ while (xwindow)
+ {
+ xwindow_last = xwindow;
+ XQueryPointer (private->xdisplay,
+ xwindow,
+ &root, &xwindow,
+ &rootx, &rooty,
+ &winx, &winy,
+ &xmask);
+ }
+ XUngrabServer (private->xdisplay);
+
+ window = gdk_window_lookup (xwindow_last);
+
+ if (win_x)
+ *win_x = window ? winx : -1;
+ if (win_y)
+ *win_y = window ? winy : -1;
+
+ return window;
+}
+
GdkWindow*
gdk_window_get_parent (GdkWindow *window)
{
children = g_list_prepend (children, child);
}
- XFree (xchildren);
+ if (xchildren)
+ XFree (xchildren);
}
return children;
&attrs);
event_mask = 0;
- for (i = 0; i < nevent_masks; i++)
+ for (i = 0; i < gdk_nevent_masks; i++)
{
- if (attrs.your_event_mask & event_mask_table[i])
+ if (attrs.your_event_mask & gdk_event_mask_table[i])
event_mask |= 1 << (i + 1);
}
return;
xevent_mask = StructureNotifyMask;
- for (i = 0; i < nevent_masks; i++)
+ for (i = 0; i < gdk_nevent_masks; i++)
{
if (event_mask & (1 << (i + 1)))
- xevent_mask |= event_mask_table[i];
+ xevent_mask |= gdk_event_mask_table[i];
}
XSelectInput (gdk_display, private->xwindow,
if (window_private->destroyed)
return;
+ old_windows = NULL;
if (!XGetWMColormapWindows (toplevel_private->xdisplay,
toplevel_private->xwindow,
&old_windows, &count))
{
- old_windows = NULL;
count = 0;
}
for (i = 0; i < count; i++)
if (old_windows[i] == window_private->xwindow)
- return;
+ {
+ XFree (old_windows);
+ return;
+ }
new_windows = g_new (Window, count + 1);
XFree (old_windows);
}
+static gboolean
+gdk_window_have_shape_ext (void)
+{
+ enum { UNKNOWN, NO, YES };
+ static gint have_shape = UNKNOWN;
+
+ if (have_shape == UNKNOWN)
+ {
+ int ignore;
+ if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
+ have_shape = YES;
+ else
+ have_shape = NO;
+ }
+
+ return (have_shape == YES);
+}
+
/*
* This needs the X11 shape extension.
- * If not available, simply remove the call to
- * XShapeCombineMask. Shaped windows will look
+ * If not available, shaped windows will look
* ugly, but programs still work. Stefan Wille
*/
void
g_return_if_fail (window != NULL);
- /* This is needed, according to raster */
- gdk_window_set_override_redirect(window, TRUE);
-
+#ifdef HAVE_SHAPE_EXT
window_private = (GdkWindowPrivate*) window;
if (window_private->destroyed)
return;
- if (mask)
+ if (gdk_window_have_shape_ext())
{
- GdkWindowPrivate *pixmap_private;
-
- pixmap_private = (GdkWindowPrivate*) mask;
- pixmap = (Pixmap) pixmap_private->xwindow;
- }
- else
- {
- x = 0;
- y = 0;
- pixmap = None;
- }
-
- XShapeCombineMask (window_private->xdisplay,
- window_private->xwindow,
- ShapeBounding,
- x, y,
- pixmap,
- ShapeSet);
-}
-
-void
-gdk_dnd_drag_addwindow (GdkWindow *window)
-{
- GdkWindowPrivate *window_private;
-
- g_return_if_fail (window != NULL);
-
- window_private = (GdkWindowPrivate *) window;
- if (window_private->destroyed)
- return;
-
- if (window_private->dnd_drag_enabled == 1 && gdk_dnd.drag_really == 0)
- {
- gdk_dnd.drag_numwindows++;
- gdk_dnd.drag_startwindows = g_realloc (gdk_dnd.drag_startwindows,
- gdk_dnd.drag_numwindows
- * sizeof(GdkWindow *));
- gdk_dnd.drag_startwindows[gdk_dnd.drag_numwindows - 1] = window;
- window_private->dnd_drag_accepted = 0;
- }
- else
- g_warning ("dnd_really is 1 or drag is not enabled! can't addwindow\n");
-}
-
-void
-gdk_window_dnd_drag_set (GdkWindow *window,
- guint8 drag_enable,
- gchar **typelist,
- guint numtypes)
-{
- GdkWindowPrivate *window_private;
- int i, wasset = 0;
-
- g_return_if_fail (window != NULL);
- window_private = (GdkWindowPrivate *) window;
- if (window_private->destroyed)
- return;
-
- window_private->dnd_drag_enabled = drag_enable ? 1 : 0;
-
- if (drag_enable)
- {
- g_return_if_fail(typelist != NULL);
-
- if (window_private->dnd_drag_data_numtypesavail > 3)
- wasset = 1;
- window_private->dnd_drag_data_numtypesavail = numtypes;
-
- window_private->dnd_drag_data_typesavail =
- g_realloc (window_private->dnd_drag_data_typesavail,
- (numtypes + 1) * sizeof (GdkAtom));
-
- for (i = 0; i < numtypes; i++)
+ if (mask)
{
- /* Allow blanket use of ALL to get anything... */
- if (strcmp (typelist[i], "ALL"))
- window_private->dnd_drag_data_typesavail[i] =
- gdk_atom_intern (typelist[i], FALSE);
- else
- window_private->dnd_drag_data_typesavail[i] = None;
+ GdkWindowPrivate *pixmap_private;
+
+ pixmap_private = (GdkWindowPrivate*) mask;
+ pixmap = (Pixmap) pixmap_private->xwindow;
+ }
+ else
+ {
+ x = 0;
+ y = 0;
+ pixmap = None;
}
- /*
- * set our extended type list if we need to
- */
- if (numtypes > 3)
- gdk_property_change(window, gdk_dnd.gdk_XdeTypelist,
- XA_PRIMARY, 32, GDK_PROP_MODE_REPLACE,
- (guchar *)(window_private->dnd_drag_data_typesavail
- + (sizeof(GdkAtom) * 3)),
- (numtypes - 3) * sizeof(GdkAtom));
- else if (wasset)
- gdk_property_delete (window, gdk_dnd.gdk_XdeTypelist);
- }
- else
- {
- g_free (window_private->dnd_drag_data_typesavail);
- window_private->dnd_drag_data_typesavail = NULL;
- window_private->dnd_drag_data_numtypesavail = 0;
- }
-}
-
-void
-gdk_window_dnd_drop_set (GdkWindow *window,
- guint8 drop_enable,
- gchar **typelist,
- guint numtypes,
- guint8 destructive_op)
-{
- GdkWindowPrivate *window_private;
- int i;
-
- g_return_if_fail (window != NULL);
- window_private = (GdkWindowPrivate *) window;
- if (window_private->destroyed)
- return;
-
- window_private->dnd_drop_enabled = drop_enable ? 1 : 0;
- if (drop_enable)
- {
- g_return_if_fail(typelist != NULL);
-
- window_private->dnd_drop_data_numtypesavail = numtypes;
-
- window_private->dnd_drop_data_typesavail =
- g_realloc (window_private->dnd_drop_data_typesavail,
- (numtypes + 1) * sizeof (GdkAtom));
-
- for (i = 0; i < numtypes; i++)
- window_private->dnd_drop_data_typesavail[i] =
- gdk_atom_intern (typelist[i], FALSE);
-
- window_private->dnd_drop_destructive_op = destructive_op;
+ XShapeCombineMask (window_private->xdisplay,
+ window_private->xwindow,
+ ShapeBounding,
+ x, y,
+ pixmap,
+ ShapeSet);
}
-}
-
-/*
- * This is used to reply to a GDK_DRAG_REQUEST event
- * (which may be generated by XdeRequest or a confirmed drop...
- */
-void
-gdk_window_dnd_data_set (GdkWindow *window,
- GdkEvent *event,
- gpointer data,
- gulong data_numbytes)
-{
- GdkWindowPrivate *window_private;
- XEvent sev;
- GdkEventDropDataAvailable tmp_ev;
- gchar *tmp;
-
- g_return_if_fail (window != NULL);
- g_return_if_fail (event != NULL);
- g_return_if_fail (data != NULL);
- g_return_if_fail (data_numbytes > 0);
- g_return_if_fail (event->type == GDK_DRAG_REQUEST);
-
- window_private = (GdkWindowPrivate *) window;
- g_return_if_fail (window_private->dnd_drag_accepted != 0);
- if (window_private->destroyed)
- return;
-
- /* We set the property on our window... */
- gdk_property_change (window, window_private->dnd_drag_data_type,
- XA_PRIMARY, 8, GDK_PROP_MODE_REPLACE, data,
- data_numbytes);
- tmp = gdk_atom_name(window_private->dnd_drag_data_type);
-#ifdef DEBUG_DND
- g_print("DnD type %s on window %ld\n", tmp, window_private->xwindow);
-#endif
- g_free(tmp);
-
- /*
- * Then we send the event to tell the receiving window that the
- * drop has happened
- */
- tmp_ev.u.allflags = 0;
- tmp_ev.u.flags.protocol_version = DND_PROTOCOL_VERSION;
- tmp_ev.u.flags.isdrop = event->dragrequest.isdrop;
-
- sev.xclient.type = ClientMessage;
- sev.xclient.format = 32;
- sev.xclient.window = event->dragrequest.requestor;
- sev.xclient.message_type = gdk_dnd.gdk_XdeDataAvailable;
- sev.xclient.data.l[0] = window_private->xwindow;
- sev.xclient.data.l[1] = tmp_ev.u.allflags;
- sev.xclient.data.l[2] = window_private->dnd_drag_data_type;
-
- if (event->dragrequest.isdrop)
- sev.xclient.data.l[3] = event->dragrequest.drop_coords.x +
- (event->dragrequest.drop_coords.y << 16);
- else
- sev.xclient.data.l[3] = 0;
-
- sev.xclient.data.l[4] = event->dragrequest.timestamp;
-
- if (!gdk_send_xevent (event->dragrequest.requestor, False,
- StructureNotifyMask, &sev))
- GDK_NOTE (DND, g_print("Sending XdeDataAvailable to %#x failed\n",
- event->dragrequest.requestor));
-
+#endif /* HAVE_SHAPE_EXT */
}
void
gpointer data)
{
GdkWindowPrivate *private;
- GList *tmp_list;
+ GList *tmp_list, *node;
GdkEventFilter *filter;
private = (GdkWindowPrivate*) window;
while (tmp_list)
{
filter = (GdkEventFilter *)tmp_list->data;
+ node = tmp_list;
tmp_list = tmp_list->next;
if ((filter->function == function) && (filter->data == data))
{
if(private)
- private->filters = g_list_remove_link (private->filters, tmp_list);
+ private->filters = g_list_remove_link (private->filters, node);
else
gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
- g_list_free_1 (tmp_list);
+ g_list_free_1 (node);
g_free (filter);
return;
XSetWMIconName (window_private->xdisplay, window_private->xwindow,
&property);
- XFree(property.value);
+ if (property.value)
+ XFree (property.value);
}
void
gdk_window_set_mwm_hints (window, &hints);
}
+
+GList *
+gdk_window_get_toplevels (void)
+{
+ GList *new_list = NULL;
+ GList *tmp_list;
+
+ tmp_list = gdk_root_parent.children;
+ while (tmp_list)
+ {
+ new_list = g_list_prepend (new_list, tmp_list->data);
+ tmp_list = tmp_list->next;
+ }
+
+ return new_list;
+}
+
+/*
+ * propagate the shapes from all child windows of a GDK window to the parent
+ * window. Shamelessly ripped from Enlightenment's code
+ *
+ * - Raster
+ */
+
+struct _gdk_span
+{
+ gint start;
+ gint end;
+ struct _gdk_span *next;
+};
+
+static void
+gdk_add_to_span(struct _gdk_span **s, int x, int xx)
+{
+ struct _gdk_span *ptr1, *ptr2, *noo, *ss;
+ gchar spanning;
+
+ ptr2 = NULL;
+ ptr1 = *s;
+ spanning = 0;
+ ss = NULL;
+ /* scan the spans for this line */
+ while (ptr1)
+ {
+ /* -- -> new span */
+ /* == -> existing span */
+ /* ## -> spans intersect */
+ /* if we are in the middle of spanning the span into the line */
+ if (spanning)
+ {
+ /* case: ---- ==== */
+ if (xx < ptr1->start - 1)
+ {
+ /* ends before next span - extend to here */
+ ss->end = xx;
+ return;
+ }
+ /* case: ----##=== */
+ else if (xx <= ptr1->end)
+ {
+ /* crosses into next span - delete next span and append */
+ ss->end = ptr1->end;
+ ss->next = ptr1->next;
+ g_free(ptr1);
+ return;
+ }
+ /* case: ---###--- */
+ else
+ {
+ /* overlaps next span - delete and keep checking */
+ ss->next = ptr1->next;
+ g_free(ptr1);
+ ptr1 = ss;
+ }
+ }
+ /* otherwise havent started spanning it in yet */
+ else
+ {
+ /* case: ---- ==== */
+ if (xx < ptr1->start - 1)
+ {
+ /* insert span here in list */
+ noo = g_malloc(sizeof(struct _gdk_span));
+
+ if (noo)
+ {
+ noo->start = x;
+ noo->end = xx;
+ noo->next = ptr1;
+ if (ptr2)
+ ptr2->next = noo;
+ else
+ *s = noo;
+ }
+ return;
+ }
+ /* case: ----##=== */
+ else if ((x < ptr1->start) && (xx <= ptr1->end))
+ {
+ /* expand this span to the left point of the new one */
+ ptr1->start = x;
+ return;
+ }
+ /* case: ===###=== */
+ else if ((x >= ptr1->start) && (xx <= ptr1->end))
+ {
+ /* throw the span away */
+ return;
+ }
+ /* case: ---###--- */
+ else if ((x < ptr1->start) && (xx > ptr1->end))
+ {
+ ss = ptr1;
+ spanning = 1;
+ ptr1->start = x;
+ ptr1->end = xx;
+ }
+ /* case: ===##---- */
+ else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
+ {
+ ss = ptr1;
+ spanning = 1;
+ ptr1->end = xx;
+ }
+ /* case: ==== ---- */
+ /* case handled by next loop iteration - first case */
+ }
+ ptr2 = ptr1;
+ ptr1 = ptr1->next;
+ }
+ /* it started in the middle but spans beyond your current list */
+ if (spanning)
+ {
+ ptr2->end = xx;
+ return;
+ }
+ /* it does not start inside a span or in the middle, so add it to the end */
+ noo = g_malloc(sizeof(struct _gdk_span));
+
+ if (noo)
+ {
+ noo->start = x;
+ noo->end = xx;
+ if (ptr2)
+ {
+ noo->next = ptr2->next;
+ ptr2->next = noo;
+ }
+ else
+ {
+ noo->next = NULL;
+ *s = noo;
+ }
+ }
+ return;
+}
+
+static void
+gdk_add_rectangles (Display *disp, Window win, struct _gdk_span **spans,
+ gint basew, gint baseh, gint x, gint y)
+{
+ gint a, k;
+ gint x1, y1, x2, y2;
+ gint rn, ord;
+ XRectangle *rl;
+
+ rl = XShapeGetRectangles(disp, win, ShapeBounding, &rn, &ord);
+ if (rl)
+ {
+ /* go through all clip rects in this window's shape */
+ for (k = 0; k < rn; k++)
+ {
+ /* for each clip rect, add it to each line's spans */
+ x1 = x + rl[k].x;
+ x2 = x + rl[k].x + (rl[k].width - 1);
+ y1 = y + rl[k].y;
+ y2 = y + rl[k].y + (rl[k].height - 1);
+ if (x1 < 0)
+ x1 = 0;
+ if (y1 < 0)
+ y1 = 0;
+ if (x2 >= basew)
+ x2 = basew - 1;
+ if (y2 >= baseh)
+ y2 = baseh - 1;
+ for (a = y1; a <= y2; a++)
+ {
+ if ((x2 - x1) >= 0)
+ gdk_add_to_span(&spans[a], x1, x2);
+ }
+ }
+ XFree(rl);
+ }
+}
+
+static void
+gdk_propagate_shapes(Display *disp, Window win, gboolean merge)
+{
+ Window rt, par, *list = NULL;
+ gint i, j, num = 0, num_rects = 0;
+ gint x, y, contig;
+ guint w, h, d;
+ gint baseh, basew;
+ XRectangle *rects = NULL;
+ struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
+ XWindowAttributes xatt;
+
+ XGetGeometry(disp, win, &rt, &x, &y, &w, &h, &d, &d);
+ if (h <= 0)
+ return;
+ basew = w;
+ baseh = h;
+ spans = g_malloc(sizeof(struct _gdk_span *) * h);
+
+ for (i = 0; i < h; i++)
+ spans[i] = NULL;
+ XQueryTree(disp, win, &rt, &par, &list, (unsigned int *)&num);
+ if (list)
+ {
+ /* go through all child windows and create/insert spans */
+ for (i = 0; i < num; i++)
+ {
+ if (XGetWindowAttributes(disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
+ if (XGetGeometry(disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
+ gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
+ }
+ if (merge)
+ gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
+
+ /* go through the spans list and build a list of rects */
+ rects = g_malloc(sizeof(XRectangle) * 256);
+ num_rects = 0;
+ for (i = 0; i < baseh; i++)
+ {
+ ptr1 = spans[i];
+ /* go through the line for all spans */
+ while (ptr1)
+ {
+ rects[num_rects].x = ptr1->start;
+ rects[num_rects].y = i;
+ rects[num_rects].width = ptr1->end - ptr1->start + 1;
+ rects[num_rects].height = 1;
+ j = i + 1;
+ /* if there are more lines */
+ contig = 1;
+ /* while contigous rects (same start/end coords) exist */
+ while ((contig) && (j < baseh))
+ {
+ /* search next line for spans matching this one */
+ contig = 0;
+ ptr2 = spans[j];
+ ptr3 = NULL;
+ while (ptr2)
+ {
+ /* if we have an exact span match set contig */
+ if ((ptr2->start == ptr1->start) &&
+ (ptr2->end == ptr1->end))
+ {
+ contig = 1;
+ /* remove the span - not needed */
+ if (ptr3)
+ {
+ ptr3->next = ptr2->next;
+ g_free(ptr2);
+ ptr2 = NULL;
+ }
+ else
+ {
+ spans[j] = ptr2->next;
+ g_free(ptr2);
+ ptr2 = NULL;
+ }
+ break;
+ }
+ /* gone past the span point no point looking */
+ else if (ptr2->start < ptr1->start)
+ break;
+ if (ptr2)
+ {
+ ptr3 = ptr2;
+ ptr2 = ptr2->next;
+ }
+ }
+ /* if a contiguous span was found increase the rect h */
+ if (contig)
+ {
+ rects[num_rects].height++;
+ j++;
+ }
+ }
+ /* up the rect count */
+ num_rects++;
+ /* every 256 new rects increase the rect array */
+ if ((num_rects % 256) == 0)
+ rects = g_realloc(rects, sizeof(XRectangle) * (num_rects + 256));
+ ptr1 = ptr1->next;
+ }
+ }
+ /* set the rects as the shape mask */
+ if (rects)
+ {
+ XShapeCombineRectangles(disp, win, ShapeBounding, 0, 0, rects, num_rects,
+ ShapeSet, YXSorted);
+ g_free(rects);
+ }
+ XFree(list);
+ }
+ /* free up all the spans we made */
+ for (i = 0; i < baseh; i++)
+ {
+ ptr1 = spans[i];
+ while (ptr1)
+ {
+ ptr2 = ptr1;
+ ptr1 = ptr1->next;
+ g_free(ptr2);
+ }
+ }
+ g_free(spans);
+}
+
+void
+gdk_window_set_child_shapes (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+#ifdef HAVE_SHAPE_EXT
+ private = (GdkWindowPrivate*) window;
+ if (private->destroyed)
+ return;
+
+ if (gdk_window_have_shape_ext())
+ gdk_propagate_shapes (private->xdisplay, private->xwindow, FALSE);
+#endif
+}
+
+void
+gdk_window_merge_child_shapes (GdkWindow *window)
+{
+ GdkWindowPrivate *private;
+
+ g_return_if_fail (window != NULL);
+
+#ifdef HAVE_SHAPE_EXT
+ private = (GdkWindowPrivate*) window;
+ if (private->destroyed)
+ return;
+
+ if (gdk_window_have_shape_ext())
+ gdk_propagate_shapes (private->xdisplay, private->xwindow, TRUE);
+#endif
+}
+
+/*************************************************************
+ * gdk_window_is_visible:
+ * Check if the given window is mapped.
+ * arguments:
+ * window:
+ * results:
+ * is the window mapped
+ *************************************************************/
+
+gboolean
+gdk_window_is_visible (GdkWindow *window)
+{
+ GdkWindowPrivate *private = (GdkWindowPrivate *)window;
+
+ g_return_val_if_fail (window != NULL, FALSE);
+
+ return private->mapped;
+}
+
+/*************************************************************
+ * gdk_window_is_viewable:
+ * Check if the window and all ancestors of the window
+ * are mapped. (This is not necessarily "viewable" in
+ * the X sense, since we only check as far as we have
+ * GDK window parents, not to the root window)
+ * arguments:
+ * window:
+ * results:
+ * is the window viewable
+ *************************************************************/
+
+gboolean
+gdk_window_is_viewable (GdkWindow *window)
+{
+ GdkWindowPrivate *private = (GdkWindowPrivate *)window;
+
+ g_return_val_if_fail (window != NULL, FALSE);
+
+ while (private && (private != &gdk_root_parent))
+ {
+ if (!private->mapped)
+ return FALSE;
+
+ private = (GdkWindowPrivate *)private->parent;
+ }
+
+ return TRUE;
+}
+
+void
+gdk_drawable_set_data (GdkDrawable *drawable,
+ const gchar *key,
+ gpointer data,
+ GDestroyNotify destroy_func)
+{
+ g_dataset_set_data_full (drawable, key, data, destroy_func);
+}
+
+