1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
28 #include <X11/Xutil.h>
29 #include <X11/Xatom.h>
30 #include <netinet/in.h>
34 #include "gdkwindow.h"
35 #include "gdkinputprivate.h"
36 #include "gdkprivate-x11.h"
37 #include "gdkregion.h"
38 #include "gdkinternals.h"
40 #include "gdkwindow-x11.h"
48 #include <X11/extensions/shape.h>
51 const int gdk_event_mask_table[21] =
55 PointerMotionHintMask,
72 SubstructureNotifyMask,
73 ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */
75 const int gdk_nevent_masks = sizeof (gdk_event_mask_table) / sizeof (int);
77 /* Forward declarations */
78 static gboolean gdk_window_gravity_works (void);
79 static void gdk_window_set_static_win_gravity (GdkWindow *window,
81 static gboolean gdk_window_have_shape_ext (void);
82 static gboolean gdk_window_icon_name_set (GdkWindow *window);
84 static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable *drawable);
85 static void gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
87 static void gdk_window_impl_x11_get_size (GdkDrawable *drawable,
90 static GdkRegion* gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable);
91 static void gdk_window_impl_x11_init (GdkWindowImplX11 *window);
92 static void gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass);
93 static void gdk_window_impl_x11_finalize (GObject *object);
95 static gpointer parent_class = NULL;
98 gdk_window_impl_x11_get_type (void)
100 static GType object_type = 0;
104 static const GTypeInfo object_info =
106 sizeof (GdkWindowImplX11Class),
107 (GBaseInitFunc) NULL,
108 (GBaseFinalizeFunc) NULL,
109 (GClassInitFunc) gdk_window_impl_x11_class_init,
110 NULL, /* class_finalize */
111 NULL, /* class_data */
112 sizeof (GdkWindowImplX11),
114 (GInstanceInitFunc) gdk_window_impl_x11_init,
117 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_X11,
126 _gdk_window_impl_get_type (void)
128 return gdk_window_impl_x11_get_type ();
132 gdk_window_impl_x11_init (GdkWindowImplX11 *impl)
139 gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
141 GObjectClass *object_class = G_OBJECT_CLASS (klass);
142 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
144 parent_class = g_type_class_peek_parent (klass);
146 object_class->finalize = gdk_window_impl_x11_finalize;
148 drawable_class->set_colormap = gdk_window_impl_x11_set_colormap;
149 drawable_class->get_colormap = gdk_window_impl_x11_get_colormap;
150 drawable_class->get_size = gdk_window_impl_x11_get_size;
152 /* Visible and clip regions are the same */
153 drawable_class->get_clip_region = gdk_window_impl_x11_get_visible_region;
154 drawable_class->get_visible_region = gdk_window_impl_x11_get_visible_region;
158 gdk_window_impl_x11_finalize (GObject *object)
160 GdkWindowObject *wrapper;
161 GdkDrawableImplX11 *draw_impl;
162 GdkWindowImplX11 *window_impl;
164 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (object));
166 draw_impl = GDK_DRAWABLE_IMPL_X11 (object);
167 window_impl = GDK_WINDOW_IMPL_X11 (object);
169 wrapper = (GdkWindowObject*) draw_impl->wrapper;
171 if (!GDK_WINDOW_DESTROYED (wrapper))
173 gdk_xid_table_remove (draw_impl->xid);
176 G_OBJECT_CLASS (parent_class)->finalize (object);
180 gdk_window_impl_x11_get_colormap (GdkDrawable *drawable)
182 GdkDrawableImplX11 *drawable_impl;
183 GdkWindowImplX11 *window_impl;
185 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable), NULL);
187 drawable_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
188 window_impl = GDK_WINDOW_IMPL_X11 (drawable);
190 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
191 drawable_impl->colormap == NULL)
193 XWindowAttributes window_attributes;
195 XGetWindowAttributes (drawable_impl->xdisplay,
198 drawable_impl->colormap =
199 gdk_colormap_lookup (window_attributes.colormap);
202 return drawable_impl->colormap;
206 gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
209 GdkWindowImplX11 *impl;
210 GdkDrawableImplX11 *draw_impl;
212 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
214 impl = GDK_WINDOW_IMPL_X11 (drawable);
215 draw_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
218 GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
222 XSetWindowColormap (draw_impl->xdisplay,
224 GDK_COLORMAP_XCOLORMAP (cmap));
226 if (((GdkWindowObject*)draw_impl->wrapper)->window_type !=
228 gdk_window_add_colormap_windows (GDK_WINDOW (draw_impl->wrapper));
234 gdk_window_impl_x11_get_size (GdkDrawable *drawable,
238 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
241 *width = GDK_WINDOW_IMPL_X11 (drawable)->width;
243 *height = GDK_WINDOW_IMPL_X11 (drawable)->height;
247 gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable)
249 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (drawable);
250 GdkRectangle result_rect;
254 result_rect.width = impl->width;
255 result_rect.height = impl->height;
257 gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
259 return gdk_region_rectangle (&result_rect);
263 _gdk_windowing_window_init (void)
265 GdkWindowObject *private;
266 GdkWindowImplX11 *impl;
267 GdkDrawableImplX11 *draw_impl;
268 XWindowAttributes xattributes;
271 unsigned int border_width;
275 g_assert (gdk_parent_root == NULL);
277 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
278 &x, &y, &width, &height, &border_width, &depth);
279 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
281 gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
282 private = (GdkWindowObject *)gdk_parent_root;
283 impl = GDK_WINDOW_IMPL_X11 (private->impl);
284 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
286 draw_impl->xdisplay = gdk_display;
287 draw_impl->xid = gdk_root_window;
288 draw_impl->wrapper = GDK_DRAWABLE (private);
290 private->window_type = GDK_WINDOW_ROOT;
291 private->depth = depth;
293 impl->height = height;
295 gdk_xid_table_insert (&gdk_root_window, gdk_parent_root);
298 static GdkAtom wm_client_leader_atom = GDK_NONE;
301 gdk_window_new (GdkWindow *parent,
302 GdkWindowAttr *attributes,
303 gint attributes_mask)
306 GdkWindowObject *private;
307 GdkWindowObject *parent_private;
308 GdkWindowImplX11 *impl;
309 GdkDrawableImplX11 *draw_impl;
315 XSetWindowAttributes xattributes;
316 long xattributes_mask;
317 XSizeHints size_hints;
319 XClassHint *class_hint;
326 g_return_val_if_fail (attributes != NULL, NULL);
329 parent = gdk_parent_root;
331 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
333 parent_private = (GdkWindowObject*) parent;
334 if (GDK_WINDOW_DESTROYED (parent))
337 xparent = GDK_WINDOW_XID (parent);
339 window = g_object_new (GDK_TYPE_WINDOW, NULL);
340 private = (GdkWindowObject *)window;
341 impl = GDK_WINDOW_IMPL_X11 (private->impl);
342 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
343 draw_impl->wrapper = GDK_DRAWABLE (window);
345 draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (parent);
347 private->parent = (GdkWindowObject *)parent;
349 xattributes_mask = 0;
351 if (attributes_mask & GDK_WA_X)
356 if (attributes_mask & GDK_WA_Y)
363 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
364 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
365 private->window_type = attributes->window_type;
367 _gdk_window_init_position (GDK_WINDOW (private));
368 if (impl->position_info.big)
369 private->guffaw_gravity = TRUE;
371 if (attributes_mask & GDK_WA_VISUAL)
372 visual = attributes->visual;
374 visual = gdk_visual_get_system ();
375 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
377 xattributes.event_mask = StructureNotifyMask;
378 for (i = 0; i < gdk_nevent_masks; i++)
380 if (attributes->event_mask & (1 << (i + 1)))
381 xattributes.event_mask |= gdk_event_mask_table[i];
384 if (xattributes.event_mask)
385 xattributes_mask |= CWEventMask;
387 if (attributes_mask & GDK_WA_NOREDIR)
389 xattributes.override_redirect =
390 (attributes->override_redirect == FALSE)?False:True;
391 xattributes_mask |= CWOverrideRedirect;
394 xattributes.override_redirect = False;
396 if (parent_private && parent_private->guffaw_gravity)
398 xattributes.win_gravity = StaticGravity;
399 xattributes_mask |= CWWinGravity;
402 if (attributes->wclass == GDK_INPUT_OUTPUT)
405 depth = visual->depth;
407 private->input_only = FALSE;
408 private->depth = depth;
410 if (attributes_mask & GDK_WA_COLORMAP)
412 draw_impl->colormap = attributes->colormap;
413 gdk_colormap_ref (attributes->colormap);
417 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
419 draw_impl->colormap =
420 gdk_colormap_get_system ();
421 gdk_colormap_ref (draw_impl->colormap);
425 draw_impl->colormap =
426 gdk_colormap_new (visual, FALSE);
430 private->bg_color.pixel = BlackPixel (gdk_display, gdk_screen);
431 xattributes.background_pixel = private->bg_color.pixel;
433 private->bg_pixmap = NULL;
435 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
436 xattributes_mask |= CWBorderPixel | CWBackPixel;
438 if (private->guffaw_gravity)
439 xattributes.bit_gravity = StaticGravity;
441 xattributes.bit_gravity = NorthWestGravity;
443 xattributes_mask |= CWBitGravity;
445 switch (private->window_type)
447 case GDK_WINDOW_TOPLEVEL:
448 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
449 xattributes_mask |= CWColormap;
451 xparent = gdk_root_window;
454 case GDK_WINDOW_CHILD:
455 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
456 xattributes_mask |= CWColormap;
459 case GDK_WINDOW_DIALOG:
460 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
461 xattributes_mask |= CWColormap;
463 xparent = gdk_root_window;
466 case GDK_WINDOW_TEMP:
467 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
468 xattributes_mask |= CWColormap;
470 xparent = gdk_root_window;
472 xattributes.save_under = True;
473 xattributes.override_redirect = True;
474 xattributes.cursor = None;
475 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
477 case GDK_WINDOW_ROOT:
478 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
487 private->input_only = TRUE;
488 draw_impl->colormap = gdk_colormap_get_system ();
489 gdk_colormap_ref (draw_impl->colormap);
492 draw_impl->xid = XCreateWindow (GDK_WINDOW_XDISPLAY (parent),
494 impl->position_info.x, impl->position_info.y,
495 impl->position_info.width, impl->position_info.height,
496 0, depth, class, xvisual,
497 xattributes_mask, &xattributes);
499 gdk_drawable_ref (window);
500 gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
502 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
503 (attributes->cursor) :
507 parent_private->children = g_list_prepend (parent_private->children, window);
509 switch (GDK_WINDOW_TYPE (private))
511 case GDK_WINDOW_DIALOG:
512 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
513 GDK_WINDOW_XID (window),
515 case GDK_WINDOW_TOPLEVEL:
516 case GDK_WINDOW_TEMP:
517 XSetWMProtocols (GDK_WINDOW_XDISPLAY (window),
518 GDK_WINDOW_XID (window),
519 gdk_wm_window_protocols, 3);
521 case GDK_WINDOW_CHILD:
522 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
523 (draw_impl->colormap != gdk_colormap_get_system ()) &&
524 (draw_impl->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
526 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
527 gdk_window_add_colormap_windows (window);
536 size_hints.flags = PSize;
537 size_hints.width = impl->width;
538 size_hints.height = impl->height;
540 wm_hints.flags = InputHint | StateHint | WindowGroupHint;
541 wm_hints.window_group = gdk_leader_window;
542 wm_hints.input = True;
543 wm_hints.initial_state = NormalState;
545 /* FIXME: Is there any point in doing this? Do any WM's pay
546 * attention to PSize, and even if they do, is this the
549 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
550 GDK_WINDOW_XID (window),
553 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
554 GDK_WINDOW_XID (window),
557 if (!wm_client_leader_atom)
558 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
560 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
561 GDK_WINDOW_XID (window),
562 wm_client_leader_atom,
563 XA_WINDOW, 32, PropModeReplace,
564 (guchar*) &gdk_leader_window, 1);
566 if (attributes_mask & GDK_WA_TITLE)
567 title = attributes->title;
569 title = g_get_prgname ();
571 gdk_window_set_title (window, title);
573 if (attributes_mask & GDK_WA_WMCLASS)
575 class_hint = XAllocClassHint ();
576 class_hint->res_name = attributes->wmclass_name;
577 class_hint->res_class = attributes->wmclass_class;
578 XSetClassHint (GDK_WINDOW_XDISPLAY (window),
579 GDK_WINDOW_XID (window),
588 gdk_window_foreign_new (GdkNativeWindow anid)
591 GdkWindowObject *private;
592 GdkWindowObject *parent_private;
593 GdkWindowImplX11 *impl;
594 GdkDrawableImplX11 *draw_impl;
595 XWindowAttributes attrs;
597 Window *children = NULL;
601 gdk_error_trap_push ();
602 result = XGetWindowAttributes (gdk_display, anid, &attrs);
603 if (gdk_error_trap_pop () || !result)
606 /* FIXME: This is pretty expensive. Maybe the caller should supply
608 gdk_error_trap_push ();
609 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
610 if (gdk_error_trap_pop () || !result)
616 window = g_object_new (GDK_TYPE_WINDOW, NULL);
617 private = (GdkWindowObject *)window;
618 impl = GDK_WINDOW_IMPL_X11 (private->impl);
619 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
620 draw_impl->wrapper = GDK_DRAWABLE (window);
622 private->parent = gdk_xid_table_lookup (parent);
624 parent_private = (GdkWindowObject *)private->parent;
627 parent_private->children = g_list_prepend (parent_private->children, window);
629 draw_impl->xid = anid;
630 draw_impl->xdisplay = gdk_display;
632 private->x = attrs.x;
633 private->y = attrs.y;
634 impl->width = attrs.width;
635 impl->height = attrs.height;
636 private->window_type = GDK_WINDOW_FOREIGN;
637 private->destroyed = FALSE;
639 if (attrs.map_state == IsUnmapped)
640 private->state = GDK_WINDOW_STATE_WITHDRAWN;
644 private->depth = attrs.depth;
646 gdk_drawable_ref (window);
647 gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
653 _gdk_windowing_window_destroy (GdkWindow *window,
655 gboolean foreign_destroy)
657 GdkWindowObject *private = (GdkWindowObject *)window;
659 g_return_if_fail (GDK_IS_WINDOW (window));
661 _gdk_selection_window_destroyed (window);
663 if (private->extension_events != 0)
664 gdk_input_window_destroy (window);
666 if (private->window_type == GDK_WINDOW_FOREIGN)
668 if (!foreign_destroy && (private->parent != NULL))
670 /* It's somebody else's window, but in our heirarchy,
671 * so reparent it to the root window, and then send
672 * it a delete event, as if we were a WM
674 XClientMessageEvent xevent;
676 gdk_error_trap_push ();
677 gdk_window_hide (window);
678 gdk_window_reparent (window, NULL, 0, 0);
680 xevent.type = ClientMessage;
681 xevent.window = GDK_WINDOW_XID (window);
682 xevent.message_type = gdk_wm_protocols;
684 xevent.data.l[0] = gdk_wm_delete_window;
685 xevent.data.l[1] = CurrentTime;
687 XSendEvent (GDK_WINDOW_XDISPLAY (window),
688 GDK_WINDOW_XID (window),
689 False, 0, (XEvent *)&xevent);
691 gdk_error_trap_pop ();
694 else if (!recursing && !foreign_destroy)
695 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
698 /* This function is called when the XWindow is really gone.
701 gdk_window_destroy_notify (GdkWindow *window)
703 g_return_if_fail (window != NULL);
705 if (!GDK_WINDOW_DESTROYED (window))
707 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
708 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_WINDOW_XID (window));
710 _gdk_window_destroy (window, TRUE);
713 gdk_xid_table_remove (GDK_WINDOW_XID (window));
714 gdk_drawable_unref (window);
718 set_initial_hints (GdkWindow *window)
720 GdkWindowObject *private;
724 private = (GdkWindowObject*) window;
726 if (private->state & GDK_WINDOW_STATE_ICONIFIED)
730 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
731 GDK_WINDOW_XID (window));
733 wm_hints = XAllocWMHints ();
735 wm_hints->flags |= StateHint;
736 wm_hints->initial_state = IconicState;
738 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
739 GDK_WINDOW_XID (window), wm_hints);
743 /* We set the spec hints regardless of whether the spec is supported,
744 * since it can't hurt and it's kind of expensive to check whether
750 if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
752 atoms[i] = gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE);
754 atoms[i] = gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE);
758 if (private->state & GDK_WINDOW_STATE_STICKY)
760 atoms[i] = gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE);
764 if (private->modal_hint)
766 atoms[i] = gdk_atom_intern ("_NET_WM_STATE_MODAL", FALSE);
772 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
773 GDK_WINDOW_XID (window),
774 gdk_atom_intern ("_NET_WM_STATE", FALSE),
775 XA_ATOM, 32, PropModeReplace,
779 if (private->state & GDK_WINDOW_STATE_STICKY)
781 atoms[0] = 0xFFFFFFFF;
782 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
783 GDK_WINDOW_XID (window),
784 gdk_atom_intern ("_NET_WM_DESKTOP", FALSE),
785 XA_CARDINAL, 32, PropModeReplace,
791 gdk_window_show (GdkWindow *window)
793 GdkWindowObject *private;
795 g_return_if_fail (GDK_IS_WINDOW (window));
797 private = (GdkWindowObject*) window;
798 if (!private->destroyed)
800 XRaiseWindow (GDK_WINDOW_XDISPLAY (window),
801 GDK_WINDOW_XID (window));
803 if (!GDK_WINDOW_IS_MAPPED (window))
805 set_initial_hints (window);
807 gdk_synthesize_window_state (window,
808 GDK_WINDOW_STATE_WITHDRAWN,
812 g_assert (GDK_WINDOW_IS_MAPPED (window));
814 if (GDK_WINDOW_IMPL_X11 (private->impl)->position_info.mapped)
815 XMapWindow (GDK_WINDOW_XDISPLAY (window),
816 GDK_WINDOW_XID (window));
821 gdk_window_hide (GdkWindow *window)
823 GdkWindowObject *private;
825 g_return_if_fail (window != NULL);
827 private = (GdkWindowObject*) window;
829 /* You can't simply unmap toplevel windows. */
830 switch (private->window_type)
832 case GDK_WINDOW_TOPLEVEL:
833 case GDK_WINDOW_DIALOG:
834 case GDK_WINDOW_TEMP: /* ? */
835 gdk_window_withdraw (window);
839 case GDK_WINDOW_FOREIGN:
840 case GDK_WINDOW_ROOT:
841 case GDK_WINDOW_CHILD:
845 if (!private->destroyed)
847 if (GDK_WINDOW_IS_MAPPED (window))
848 gdk_synthesize_window_state (window,
850 GDK_WINDOW_STATE_WITHDRAWN);
852 g_assert (!GDK_WINDOW_IS_MAPPED (window));
854 _gdk_window_clear_update_area (window);
856 XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
857 GDK_WINDOW_XID (window));
862 gdk_window_withdraw (GdkWindow *window)
864 GdkWindowObject *private;
866 g_return_if_fail (window != NULL);
868 private = (GdkWindowObject*) window;
869 if (!private->destroyed)
871 if (GDK_WINDOW_IS_MAPPED (window))
872 gdk_synthesize_window_state (window,
874 GDK_WINDOW_STATE_WITHDRAWN);
876 g_assert (!GDK_WINDOW_IS_MAPPED (window));
878 XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
879 GDK_WINDOW_XID (window), 0);
884 gdk_window_move (GdkWindow *window,
888 GdkWindowObject *private = (GdkWindowObject *)window;
889 GdkWindowImplX11 *impl;
891 g_return_if_fail (window != NULL);
892 g_return_if_fail (GDK_IS_WINDOW (window));
894 impl = GDK_WINDOW_IMPL_X11 (private->impl);
896 if (!GDK_WINDOW_DESTROYED (window))
898 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
899 _gdk_window_move_resize_child (window, x, y,
900 impl->width, impl->height);
903 XMoveWindow (GDK_WINDOW_XDISPLAY (window),
904 GDK_WINDOW_XID (window),
911 gdk_window_resize (GdkWindow *window,
915 GdkWindowObject *private;
917 g_return_if_fail (window != NULL);
918 g_return_if_fail (GDK_IS_WINDOW (window));
925 private = (GdkWindowObject*) window;
927 if (!GDK_WINDOW_DESTROYED (window))
929 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
930 _gdk_window_move_resize_child (window, private->x, private->y,
934 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
936 if (width != impl->width || height != impl->height)
937 private->resize_count += 1;
939 XResizeWindow (GDK_WINDOW_XDISPLAY (window),
940 GDK_WINDOW_XID (window),
947 gdk_window_move_resize (GdkWindow *window,
953 GdkWindowObject *private;
955 g_return_if_fail (window != NULL);
956 g_return_if_fail (GDK_IS_WINDOW (window));
963 private = (GdkWindowObject*) window;
965 if (!GDK_WINDOW_DESTROYED (window))
967 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
968 _gdk_window_move_resize_child (window, x, y, width, height);
971 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
973 if (width != impl->width || height != impl->height)
974 private->resize_count += 1;
976 XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
977 GDK_WINDOW_XID (window),
978 x, y, width, height);
984 gdk_window_reparent (GdkWindow *window,
985 GdkWindow *new_parent,
989 GdkWindowObject *window_private;
990 GdkWindowObject *parent_private;
991 GdkWindowObject *old_parent_private;
993 g_return_if_fail (window != NULL);
994 g_return_if_fail (GDK_IS_WINDOW (window));
995 g_return_if_fail (new_parent != NULL);
996 g_return_if_fail (GDK_IS_WINDOW (new_parent));
999 new_parent = gdk_parent_root;
1001 window_private = (GdkWindowObject*) window;
1002 old_parent_private = (GdkWindowObject*)window_private->parent;
1003 parent_private = (GdkWindowObject*) new_parent;
1005 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
1006 XReparentWindow (GDK_WINDOW_XDISPLAY (window),
1007 GDK_WINDOW_XID (window),
1008 GDK_WINDOW_XID (new_parent),
1011 window_private->parent = (GdkWindowObject *)new_parent;
1013 if (old_parent_private)
1014 old_parent_private->children = g_list_remove (old_parent_private->children, window);
1016 if ((old_parent_private &&
1017 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1018 (!old_parent_private && parent_private->guffaw_gravity))
1019 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1021 parent_private->children = g_list_prepend (parent_private->children, window);
1025 _gdk_windowing_window_clear_area (GdkWindow *window,
1031 g_return_if_fail (window != NULL);
1032 g_return_if_fail (GDK_IS_WINDOW (window));
1034 if (!GDK_WINDOW_DESTROYED (window))
1035 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1036 x, y, width, height, False);
1040 _gdk_windowing_window_clear_area_e (GdkWindow *window,
1046 g_return_if_fail (window != NULL);
1047 g_return_if_fail (GDK_IS_WINDOW (window));
1049 if (!GDK_WINDOW_DESTROYED (window))
1050 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1051 x, y, width, height, True);
1055 gdk_window_raise (GdkWindow *window)
1057 g_return_if_fail (window != NULL);
1058 g_return_if_fail (GDK_IS_WINDOW (window));
1060 if (!GDK_WINDOW_DESTROYED (window))
1061 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1065 gdk_window_lower (GdkWindow *window)
1067 g_return_if_fail (window != NULL);
1068 g_return_if_fail (GDK_IS_WINDOW (window));
1070 if (!GDK_WINDOW_DESTROYED (window))
1071 XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1075 gdk_window_focus (GdkWindow *window,
1078 g_return_if_fail (GDK_IS_WINDOW (window));
1080 if (GDK_WINDOW_DESTROYED (window))
1083 if (gdk_net_wm_supports (gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE)))
1087 xev.xclient.type = ClientMessage;
1088 xev.xclient.serial = 0;
1089 xev.xclient.send_event = True;
1090 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
1091 xev.xclient.display = gdk_display;
1092 xev.xclient.message_type = gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE);
1093 xev.xclient.format = 32;
1094 xev.xclient.data.l[0] = 0;
1096 XSendEvent (gdk_display, gdk_root_window, False,
1097 SubstructureRedirectMask | SubstructureNotifyMask,
1102 XSetInputFocus (GDK_DISPLAY (),
1103 GDK_WINDOW_XWINDOW (window),
1110 gdk_window_set_hints (GdkWindow *window,
1119 XSizeHints size_hints;
1121 g_return_if_fail (window != NULL);
1122 g_return_if_fail (GDK_IS_WINDOW (window));
1124 if (GDK_WINDOW_DESTROYED (window))
1127 size_hints.flags = 0;
1129 if (flags & GDK_HINT_POS)
1131 size_hints.flags |= PPosition;
1136 if (flags & GDK_HINT_MIN_SIZE)
1138 size_hints.flags |= PMinSize;
1139 size_hints.min_width = min_width;
1140 size_hints.min_height = min_height;
1143 if (flags & GDK_HINT_MAX_SIZE)
1145 size_hints.flags |= PMaxSize;
1146 size_hints.max_width = max_width;
1147 size_hints.max_height = max_height;
1150 /* FIXME: Would it be better to delete this property of
1151 * flags == 0? It would save space on the server
1153 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1154 GDK_WINDOW_XID (window),
1159 * gdk_window_set_type_hint:
1160 * @window: A #GdkWindow
1161 * @hint: A hint of the function this window will have
1163 * The application can use this call to provide a hint to the window
1164 * manager about the functionality of a window. The window manager
1165 * can use this information when determining the decoration and behaviour
1168 * The hint must be set before the window is mapped.
1171 gdk_window_set_type_hint (GdkWindow *window,
1172 GdkWindowTypeHint hint)
1176 g_return_if_fail (window != NULL);
1177 g_return_if_fail (GDK_IS_WINDOW (window));
1179 if (GDK_WINDOW_DESTROYED (window))
1184 case GDK_WINDOW_TYPE_HINT_DIALOG:
1185 atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_DIALOG", FALSE);
1187 case GDK_WINDOW_TYPE_HINT_MENU:
1188 atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_MENU", FALSE);
1190 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1191 atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_TOOLBAR", FALSE);
1194 g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
1196 case GDK_WINDOW_TYPE_HINT_NORMAL:
1197 atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_NORMAL", FALSE);
1201 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1202 GDK_WINDOW_XID (window),
1203 gdk_atom_intern ("_NET_WM_WINDOW_TYPE", FALSE),
1204 XA_ATOM, 32, PropModeReplace,
1205 (guchar *)&atom, 1);
1210 gdk_wmspec_change_state (gboolean add,
1219 op = gdk_atom_intern ("_NET_WM_STATE_ADD", FALSE);
1221 op = gdk_atom_intern ("_NET_WM_STATE_REMOVE", FALSE);
1223 xev.xclient.type = ClientMessage;
1224 xev.xclient.serial = 0;
1225 xev.xclient.send_event = True;
1226 xev.xclient.display = gdk_display;
1227 xev.xclient.window = GDK_WINDOW_XID (window);
1228 xev.xclient.message_type = gdk_atom_intern ("_NET_WM_STATE", FALSE);
1229 xev.xclient.format = 32;
1230 xev.xclient.data.l[0] = op;
1231 xev.xclient.data.l[1] = state1;
1232 xev.xclient.data.l[2] = state2;
1234 XSendEvent (gdk_display, gdk_root_window, False,
1235 SubstructureRedirectMask | SubstructureNotifyMask,
1239 * gdk_window_set_modal_hint:
1240 * @window: A #GdkWindow
1241 * @modal: TRUE if the window is modal, FALSE otherwise.
1243 * The application can use this hint to tell the window manager
1244 * that a certain window has modal behaviour. The window manager
1245 * can use this information to handle modal windows in a special
1248 * You should only use this on windows for which you have
1249 * previously called #gdk_window_set_transient_for()
1252 gdk_window_set_modal_hint (GdkWindow *window,
1255 GdkWindowObject *private;
1257 g_return_if_fail (window != NULL);
1258 g_return_if_fail (GDK_IS_WINDOW (window));
1260 if (GDK_WINDOW_DESTROYED (window))
1263 private = (GdkWindowObject*) window;
1265 private->modal_hint = modal;
1267 if (GDK_WINDOW_IS_MAPPED (window))
1268 gdk_wmspec_change_state (modal, window,
1269 gdk_atom_intern ("_NET_WM_STATE_MODAL", FALSE),
1274 gdk_window_set_geometry_hints (GdkWindow *window,
1275 GdkGeometry *geometry,
1276 GdkWindowHints geom_mask)
1278 XSizeHints size_hints;
1280 g_return_if_fail (window != NULL);
1281 g_return_if_fail (GDK_IS_WINDOW (window));
1283 if (GDK_WINDOW_DESTROYED (window))
1286 size_hints.flags = 0;
1288 if (geom_mask & GDK_HINT_POS)
1290 size_hints.flags |= PPosition;
1291 /* We need to initialize the following obsolete fields because KWM
1292 * apparently uses these fields if they are non-zero.
1299 if (geom_mask & GDK_HINT_MIN_SIZE)
1301 size_hints.flags |= PMinSize;
1302 size_hints.min_width = geometry->min_width;
1303 size_hints.min_height = geometry->min_height;
1306 if (geom_mask & GDK_HINT_MAX_SIZE)
1308 size_hints.flags |= PMaxSize;
1309 size_hints.max_width = MAX (geometry->max_width, 1);
1310 size_hints.max_height = MAX (geometry->max_height, 1);
1313 if (geom_mask & GDK_HINT_BASE_SIZE)
1315 size_hints.flags |= PBaseSize;
1316 size_hints.base_width = geometry->base_width;
1317 size_hints.base_height = geometry->base_height;
1320 if (geom_mask & GDK_HINT_RESIZE_INC)
1322 size_hints.flags |= PResizeInc;
1323 size_hints.width_inc = geometry->width_inc;
1324 size_hints.height_inc = geometry->height_inc;
1327 if (geom_mask & GDK_HINT_ASPECT)
1329 size_hints.flags |= PAspect;
1330 if (geometry->min_aspect <= 1)
1332 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
1333 size_hints.min_aspect.y = 65536;
1337 size_hints.min_aspect.x = 65536;
1338 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
1340 if (geometry->max_aspect <= 1)
1342 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
1343 size_hints.max_aspect.y = 65536;
1347 size_hints.max_aspect.x = 65536;
1348 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
1352 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1354 size_hints.flags |= PWinGravity;
1355 size_hints.win_gravity = geometry->win_gravity;
1358 /* FIXME: Would it be better to delete this property of
1359 * geom_mask == 0? It would save space on the server
1361 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1362 GDK_WINDOW_XID (window),
1367 gdk_window_get_geometry_hints (GdkWindow *window,
1368 GdkGeometry *geometry,
1369 GdkWindowHints *geom_mask)
1371 XSizeHints size_hints;
1372 glong junk_size_mask = 0;
1374 g_return_if_fail (GDK_IS_WINDOW (window));
1375 g_return_if_fail (geometry != NULL);
1376 g_return_if_fail (geom_mask != NULL);
1380 if (GDK_WINDOW_DESTROYED (window))
1383 if (!XGetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1384 GDK_WINDOW_XID (window),
1389 if (size_hints.flags & PMinSize)
1391 *geom_mask |= GDK_HINT_MIN_SIZE;
1392 geometry->min_width = size_hints.min_width;
1393 geometry->min_height = size_hints.min_height;
1396 if (size_hints.flags & PMaxSize)
1398 *geom_mask |= GDK_HINT_MAX_SIZE;
1399 geometry->max_width = MAX (size_hints.max_width, 1);
1400 geometry->max_height = MAX (size_hints.max_height, 1);
1403 if (size_hints.flags & PResizeInc)
1405 *geom_mask |= GDK_HINT_RESIZE_INC;
1406 geometry->width_inc = size_hints.width_inc;
1407 geometry->height_inc = size_hints.height_inc;
1410 if (size_hints.flags & PAspect)
1412 *geom_mask |= GDK_HINT_ASPECT;
1414 geometry->min_aspect = (gdouble) size_hints.min_aspect.x / (gdouble) size_hints.min_aspect.y;
1415 geometry->max_aspect = (gdouble) size_hints.max_aspect.x / (gdouble) size_hints.max_aspect.y;
1418 if (size_hints.flags & PWinGravity)
1420 *geom_mask |= GDK_HINT_WIN_GRAVITY;
1421 geometry->win_gravity = size_hints.win_gravity;
1426 utf8_is_latin1 (const gchar *str)
1428 const char *p = str;
1432 gunichar ch = g_utf8_get_char (p);
1437 p = g_utf8_next_char (p);
1443 /* Set the property to @utf8_str as STRING if the @utf8_str is fully
1444 * convertable to STRING, otherwise, set it as compound text
1447 set_text_property (GdkWindow *window,
1449 const gchar *utf8_str)
1451 guchar *prop_text = NULL;
1456 if (utf8_is_latin1 (utf8_str))
1458 prop_type = GDK_TARGET_STRING;
1459 prop_text = gdk_utf8_to_string_target (utf8_str);
1460 prop_length = strlen (prop_text);
1465 gdk_utf8_to_compound_text (utf8_str, &prop_type, &prop_format,
1466 &prop_text, &prop_length);
1471 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1472 GDK_WINDOW_XID (window),
1474 prop_type, prop_format,
1475 PropModeReplace, prop_text,
1483 gdk_window_set_title (GdkWindow *window,
1486 g_return_if_fail (window != NULL);
1487 g_return_if_fail (GDK_IS_WINDOW (window));
1489 if (GDK_WINDOW_DESTROYED (window))
1492 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1493 GDK_WINDOW_XID (window),
1494 gdk_atom_intern ("_NET_WM_NAME", FALSE),
1495 gdk_atom_intern ("UTF8_STRING", FALSE), 8,
1496 PropModeReplace, title,
1499 set_text_property (window, gdk_atom_intern ("WM_NAME", FALSE), title);
1500 if (!gdk_window_icon_name_set (window))
1502 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1503 GDK_WINDOW_XID (window),
1504 gdk_atom_intern ("_NET_WM_ICON_NAME", FALSE),
1505 gdk_atom_intern ("UTF8_STRING", FALSE), 8,
1506 PropModeReplace, title,
1508 set_text_property (window, gdk_atom_intern ("WM_ICON_NAME", FALSE), title);
1513 gdk_window_set_role (GdkWindow *window,
1516 g_return_if_fail (window != NULL);
1517 g_return_if_fail (GDK_IS_WINDOW (window));
1519 if (!GDK_WINDOW_DESTROYED (window))
1522 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1523 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1524 8, PropModeReplace, role, strlen (role));
1526 XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1527 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1532 gdk_window_set_transient_for (GdkWindow *window,
1535 GdkWindowObject *private;
1536 GdkWindowObject *parent_private;
1538 g_return_if_fail (window != NULL);
1539 g_return_if_fail (GDK_IS_WINDOW (window));
1541 private = (GdkWindowObject*) window;
1542 parent_private = (GdkWindowObject*) parent;
1544 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent))
1545 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
1546 GDK_WINDOW_XID (window),
1547 GDK_WINDOW_XID (parent));
1551 gdk_window_set_background (GdkWindow *window,
1554 GdkWindowObject *private = (GdkWindowObject *)window;
1556 g_return_if_fail (window != NULL);
1557 g_return_if_fail (GDK_IS_WINDOW (window));
1559 if (!GDK_WINDOW_DESTROYED (window))
1560 XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
1561 GDK_WINDOW_XID (window), color->pixel);
1563 private->bg_color = *color;
1565 if (private->bg_pixmap &&
1566 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1567 private->bg_pixmap != GDK_NO_BG)
1569 gdk_pixmap_unref (private->bg_pixmap);
1570 private->bg_pixmap = NULL;
1575 gdk_window_set_back_pixmap (GdkWindow *window,
1577 gboolean parent_relative)
1579 GdkWindowObject *private = (GdkWindowObject *)window;
1582 g_return_if_fail (window != NULL);
1583 g_return_if_fail (GDK_IS_WINDOW (window));
1584 g_return_if_fail (pixmap == NULL || !parent_relative);
1586 if (private->bg_pixmap &&
1587 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1588 private->bg_pixmap != GDK_NO_BG)
1589 gdk_pixmap_unref (private->bg_pixmap);
1591 if (parent_relative)
1593 xpixmap = ParentRelative;
1594 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1600 gdk_pixmap_ref (pixmap);
1601 private->bg_pixmap = pixmap;
1602 xpixmap = GDK_PIXMAP_XID (pixmap);
1607 private->bg_pixmap = GDK_NO_BG;
1611 if (!GDK_WINDOW_DESTROYED (window))
1612 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
1613 GDK_WINDOW_XID (window), xpixmap);
1617 gdk_window_set_cursor (GdkWindow *window,
1620 GdkCursorPrivate *cursor_private;
1623 g_return_if_fail (window != NULL);
1624 g_return_if_fail (GDK_IS_WINDOW (window));
1626 cursor_private = (GdkCursorPrivate*) cursor;
1631 xcursor = cursor_private->xcursor;
1633 if (!GDK_WINDOW_DESTROYED (window))
1634 XDefineCursor (GDK_WINDOW_XDISPLAY (window),
1635 GDK_WINDOW_XID (window),
1640 gdk_window_get_geometry (GdkWindow *window,
1652 guint tborder_width;
1655 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1658 window = gdk_parent_root;
1660 if (!GDK_WINDOW_DESTROYED (window))
1662 XGetGeometry (GDK_WINDOW_XDISPLAY (window),
1663 GDK_WINDOW_XID (window),
1664 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1680 * gdk_window_get_origin:
1681 * @window: a #GdkWindow
1682 * @x: return location for X coordinate
1683 * @y: return location for Y coordinate
1685 * Obtains the position of a window in root window coordinates.
1686 * (Compare with gdk_window_get_position() and
1687 * gdk_window_get_geometry() which return the position of a window
1688 * relative to its parent window.)
1690 * Return value: not meaningful, ignore
1693 gdk_window_get_origin (GdkWindow *window,
1702 g_return_val_if_fail (window != NULL, 0);
1704 if (!GDK_WINDOW_DESTROYED (window))
1706 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1707 GDK_WINDOW_XID (window),
1725 * gdk_window_get_deskrelative_origin:
1726 * @window: a #GdkWindow
1727 * @x: return location for X coordinate
1728 * @y: return location for Y coordinate
1730 * This gets the origin of a #GdkWindow relative to
1731 * an Enlightenment-window-manager desktop. As long as you don't
1732 * assume that the user's desktop/workspace covers the entire
1733 * root window (i.e. you don't assume that the desktop begins
1734 * at root window coordinate 0,0) this function is not necessary.
1735 * It's deprecated for that reason.
1737 * Return value: not meaningful
1740 gdk_window_get_deskrelative_origin (GdkWindow *window,
1744 gboolean return_val = FALSE;
1745 gint num_children, format_return;
1746 Window win, *child, parent, root;
1750 static Atom atom = 0;
1751 gulong number_return, bytes_after_return;
1752 guchar *data_return;
1754 g_return_val_if_fail (window != NULL, 0);
1755 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1757 if (!GDK_WINDOW_DESTROYED (window))
1760 atom = gdk_atom_intern ("ENLIGHTENMENT_DESKTOP", FALSE);
1761 win = GDK_WINDOW_XID (window);
1763 while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent,
1764 &child, (unsigned int *)&num_children))
1766 if ((child) && (num_children > 0))
1778 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0,
1779 False, XA_CARDINAL, &type_return, &format_return,
1780 &number_return, &bytes_after_return, &data_return);
1781 if (type_return == XA_CARDINAL)
1783 XFree (data_return);
1788 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1789 GDK_WINDOW_XID (window),
1804 * gdk_window_get_root_origin:
1805 * @window: a #GdkWindow
1806 * @x: return location for X position of window frame
1807 * @y: return location for Y position of window frame
1809 * Obtains the top-left corner of the window manager frame in root
1810 * window coordinates.
1814 gdk_window_get_root_origin (GdkWindow *window,
1820 g_return_if_fail (GDK_IS_WINDOW (window));
1822 gdk_window_get_frame_extents (window, &rect);
1832 * gdk_window_get_frame_extents:
1833 * @window: a #GdkWindow
1834 * @rect: rectangle to fill with bounding box of the window frame
1836 * Obtains the bounding box of the window, including window manager
1837 * titlebar/borders if any. The frame position is given in root window
1838 * coordinates. To get the position of the window itself (rather than
1839 * the frame) in root window coordinates, use gdk_window_get_origin().
1843 gdk_window_get_frame_extents (GdkWindow *window,
1846 GdkWindowObject *private;
1851 unsigned int nchildren;
1853 g_return_if_fail (GDK_IS_WINDOW (window));
1854 g_return_if_fail (rect != NULL);
1856 private = (GdkWindowObject*) window;
1863 if (GDK_WINDOW_DESTROYED (window))
1866 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
1867 private = (GdkWindowObject*) private->parent;
1868 if (GDK_WINDOW_DESTROYED (window))
1871 xparent = GDK_WINDOW_XID (window);
1875 if (!XQueryTree (GDK_WINDOW_XDISPLAY (window), xwindow,
1877 &children, &nchildren))
1883 while (xparent != root);
1885 if (xparent == root)
1887 unsigned int ww, wh, wb, wd;
1890 if (XGetGeometry (GDK_WINDOW_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1901 gdk_window_get_pointer (GdkWindow *window,
1904 GdkModifierType *mask)
1906 GdkWindow *return_val;
1912 unsigned int xmask = 0;
1913 gint xoffset, yoffset;
1915 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1918 window = gdk_parent_root;
1920 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
1923 if (!GDK_WINDOW_DESTROYED (window) &&
1924 XQueryPointer (GDK_WINDOW_XDISPLAY (window),
1925 GDK_WINDOW_XID (window),
1926 &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
1929 return_val = gdk_window_lookup (child);
1933 *x = winx + xoffset;
1935 *y = winy + yoffset;
1943 gdk_window_at_pointer (gint *win_x,
1949 Window xwindow_last = 0;
1951 int rootx = -1, rooty = -1;
1955 xwindow = GDK_ROOT_WINDOW ();
1956 xdisplay = GDK_DISPLAY ();
1958 XGrabServer (xdisplay);
1961 xwindow_last = xwindow;
1962 XQueryPointer (xdisplay, xwindow,
1968 XUngrabServer (xdisplay);
1970 window = gdk_window_lookup (xwindow_last);
1973 *win_x = window ? winx : -1;
1975 *win_y = window ? winy : -1;
1981 gdk_window_get_events (GdkWindow *window)
1983 XWindowAttributes attrs;
1984 GdkEventMask event_mask;
1987 g_return_val_if_fail (window != NULL, 0);
1988 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1990 if (GDK_WINDOW_DESTROYED (window))
1994 XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
1995 GDK_WINDOW_XID (window),
1999 for (i = 0; i < gdk_nevent_masks; i++)
2001 if (attrs.your_event_mask & gdk_event_mask_table[i])
2002 event_mask |= 1 << (i + 1);
2010 gdk_window_set_events (GdkWindow *window,
2011 GdkEventMask event_mask)
2016 g_return_if_fail (window != NULL);
2017 g_return_if_fail (GDK_IS_WINDOW (window));
2019 if (!GDK_WINDOW_DESTROYED (window))
2021 xevent_mask = StructureNotifyMask;
2022 for (i = 0; i < gdk_nevent_masks; i++)
2024 if (event_mask & (1 << (i + 1)))
2025 xevent_mask |= gdk_event_mask_table[i];
2028 XSelectInput (GDK_WINDOW_XDISPLAY (window),
2029 GDK_WINDOW_XID (window),
2035 gdk_window_add_colormap_windows (GdkWindow *window)
2037 GdkWindow *toplevel;
2038 Window *old_windows;
2039 Window *new_windows;
2042 g_return_if_fail (window != NULL);
2043 g_return_if_fail (GDK_IS_WINDOW (window));
2045 toplevel = gdk_window_get_toplevel (window);
2046 if (GDK_WINDOW_DESTROYED (toplevel))
2050 if (!XGetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
2051 GDK_WINDOW_XID (toplevel),
2052 &old_windows, &count))
2057 for (i = 0; i < count; i++)
2058 if (old_windows[i] == GDK_WINDOW_XID (window))
2060 XFree (old_windows);
2064 new_windows = g_new (Window, count + 1);
2066 for (i = 0; i < count; i++)
2067 new_windows[i] = old_windows[i];
2068 new_windows[count] = GDK_WINDOW_XID (window);
2070 XSetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
2071 GDK_WINDOW_XID (toplevel),
2072 new_windows, count + 1);
2074 g_free (new_windows);
2076 XFree (old_windows);
2080 gdk_window_have_shape_ext (void)
2082 enum { UNKNOWN, NO, YES };
2083 static gint have_shape = UNKNOWN;
2085 if (have_shape == UNKNOWN)
2088 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
2094 return (have_shape == YES);
2097 #define WARN_SHAPE_TOO_BIG() g_warning ("GdkWindow is too large to allow the use of shape masks or shape regions.")
2100 * This needs the X11 shape extension.
2101 * If not available, shaped windows will look
2102 * ugly, but programs still work. Stefan Wille
2105 gdk_window_shape_combine_mask (GdkWindow *window,
2110 gint xoffset, yoffset;
2112 g_return_if_fail (window != NULL);
2113 g_return_if_fail (GDK_IS_WINDOW (window));
2115 #ifdef HAVE_SHAPE_EXT
2116 if (GDK_WINDOW_DESTROYED (window))
2119 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2121 if (xoffset != 0 || yoffset != 0)
2123 WARN_SHAPE_TOO_BIG ();
2127 if (gdk_window_have_shape_ext ())
2131 pixmap = GDK_PIXMAP_XID (mask);
2140 XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
2141 GDK_WINDOW_XID (window),
2147 #endif /* HAVE_SHAPE_EXT */
2151 gdk_window_shape_combine_region (GdkWindow *window,
2152 GdkRegion *shape_region,
2156 gint xoffset, yoffset;
2158 g_return_if_fail (GDK_IS_WINDOW (window));
2160 #ifdef HAVE_SHAPE_EXT
2161 if (GDK_WINDOW_DESTROYED (window))
2164 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2166 if (xoffset != 0 || yoffset != 0)
2168 WARN_SHAPE_TOO_BIG ();
2172 if (shape_region == NULL)
2174 /* Use NULL mask to unset the shape */
2175 gdk_window_shape_combine_mask (window, NULL, 0, 0);
2179 if (gdk_window_have_shape_ext ())
2182 XRectangle *xrects = NULL;
2184 _gdk_region_get_xrectangles (shape_region,
2188 XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window),
2189 GDK_WINDOW_XID (window),
2198 #endif /* HAVE_SHAPE_EXT */
2203 gdk_window_set_override_redirect (GdkWindow *window,
2204 gboolean override_redirect)
2206 XSetWindowAttributes attr;
2208 g_return_if_fail (window != NULL);
2209 g_return_if_fail (GDK_IS_WINDOW (window));
2211 if (GDK_WINDOW_DESTROYED (window))
2213 attr.override_redirect = (override_redirect == FALSE)?False:True;
2214 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2215 GDK_WINDOW_XID (window),
2223 * gdk_window_set_icon_list:
2224 * @window: The #GdkWindow toplevel window to set the icon of.
2225 * @pixbufs: A list of pixbufs, of different sizes.
2226 * @Returns: TRUE if the icons were set, false otherwise
2228 * Sets a list of icons for the window. One of these will be used
2229 * to represent the window when it has been iconified. The icon is
2230 * usually shown in an icon box or some sort of task bar. Which icon
2231 * size is shown depends on the window manager. The window manager
2232 * can scale the icon but setting several size icons can give better
2233 * image quality since the window manager may only need to scale the
2234 * icon by a small amount or not at all.
2236 * On the X11 backend this call might fail if the window manager
2237 * doesn't support the Extended Window Manager Hints. Then this
2238 * function returns FALSE, and the application should fall back
2239 * to #gdk_window_set_icon().
2242 gdk_window_set_icon_list (GdkWindow *window,
2251 gint width, height, stride;
2255 g_return_val_if_fail (window != NULL, FALSE);
2256 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2258 if (GDK_WINDOW_DESTROYED (window))
2261 if (!gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_ICON", FALSE)))
2270 g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE);
2272 width = gdk_pixbuf_get_width (pixbuf);
2273 height = gdk_pixbuf_get_height (pixbuf);
2275 size += 2 + width * height;
2277 l = g_list_next (l);
2280 data = g_malloc (size*4);
2288 width = gdk_pixbuf_get_width (pixbuf);
2289 height = gdk_pixbuf_get_height (pixbuf);
2290 stride = gdk_pixbuf_get_rowstride (pixbuf);
2291 n_channels = gdk_pixbuf_get_n_channels (pixbuf);
2296 pixels = gdk_pixbuf_get_pixels (pixbuf);
2298 for (y = 0; y < height; y++)
2300 for (x = 0; x < width; x++)
2304 r = pixels[y*stride + x*n_channels + 0];
2305 g = pixels[y*stride + x*n_channels + 1];
2306 b = pixels[y*stride + x*n_channels + 2];
2307 if (n_channels >= 4)
2308 a = pixels[y*stride + x*n_channels + 3];
2312 *p++ = a << 24 | r << 16 | g << 8 | b ;
2316 l = g_list_next (l);
2319 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
2320 GDK_WINDOW_XID (window),
2321 gdk_atom_intern ("_NET_WM_ICON", FALSE),
2324 (guchar*) data, size);
2330 gdk_window_set_icon (GdkWindow *window,
2331 GdkWindow *icon_window,
2337 g_return_if_fail (window != NULL);
2338 g_return_if_fail (GDK_IS_WINDOW (window));
2340 if (GDK_WINDOW_DESTROYED (window))
2343 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
2344 GDK_WINDOW_XID (window));
2346 wm_hints = XAllocWMHints ();
2348 if (icon_window != NULL)
2350 wm_hints->flags |= IconWindowHint;
2351 wm_hints->icon_window = GDK_WINDOW_XID (icon_window);
2356 wm_hints->flags |= IconPixmapHint;
2357 wm_hints->icon_pixmap = GDK_PIXMAP_XID (pixmap);
2362 wm_hints->flags |= IconMaskHint;
2363 wm_hints->icon_mask = GDK_PIXMAP_XID (mask);
2366 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
2367 GDK_WINDOW_XID (window), wm_hints);
2372 gdk_window_icon_name_set (GdkWindow *window)
2374 return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window),
2375 g_quark_from_static_string ("gdk-icon-name-set")));
2379 gdk_window_set_icon_name (GdkWindow *window,
2382 g_return_if_fail (window != NULL);
2383 g_return_if_fail (GDK_IS_WINDOW (window));
2385 if (GDK_WINDOW_DESTROYED (window))
2388 g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
2389 GUINT_TO_POINTER (TRUE));
2391 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
2392 GDK_WINDOW_XID (window),
2393 gdk_atom_intern ("_NET_WM_ICON_NAME", FALSE),
2394 gdk_atom_intern ("UTF8_STRING", FALSE), 8,
2395 PropModeReplace, name,
2397 set_text_property (window, gdk_atom_intern ("WM_ICON_NAME", FALSE), name);
2401 gdk_window_iconify (GdkWindow *window)
2404 GdkWindowObject *private;
2406 g_return_if_fail (window != NULL);
2407 g_return_if_fail (GDK_IS_WINDOW (window));
2409 if (GDK_WINDOW_DESTROYED (window))
2412 display = GDK_WINDOW_XDISPLAY (window);
2414 private = (GdkWindowObject*) window;
2416 if (GDK_WINDOW_IS_MAPPED (window))
2418 XIconifyWindow (display, GDK_WINDOW_XWINDOW (window), DefaultScreen (display));
2423 /* Flip our client side flag, the real work happens on map. */
2424 gdk_synthesize_window_state (window,
2426 GDK_WINDOW_STATE_ICONIFIED);
2431 gdk_window_deiconify (GdkWindow *window)
2434 GdkWindowObject *private;
2436 g_return_if_fail (window != NULL);
2437 g_return_if_fail (GDK_IS_WINDOW (window));
2439 if (GDK_WINDOW_DESTROYED (window))
2442 display = GDK_WINDOW_XDISPLAY (window);
2444 private = (GdkWindowObject*) window;
2446 if (GDK_WINDOW_IS_MAPPED (window))
2448 gdk_window_show (window);
2452 /* Flip our client side flag, the real work happens on map. */
2453 gdk_synthesize_window_state (window,
2454 GDK_WINDOW_STATE_ICONIFIED,
2460 gdk_window_stick (GdkWindow *window)
2462 g_return_if_fail (GDK_IS_WINDOW (window));
2464 if (GDK_WINDOW_DESTROYED (window))
2467 if (GDK_WINDOW_IS_MAPPED (window))
2469 /* "stick" means stick to all desktops _and_ do not scroll with the
2470 * viewport. i.e. glue to the monitor glass in all cases.
2475 /* Request stick during viewport scroll */
2476 gdk_wmspec_change_state (TRUE, window,
2477 gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
2480 /* Request desktop 0xFFFFFFFF */
2481 xev.xclient.type = ClientMessage;
2482 xev.xclient.serial = 0;
2483 xev.xclient.send_event = True;
2484 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
2485 xev.xclient.display = gdk_display;
2486 xev.xclient.message_type = gdk_atom_intern ("_NET_WM_DESKTOP", FALSE);
2487 xev.xclient.format = 32;
2489 xev.xclient.data.l[0] = 0xFFFFFFFF;
2491 XSendEvent (gdk_display, gdk_root_window, False,
2492 SubstructureRedirectMask | SubstructureNotifyMask,
2497 /* Flip our client side flag, the real work happens on map. */
2498 gdk_synthesize_window_state (window,
2500 GDK_WINDOW_STATE_STICKY);
2505 gdk_window_unstick (GdkWindow *window)
2507 g_return_if_fail (GDK_IS_WINDOW (window));
2509 if (GDK_WINDOW_DESTROYED (window))
2512 if (GDK_WINDOW_IS_MAPPED (window))
2519 gulong *current_desktop;
2521 /* Request unstick from viewport */
2522 gdk_wmspec_change_state (FALSE, window,
2523 gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
2526 /* Get current desktop, then set it; this is a race, but not
2527 * one that matters much in practice.
2529 XGetWindowProperty (gdk_display, gdk_root_window,
2530 gdk_atom_intern ("_NET_CURRENT_DESKTOP", FALSE),
2532 False, XA_CARDINAL, &type, &format, &nitems,
2533 &bytes_after, (guchar **)¤t_desktop);
2535 if (type == XA_CARDINAL)
2537 xev.xclient.type = ClientMessage;
2538 xev.xclient.serial = 0;
2539 xev.xclient.send_event = True;
2540 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
2541 xev.xclient.display = gdk_display;
2542 xev.xclient.message_type = gdk_atom_intern ("_NET_WM_DESKTOP", FALSE);
2543 xev.xclient.format = 32;
2545 xev.xclient.data.l[0] = *current_desktop;
2547 XSendEvent (gdk_display, gdk_root_window, False,
2548 SubstructureRedirectMask | SubstructureNotifyMask,
2551 XFree (current_desktop);
2556 /* Flip our client side flag, the real work happens on map. */
2557 gdk_synthesize_window_state (window,
2558 GDK_WINDOW_STATE_STICKY,
2565 gdk_window_maximize (GdkWindow *window)
2567 g_return_if_fail (GDK_IS_WINDOW (window));
2569 if (GDK_WINDOW_DESTROYED (window))
2572 if (GDK_WINDOW_IS_MAPPED (window))
2573 gdk_wmspec_change_state (TRUE, window,
2574 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
2575 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
2577 gdk_synthesize_window_state (window,
2579 GDK_WINDOW_STATE_MAXIMIZED);
2583 gdk_window_unmaximize (GdkWindow *window)
2585 g_return_if_fail (GDK_IS_WINDOW (window));
2587 if (GDK_WINDOW_DESTROYED (window))
2590 if (GDK_WINDOW_IS_MAPPED (window))
2591 gdk_wmspec_change_state (FALSE, window,
2592 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
2593 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
2595 gdk_synthesize_window_state (window,
2596 GDK_WINDOW_STATE_MAXIMIZED,
2601 gdk_window_set_group (GdkWindow *window,
2606 g_return_if_fail (window != NULL);
2607 g_return_if_fail (GDK_IS_WINDOW (window));
2608 g_return_if_fail (leader != NULL);
2609 g_return_if_fail (GDK_IS_WINDOW (leader));
2611 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2614 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
2615 GDK_WINDOW_XID (window));
2617 wm_hints = XAllocWMHints ();
2619 wm_hints->flags |= WindowGroupHint;
2620 wm_hints->window_group = GDK_WINDOW_XID (leader);
2622 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
2623 GDK_WINDOW_XID (window), wm_hints);
2627 static MotifWmHints *
2628 gdk_window_get_mwm_hints (GdkWindow *window)
2630 static Atom hints_atom = None;
2631 MotifWmHints *hints;
2637 if (GDK_WINDOW_DESTROYED (window))
2641 hints_atom = XInternAtom (GDK_WINDOW_XDISPLAY (window),
2642 _XA_MOTIF_WM_HINTS, FALSE);
2644 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
2645 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
2646 False, AnyPropertyType, &type, &format, &nitems,
2647 &bytes_after, (guchar **)&hints);
2656 gdk_window_set_mwm_hints (GdkWindow *window,
2657 MotifWmHints *new_hints)
2659 static Atom hints_atom = None;
2660 MotifWmHints *hints;
2666 if (GDK_WINDOW_DESTROYED (window))
2670 hints_atom = XInternAtom (GDK_WINDOW_XDISPLAY (window),
2671 _XA_MOTIF_WM_HINTS, FALSE);
2673 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
2674 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
2675 False, AnyPropertyType, &type, &format, &nitems,
2676 &bytes_after, (guchar **)&hints);
2682 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2684 hints->flags |= MWM_HINTS_FUNCTIONS;
2685 hints->functions = new_hints->functions;
2687 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2689 hints->flags |= MWM_HINTS_DECORATIONS;
2690 hints->decorations = new_hints->decorations;
2694 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
2695 hints_atom, hints_atom, 32, PropModeReplace,
2696 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
2698 if (hints != new_hints)
2703 gdk_window_set_decorations (GdkWindow *window,
2704 GdkWMDecoration decorations)
2708 g_return_if_fail (window != NULL);
2709 g_return_if_fail (GDK_IS_WINDOW (window));
2711 hints.flags = MWM_HINTS_DECORATIONS;
2712 hints.decorations = decorations;
2714 gdk_window_set_mwm_hints (window, &hints);
2718 * gdk_window_get_decorations:
2719 * @window: The #GdkWindow to get the decorations from
2720 * @decorations: The window decorations will be written here
2722 * Returns the decorations set on the GdkWindow with #gdk_window_set_decorations
2723 * Returns: TRUE if the window has decorations set, FALSE otherwise.
2726 gdk_window_get_decorations(GdkWindow *window,
2727 GdkWMDecoration *decorations)
2729 MotifWmHints *hints;
2730 gboolean result = FALSE;
2732 hints = gdk_window_get_mwm_hints (window);
2736 if (hints->flags & MWM_HINTS_DECORATIONS)
2738 *decorations = hints->decorations;
2749 gdk_window_set_functions (GdkWindow *window,
2750 GdkWMFunction functions)
2754 g_return_if_fail (window != NULL);
2755 g_return_if_fail (GDK_IS_WINDOW (window));
2757 hints.flags = MWM_HINTS_FUNCTIONS;
2758 hints.functions = functions;
2760 gdk_window_set_mwm_hints (window, &hints);
2763 #ifdef HAVE_SHAPE_EXT
2766 * propagate the shapes from all child windows of a GDK window to the parent
2767 * window. Shamelessly ripped from Enlightenment's code
2775 struct _gdk_span *next;
2779 gdk_add_to_span (struct _gdk_span **s,
2783 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
2790 /* scan the spans for this line */
2793 /* -- -> new span */
2794 /* == -> existing span */
2795 /* ## -> spans intersect */
2796 /* if we are in the middle of spanning the span into the line */
2799 /* case: ---- ==== */
2800 if (xx < ptr1->start - 1)
2802 /* ends before next span - extend to here */
2806 /* case: ----##=== */
2807 else if (xx <= ptr1->end)
2809 /* crosses into next span - delete next span and append */
2810 ss->end = ptr1->end;
2811 ss->next = ptr1->next;
2815 /* case: ---###--- */
2818 /* overlaps next span - delete and keep checking */
2819 ss->next = ptr1->next;
2824 /* otherwise havent started spanning it in yet */
2827 /* case: ---- ==== */
2828 if (xx < ptr1->start - 1)
2830 /* insert span here in list */
2831 noo = g_malloc (sizeof (struct _gdk_span));
2845 /* case: ----##=== */
2846 else if ((x < ptr1->start) && (xx <= ptr1->end))
2848 /* expand this span to the left point of the new one */
2852 /* case: ===###=== */
2853 else if ((x >= ptr1->start) && (xx <= ptr1->end))
2855 /* throw the span away */
2858 /* case: ---###--- */
2859 else if ((x < ptr1->start) && (xx > ptr1->end))
2866 /* case: ===##---- */
2867 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2873 /* case: ==== ---- */
2874 /* case handled by next loop iteration - first case */
2879 /* it started in the middle but spans beyond your current list */
2885 /* it does not start inside a span or in the middle, so add it to the end */
2886 noo = g_malloc (sizeof (struct _gdk_span));
2894 noo->next = ptr2->next;
2907 gdk_add_rectangles (Display *disp,
2909 struct _gdk_span **spans,
2916 gint x1, y1, x2, y2;
2920 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
2923 /* go through all clip rects in this window's shape */
2924 for (k = 0; k < rn; k++)
2926 /* for each clip rect, add it to each line's spans */
2928 x2 = x + rl[k].x + (rl[k].width - 1);
2930 y2 = y + rl[k].y + (rl[k].height - 1);
2939 for (a = y1; a <= y2; a++)
2942 gdk_add_to_span (&spans[a], x1, x2);
2950 gdk_propagate_shapes (Display *disp,
2954 Window rt, par, *list = NULL;
2955 gint i, j, num = 0, num_rects = 0;
2959 XRectangle *rects = NULL;
2960 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
2961 XWindowAttributes xatt;
2963 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
2968 spans = g_malloc (sizeof (struct _gdk_span *) * h);
2970 for (i = 0; i < h; i++)
2972 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
2975 /* go through all child windows and create/insert spans */
2976 for (i = 0; i < num; i++)
2978 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
2979 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
2980 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
2983 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
2985 /* go through the spans list and build a list of rects */
2986 rects = g_malloc (sizeof (XRectangle) * 256);
2988 for (i = 0; i < baseh; i++)
2991 /* go through the line for all spans */
2994 rects[num_rects].x = ptr1->start;
2995 rects[num_rects].y = i;
2996 rects[num_rects].width = ptr1->end - ptr1->start + 1;
2997 rects[num_rects].height = 1;
2999 /* if there are more lines */
3001 /* while contigous rects (same start/end coords) exist */
3002 while ((contig) && (j < baseh))
3004 /* search next line for spans matching this one */
3010 /* if we have an exact span match set contig */
3011 if ((ptr2->start == ptr1->start) &&
3012 (ptr2->end == ptr1->end))
3015 /* remove the span - not needed */
3018 ptr3->next = ptr2->next;
3024 spans[j] = ptr2->next;
3030 /* gone past the span point no point looking */
3031 else if (ptr2->start < ptr1->start)
3039 /* if a contiguous span was found increase the rect h */
3042 rects[num_rects].height++;
3046 /* up the rect count */
3048 /* every 256 new rects increase the rect array */
3049 if ((num_rects % 256) == 0)
3050 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
3054 /* set the rects as the shape mask */
3057 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
3058 ShapeSet, YXSorted);
3063 /* free up all the spans we made */
3064 for (i = 0; i < baseh; i++)
3077 #endif /* HAVE_SHAPE_EXT */
3080 gdk_window_set_child_shapes (GdkWindow *window)
3082 g_return_if_fail (window != NULL);
3083 g_return_if_fail (GDK_IS_WINDOW (window));
3085 #ifdef HAVE_SHAPE_EXT
3086 if (!GDK_WINDOW_DESTROYED (window) &&
3087 gdk_window_have_shape_ext ())
3088 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
3089 GDK_WINDOW_XID (window), FALSE);
3094 gdk_window_merge_child_shapes (GdkWindow *window)
3096 g_return_if_fail (window != NULL);
3097 g_return_if_fail (GDK_IS_WINDOW (window));
3099 #ifdef HAVE_SHAPE_EXT
3100 if (!GDK_WINDOW_DESTROYED (window) &&
3101 gdk_window_have_shape_ext ())
3102 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
3103 GDK_WINDOW_XID (window), TRUE);
3107 /* Support for windows that can be guffaw-scrolled
3108 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
3112 gdk_window_gravity_works (void)
3114 enum { UNKNOWN, NO, YES };
3115 static gint gravity_works = UNKNOWN;
3117 if (gravity_works == UNKNOWN)
3124 /* This particular server apparently has a bug so that the test
3125 * works but the actual code crashes it
3127 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
3128 (VendorRelease (gdk_display) == 3400))
3134 attr.window_type = GDK_WINDOW_TEMP;
3135 attr.wclass = GDK_INPUT_OUTPUT;
3140 attr.event_mask = 0;
3142 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
3144 attr.window_type = GDK_WINDOW_CHILD;
3145 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
3147 gdk_window_set_static_win_gravity (child, TRUE);
3149 gdk_window_resize (parent, 100, 110);
3150 gdk_window_move (parent, 0, -10);
3151 gdk_window_move_resize (parent, 0, 0, 100, 100);
3153 gdk_window_resize (parent, 100, 110);
3154 gdk_window_move (parent, 0, -10);
3155 gdk_window_move_resize (parent, 0, 0, 100, 100);
3157 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
3159 gdk_window_destroy (parent);
3160 gdk_window_destroy (child);
3162 gravity_works = ((y == -20) ? YES : NO);
3165 return (gravity_works == YES);
3169 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
3171 XSetWindowAttributes xattributes;
3172 guint xattributes_mask = 0;
3174 g_return_if_fail (window != NULL);
3176 xattributes.bit_gravity = StaticGravity;
3177 xattributes_mask |= CWBitGravity;
3178 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
3179 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
3180 GDK_WINDOW_XID (window),
3181 CWBitGravity, &xattributes);
3185 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
3187 XSetWindowAttributes xattributes;
3189 g_return_if_fail (window != NULL);
3191 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
3193 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
3194 GDK_WINDOW_XID (window),
3195 CWWinGravity, &xattributes);
3198 /*************************************************************
3199 * gdk_window_set_static_gravities:
3200 * Set the bit gravity of the given window to static,
3201 * and flag it so all children get static subwindow
3204 * window: window for which to set static gravity
3205 * use_static: Whether to turn static gravity on or off.
3207 * Does the XServer support static gravity?
3208 *************************************************************/
3211 gdk_window_set_static_gravities (GdkWindow *window,
3212 gboolean use_static)
3214 GdkWindowObject *private = (GdkWindowObject *)window;
3217 g_return_val_if_fail (window != NULL, FALSE);
3218 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
3220 if (!use_static == !private->guffaw_gravity)
3223 if (use_static && !gdk_window_gravity_works ())
3226 private->guffaw_gravity = use_static;
3228 if (!GDK_WINDOW_DESTROYED (window))
3230 gdk_window_set_static_bit_gravity (window, use_static);
3232 tmp_list = private->children;
3235 gdk_window_set_static_win_gravity (window, use_static);
3237 tmp_list = tmp_list->next;
3244 /* internal function created for and used by gdk_window_xid_at_coords */
3246 gdk_window_xid_at (Window base,
3252 gboolean excl_child)
3255 Window *list = NULL;
3256 Window child = 0, parent_win = 0, root_win = 0;
3258 unsigned int ww, wh, wb, wd, num;
3261 xdisplay = GDK_DISPLAY ();
3262 if (!XGetGeometry (xdisplay, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
3269 (x < (int) (wx + ww)) &&
3270 (y < (int) (wy + wh))))
3273 if (!XQueryTree (xdisplay, base, &root_win, &parent_win, &list, &num))
3278 for (i = num - 1; ; i--)
3280 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
3282 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
3297 * The following fucntion by The Rasterman <raster@redhat.com>
3298 * This function returns the X Window ID in which the x y location is in
3299 * (x and y being relative to the root window), excluding any windows listed
3300 * in the GList excludes (this is a list of X Window ID's - gpointer being
3303 * This is primarily designed for internal gdk use - for DND for example
3304 * when using a shaped icon window as the drag object - you exclude the
3305 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
3306 * You can get back an X Window ID as to what X Window ID is infact under
3307 * those X,Y co-ordinates.
3310 gdk_window_xid_at_coords (gint x,
3313 gboolean excl_child)
3317 Window *list = NULL;
3318 Window root, child = 0, parent_win = 0, root_win = 0;
3322 window = gdk_parent_root;
3323 xdisplay = GDK_WINDOW_XDISPLAY (window);
3324 root = GDK_WINDOW_XID (window);
3325 num = g_list_length (excludes);
3327 XGrabServer (xdisplay);
3328 if (!XQueryTree (xdisplay, root, &root_win, &parent_win, &list, &num))
3330 XUngrabServer (xdisplay);
3338 XWindowAttributes xwa;
3340 XGetWindowAttributes (xdisplay, list [i], &xwa);
3342 if (xwa.map_state != IsViewable)
3345 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
3348 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
3353 if (!g_list_find (excludes, (gpointer *) child))
3356 XUngrabServer (xdisplay);
3363 XUngrabServer (xdisplay);
3369 XUngrabServer (xdisplay);
3374 wmspec_moveresize (GdkWindow *window,
3382 /* Release passive grab */
3383 gdk_pointer_ungrab (timestamp);
3385 xev.xclient.type = ClientMessage;
3386 xev.xclient.serial = 0;
3387 xev.xclient.send_event = True;
3388 xev.xclient.display = gdk_display;
3389 xev.xclient.window = GDK_WINDOW_XID (window);
3390 xev.xclient.message_type = gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE);
3391 xev.xclient.format = 32;
3392 xev.xclient.data.l[0] = root_x;
3393 xev.xclient.data.l[1] = root_y;
3394 xev.xclient.data.l[2] = direction;
3395 xev.xclient.data.l[3] = 0;
3396 xev.xclient.data.l[4] = 0;
3398 XSendEvent (gdk_display, gdk_root_window, False,
3399 SubstructureRedirectMask | SubstructureNotifyMask,
3403 /* From the WM spec */
3404 #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
3405 #define _NET_WM_MOVERESIZE_SIZE_TOP 1
3406 #define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
3407 #define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
3408 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
3409 #define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
3410 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
3411 #define _NET_WM_MOVERESIZE_SIZE_LEFT 7
3412 #define _NET_WM_MOVERESIZE_MOVE 8
3415 wmspec_resize_drag (GdkWindow *window,
3424 /* Let the compiler turn a switch into a table, instead
3425 * of doing the table manually, this way is easier to verify.
3429 case GDK_WINDOW_EDGE_NORTH_WEST:
3430 direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
3433 case GDK_WINDOW_EDGE_NORTH:
3434 direction = _NET_WM_MOVERESIZE_SIZE_TOP;
3437 case GDK_WINDOW_EDGE_NORTH_EAST:
3438 direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
3441 case GDK_WINDOW_EDGE_WEST:
3442 direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
3445 case GDK_WINDOW_EDGE_EAST:
3446 direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
3449 case GDK_WINDOW_EDGE_SOUTH_WEST:
3450 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
3453 case GDK_WINDOW_EDGE_SOUTH:
3454 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
3457 case GDK_WINDOW_EDGE_SOUTH_EAST:
3458 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
3462 g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
3468 wmspec_moveresize (window, direction, root_x, root_y, timestamp);
3471 /* This is global for use in gdkevents-x11.c */
3472 GdkWindow *_gdk_moveresize_window;
3474 static GdkWindow *moveresize_emulation_window = NULL;
3475 static gboolean is_resize = FALSE;
3476 static GdkWindowEdge resize_edge;
3477 static gint moveresize_button;
3478 static gint moveresize_x;
3479 static gint moveresize_y;
3480 static gint moveresize_orig_x;
3481 static gint moveresize_orig_y;
3482 static gint moveresize_orig_width;
3483 static gint moveresize_orig_height;
3484 static GdkWindowHints moveresize_geom_mask = 0;
3485 static GdkGeometry moveresize_geometry;
3486 static Time moveresize_process_time;
3488 static XEvent *moveresize_pending_event;
3491 update_pos (gint new_root_x,
3496 dx = new_root_x - moveresize_x;
3497 dy = new_root_y - moveresize_y;
3503 w = moveresize_orig_width;
3504 h = moveresize_orig_height;
3506 switch (resize_edge)
3508 case GDK_WINDOW_EDGE_SOUTH_EAST:
3517 if (moveresize_geom_mask)
3519 gdk_window_constrain_size (&moveresize_geometry,
3520 moveresize_geom_mask,
3525 gdk_window_resize (_gdk_moveresize_window, w, h);
3531 x = moveresize_orig_x + dx;
3532 y = moveresize_orig_y + dy;
3534 gdk_window_move (_gdk_moveresize_window, x, y);
3541 gdk_window_destroy (moveresize_emulation_window);
3542 moveresize_emulation_window = NULL;
3543 _gdk_moveresize_window = NULL;
3545 if (moveresize_pending_event)
3547 g_free (moveresize_pending_event);
3548 moveresize_pending_event = NULL;
3553 lookahead_motion_predicate (Display *display,
3557 gboolean *seen_release = (gboolean *)arg;
3562 switch (event->xany.type)
3565 *seen_release = TRUE;
3568 moveresize_process_time = event->xmotion.time;
3578 moveresize_lookahead (XEvent *event)
3581 gboolean seen_release = FALSE;
3583 if (moveresize_process_time)
3585 if (event->xmotion.time == moveresize_process_time)
3587 moveresize_process_time = 0;
3594 XCheckIfEvent (gdk_display, &tmp_event,
3595 lookahead_motion_predicate, (XPointer)&seen_release);
3597 return moveresize_process_time == 0;
3601 _gdk_moveresize_handle_event (XEvent *event)
3603 guint button_mask = 0;
3604 GdkWindowObject *window_private = (GdkWindowObject *) _gdk_moveresize_window;
3606 button_mask = GDK_BUTTON1_MASK << (moveresize_button - 1);
3608 switch (event->xany.type)
3611 if (window_private->resize_count > 0)
3613 if (moveresize_pending_event)
3614 *moveresize_pending_event = *event;
3616 moveresize_pending_event = g_memdup (event, sizeof (XEvent));
3620 if (!moveresize_lookahead (event))
3623 update_pos (event->xmotion.x_root,
3624 event->xmotion.y_root);
3626 /* This should never be triggered in normal cases, but in the
3627 * case where the drag started without an implicit grab being
3628 * in effect, we could miss the release if it occurs before
3629 * we grab the pointer; this ensures that we will never
3630 * get a permanently stuck grab.
3632 if ((event->xmotion.state & button_mask) == 0)
3637 update_pos (event->xbutton.x_root,
3638 event->xbutton.y_root);
3640 if (event->xbutton.button == moveresize_button)
3647 _gdk_moveresize_configure_done (void)
3651 if (moveresize_pending_event)
3653 tmp_event = moveresize_pending_event;
3654 moveresize_pending_event = NULL;
3655 _gdk_moveresize_handle_event (tmp_event);
3661 create_moveresize_window (guint32 timestamp)
3663 GdkWindowAttr attributes;
3664 gint attributes_mask;
3665 GdkGrabStatus status;
3667 g_assert (moveresize_emulation_window == NULL);
3669 attributes.x = -100;
3670 attributes.y = -100;
3671 attributes.width = 10;
3672 attributes.height = 10;
3673 attributes.window_type = GDK_WINDOW_TEMP;
3674 attributes.wclass = GDK_INPUT_ONLY;
3675 attributes.override_redirect = TRUE;
3676 attributes.event_mask = 0;
3678 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
3680 moveresize_emulation_window =
3681 gdk_window_new (NULL, &attributes, attributes_mask);
3683 gdk_window_show (moveresize_emulation_window);
3685 status = gdk_pointer_grab (moveresize_emulation_window,
3687 GDK_BUTTON_RELEASE_MASK |
3688 GDK_POINTER_MOTION_MASK,
3693 if (status != GDK_GRAB_SUCCESS)
3695 /* If this fails, some other client has grabbed the window
3698 gdk_window_destroy (moveresize_emulation_window);
3699 moveresize_emulation_window = NULL;
3702 moveresize_process_time = 0;
3706 emulate_resize_drag (GdkWindow *window,
3714 moveresize_button = button;
3716 moveresize_x = root_x;
3717 moveresize_y = root_y;
3718 _gdk_moveresize_window = GDK_WINDOW (g_object_ref (G_OBJECT (window)));
3720 gdk_window_get_size (window, &moveresize_orig_width, &moveresize_orig_height);
3722 moveresize_geom_mask = 0;
3723 gdk_window_get_geometry_hints (window,
3724 &moveresize_geometry,
3725 &moveresize_geom_mask);
3727 create_moveresize_window (timestamp);
3731 emulate_move_drag (GdkWindow *window,
3738 moveresize_button = button;
3739 moveresize_x = root_x;
3740 moveresize_y = root_y;
3741 _gdk_moveresize_window = GDK_WINDOW (g_object_ref (G_OBJECT (window)));
3743 gdk_window_get_deskrelative_origin (_gdk_moveresize_window,
3745 &moveresize_orig_y);
3747 create_moveresize_window (timestamp);
3751 gdk_window_begin_resize_drag (GdkWindow *window,
3758 g_return_if_fail (GDK_IS_WINDOW (window));
3759 g_return_if_fail (moveresize_emulation_window == NULL);
3761 if (GDK_WINDOW_DESTROYED (window))
3764 if (gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
3765 wmspec_resize_drag (window, edge, button, root_x, root_y, timestamp);
3767 emulate_resize_drag (window, edge, button, root_x, root_y, timestamp);
3771 gdk_window_begin_move_drag (GdkWindow *window,
3777 g_return_if_fail (GDK_IS_WINDOW (window));
3778 g_return_if_fail (moveresize_emulation_window == NULL);
3780 if (GDK_WINDOW_DESTROYED (window))
3783 if (gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
3784 wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE,
3785 root_x, root_y, timestamp);
3787 emulate_move_drag (window, button, root_x, root_y, timestamp);