summaryrefslogtreecommitdiff
path: root/gdk/gdkwindow.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdk/gdkwindow.c')
-rw-r--r--gdk/gdkwindow.c193
1 files changed, 135 insertions, 58 deletions
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 4edb1ead66..21b10590d0 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -20,7 +20,6 @@
#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"
@@ -30,6 +29,10 @@
#include <stdlib.h>
#include <stdio.h>
+#ifdef HAVE_SHAPE_EXT
+#include <X11/extensions/shape.h>
+#endif
+
int nevent_masks = 17;
int event_mask_table[19] =
{
@@ -65,18 +68,18 @@ gdk_window_xid_at(Window base, gint bx, gint by, gint x, gint y,
Display *disp;
Window *list=NULL;
Window child=0,parent_win=0,root_win=0;
+
int i;
- guint num;
+ unsigned int ww, wh, wb, wd, num;
int wx,wy;
- guint 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))))
+ 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))
return base;
@@ -172,7 +175,7 @@ gdk_window_xid_at_coords(gint x, gint y, GList *excludes, gboolean excl_child)
}
void
-gdk_window_init ()
+gdk_window_init (void)
{
XWindowAttributes xattributes;
unsigned int width;
@@ -191,6 +194,8 @@ gdk_window_init ()
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;
}
GdkWindow*
@@ -202,7 +207,6 @@ gdk_window_new (GdkWindow *parent,
GdkWindowPrivate *private;
GdkWindowPrivate *parent_private;
GdkVisual *visual;
- GdkColormap *colormap;
Display *parent_display;
Window xparent;
Visual *xvisual;
@@ -232,6 +236,10 @@ gdk_window_new (GdkWindow *parent,
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->resize_count = 0;
@@ -264,6 +272,7 @@ gdk_window_new (GdkWindow *parent,
private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
private->filters = NULL;
+ private->children = NULL;
window->user_data = NULL;
@@ -296,9 +305,9 @@ gdk_window_new (GdkWindow *parent,
depth = visual->depth;
if (attributes_mask & GDK_WA_COLORMAP)
- colormap = attributes->colormap;
+ private->colormap = attributes->colormap;
else
- colormap = gdk_colormap_get_system ();
+ private->colormap = gdk_colormap_get_system ();
xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
@@ -307,26 +316,26 @@ gdk_window_new (GdkWindow *parent,
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;
@@ -348,7 +357,7 @@ gdk_window_new (GdkWindow *parent,
{
depth = 0;
class = InputOnly;
- colormap = NULL;
+ private->colormap = NULL;
}
private->xwindow = XCreateWindow (private->xdisplay, xparent,
@@ -358,6 +367,9 @@ gdk_window_new (GdkWindow *parent,
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));
@@ -372,8 +384,8 @@ gdk_window_new (GdkWindow *parent,
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_window_add_colormap_windows (window);
@@ -430,6 +442,7 @@ gdk_window_foreign_new (guint32 anid)
{
GdkWindow *window;
GdkWindowPrivate *private;
+ GdkWindowPrivate *parent_private;
XWindowAttributes attrs;
Window root, parent;
Window *children;
@@ -446,6 +459,11 @@ gdk_window_foreign_new (guint32 anid)
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;
@@ -458,6 +476,7 @@ gdk_window_foreign_new (guint32 anid)
private->destroyed = FALSE;
private->extension_events = 0;
+ private->colormap = NULL;
private->dnd_drag_data_type = None;
private->dnd_drag_data_typesavail =
@@ -469,6 +488,7 @@ gdk_window_foreign_new (guint32 anid)
private->dnd_drag_eventmask = private->dnd_drag_savedeventmask = 0;
private->filters = NULL;
+ private->children = NULL;
window->user_data = NULL;
@@ -507,10 +527,17 @@ gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
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)
{
@@ -522,7 +549,7 @@ gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
gdk_window_internal_destroy (temp_window, FALSE,
our_destroy);
}
-
+
g_list_free (children);
}
@@ -581,6 +608,9 @@ gdk_window_internal_destroy (GdkWindow *window, gboolean xdestroy,
else if (xdestroy)
XDestroyWindow (private->xdisplay, private->xwindow);
+ if (private->colormap)
+ gdk_colormap_unref (private->colormap);
+
private->destroyed = TRUE;
}
break;
@@ -1059,6 +1089,11 @@ gdk_window_set_colormap (GdkWindow *window,
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);
@@ -1153,20 +1188,27 @@ gdk_window_get_visual (GdkWindow *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;
@@ -1179,16 +1221,20 @@ gdk_window_get_colormap (GdkWindow *window)
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;
@@ -1436,8 +1482,7 @@ gdk_window_add_colormap_windows (GdkWindow *window)
/*
* 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
@@ -1445,38 +1490,53 @@ gdk_window_shape_combine_mask (GdkWindow *window,
GdkBitmap *mask,
gint x, gint y)
{
+ enum { UNKNOWN, NO, YES };
+
+ static gint have_shape = UNKNOWN;
+
GdkWindowPrivate *window_private;
Pixmap pixmap;
g_return_if_fail (window != NULL);
- /* This is needed, according to raster */
- gdk_window_set_override_redirect(window, TRUE);
-
- window_private = (GdkWindowPrivate*) window;
- if (window_private->destroyed)
- return;
-
- if (mask)
+#ifdef HAVE_SHAPE_EXT
+ if (have_shape == UNKNOWN)
{
- GdkWindowPrivate *pixmap_private;
-
- pixmap_private = (GdkWindowPrivate*) mask;
- pixmap = (Pixmap) pixmap_private->xwindow;
+ int ignore;
+ if (XQueryExtension(gdk_display, "SHAPE", &ignore, &ignore, &ignore))
+ have_shape = YES;
+ else
+ have_shape = NO;
}
- else
+
+ if (have_shape == YES)
{
- x = 0;
- y = 0;
- pixmap = None;
+ window_private = (GdkWindowPrivate*) window;
+ if (window_private->destroyed)
+ return;
+
+ if (mask)
+ {
+ 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);
}
-
- XShapeCombineMask (window_private->xdisplay,
- window_private->xwindow,
- ShapeBounding,
- x, y,
- pixmap,
- ShapeSet);
+#endif /* HAVE_SHAPE_EXT */
}
void
@@ -1915,3 +1975,20 @@ gdk_window_set_functions (GdkWindow *window,
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;
+}
+