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);
174 if (window_impl->focus_window)
175 gdk_xid_table_remove (window_impl->focus_window);
178 G_OBJECT_CLASS (parent_class)->finalize (object);
182 gdk_window_impl_x11_get_colormap (GdkDrawable *drawable)
184 GdkDrawableImplX11 *drawable_impl;
185 GdkWindowImplX11 *window_impl;
187 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable), NULL);
189 drawable_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
190 window_impl = GDK_WINDOW_IMPL_X11 (drawable);
192 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
193 drawable_impl->colormap == NULL)
195 XWindowAttributes window_attributes;
197 XGetWindowAttributes (drawable_impl->xdisplay,
200 drawable_impl->colormap =
201 gdk_colormap_lookup (window_attributes.colormap);
204 return drawable_impl->colormap;
208 gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
211 GdkWindowImplX11 *impl;
212 GdkDrawableImplX11 *draw_impl;
214 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
216 impl = GDK_WINDOW_IMPL_X11 (drawable);
217 draw_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
220 GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
224 XSetWindowColormap (draw_impl->xdisplay,
226 GDK_COLORMAP_XCOLORMAP (cmap));
228 if (((GdkWindowObject*)draw_impl->wrapper)->window_type !=
230 gdk_window_add_colormap_windows (GDK_WINDOW (draw_impl->wrapper));
236 gdk_window_impl_x11_get_size (GdkDrawable *drawable,
240 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
243 *width = GDK_WINDOW_IMPL_X11 (drawable)->width;
245 *height = GDK_WINDOW_IMPL_X11 (drawable)->height;
249 gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable)
251 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (drawable);
252 GdkRectangle result_rect;
256 result_rect.width = impl->width;
257 result_rect.height = impl->height;
259 gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
261 return gdk_region_rectangle (&result_rect);
265 _gdk_windowing_window_init (void)
267 GdkWindowObject *private;
268 GdkWindowImplX11 *impl;
269 GdkDrawableImplX11 *draw_impl;
270 XWindowAttributes xattributes;
273 unsigned int border_width;
277 g_assert (gdk_parent_root == NULL);
279 XGetGeometry (gdk_display, gdk_root_window, &gdk_root_window,
280 &x, &y, &width, &height, &border_width, &depth);
281 XGetWindowAttributes (gdk_display, gdk_root_window, &xattributes);
283 gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
284 private = (GdkWindowObject *)gdk_parent_root;
285 impl = GDK_WINDOW_IMPL_X11 (private->impl);
286 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
288 draw_impl->xdisplay = gdk_display;
289 draw_impl->xid = gdk_root_window;
290 draw_impl->wrapper = GDK_DRAWABLE (private);
292 private->window_type = GDK_WINDOW_ROOT;
293 private->depth = depth;
295 impl->height = height;
297 gdk_xid_table_insert (&gdk_root_window, gdk_parent_root);
300 static GdkAtom wm_client_leader_atom = GDK_NONE;
303 gdk_window_new (GdkWindow *parent,
304 GdkWindowAttr *attributes,
305 gint attributes_mask)
308 GdkWindowObject *private;
309 GdkWindowObject *parent_private;
310 GdkWindowImplX11 *impl;
311 GdkDrawableImplX11 *draw_impl;
319 XSetWindowAttributes xattributes;
320 long xattributes_mask;
321 XSizeHints size_hints;
323 XClassHint *class_hint;
330 g_return_val_if_fail (attributes != NULL, NULL);
333 parent = gdk_parent_root;
335 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
337 parent_private = (GdkWindowObject*) parent;
338 if (GDK_WINDOW_DESTROYED (parent))
341 xparent = GDK_WINDOW_XID (parent);
343 window = g_object_new (GDK_TYPE_WINDOW, NULL);
344 private = (GdkWindowObject *)window;
345 impl = GDK_WINDOW_IMPL_X11 (private->impl);
346 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
347 draw_impl->wrapper = GDK_DRAWABLE (window);
349 xdisplay = draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (parent);
351 private->parent = (GdkWindowObject *)parent;
353 xattributes_mask = 0;
355 if (attributes_mask & GDK_WA_X)
360 if (attributes_mask & GDK_WA_Y)
367 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
368 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
369 private->window_type = attributes->window_type;
371 _gdk_window_init_position (GDK_WINDOW (private));
372 if (impl->position_info.big)
373 private->guffaw_gravity = TRUE;
375 if (attributes_mask & GDK_WA_VISUAL)
376 visual = attributes->visual;
378 visual = gdk_visual_get_system ();
379 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
381 xattributes.event_mask = StructureNotifyMask;
382 for (i = 0; i < gdk_nevent_masks; i++)
384 if (attributes->event_mask & (1 << (i + 1)))
385 xattributes.event_mask |= gdk_event_mask_table[i];
388 if (xattributes.event_mask)
389 xattributes_mask |= CWEventMask;
391 if (attributes_mask & GDK_WA_NOREDIR)
393 xattributes.override_redirect =
394 (attributes->override_redirect == FALSE)?False:True;
395 xattributes_mask |= CWOverrideRedirect;
398 xattributes.override_redirect = False;
400 if (parent_private && parent_private->guffaw_gravity)
402 xattributes.win_gravity = StaticGravity;
403 xattributes_mask |= CWWinGravity;
406 if (attributes->wclass == GDK_INPUT_OUTPUT)
409 depth = visual->depth;
411 private->input_only = FALSE;
412 private->depth = depth;
414 if (attributes_mask & GDK_WA_COLORMAP)
416 draw_impl->colormap = attributes->colormap;
417 gdk_colormap_ref (attributes->colormap);
421 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
423 draw_impl->colormap =
424 gdk_colormap_get_system ();
425 gdk_colormap_ref (draw_impl->colormap);
429 draw_impl->colormap =
430 gdk_colormap_new (visual, FALSE);
434 private->bg_color.pixel = BlackPixel (gdk_display, gdk_screen);
435 xattributes.background_pixel = private->bg_color.pixel;
437 private->bg_pixmap = NULL;
439 xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
440 xattributes_mask |= CWBorderPixel | CWBackPixel;
442 if (private->guffaw_gravity)
443 xattributes.bit_gravity = StaticGravity;
445 xattributes.bit_gravity = NorthWestGravity;
447 xattributes_mask |= CWBitGravity;
449 switch (private->window_type)
451 case GDK_WINDOW_TOPLEVEL:
452 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
453 xattributes_mask |= CWColormap;
455 xparent = gdk_root_window;
458 case GDK_WINDOW_CHILD:
459 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
460 xattributes_mask |= CWColormap;
463 case GDK_WINDOW_DIALOG:
464 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
465 xattributes_mask |= CWColormap;
467 xparent = gdk_root_window;
470 case GDK_WINDOW_TEMP:
471 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
472 xattributes_mask |= CWColormap;
474 xparent = gdk_root_window;
476 xattributes.save_under = True;
477 xattributes.override_redirect = True;
478 xattributes.cursor = None;
479 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
481 case GDK_WINDOW_ROOT:
482 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
491 private->input_only = TRUE;
492 draw_impl->colormap = gdk_colormap_get_system ();
493 gdk_colormap_ref (draw_impl->colormap);
496 xid = draw_impl->xid = XCreateWindow (xdisplay, xparent,
497 impl->position_info.x, impl->position_info.y,
498 impl->position_info.width, impl->position_info.height,
499 0, depth, class, xvisual,
500 xattributes_mask, &xattributes);
502 gdk_drawable_ref (window);
503 gdk_xid_table_insert (&draw_impl->xid, window);
505 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
506 (attributes->cursor) :
510 parent_private->children = g_list_prepend (parent_private->children, window);
512 switch (GDK_WINDOW_TYPE (private))
514 case GDK_WINDOW_DIALOG:
515 XSetTransientForHint (xdisplay, xid, xparent);
516 case GDK_WINDOW_TOPLEVEL:
517 case GDK_WINDOW_TEMP:
518 XSetWMProtocols (xdisplay, xid,
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 if (class != InputOnly)
538 /* The focus window is off the visible area, and serves to receive key
539 * press events so they don't get sent to child windows.
541 impl->focus_window = XCreateSimpleWindow (xdisplay, xid,
543 xattributes.background_pixel,
544 xattributes.background_pixel);
545 /* FIXME: probably better to actually track the requested event mask for the toplevel
547 XSelectInput (xdisplay, impl->focus_window,
548 KeyPressMask | KeyReleaseMask | FocusChangeMask);
550 XMapWindow (xdisplay, impl->focus_window);
551 gdk_xid_table_insert (&impl->focus_window, window);
554 size_hints.flags = PSize;
555 size_hints.width = impl->width;
556 size_hints.height = impl->height;
558 wm_hints.flags = StateHint | WindowGroupHint;
559 wm_hints.window_group = gdk_leader_window;
560 wm_hints.input = True;
561 wm_hints.initial_state = NormalState;
563 /* FIXME: Is there any point in doing this? Do any WM's pay
564 * attention to PSize, and even if they do, is this the
567 XSetWMNormalHints (xdisplay, xid, &size_hints);
569 XSetWMHints (xdisplay, xid, &wm_hints);
571 if (!wm_client_leader_atom)
572 wm_client_leader_atom = gdk_atom_intern ("WM_CLIENT_LEADER", FALSE);
574 XChangeProperty (xdisplay, xid,
575 wm_client_leader_atom,
576 XA_WINDOW, 32, PropModeReplace,
577 (guchar*) &gdk_leader_window, 1);
579 if (attributes_mask & GDK_WA_TITLE)
580 title = attributes->title;
582 title = g_get_prgname ();
584 gdk_window_set_title (window, title);
586 if (attributes_mask & GDK_WA_WMCLASS)
588 class_hint = XAllocClassHint ();
589 class_hint->res_name = attributes->wmclass_name;
590 class_hint->res_class = attributes->wmclass_class;
591 XSetClassHint (xdisplay, xid, class_hint);
599 gdk_window_foreign_new (GdkNativeWindow anid)
602 GdkWindowObject *private;
603 GdkWindowObject *parent_private;
604 GdkWindowImplX11 *impl;
605 GdkDrawableImplX11 *draw_impl;
606 XWindowAttributes attrs;
608 Window *children = NULL;
612 gdk_error_trap_push ();
613 result = XGetWindowAttributes (gdk_display, anid, &attrs);
614 if (gdk_error_trap_pop () || !result)
617 /* FIXME: This is pretty expensive. Maybe the caller should supply
619 gdk_error_trap_push ();
620 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
621 if (gdk_error_trap_pop () || !result)
627 window = g_object_new (GDK_TYPE_WINDOW, NULL);
628 private = (GdkWindowObject *)window;
629 impl = GDK_WINDOW_IMPL_X11 (private->impl);
630 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
631 draw_impl->wrapper = GDK_DRAWABLE (window);
633 private->parent = gdk_xid_table_lookup (parent);
635 parent_private = (GdkWindowObject *)private->parent;
638 parent_private->children = g_list_prepend (parent_private->children, window);
640 draw_impl->xid = anid;
641 draw_impl->xdisplay = gdk_display;
643 private->x = attrs.x;
644 private->y = attrs.y;
645 impl->width = attrs.width;
646 impl->height = attrs.height;
647 private->window_type = GDK_WINDOW_FOREIGN;
648 private->destroyed = FALSE;
650 if (attrs.map_state == IsUnmapped)
651 private->state = GDK_WINDOW_STATE_WITHDRAWN;
655 private->depth = attrs.depth;
657 _gdk_window_init_position (GDK_WINDOW (private));
659 gdk_drawable_ref (window);
660 gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
666 _gdk_windowing_window_destroy (GdkWindow *window,
668 gboolean foreign_destroy)
670 GdkWindowObject *private = (GdkWindowObject *)window;
672 g_return_if_fail (GDK_IS_WINDOW (window));
674 _gdk_selection_window_destroyed (window);
676 if (private->extension_events != 0)
677 gdk_input_window_destroy (window);
679 if (private->window_type == GDK_WINDOW_FOREIGN)
681 if (!foreign_destroy && (private->parent != NULL))
683 /* It's somebody else's window, but in our heirarchy,
684 * so reparent it to the root window, and then send
685 * it a delete event, as if we were a WM
687 XClientMessageEvent xevent;
689 gdk_error_trap_push ();
690 gdk_window_hide (window);
691 gdk_window_reparent (window, NULL, 0, 0);
693 xevent.type = ClientMessage;
694 xevent.window = GDK_WINDOW_XID (window);
695 xevent.message_type = gdk_wm_protocols;
697 xevent.data.l[0] = gdk_wm_delete_window;
698 xevent.data.l[1] = CurrentTime;
700 XSendEvent (GDK_WINDOW_XDISPLAY (window),
701 GDK_WINDOW_XID (window),
702 False, 0, (XEvent *)&xevent);
704 gdk_error_trap_pop ();
707 else if (!recursing && !foreign_destroy)
708 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
711 /* This function is called when the XWindow is really gone.
714 gdk_window_destroy_notify (GdkWindow *window)
716 GdkWindowImplX11 *window_impl;
718 g_return_if_fail (window != NULL);
720 window_impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl);
722 if (!GDK_WINDOW_DESTROYED (window))
724 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
725 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_WINDOW_XID (window));
727 _gdk_window_destroy (window, TRUE);
730 gdk_xid_table_remove (GDK_WINDOW_XID (window));
731 if (window_impl->focus_window)
732 gdk_xid_table_remove (window_impl->focus_window);
734 gdk_drawable_unref (window);
738 set_initial_hints (GdkWindow *window)
740 GdkWindowObject *private;
744 private = (GdkWindowObject*) window;
746 if (private->state & GDK_WINDOW_STATE_ICONIFIED)
750 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
751 GDK_WINDOW_XID (window));
753 wm_hints = XAllocWMHints ();
755 wm_hints->flags |= StateHint;
756 wm_hints->initial_state = IconicState;
758 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
759 GDK_WINDOW_XID (window), wm_hints);
763 /* We set the spec hints regardless of whether the spec is supported,
764 * since it can't hurt and it's kind of expensive to check whether
770 if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
772 atoms[i] = gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE);
774 atoms[i] = gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE);
778 if (private->state & GDK_WINDOW_STATE_STICKY)
780 atoms[i] = gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE);
784 if (private->modal_hint)
786 atoms[i] = gdk_atom_intern ("_NET_WM_STATE_MODAL", FALSE);
792 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
793 GDK_WINDOW_XID (window),
794 gdk_atom_intern ("_NET_WM_STATE", FALSE),
795 XA_ATOM, 32, PropModeReplace,
799 if (private->state & GDK_WINDOW_STATE_STICKY)
801 atoms[0] = 0xFFFFFFFF;
802 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
803 GDK_WINDOW_XID (window),
804 gdk_atom_intern ("_NET_WM_DESKTOP", FALSE),
805 XA_CARDINAL, 32, PropModeReplace,
811 show_window_internal (GdkWindow *window,
814 GdkWindowObject *private;
816 g_return_if_fail (GDK_IS_WINDOW (window));
818 private = (GdkWindowObject*) window;
819 if (!private->destroyed)
822 XRaiseWindow (GDK_WINDOW_XDISPLAY (window),
823 GDK_WINDOW_XID (window));
825 if (!GDK_WINDOW_IS_MAPPED (window))
827 set_initial_hints (window);
829 gdk_synthesize_window_state (window,
830 GDK_WINDOW_STATE_WITHDRAWN,
834 g_assert (GDK_WINDOW_IS_MAPPED (window));
836 if (GDK_WINDOW_IMPL_X11 (private->impl)->position_info.mapped)
837 XMapWindow (GDK_WINDOW_XDISPLAY (window),
838 GDK_WINDOW_XID (window));
843 * gdk_window_show_unraised:
844 * @window: a #GdkWindow
846 * Shows a #GdkWindow onscreen, but does not modify its stacking
847 * order. In contrast, gdk_window_show() will raise the window
848 * to the top of the window stack.
852 gdk_window_show_unraised (GdkWindow *window)
854 g_return_if_fail (GDK_IS_WINDOW (window));
856 show_window_internal (window, FALSE);
860 gdk_window_show (GdkWindow *window)
862 g_return_if_fail (GDK_IS_WINDOW (window));
864 show_window_internal (window, TRUE);
868 gdk_window_hide (GdkWindow *window)
870 GdkWindowObject *private;
872 g_return_if_fail (window != NULL);
874 private = (GdkWindowObject*) window;
876 /* You can't simply unmap toplevel windows. */
877 switch (private->window_type)
879 case GDK_WINDOW_TOPLEVEL:
880 case GDK_WINDOW_DIALOG:
881 case GDK_WINDOW_TEMP: /* ? */
882 gdk_window_withdraw (window);
886 case GDK_WINDOW_FOREIGN:
887 case GDK_WINDOW_ROOT:
888 case GDK_WINDOW_CHILD:
892 if (!private->destroyed)
894 if (GDK_WINDOW_IS_MAPPED (window))
895 gdk_synthesize_window_state (window,
897 GDK_WINDOW_STATE_WITHDRAWN);
899 g_assert (!GDK_WINDOW_IS_MAPPED (window));
901 _gdk_window_clear_update_area (window);
903 XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
904 GDK_WINDOW_XID (window));
909 gdk_window_withdraw (GdkWindow *window)
911 GdkWindowObject *private;
913 g_return_if_fail (window != NULL);
915 private = (GdkWindowObject*) window;
916 if (!private->destroyed)
918 if (GDK_WINDOW_IS_MAPPED (window))
919 gdk_synthesize_window_state (window,
921 GDK_WINDOW_STATE_WITHDRAWN);
923 g_assert (!GDK_WINDOW_IS_MAPPED (window));
925 XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
926 GDK_WINDOW_XID (window), 0);
931 gdk_window_move (GdkWindow *window,
935 GdkWindowObject *private = (GdkWindowObject *)window;
936 GdkWindowImplX11 *impl;
938 g_return_if_fail (window != NULL);
939 g_return_if_fail (GDK_IS_WINDOW (window));
941 impl = GDK_WINDOW_IMPL_X11 (private->impl);
943 if (!GDK_WINDOW_DESTROYED (window))
945 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
946 _gdk_window_move_resize_child (window, x, y,
947 impl->width, impl->height);
950 XMoveWindow (GDK_WINDOW_XDISPLAY (window),
951 GDK_WINDOW_XID (window),
958 gdk_window_resize (GdkWindow *window,
962 GdkWindowObject *private;
964 g_return_if_fail (window != NULL);
965 g_return_if_fail (GDK_IS_WINDOW (window));
972 private = (GdkWindowObject*) window;
974 if (!GDK_WINDOW_DESTROYED (window))
976 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
977 _gdk_window_move_resize_child (window, private->x, private->y,
981 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
983 if (width != impl->width || height != impl->height)
984 private->resize_count += 1;
986 XResizeWindow (GDK_WINDOW_XDISPLAY (window),
987 GDK_WINDOW_XID (window),
994 gdk_window_move_resize (GdkWindow *window,
1000 GdkWindowObject *private;
1002 g_return_if_fail (window != NULL);
1003 g_return_if_fail (GDK_IS_WINDOW (window));
1010 private = (GdkWindowObject*) window;
1012 if (!GDK_WINDOW_DESTROYED (window))
1014 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1015 _gdk_window_move_resize_child (window, x, y, width, height);
1018 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1020 if (width != impl->width || height != impl->height)
1021 private->resize_count += 1;
1023 XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
1024 GDK_WINDOW_XID (window),
1025 x, y, width, height);
1031 gdk_window_reparent (GdkWindow *window,
1032 GdkWindow *new_parent,
1036 GdkWindowObject *window_private;
1037 GdkWindowObject *parent_private;
1038 GdkWindowObject *old_parent_private;
1040 g_return_if_fail (window != NULL);
1041 g_return_if_fail (GDK_IS_WINDOW (window));
1042 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1045 new_parent = gdk_parent_root;
1047 window_private = (GdkWindowObject*) window;
1048 old_parent_private = (GdkWindowObject*)window_private->parent;
1049 parent_private = (GdkWindowObject*) new_parent;
1051 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
1052 XReparentWindow (GDK_WINDOW_XDISPLAY (window),
1053 GDK_WINDOW_XID (window),
1054 GDK_WINDOW_XID (new_parent),
1057 window_private->parent = (GdkWindowObject *)new_parent;
1059 if (old_parent_private)
1060 old_parent_private->children = g_list_remove (old_parent_private->children, window);
1062 if ((old_parent_private &&
1063 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1064 (!old_parent_private && parent_private->guffaw_gravity))
1065 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1067 parent_private->children = g_list_prepend (parent_private->children, window);
1068 _gdk_window_init_position (GDK_WINDOW (window_private));
1072 _gdk_windowing_window_clear_area (GdkWindow *window,
1078 g_return_if_fail (window != NULL);
1079 g_return_if_fail (GDK_IS_WINDOW (window));
1081 if (!GDK_WINDOW_DESTROYED (window))
1082 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1083 x, y, width, height, False);
1087 _gdk_windowing_window_clear_area_e (GdkWindow *window,
1093 g_return_if_fail (window != NULL);
1094 g_return_if_fail (GDK_IS_WINDOW (window));
1096 if (!GDK_WINDOW_DESTROYED (window))
1097 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1098 x, y, width, height, True);
1102 gdk_window_raise (GdkWindow *window)
1104 g_return_if_fail (window != NULL);
1105 g_return_if_fail (GDK_IS_WINDOW (window));
1107 if (!GDK_WINDOW_DESTROYED (window))
1108 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1112 gdk_window_lower (GdkWindow *window)
1114 g_return_if_fail (window != NULL);
1115 g_return_if_fail (GDK_IS_WINDOW (window));
1117 if (!GDK_WINDOW_DESTROYED (window))
1118 XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1122 gdk_window_focus (GdkWindow *window,
1125 g_return_if_fail (GDK_IS_WINDOW (window));
1127 if (GDK_WINDOW_DESTROYED (window))
1130 if (gdk_net_wm_supports (gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE)))
1134 xev.xclient.type = ClientMessage;
1135 xev.xclient.serial = 0;
1136 xev.xclient.send_event = True;
1137 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
1138 xev.xclient.display = gdk_display;
1139 xev.xclient.message_type = gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE);
1140 xev.xclient.format = 32;
1141 xev.xclient.data.l[0] = 0;
1143 XSendEvent (gdk_display, gdk_root_window, False,
1144 SubstructureRedirectMask | SubstructureNotifyMask,
1149 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1151 /* There is no way of knowing reliably whether we are viewable so we need
1152 * to trap errors so we don't cause a BadMatch.
1154 gdk_error_trap_push ();
1155 XSetInputFocus (GDK_WINDOW_XDISPLAY (window),
1156 GDK_WINDOW_XWINDOW (window),
1159 XSync (GDK_WINDOW_XDISPLAY (window), False);
1160 gdk_error_trap_pop ();
1165 gdk_window_set_hints (GdkWindow *window,
1174 XSizeHints size_hints;
1176 g_return_if_fail (window != NULL);
1177 g_return_if_fail (GDK_IS_WINDOW (window));
1179 if (GDK_WINDOW_DESTROYED (window))
1182 size_hints.flags = 0;
1184 if (flags & GDK_HINT_POS)
1186 size_hints.flags |= PPosition;
1191 if (flags & GDK_HINT_MIN_SIZE)
1193 size_hints.flags |= PMinSize;
1194 size_hints.min_width = min_width;
1195 size_hints.min_height = min_height;
1198 if (flags & GDK_HINT_MAX_SIZE)
1200 size_hints.flags |= PMaxSize;
1201 size_hints.max_width = max_width;
1202 size_hints.max_height = max_height;
1205 /* FIXME: Would it be better to delete this property if
1206 * flags == 0? It would save space on the server
1208 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1209 GDK_WINDOW_XID (window),
1214 * gdk_window_set_type_hint:
1215 * @window: A #GdkWindow
1216 * @hint: A hint of the function this window will have
1218 * The application can use this call to provide a hint to the window
1219 * manager about the functionality of a window. The window manager
1220 * can use this information when determining the decoration and behaviour
1223 * The hint must be set before the window is mapped.
1226 gdk_window_set_type_hint (GdkWindow *window,
1227 GdkWindowTypeHint hint)
1231 g_return_if_fail (window != NULL);
1232 g_return_if_fail (GDK_IS_WINDOW (window));
1234 if (GDK_WINDOW_DESTROYED (window))
1239 case GDK_WINDOW_TYPE_HINT_DIALOG:
1240 atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_DIALOG", FALSE);
1242 case GDK_WINDOW_TYPE_HINT_MENU:
1243 atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_MENU", FALSE);
1245 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1246 atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_TOOLBAR", FALSE);
1249 g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
1251 case GDK_WINDOW_TYPE_HINT_NORMAL:
1252 atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_NORMAL", FALSE);
1256 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1257 GDK_WINDOW_XID (window),
1258 gdk_atom_intern ("_NET_WM_WINDOW_TYPE", FALSE),
1259 XA_ATOM, 32, PropModeReplace,
1260 (guchar *)&atom, 1);
1265 gdk_wmspec_change_state (gboolean add,
1272 #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
1273 #define _NET_WM_STATE_ADD 1 /* add/set property */
1274 #define _NET_WM_STATE_TOGGLE 2 /* toggle property */
1276 xev.xclient.type = ClientMessage;
1277 xev.xclient.serial = 0;
1278 xev.xclient.send_event = True;
1279 xev.xclient.display = gdk_display;
1280 xev.xclient.window = GDK_WINDOW_XID (window);
1281 xev.xclient.message_type = gdk_atom_intern ("_NET_WM_STATE", FALSE);
1282 xev.xclient.format = 32;
1283 xev.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
1284 xev.xclient.data.l[1] = state1;
1285 xev.xclient.data.l[2] = state2;
1287 XSendEvent (gdk_display, gdk_root_window, False,
1288 SubstructureRedirectMask | SubstructureNotifyMask,
1292 * gdk_window_set_modal_hint:
1293 * @window: A #GdkWindow
1294 * @modal: TRUE if the window is modal, FALSE otherwise.
1296 * The application can use this hint to tell the window manager
1297 * that a certain window has modal behaviour. The window manager
1298 * can use this information to handle modal windows in a special
1301 * You should only use this on windows for which you have
1302 * previously called #gdk_window_set_transient_for()
1305 gdk_window_set_modal_hint (GdkWindow *window,
1308 GdkWindowObject *private;
1310 g_return_if_fail (window != NULL);
1311 g_return_if_fail (GDK_IS_WINDOW (window));
1313 if (GDK_WINDOW_DESTROYED (window))
1316 private = (GdkWindowObject*) window;
1318 private->modal_hint = modal;
1320 if (GDK_WINDOW_IS_MAPPED (window))
1321 gdk_wmspec_change_state (modal, window,
1322 gdk_atom_intern ("_NET_WM_STATE_MODAL", FALSE),
1327 gdk_window_set_geometry_hints (GdkWindow *window,
1328 GdkGeometry *geometry,
1329 GdkWindowHints geom_mask)
1331 XSizeHints size_hints;
1333 g_return_if_fail (window != NULL);
1334 g_return_if_fail (GDK_IS_WINDOW (window));
1336 if (GDK_WINDOW_DESTROYED (window))
1339 size_hints.flags = 0;
1341 if (geom_mask & GDK_HINT_POS)
1343 size_hints.flags |= PPosition;
1344 /* We need to initialize the following obsolete fields because KWM
1345 * apparently uses these fields if they are non-zero.
1352 if (geom_mask & GDK_HINT_MIN_SIZE)
1354 size_hints.flags |= PMinSize;
1355 size_hints.min_width = geometry->min_width;
1356 size_hints.min_height = geometry->min_height;
1359 if (geom_mask & GDK_HINT_MAX_SIZE)
1361 size_hints.flags |= PMaxSize;
1362 size_hints.max_width = MAX (geometry->max_width, 1);
1363 size_hints.max_height = MAX (geometry->max_height, 1);
1366 if (geom_mask & GDK_HINT_BASE_SIZE)
1368 size_hints.flags |= PBaseSize;
1369 size_hints.base_width = geometry->base_width;
1370 size_hints.base_height = geometry->base_height;
1373 if (geom_mask & GDK_HINT_RESIZE_INC)
1375 size_hints.flags |= PResizeInc;
1376 size_hints.width_inc = geometry->width_inc;
1377 size_hints.height_inc = geometry->height_inc;
1380 if (geom_mask & GDK_HINT_ASPECT)
1382 size_hints.flags |= PAspect;
1383 if (geometry->min_aspect <= 1)
1385 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
1386 size_hints.min_aspect.y = 65536;
1390 size_hints.min_aspect.x = 65536;
1391 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
1393 if (geometry->max_aspect <= 1)
1395 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
1396 size_hints.max_aspect.y = 65536;
1400 size_hints.max_aspect.x = 65536;
1401 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
1405 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1407 size_hints.flags |= PWinGravity;
1408 size_hints.win_gravity = geometry->win_gravity;
1411 /* FIXME: Would it be better to delete this property if
1412 * geom_mask == 0? It would save space on the server
1414 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1415 GDK_WINDOW_XID (window),
1420 gdk_window_get_geometry_hints (GdkWindow *window,
1421 GdkGeometry *geometry,
1422 GdkWindowHints *geom_mask)
1424 XSizeHints size_hints;
1425 glong junk_size_mask = 0;
1427 g_return_if_fail (GDK_IS_WINDOW (window));
1428 g_return_if_fail (geometry != NULL);
1429 g_return_if_fail (geom_mask != NULL);
1433 if (GDK_WINDOW_DESTROYED (window))
1436 if (!XGetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1437 GDK_WINDOW_XID (window),
1442 if (size_hints.flags & PMinSize)
1444 *geom_mask |= GDK_HINT_MIN_SIZE;
1445 geometry->min_width = size_hints.min_width;
1446 geometry->min_height = size_hints.min_height;
1449 if (size_hints.flags & PMaxSize)
1451 *geom_mask |= GDK_HINT_MAX_SIZE;
1452 geometry->max_width = MAX (size_hints.max_width, 1);
1453 geometry->max_height = MAX (size_hints.max_height, 1);
1456 if (size_hints.flags & PResizeInc)
1458 *geom_mask |= GDK_HINT_RESIZE_INC;
1459 geometry->width_inc = size_hints.width_inc;
1460 geometry->height_inc = size_hints.height_inc;
1463 if (size_hints.flags & PAspect)
1465 *geom_mask |= GDK_HINT_ASPECT;
1467 geometry->min_aspect = (gdouble) size_hints.min_aspect.x / (gdouble) size_hints.min_aspect.y;
1468 geometry->max_aspect = (gdouble) size_hints.max_aspect.x / (gdouble) size_hints.max_aspect.y;
1471 if (size_hints.flags & PWinGravity)
1473 *geom_mask |= GDK_HINT_WIN_GRAVITY;
1474 geometry->win_gravity = size_hints.win_gravity;
1479 utf8_is_latin1 (const gchar *str)
1481 const char *p = str;
1485 gunichar ch = g_utf8_get_char (p);
1490 p = g_utf8_next_char (p);
1496 /* Set the property to @utf8_str as STRING if the @utf8_str is fully
1497 * convertable to STRING, otherwise, set it as compound text
1500 set_text_property (GdkWindow *window,
1502 const gchar *utf8_str)
1504 guchar *prop_text = NULL;
1509 if (utf8_is_latin1 (utf8_str))
1511 prop_type = GDK_TARGET_STRING;
1512 prop_text = gdk_utf8_to_string_target (utf8_str);
1513 prop_length = strlen (prop_text);
1518 gdk_utf8_to_compound_text (utf8_str, &prop_type, &prop_format,
1519 &prop_text, &prop_length);
1524 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1525 GDK_WINDOW_XID (window),
1527 prop_type, prop_format,
1528 PropModeReplace, prop_text,
1536 gdk_window_set_title (GdkWindow *window,
1539 g_return_if_fail (window != NULL);
1540 g_return_if_fail (GDK_IS_WINDOW (window));
1542 if (GDK_WINDOW_DESTROYED (window))
1545 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1546 GDK_WINDOW_XID (window),
1547 gdk_atom_intern ("_NET_WM_NAME", FALSE),
1548 gdk_atom_intern ("UTF8_STRING", FALSE), 8,
1549 PropModeReplace, title,
1552 set_text_property (window, gdk_atom_intern ("WM_NAME", FALSE), title);
1553 if (!gdk_window_icon_name_set (window))
1555 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1556 GDK_WINDOW_XID (window),
1557 gdk_atom_intern ("_NET_WM_ICON_NAME", FALSE),
1558 gdk_atom_intern ("UTF8_STRING", FALSE), 8,
1559 PropModeReplace, title,
1561 set_text_property (window, gdk_atom_intern ("WM_ICON_NAME", FALSE), title);
1566 gdk_window_set_role (GdkWindow *window,
1569 g_return_if_fail (window != NULL);
1570 g_return_if_fail (GDK_IS_WINDOW (window));
1572 if (!GDK_WINDOW_DESTROYED (window))
1575 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1576 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE), XA_STRING,
1577 8, PropModeReplace, role, strlen (role));
1579 XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1580 gdk_atom_intern ("WM_WINDOW_ROLE", FALSE));
1585 gdk_window_set_transient_for (GdkWindow *window,
1588 GdkWindowObject *private;
1589 GdkWindowObject *parent_private;
1591 g_return_if_fail (window != NULL);
1592 g_return_if_fail (GDK_IS_WINDOW (window));
1594 private = (GdkWindowObject*) window;
1595 parent_private = (GdkWindowObject*) parent;
1597 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent))
1598 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
1599 GDK_WINDOW_XID (window),
1600 GDK_WINDOW_XID (parent));
1604 gdk_window_set_background (GdkWindow *window,
1607 GdkWindowObject *private = (GdkWindowObject *)window;
1609 g_return_if_fail (window != NULL);
1610 g_return_if_fail (GDK_IS_WINDOW (window));
1612 if (!GDK_WINDOW_DESTROYED (window))
1613 XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
1614 GDK_WINDOW_XID (window), color->pixel);
1616 private->bg_color = *color;
1618 if (private->bg_pixmap &&
1619 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1620 private->bg_pixmap != GDK_NO_BG)
1622 gdk_pixmap_unref (private->bg_pixmap);
1623 private->bg_pixmap = NULL;
1628 gdk_window_set_back_pixmap (GdkWindow *window,
1630 gboolean parent_relative)
1632 GdkWindowObject *private = (GdkWindowObject *)window;
1635 g_return_if_fail (window != NULL);
1636 g_return_if_fail (GDK_IS_WINDOW (window));
1637 g_return_if_fail (pixmap == NULL || !parent_relative);
1639 if (private->bg_pixmap &&
1640 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1641 private->bg_pixmap != GDK_NO_BG)
1642 gdk_pixmap_unref (private->bg_pixmap);
1644 if (parent_relative)
1646 xpixmap = ParentRelative;
1647 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1653 gdk_pixmap_ref (pixmap);
1654 private->bg_pixmap = pixmap;
1655 xpixmap = GDK_PIXMAP_XID (pixmap);
1660 private->bg_pixmap = GDK_NO_BG;
1664 if (!GDK_WINDOW_DESTROYED (window))
1665 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
1666 GDK_WINDOW_XID (window), xpixmap);
1670 gdk_window_set_cursor (GdkWindow *window,
1673 GdkCursorPrivate *cursor_private;
1676 g_return_if_fail (window != NULL);
1677 g_return_if_fail (GDK_IS_WINDOW (window));
1679 cursor_private = (GdkCursorPrivate*) cursor;
1684 xcursor = cursor_private->xcursor;
1686 if (!GDK_WINDOW_DESTROYED (window))
1687 XDefineCursor (GDK_WINDOW_XDISPLAY (window),
1688 GDK_WINDOW_XID (window),
1693 gdk_window_get_geometry (GdkWindow *window,
1705 guint tborder_width;
1708 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1711 window = gdk_parent_root;
1713 if (!GDK_WINDOW_DESTROYED (window))
1715 XGetGeometry (GDK_WINDOW_XDISPLAY (window),
1716 GDK_WINDOW_XID (window),
1717 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
1733 * gdk_window_get_origin:
1734 * @window: a #GdkWindow
1735 * @x: return location for X coordinate
1736 * @y: return location for Y coordinate
1738 * Obtains the position of a window in root window coordinates.
1739 * (Compare with gdk_window_get_position() and
1740 * gdk_window_get_geometry() which return the position of a window
1741 * relative to its parent window.)
1743 * Return value: not meaningful, ignore
1746 gdk_window_get_origin (GdkWindow *window,
1755 g_return_val_if_fail (window != NULL, 0);
1757 if (!GDK_WINDOW_DESTROYED (window))
1759 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1760 GDK_WINDOW_XID (window),
1778 * gdk_window_get_deskrelative_origin:
1779 * @window: a #GdkWindow
1780 * @x: return location for X coordinate
1781 * @y: return location for Y coordinate
1783 * This gets the origin of a #GdkWindow relative to
1784 * an Enlightenment-window-manager desktop. As long as you don't
1785 * assume that the user's desktop/workspace covers the entire
1786 * root window (i.e. you don't assume that the desktop begins
1787 * at root window coordinate 0,0) this function is not necessary.
1788 * It's deprecated for that reason.
1790 * Return value: not meaningful
1793 gdk_window_get_deskrelative_origin (GdkWindow *window,
1797 gboolean return_val = FALSE;
1798 gint num_children, format_return;
1799 Window win, *child, parent, root;
1803 static Atom atom = 0;
1804 gulong number_return, bytes_after_return;
1805 guchar *data_return;
1807 g_return_val_if_fail (window != NULL, 0);
1808 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1810 if (!GDK_WINDOW_DESTROYED (window))
1813 atom = gdk_atom_intern ("ENLIGHTENMENT_DESKTOP", FALSE);
1814 win = GDK_WINDOW_XID (window);
1816 while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent,
1817 &child, (unsigned int *)&num_children))
1819 if ((child) && (num_children > 0))
1831 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0,
1832 False, XA_CARDINAL, &type_return, &format_return,
1833 &number_return, &bytes_after_return, &data_return);
1834 if (type_return == XA_CARDINAL)
1836 XFree (data_return);
1841 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
1842 GDK_WINDOW_XID (window),
1857 * gdk_window_get_root_origin:
1858 * @window: a #GdkWindow
1859 * @x: return location for X position of window frame
1860 * @y: return location for Y position of window frame
1862 * Obtains the top-left corner of the window manager frame in root
1863 * window coordinates.
1867 gdk_window_get_root_origin (GdkWindow *window,
1873 g_return_if_fail (GDK_IS_WINDOW (window));
1875 gdk_window_get_frame_extents (window, &rect);
1885 * gdk_window_get_frame_extents:
1886 * @window: a #GdkWindow
1887 * @rect: rectangle to fill with bounding box of the window frame
1889 * Obtains the bounding box of the window, including window manager
1890 * titlebar/borders if any. The frame position is given in root window
1891 * coordinates. To get the position of the window itself (rather than
1892 * the frame) in root window coordinates, use gdk_window_get_origin().
1896 gdk_window_get_frame_extents (GdkWindow *window,
1899 GdkWindowObject *private;
1904 unsigned int nchildren;
1906 g_return_if_fail (GDK_IS_WINDOW (window));
1907 g_return_if_fail (rect != NULL);
1909 private = (GdkWindowObject*) window;
1916 if (GDK_WINDOW_DESTROYED (window))
1919 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
1920 private = (GdkWindowObject*) private->parent;
1921 if (GDK_WINDOW_DESTROYED (window))
1924 xparent = GDK_WINDOW_XID (window);
1928 if (!XQueryTree (GDK_WINDOW_XDISPLAY (window), xwindow,
1930 &children, &nchildren))
1936 while (xparent != root);
1938 if (xparent == root)
1940 unsigned int ww, wh, wb, wd;
1943 if (XGetGeometry (GDK_WINDOW_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
1954 gdk_window_get_pointer (GdkWindow *window,
1957 GdkModifierType *mask)
1959 GdkWindow *return_val;
1965 unsigned int xmask = 0;
1966 gint xoffset, yoffset;
1968 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1971 window = gdk_parent_root;
1973 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
1976 if (!GDK_WINDOW_DESTROYED (window) &&
1977 XQueryPointer (GDK_WINDOW_XDISPLAY (window),
1978 GDK_WINDOW_XID (window),
1979 &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
1982 return_val = gdk_window_lookup (child);
1986 *x = winx + xoffset;
1988 *y = winy + yoffset;
1996 gdk_window_at_pointer (gint *win_x,
2002 Window xwindow_last = 0;
2004 int rootx = -1, rooty = -1;
2008 xwindow = GDK_ROOT_WINDOW ();
2009 xdisplay = GDK_DISPLAY ();
2011 gdk_x11_grab_server ();
2014 xwindow_last = xwindow;
2015 XQueryPointer (xdisplay, xwindow,
2021 gdk_x11_ungrab_server ();
2023 window = gdk_window_lookup (xwindow_last);
2026 *win_x = window ? winx : -1;
2028 *win_y = window ? winy : -1;
2034 gdk_window_get_events (GdkWindow *window)
2036 XWindowAttributes attrs;
2037 GdkEventMask event_mask;
2040 g_return_val_if_fail (window != NULL, 0);
2041 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2043 if (GDK_WINDOW_DESTROYED (window))
2047 XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2048 GDK_WINDOW_XID (window),
2052 for (i = 0; i < gdk_nevent_masks; i++)
2054 if (attrs.your_event_mask & gdk_event_mask_table[i])
2055 event_mask |= 1 << (i + 1);
2063 gdk_window_set_events (GdkWindow *window,
2064 GdkEventMask event_mask)
2069 g_return_if_fail (window != NULL);
2070 g_return_if_fail (GDK_IS_WINDOW (window));
2072 if (!GDK_WINDOW_DESTROYED (window))
2074 xevent_mask = StructureNotifyMask;
2075 for (i = 0; i < gdk_nevent_masks; i++)
2077 if (event_mask & (1 << (i + 1)))
2078 xevent_mask |= gdk_event_mask_table[i];
2081 XSelectInput (GDK_WINDOW_XDISPLAY (window),
2082 GDK_WINDOW_XID (window),
2088 gdk_window_add_colormap_windows (GdkWindow *window)
2090 GdkWindow *toplevel;
2091 Window *old_windows;
2092 Window *new_windows;
2095 g_return_if_fail (window != NULL);
2096 g_return_if_fail (GDK_IS_WINDOW (window));
2098 toplevel = gdk_window_get_toplevel (window);
2099 if (GDK_WINDOW_DESTROYED (toplevel))
2103 if (!XGetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
2104 GDK_WINDOW_XID (toplevel),
2105 &old_windows, &count))
2110 for (i = 0; i < count; i++)
2111 if (old_windows[i] == GDK_WINDOW_XID (window))
2113 XFree (old_windows);
2117 new_windows = g_new (Window, count + 1);
2119 for (i = 0; i < count; i++)
2120 new_windows[i] = old_windows[i];
2121 new_windows[count] = GDK_WINDOW_XID (window);
2123 XSetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
2124 GDK_WINDOW_XID (toplevel),
2125 new_windows, count + 1);
2127 g_free (new_windows);
2129 XFree (old_windows);
2133 gdk_window_have_shape_ext (void)
2135 enum { UNKNOWN, NO, YES };
2136 static gint have_shape = UNKNOWN;
2138 if (have_shape == UNKNOWN)
2141 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
2147 return (have_shape == YES);
2150 #define WARN_SHAPE_TOO_BIG() g_warning ("GdkWindow is too large to allow the use of shape masks or shape regions.")
2153 * This needs the X11 shape extension.
2154 * If not available, shaped windows will look
2155 * ugly, but programs still work. Stefan Wille
2158 gdk_window_shape_combine_mask (GdkWindow *window,
2163 gint xoffset, yoffset;
2165 g_return_if_fail (window != NULL);
2166 g_return_if_fail (GDK_IS_WINDOW (window));
2168 #ifdef HAVE_SHAPE_EXT
2169 if (GDK_WINDOW_DESTROYED (window))
2172 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2174 if (xoffset != 0 || yoffset != 0)
2176 WARN_SHAPE_TOO_BIG ();
2180 if (gdk_window_have_shape_ext ())
2184 pixmap = GDK_PIXMAP_XID (mask);
2193 XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
2194 GDK_WINDOW_XID (window),
2200 #endif /* HAVE_SHAPE_EXT */
2204 gdk_window_shape_combine_region (GdkWindow *window,
2205 GdkRegion *shape_region,
2209 gint xoffset, yoffset;
2211 g_return_if_fail (GDK_IS_WINDOW (window));
2213 #ifdef HAVE_SHAPE_EXT
2214 if (GDK_WINDOW_DESTROYED (window))
2217 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2219 if (xoffset != 0 || yoffset != 0)
2221 WARN_SHAPE_TOO_BIG ();
2225 if (shape_region == NULL)
2227 /* Use NULL mask to unset the shape */
2228 gdk_window_shape_combine_mask (window, NULL, 0, 0);
2232 if (gdk_window_have_shape_ext ())
2235 XRectangle *xrects = NULL;
2237 _gdk_region_get_xrectangles (shape_region,
2241 XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window),
2242 GDK_WINDOW_XID (window),
2251 #endif /* HAVE_SHAPE_EXT */
2256 gdk_window_set_override_redirect (GdkWindow *window,
2257 gboolean override_redirect)
2259 XSetWindowAttributes attr;
2261 g_return_if_fail (window != NULL);
2262 g_return_if_fail (GDK_IS_WINDOW (window));
2264 if (GDK_WINDOW_DESTROYED (window))
2266 attr.override_redirect = (override_redirect == FALSE)?False:True;
2267 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2268 GDK_WINDOW_XID (window),
2276 * gdk_window_set_icon_list:
2277 * @window: The #GdkWindow toplevel window to set the icon of.
2278 * @pixbufs: A list of pixbufs, of different sizes.
2279 * @Returns: %TRUE if the icons were set, false otherwise
2281 * Sets a list of icons for the window. One of these will be used
2282 * to represent the window when it has been iconified. The icon is
2283 * usually shown in an icon box or some sort of task bar. Which icon
2284 * size is shown depends on the window manager. The window manager
2285 * can scale the icon but setting several size icons can give better
2286 * image quality since the window manager may only need to scale the
2287 * icon by a small amount or not at all.
2289 * On the X11 backend this call might fail if the window manager
2290 * doesn't support the Extended Window Manager Hints. Then this
2291 * function returns FALSE, and the application should fall back
2292 * to #gdk_window_set_icon().
2295 gdk_window_set_icon_list (GdkWindow *window,
2304 gint width, height, stride;
2308 g_return_val_if_fail (window != NULL, FALSE);
2309 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2311 if (GDK_WINDOW_DESTROYED (window))
2314 if (!gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_ICON", FALSE)))
2323 g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE);
2325 width = gdk_pixbuf_get_width (pixbuf);
2326 height = gdk_pixbuf_get_height (pixbuf);
2328 size += 2 + width * height;
2330 l = g_list_next (l);
2333 data = g_malloc (size*4);
2341 width = gdk_pixbuf_get_width (pixbuf);
2342 height = gdk_pixbuf_get_height (pixbuf);
2343 stride = gdk_pixbuf_get_rowstride (pixbuf);
2344 n_channels = gdk_pixbuf_get_n_channels (pixbuf);
2349 pixels = gdk_pixbuf_get_pixels (pixbuf);
2351 for (y = 0; y < height; y++)
2353 for (x = 0; x < width; x++)
2357 r = pixels[y*stride + x*n_channels + 0];
2358 g = pixels[y*stride + x*n_channels + 1];
2359 b = pixels[y*stride + x*n_channels + 2];
2360 if (n_channels >= 4)
2361 a = pixels[y*stride + x*n_channels + 3];
2365 *p++ = a << 24 | r << 16 | g << 8 | b ;
2369 l = g_list_next (l);
2372 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
2373 GDK_WINDOW_XID (window),
2374 gdk_atom_intern ("_NET_WM_ICON", FALSE),
2377 (guchar*) data, size);
2383 gdk_window_set_icon (GdkWindow *window,
2384 GdkWindow *icon_window,
2390 g_return_if_fail (window != NULL);
2391 g_return_if_fail (GDK_IS_WINDOW (window));
2393 if (GDK_WINDOW_DESTROYED (window))
2396 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
2397 GDK_WINDOW_XID (window));
2399 wm_hints = XAllocWMHints ();
2401 if (icon_window != NULL)
2403 wm_hints->flags |= IconWindowHint;
2404 wm_hints->icon_window = GDK_WINDOW_XID (icon_window);
2409 wm_hints->flags |= IconPixmapHint;
2410 wm_hints->icon_pixmap = GDK_PIXMAP_XID (pixmap);
2415 wm_hints->flags |= IconMaskHint;
2416 wm_hints->icon_mask = GDK_PIXMAP_XID (mask);
2419 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
2420 GDK_WINDOW_XID (window), wm_hints);
2425 gdk_window_icon_name_set (GdkWindow *window)
2427 return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window),
2428 g_quark_from_static_string ("gdk-icon-name-set")));
2432 gdk_window_set_icon_name (GdkWindow *window,
2435 g_return_if_fail (window != NULL);
2436 g_return_if_fail (GDK_IS_WINDOW (window));
2438 if (GDK_WINDOW_DESTROYED (window))
2441 g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
2442 GUINT_TO_POINTER (TRUE));
2444 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
2445 GDK_WINDOW_XID (window),
2446 gdk_atom_intern ("_NET_WM_ICON_NAME", FALSE),
2447 gdk_atom_intern ("UTF8_STRING", FALSE), 8,
2448 PropModeReplace, name,
2450 set_text_property (window, gdk_atom_intern ("WM_ICON_NAME", FALSE), name);
2454 gdk_window_iconify (GdkWindow *window)
2457 GdkWindowObject *private;
2459 g_return_if_fail (window != NULL);
2460 g_return_if_fail (GDK_IS_WINDOW (window));
2462 if (GDK_WINDOW_DESTROYED (window))
2465 display = GDK_WINDOW_XDISPLAY (window);
2467 private = (GdkWindowObject*) window;
2469 if (GDK_WINDOW_IS_MAPPED (window))
2471 XIconifyWindow (display, GDK_WINDOW_XWINDOW (window), DefaultScreen (display));
2476 /* Flip our client side flag, the real work happens on map. */
2477 gdk_synthesize_window_state (window,
2479 GDK_WINDOW_STATE_ICONIFIED);
2484 gdk_window_deiconify (GdkWindow *window)
2487 GdkWindowObject *private;
2489 g_return_if_fail (window != NULL);
2490 g_return_if_fail (GDK_IS_WINDOW (window));
2492 if (GDK_WINDOW_DESTROYED (window))
2495 display = GDK_WINDOW_XDISPLAY (window);
2497 private = (GdkWindowObject*) window;
2499 if (GDK_WINDOW_IS_MAPPED (window))
2501 gdk_window_show (window);
2505 /* Flip our client side flag, the real work happens on map. */
2506 gdk_synthesize_window_state (window,
2507 GDK_WINDOW_STATE_ICONIFIED,
2513 gdk_window_stick (GdkWindow *window)
2515 g_return_if_fail (GDK_IS_WINDOW (window));
2517 if (GDK_WINDOW_DESTROYED (window))
2520 if (GDK_WINDOW_IS_MAPPED (window))
2522 /* "stick" means stick to all desktops _and_ do not scroll with the
2523 * viewport. i.e. glue to the monitor glass in all cases.
2528 /* Request stick during viewport scroll */
2529 gdk_wmspec_change_state (TRUE, window,
2530 gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
2533 /* Request desktop 0xFFFFFFFF */
2534 xev.xclient.type = ClientMessage;
2535 xev.xclient.serial = 0;
2536 xev.xclient.send_event = True;
2537 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
2538 xev.xclient.display = gdk_display;
2539 xev.xclient.message_type = gdk_atom_intern ("_NET_WM_DESKTOP", FALSE);
2540 xev.xclient.format = 32;
2542 xev.xclient.data.l[0] = 0xFFFFFFFF;
2544 XSendEvent (gdk_display, gdk_root_window, False,
2545 SubstructureRedirectMask | SubstructureNotifyMask,
2550 /* Flip our client side flag, the real work happens on map. */
2551 gdk_synthesize_window_state (window,
2553 GDK_WINDOW_STATE_STICKY);
2558 gdk_window_unstick (GdkWindow *window)
2560 g_return_if_fail (GDK_IS_WINDOW (window));
2562 if (GDK_WINDOW_DESTROYED (window))
2565 if (GDK_WINDOW_IS_MAPPED (window))
2572 gulong *current_desktop;
2574 /* Request unstick from viewport */
2575 gdk_wmspec_change_state (FALSE, window,
2576 gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
2579 /* Get current desktop, then set it; this is a race, but not
2580 * one that matters much in practice.
2582 XGetWindowProperty (gdk_display, gdk_root_window,
2583 gdk_atom_intern ("_NET_CURRENT_DESKTOP", FALSE),
2585 False, XA_CARDINAL, &type, &format, &nitems,
2586 &bytes_after, (guchar **)¤t_desktop);
2588 if (type == XA_CARDINAL)
2590 xev.xclient.type = ClientMessage;
2591 xev.xclient.serial = 0;
2592 xev.xclient.send_event = True;
2593 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
2594 xev.xclient.display = gdk_display;
2595 xev.xclient.message_type = gdk_atom_intern ("_NET_WM_DESKTOP", FALSE);
2596 xev.xclient.format = 32;
2598 xev.xclient.data.l[0] = *current_desktop;
2600 XSendEvent (gdk_display, gdk_root_window, False,
2601 SubstructureRedirectMask | SubstructureNotifyMask,
2604 XFree (current_desktop);
2609 /* Flip our client side flag, the real work happens on map. */
2610 gdk_synthesize_window_state (window,
2611 GDK_WINDOW_STATE_STICKY,
2618 gdk_window_maximize (GdkWindow *window)
2620 g_return_if_fail (GDK_IS_WINDOW (window));
2622 if (GDK_WINDOW_DESTROYED (window))
2625 if (GDK_WINDOW_IS_MAPPED (window))
2626 gdk_wmspec_change_state (TRUE, window,
2627 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
2628 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
2630 gdk_synthesize_window_state (window,
2632 GDK_WINDOW_STATE_MAXIMIZED);
2636 gdk_window_unmaximize (GdkWindow *window)
2638 g_return_if_fail (GDK_IS_WINDOW (window));
2640 if (GDK_WINDOW_DESTROYED (window))
2643 if (GDK_WINDOW_IS_MAPPED (window))
2644 gdk_wmspec_change_state (FALSE, window,
2645 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
2646 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
2648 gdk_synthesize_window_state (window,
2649 GDK_WINDOW_STATE_MAXIMIZED,
2654 gdk_window_set_group (GdkWindow *window,
2659 g_return_if_fail (window != NULL);
2660 g_return_if_fail (GDK_IS_WINDOW (window));
2661 g_return_if_fail (leader != NULL);
2662 g_return_if_fail (GDK_IS_WINDOW (leader));
2664 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2667 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
2668 GDK_WINDOW_XID (window));
2670 wm_hints = XAllocWMHints ();
2672 wm_hints->flags |= WindowGroupHint;
2673 wm_hints->window_group = GDK_WINDOW_XID (leader);
2675 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
2676 GDK_WINDOW_XID (window), wm_hints);
2680 static MotifWmHints *
2681 gdk_window_get_mwm_hints (GdkWindow *window)
2683 static Atom hints_atom = None;
2684 MotifWmHints *hints;
2690 if (GDK_WINDOW_DESTROYED (window))
2694 hints_atom = XInternAtom (GDK_WINDOW_XDISPLAY (window),
2695 _XA_MOTIF_WM_HINTS, FALSE);
2697 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
2698 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
2699 False, AnyPropertyType, &type, &format, &nitems,
2700 &bytes_after, (guchar **)&hints);
2709 gdk_window_set_mwm_hints (GdkWindow *window,
2710 MotifWmHints *new_hints)
2712 static Atom hints_atom = None;
2713 MotifWmHints *hints;
2719 if (GDK_WINDOW_DESTROYED (window))
2723 hints_atom = XInternAtom (GDK_WINDOW_XDISPLAY (window),
2724 _XA_MOTIF_WM_HINTS, FALSE);
2726 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
2727 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
2728 False, AnyPropertyType, &type, &format, &nitems,
2729 &bytes_after, (guchar **)&hints);
2735 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
2737 hints->flags |= MWM_HINTS_FUNCTIONS;
2738 hints->functions = new_hints->functions;
2740 if (new_hints->flags & MWM_HINTS_DECORATIONS)
2742 hints->flags |= MWM_HINTS_DECORATIONS;
2743 hints->decorations = new_hints->decorations;
2747 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
2748 hints_atom, hints_atom, 32, PropModeReplace,
2749 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
2751 if (hints != new_hints)
2756 gdk_window_set_decorations (GdkWindow *window,
2757 GdkWMDecoration decorations)
2761 g_return_if_fail (window != NULL);
2762 g_return_if_fail (GDK_IS_WINDOW (window));
2764 hints.flags = MWM_HINTS_DECORATIONS;
2765 hints.decorations = decorations;
2767 gdk_window_set_mwm_hints (window, &hints);
2771 * gdk_window_get_decorations:
2772 * @window: The #GdkWindow to get the decorations from
2773 * @decorations: The window decorations will be written here
2775 * Returns the decorations set on the GdkWindow with #gdk_window_set_decorations
2776 * Returns: TRUE if the window has decorations set, FALSE otherwise.
2779 gdk_window_get_decorations(GdkWindow *window,
2780 GdkWMDecoration *decorations)
2782 MotifWmHints *hints;
2783 gboolean result = FALSE;
2785 hints = gdk_window_get_mwm_hints (window);
2789 if (hints->flags & MWM_HINTS_DECORATIONS)
2791 *decorations = hints->decorations;
2802 gdk_window_set_functions (GdkWindow *window,
2803 GdkWMFunction functions)
2807 g_return_if_fail (window != NULL);
2808 g_return_if_fail (GDK_IS_WINDOW (window));
2810 hints.flags = MWM_HINTS_FUNCTIONS;
2811 hints.functions = functions;
2813 gdk_window_set_mwm_hints (window, &hints);
2816 #ifdef HAVE_SHAPE_EXT
2819 * propagate the shapes from all child windows of a GDK window to the parent
2820 * window. Shamelessly ripped from Enlightenment's code
2828 struct _gdk_span *next;
2832 gdk_add_to_span (struct _gdk_span **s,
2836 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
2843 /* scan the spans for this line */
2846 /* -- -> new span */
2847 /* == -> existing span */
2848 /* ## -> spans intersect */
2849 /* if we are in the middle of spanning the span into the line */
2852 /* case: ---- ==== */
2853 if (xx < ptr1->start - 1)
2855 /* ends before next span - extend to here */
2859 /* case: ----##=== */
2860 else if (xx <= ptr1->end)
2862 /* crosses into next span - delete next span and append */
2863 ss->end = ptr1->end;
2864 ss->next = ptr1->next;
2868 /* case: ---###--- */
2871 /* overlaps next span - delete and keep checking */
2872 ss->next = ptr1->next;
2877 /* otherwise havent started spanning it in yet */
2880 /* case: ---- ==== */
2881 if (xx < ptr1->start - 1)
2883 /* insert span here in list */
2884 noo = g_malloc (sizeof (struct _gdk_span));
2898 /* case: ----##=== */
2899 else if ((x < ptr1->start) && (xx <= ptr1->end))
2901 /* expand this span to the left point of the new one */
2905 /* case: ===###=== */
2906 else if ((x >= ptr1->start) && (xx <= ptr1->end))
2908 /* throw the span away */
2911 /* case: ---###--- */
2912 else if ((x < ptr1->start) && (xx > ptr1->end))
2919 /* case: ===##---- */
2920 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
2926 /* case: ==== ---- */
2927 /* case handled by next loop iteration - first case */
2932 /* it started in the middle but spans beyond your current list */
2938 /* it does not start inside a span or in the middle, so add it to the end */
2939 noo = g_malloc (sizeof (struct _gdk_span));
2947 noo->next = ptr2->next;
2960 gdk_add_rectangles (Display *disp,
2962 struct _gdk_span **spans,
2969 gint x1, y1, x2, y2;
2973 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
2976 /* go through all clip rects in this window's shape */
2977 for (k = 0; k < rn; k++)
2979 /* for each clip rect, add it to each line's spans */
2981 x2 = x + rl[k].x + (rl[k].width - 1);
2983 y2 = y + rl[k].y + (rl[k].height - 1);
2992 for (a = y1; a <= y2; a++)
2995 gdk_add_to_span (&spans[a], x1, x2);
3003 gdk_propagate_shapes (Display *disp,
3007 Window rt, par, *list = NULL;
3008 gint i, j, num = 0, num_rects = 0;
3012 XRectangle *rects = NULL;
3013 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
3014 XWindowAttributes xatt;
3016 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
3021 spans = g_malloc (sizeof (struct _gdk_span *) * h);
3023 for (i = 0; i < h; i++)
3025 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
3028 /* go through all child windows and create/insert spans */
3029 for (i = 0; i < num; i++)
3031 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
3032 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
3033 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
3036 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
3038 /* go through the spans list and build a list of rects */
3039 rects = g_malloc (sizeof (XRectangle) * 256);
3041 for (i = 0; i < baseh; i++)
3044 /* go through the line for all spans */
3047 rects[num_rects].x = ptr1->start;
3048 rects[num_rects].y = i;
3049 rects[num_rects].width = ptr1->end - ptr1->start + 1;
3050 rects[num_rects].height = 1;
3052 /* if there are more lines */
3054 /* while contigous rects (same start/end coords) exist */
3055 while ((contig) && (j < baseh))
3057 /* search next line for spans matching this one */
3063 /* if we have an exact span match set contig */
3064 if ((ptr2->start == ptr1->start) &&
3065 (ptr2->end == ptr1->end))
3068 /* remove the span - not needed */
3071 ptr3->next = ptr2->next;
3077 spans[j] = ptr2->next;
3083 /* gone past the span point no point looking */
3084 else if (ptr2->start < ptr1->start)
3092 /* if a contiguous span was found increase the rect h */
3095 rects[num_rects].height++;
3099 /* up the rect count */
3101 /* every 256 new rects increase the rect array */
3102 if ((num_rects % 256) == 0)
3103 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
3107 /* set the rects as the shape mask */
3110 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
3111 ShapeSet, YXSorted);
3116 /* free up all the spans we made */
3117 for (i = 0; i < baseh; i++)
3130 #endif /* HAVE_SHAPE_EXT */
3133 gdk_window_set_child_shapes (GdkWindow *window)
3135 g_return_if_fail (window != NULL);
3136 g_return_if_fail (GDK_IS_WINDOW (window));
3138 #ifdef HAVE_SHAPE_EXT
3139 if (!GDK_WINDOW_DESTROYED (window) &&
3140 gdk_window_have_shape_ext ())
3141 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
3142 GDK_WINDOW_XID (window), FALSE);
3147 gdk_window_merge_child_shapes (GdkWindow *window)
3149 g_return_if_fail (window != NULL);
3150 g_return_if_fail (GDK_IS_WINDOW (window));
3152 #ifdef HAVE_SHAPE_EXT
3153 if (!GDK_WINDOW_DESTROYED (window) &&
3154 gdk_window_have_shape_ext ())
3155 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
3156 GDK_WINDOW_XID (window), TRUE);
3160 /* Support for windows that can be guffaw-scrolled
3161 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
3165 gdk_window_gravity_works (void)
3167 enum { UNKNOWN, NO, YES };
3168 static gint gravity_works = UNKNOWN;
3170 if (gravity_works == UNKNOWN)
3177 /* This particular server apparently has a bug so that the test
3178 * works but the actual code crashes it
3180 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
3181 (VendorRelease (gdk_display) == 3400))
3187 attr.window_type = GDK_WINDOW_TEMP;
3188 attr.wclass = GDK_INPUT_OUTPUT;
3193 attr.event_mask = 0;
3195 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
3197 attr.window_type = GDK_WINDOW_CHILD;
3198 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
3200 gdk_window_set_static_win_gravity (child, TRUE);
3202 gdk_window_resize (parent, 100, 110);
3203 gdk_window_move (parent, 0, -10);
3204 gdk_window_move_resize (parent, 0, 0, 100, 100);
3206 gdk_window_resize (parent, 100, 110);
3207 gdk_window_move (parent, 0, -10);
3208 gdk_window_move_resize (parent, 0, 0, 100, 100);
3210 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
3212 gdk_window_destroy (parent);
3213 gdk_window_destroy (child);
3215 gravity_works = ((y == -20) ? YES : NO);
3218 return (gravity_works == YES);
3222 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
3224 XSetWindowAttributes xattributes;
3225 guint xattributes_mask = 0;
3227 g_return_if_fail (window != NULL);
3229 xattributes.bit_gravity = StaticGravity;
3230 xattributes_mask |= CWBitGravity;
3231 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
3232 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
3233 GDK_WINDOW_XID (window),
3234 CWBitGravity, &xattributes);
3238 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
3240 XSetWindowAttributes xattributes;
3242 g_return_if_fail (window != NULL);
3244 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
3246 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
3247 GDK_WINDOW_XID (window),
3248 CWWinGravity, &xattributes);
3251 /*************************************************************
3252 * gdk_window_set_static_gravities:
3253 * Set the bit gravity of the given window to static,
3254 * and flag it so all children get static subwindow
3257 * window: window for which to set static gravity
3258 * use_static: Whether to turn static gravity on or off.
3260 * Does the XServer support static gravity?
3261 *************************************************************/
3264 gdk_window_set_static_gravities (GdkWindow *window,
3265 gboolean use_static)
3267 GdkWindowObject *private = (GdkWindowObject *)window;
3270 g_return_val_if_fail (window != NULL, FALSE);
3271 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
3273 if (!use_static == !private->guffaw_gravity)
3276 if (use_static && !gdk_window_gravity_works ())
3279 private->guffaw_gravity = use_static;
3281 if (!GDK_WINDOW_DESTROYED (window))
3283 gdk_window_set_static_bit_gravity (window, use_static);
3285 tmp_list = private->children;
3288 gdk_window_set_static_win_gravity (window, use_static);
3290 tmp_list = tmp_list->next;
3297 /* internal function created for and used by gdk_window_xid_at_coords */
3299 gdk_window_xid_at (Window base,
3305 gboolean excl_child)
3308 Window *list = NULL;
3309 Window child = 0, parent_win = 0, root_win = 0;
3311 unsigned int ww, wh, wb, wd, num;
3314 xdisplay = GDK_DISPLAY ();
3315 if (!XGetGeometry (xdisplay, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
3322 (x < (int) (wx + ww)) &&
3323 (y < (int) (wy + wh))))
3326 if (!XQueryTree (xdisplay, base, &root_win, &parent_win, &list, &num))
3331 for (i = num - 1; ; i--)
3333 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
3335 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
3350 * The following fucntion by The Rasterman <raster@redhat.com>
3351 * This function returns the X Window ID in which the x y location is in
3352 * (x and y being relative to the root window), excluding any windows listed
3353 * in the GList excludes (this is a list of X Window ID's - gpointer being
3356 * This is primarily designed for internal gdk use - for DND for example
3357 * when using a shaped icon window as the drag object - you exclude the
3358 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
3359 * You can get back an X Window ID as to what X Window ID is infact under
3360 * those X,Y co-ordinates.
3363 gdk_window_xid_at_coords (gint x,
3366 gboolean excl_child)
3370 Window *list = NULL;
3371 Window root, child = 0, parent_win = 0, root_win = 0;
3375 window = gdk_parent_root;
3376 xdisplay = GDK_WINDOW_XDISPLAY (window);
3377 root = GDK_WINDOW_XID (window);
3378 num = g_list_length (excludes);
3380 gdk_x11_grab_server ();
3381 if (!XQueryTree (xdisplay, root, &root_win, &parent_win, &list, &num))
3383 gdk_x11_ungrab_server ();
3391 XWindowAttributes xwa;
3393 XGetWindowAttributes (xdisplay, list [i], &xwa);
3395 if (xwa.map_state != IsViewable)
3398 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
3401 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
3406 if (!g_list_find (excludes, (gpointer *) child))
3409 gdk_x11_ungrab_server ();
3416 gdk_x11_ungrab_server ();
3422 gdk_x11_ungrab_server ();
3427 wmspec_moveresize (GdkWindow *window,
3435 /* Release passive grab */
3436 gdk_pointer_ungrab (timestamp);
3438 xev.xclient.type = ClientMessage;
3439 xev.xclient.serial = 0;
3440 xev.xclient.send_event = True;
3441 xev.xclient.display = gdk_display;
3442 xev.xclient.window = GDK_WINDOW_XID (window);
3443 xev.xclient.message_type = gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE);
3444 xev.xclient.format = 32;
3445 xev.xclient.data.l[0] = root_x;
3446 xev.xclient.data.l[1] = root_y;
3447 xev.xclient.data.l[2] = direction;
3448 xev.xclient.data.l[3] = 0;
3449 xev.xclient.data.l[4] = 0;
3451 XSendEvent (gdk_display, gdk_root_window, False,
3452 SubstructureRedirectMask | SubstructureNotifyMask,
3456 /* From the WM spec */
3457 #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
3458 #define _NET_WM_MOVERESIZE_SIZE_TOP 1
3459 #define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
3460 #define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
3461 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
3462 #define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
3463 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
3464 #define _NET_WM_MOVERESIZE_SIZE_LEFT 7
3465 #define _NET_WM_MOVERESIZE_MOVE 8
3468 wmspec_resize_drag (GdkWindow *window,
3477 /* Let the compiler turn a switch into a table, instead
3478 * of doing the table manually, this way is easier to verify.
3482 case GDK_WINDOW_EDGE_NORTH_WEST:
3483 direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
3486 case GDK_WINDOW_EDGE_NORTH:
3487 direction = _NET_WM_MOVERESIZE_SIZE_TOP;
3490 case GDK_WINDOW_EDGE_NORTH_EAST:
3491 direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
3494 case GDK_WINDOW_EDGE_WEST:
3495 direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
3498 case GDK_WINDOW_EDGE_EAST:
3499 direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
3502 case GDK_WINDOW_EDGE_SOUTH_WEST:
3503 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
3506 case GDK_WINDOW_EDGE_SOUTH:
3507 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
3510 case GDK_WINDOW_EDGE_SOUTH_EAST:
3511 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
3515 g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
3521 wmspec_moveresize (window, direction, root_x, root_y, timestamp);
3524 /* This is global for use in gdkevents-x11.c */
3525 GdkWindow *_gdk_moveresize_window;
3527 static GdkWindow *moveresize_emulation_window = NULL;
3528 static gboolean is_resize = FALSE;
3529 static GdkWindowEdge resize_edge;
3530 static gint moveresize_button;
3531 static gint moveresize_x;
3532 static gint moveresize_y;
3533 static gint moveresize_orig_x;
3534 static gint moveresize_orig_y;
3535 static gint moveresize_orig_width;
3536 static gint moveresize_orig_height;
3537 static GdkWindowHints moveresize_geom_mask = 0;
3538 static GdkGeometry moveresize_geometry;
3539 static Time moveresize_process_time;
3541 static XEvent *moveresize_pending_event;
3544 update_pos (gint new_root_x,
3549 dx = new_root_x - moveresize_x;
3550 dy = new_root_y - moveresize_y;
3556 w = moveresize_orig_width;
3557 h = moveresize_orig_height;
3559 switch (resize_edge)
3561 case GDK_WINDOW_EDGE_SOUTH_EAST:
3570 if (moveresize_geom_mask)
3572 gdk_window_constrain_size (&moveresize_geometry,
3573 moveresize_geom_mask,
3578 gdk_window_resize (_gdk_moveresize_window, w, h);
3584 x = moveresize_orig_x + dx;
3585 y = moveresize_orig_y + dy;
3587 gdk_window_move (_gdk_moveresize_window, x, y);
3594 gdk_window_destroy (moveresize_emulation_window);
3595 moveresize_emulation_window = NULL;
3596 _gdk_moveresize_window = NULL;
3598 if (moveresize_pending_event)
3600 g_free (moveresize_pending_event);
3601 moveresize_pending_event = NULL;
3606 lookahead_motion_predicate (Display *display,
3610 gboolean *seen_release = (gboolean *)arg;
3615 switch (event->xany.type)
3618 *seen_release = TRUE;
3621 moveresize_process_time = event->xmotion.time;
3631 moveresize_lookahead (XEvent *event)
3634 gboolean seen_release = FALSE;
3636 if (moveresize_process_time)
3638 if (event->xmotion.time == moveresize_process_time)
3640 moveresize_process_time = 0;
3647 XCheckIfEvent (gdk_display, &tmp_event,
3648 lookahead_motion_predicate, (XPointer)&seen_release);
3650 return moveresize_process_time == 0;
3654 _gdk_moveresize_handle_event (XEvent *event)
3656 guint button_mask = 0;
3657 GdkWindowObject *window_private = (GdkWindowObject *) _gdk_moveresize_window;
3659 button_mask = GDK_BUTTON1_MASK << (moveresize_button - 1);
3661 switch (event->xany.type)
3664 if (window_private->resize_count > 0)
3666 if (moveresize_pending_event)
3667 *moveresize_pending_event = *event;
3669 moveresize_pending_event = g_memdup (event, sizeof (XEvent));
3673 if (!moveresize_lookahead (event))
3676 update_pos (event->xmotion.x_root,
3677 event->xmotion.y_root);
3679 /* This should never be triggered in normal cases, but in the
3680 * case where the drag started without an implicit grab being
3681 * in effect, we could miss the release if it occurs before
3682 * we grab the pointer; this ensures that we will never
3683 * get a permanently stuck grab.
3685 if ((event->xmotion.state & button_mask) == 0)
3690 update_pos (event->xbutton.x_root,
3691 event->xbutton.y_root);
3693 if (event->xbutton.button == moveresize_button)
3700 _gdk_moveresize_configure_done (void)
3704 if (moveresize_pending_event)
3706 tmp_event = moveresize_pending_event;
3707 moveresize_pending_event = NULL;
3708 _gdk_moveresize_handle_event (tmp_event);
3714 create_moveresize_window (guint32 timestamp)
3716 GdkWindowAttr attributes;
3717 gint attributes_mask;
3718 GdkGrabStatus status;
3720 g_assert (moveresize_emulation_window == NULL);
3722 attributes.x = -100;
3723 attributes.y = -100;
3724 attributes.width = 10;
3725 attributes.height = 10;
3726 attributes.window_type = GDK_WINDOW_TEMP;
3727 attributes.wclass = GDK_INPUT_ONLY;
3728 attributes.override_redirect = TRUE;
3729 attributes.event_mask = 0;
3731 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
3733 moveresize_emulation_window =
3734 gdk_window_new (NULL, &attributes, attributes_mask);
3736 gdk_window_show (moveresize_emulation_window);
3738 status = gdk_pointer_grab (moveresize_emulation_window,
3740 GDK_BUTTON_RELEASE_MASK |
3741 GDK_POINTER_MOTION_MASK,
3746 if (status != GDK_GRAB_SUCCESS)
3748 /* If this fails, some other client has grabbed the window
3751 gdk_window_destroy (moveresize_emulation_window);
3752 moveresize_emulation_window = NULL;
3755 moveresize_process_time = 0;
3759 emulate_resize_drag (GdkWindow *window,
3767 moveresize_button = button;
3769 moveresize_x = root_x;
3770 moveresize_y = root_y;
3771 _gdk_moveresize_window = GDK_WINDOW (g_object_ref (G_OBJECT (window)));
3773 gdk_window_get_size (window, &moveresize_orig_width, &moveresize_orig_height);
3775 moveresize_geom_mask = 0;
3776 gdk_window_get_geometry_hints (window,
3777 &moveresize_geometry,
3778 &moveresize_geom_mask);
3780 create_moveresize_window (timestamp);
3784 emulate_move_drag (GdkWindow *window,
3791 moveresize_button = button;
3792 moveresize_x = root_x;
3793 moveresize_y = root_y;
3794 _gdk_moveresize_window = GDK_WINDOW (g_object_ref (G_OBJECT (window)));
3796 gdk_window_get_deskrelative_origin (_gdk_moveresize_window,
3798 &moveresize_orig_y);
3800 create_moveresize_window (timestamp);
3804 gdk_window_begin_resize_drag (GdkWindow *window,
3811 g_return_if_fail (GDK_IS_WINDOW (window));
3812 g_return_if_fail (moveresize_emulation_window == NULL);
3814 if (GDK_WINDOW_DESTROYED (window))
3817 if (gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
3818 wmspec_resize_drag (window, edge, button, root_x, root_y, timestamp);
3820 emulate_resize_drag (window, edge, button, root_x, root_y, timestamp);
3824 gdk_window_begin_move_drag (GdkWindow *window,
3830 g_return_if_fail (GDK_IS_WINDOW (window));
3831 g_return_if_fail (moveresize_emulation_window == NULL);
3833 if (GDK_WINDOW_DESTROYED (window))
3836 if (gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
3837 wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE,
3838 root_x, root_y, timestamp);
3840 emulate_move_drag (window, button, root_x, root_y, timestamp);