1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * Copyright (C) 1998-1999 Tor Lillqvist
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
33 #include "gdkevents.h"
34 #include "gdkpixmap.h"
35 #include "gdkwindow.h"
36 #include "gdkprivate.h"
37 #include "gdkinputprivate.h"
40 /* The Win API function AdjustWindowRect may return negative values
41 * resulting in obscured title bars. This helper function is coreccting it.
44 SafeAdjustWindowRectEx (RECT* lpRect,
49 if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
53 lpRect->right -= lpRect->left;
58 lpRect->bottom -= lpRect->top;
64 /* Forward declarations */
65 static gboolean gdk_window_gravity_works (void);
66 static void gdk_window_set_static_win_gravity (GdkWindow *window,
70 * The following fucntion by The Rasterman <raster@redhat.com>
71 * This function returns the X Window ID in which the x y location is in
72 * (x and y being relative to the root window), excluding any windows listed
73 * in the GList excludes (this is a list of X Window ID's - gpointer being
76 * This is primarily designed for internal gdk use - for DND for example
77 * when using a shaped icon window as the drag object - you exclude the
78 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
79 * You can get back an X Window ID as to what X Window ID is infact under
80 * those X,Y co-ordinates.
83 gdk_window_xid_at_coords (gint x,
89 gboolean warned = FALSE;
93 /* This is probably not correct, just a quick hack */
97 g_warning ("gdk_window_xid_at_coords probably not implemented correctly");
102 return WindowFromPoint (pt);
106 gdk_window_init (void)
111 width = GetSystemMetrics (SM_CXSCREEN);
112 height = GetSystemMetrics (SM_CYSCREEN);
114 { RECT r; /* //HB: don't obscure tray window (task bar) */
115 SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
116 width = r.right - r.left;
117 height = r.bottom - r.top;
121 gdk_root_parent.drawable.xwindow = gdk_root_window;
122 gdk_root_parent.drawable.window_type = GDK_WINDOW_ROOT;
123 gdk_root_parent.drawable.drawable.user_data = NULL;
124 gdk_root_parent.drawable.width = width;
125 gdk_root_parent.drawable.height = height;
126 gdk_root_parent.drawable.ref_count = 1;
127 gdk_root_parent.drawable.colormap = NULL;
128 gdk_root_parent.children = NULL;
130 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
134 * is a wrapper function for RegisterWindowClassEx.
135 * It creates at least one unique class for every
136 * GdkWindowType. If support for single window-specific icons
137 * is ever needed (e.g Dialog specific), every such window should
141 RegisterGdkClass(GdkWindowType wtype)
143 static ATOM klassTOPLEVEL = 0;
144 static ATOM klassDIALOG = 0;
145 static ATOM klassCHILD = 0;
146 static ATOM klassTEMP = 0;
147 static HICON hAppIcon = NULL;
148 static WNDCLASSEX wcl;
151 wcl.cbSize = sizeof(WNDCLASSEX);
152 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
153 * on WM_SIZE and WM_MOVE. Flicker, Performance!
155 wcl.lpfnWndProc = gdk_WindowProc;
158 wcl.hInstance = gdk_ProgInstance;
160 /* initialize once! */
163 gchar sLoc [_MAX_PATH+1];
164 HINSTANCE hInst = GetModuleHandle(NULL);
166 if (0 != GetModuleFileName(hInst, sLoc, _MAX_PATH))
168 hAppIcon = ExtractIcon(hInst, sLoc, 0);
171 char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
173 hAppIcon = ExtractIcon(hInst, gdklibname, 0);
178 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
182 wcl.lpszMenuName = NULL;
185 /* initialize once per class */
186 #define ONCE_PER_CLASS() \
187 wcl.hIcon = CopyIcon (hAppIcon); \
188 wcl.hIconSm = CopyIcon (hAppIcon); \
189 wcl.hbrBackground = CreateSolidBrush( RGB(0,0,0)); \
190 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
194 case GDK_WINDOW_TOPLEVEL:
195 if (0 == klassTOPLEVEL)
197 wcl.lpszClassName = "gdkWindowToplevel";
200 klassTOPLEVEL = RegisterClassEx(&wcl);
202 klass = klassTOPLEVEL;
204 case GDK_WINDOW_CHILD:
207 wcl.lpszClassName = "gdkWindowChild";
209 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
211 klassCHILD = RegisterClassEx(&wcl);
215 case GDK_WINDOW_DIALOG:
216 if (0 == klassDIALOG)
218 wcl.lpszClassName = "gdkWindowDialog";
219 wcl.style |= CS_SAVEBITS;
221 klassDIALOG = RegisterClassEx(&wcl);
225 case GDK_WINDOW_TEMP:
228 wcl.lpszClassName = "gdkWindowTemp";
229 wcl.style |= CS_SAVEBITS;
231 klassTEMP = RegisterClassEx(&wcl);
235 case GDK_WINDOW_ROOT:
236 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
238 case GDK_DRAWABLE_PIXMAP:
239 g_error ("cannot make windows of type GDK_DRAWABLE_PIXMAP (use gdk_pixmap_new)");
244 } /* RegisterGdkClass */
248 gdk_window_new (GdkWindow *parent,
249 GdkWindowAttr *attributes,
250 gint attributes_mask)
253 GdkWindowPrivate *private;
254 GdkWindowPrivate *parent_private;
259 DWORD dwStyle, dwExStyle;
265 g_return_val_if_fail (attributes != NULL, NULL);
268 parent = (GdkWindow*) &gdk_root_parent;
270 parent_private = (GdkWindowPrivate*) parent;
271 if (GDK_DRAWABLE_DESTROYED (parent))
274 xparent = parent_private->drawable.xwindow;
276 private = g_new (GdkWindowPrivate, 1);
277 window = (GdkWindow*) private;
279 private->parent = parent;
281 private->drawable.destroyed = FALSE;
282 private->mapped = FALSE;
283 private->guffaw_gravity = FALSE;
284 private->resize_count = 0;
285 private->drawable.ref_count = 1;
287 private->x = (attributes_mask & GDK_WA_X) ? attributes->x : 0;
288 private->y = (attributes_mask & GDK_WA_Y) ? attributes->y : 0;
290 private->drawable.width = (attributes->width > 1) ? (attributes->width) : (1);
291 private->drawable.height = (attributes->height > 1) ? (attributes->height) : (1);
292 private->drawable.window_type = attributes->window_type;
293 private->extension_events = 0;
294 private->extension_events_selected = FALSE;
296 private->filters = NULL;
297 private->children = NULL;
299 window->user_data = NULL;
301 if (attributes_mask & GDK_WA_VISUAL)
302 visual = attributes->visual;
304 visual = gdk_visual_get_system ();
305 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
307 if (attributes_mask & GDK_WA_TITLE)
308 title = attributes->title;
310 title = g_get_prgname ();
312 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
313 private->bg_type = GDK_WIN32_BG_NORMAL;
314 private->hint_flags = 0;
315 private->xcursor = NULL;
317 if (parent_private && parent_private->guffaw_gravity)
322 if (attributes->wclass == GDK_INPUT_OUTPUT)
325 if (attributes_mask & GDK_WA_COLORMAP)
326 private->drawable.colormap = attributes->colormap;
328 private->drawable.colormap = gdk_colormap_get_system ();
332 dwExStyle = WS_EX_TRANSPARENT;
333 private->drawable.colormap = NULL;
334 private->bg_type = GDK_WIN32_BG_TRANSPARENT;
335 private->bg_pixmap = NULL;
338 if (attributes_mask & GDK_WA_X)
343 if (attributes_mask & GDK_WA_Y)
345 else if (attributes_mask & GDK_WA_X)
346 y = 100; /* ??? We must put it somewhere... */
348 y = 500; /* x is CW_USEDEFAULT, y doesn't matter then */
351 parent_private->children = g_list_prepend (parent_private->children, window);
353 switch (private->drawable.window_type)
355 case GDK_WINDOW_TOPLEVEL:
356 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
357 xparent = gdk_root_window;
359 case GDK_WINDOW_CHILD:
360 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
362 case GDK_WINDOW_DIALOG:
363 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
364 dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
365 xparent = gdk_root_window;
367 case GDK_WINDOW_TEMP:
368 dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
369 dwExStyle |= WS_EX_TOOLWINDOW;
371 case GDK_WINDOW_ROOT:
372 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
374 case GDK_DRAWABLE_PIXMAP:
375 g_error ("cannot make windows of type GDK_DRAWABLE_PIXMAP (use gdk_pixmap_new)");
379 klass = RegisterGdkClass (private->drawable.window_type);
381 g_error ("RegisterClassEx failed");
383 if (private->drawable.window_type != GDK_WINDOW_CHILD)
385 if (x == CW_USEDEFAULT)
396 rect.right = rect.left + private->drawable.width;
397 rect.bottom = rect.top + private->drawable.height;
399 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
400 g_warning ("gdk_window_new: AdjustWindowRectEx failed");
402 if (x != CW_USEDEFAULT)
407 width = rect.right - rect.left;
408 height = rect.bottom - rect.top;
412 width = private->drawable.width;
413 height = private->drawable.height;
416 private->drawable.xwindow =
417 CreateWindowEx (dwExStyle,
418 MAKEINTRESOURCE(klass),
428 g_print ("gdk_window_create: %s %s %#x %#x %dx%d@+%d+%d %#x = %#x\n",
429 (private->drawable.window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
430 (private->drawable.window_type == GDK_WINDOW_CHILD ? "CHILD" :
431 (private->drawable.window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
432 (private->drawable.window_type == GDK_WINDOW_TEMP ? "TEMP" :
437 width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
439 private->drawable.xwindow));
441 gdk_window_ref (window);
442 gdk_xid_table_insert (&private->drawable.xwindow, window);
444 if (private->drawable.colormap)
445 gdk_colormap_ref (private->drawable.colormap);
447 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
448 (attributes->cursor) :
455 gdk_window_foreign_new (guint32 anid)
458 GdkWindowPrivate *private;
459 GdkWindowPrivate *parent_private;
464 private = g_new (GdkWindowPrivate, 1);
465 window = (GdkWindow*) private;
467 parent = GetParent ((HWND) anid);
468 private->parent = gdk_xid_table_lookup (parent);
470 parent_private = (GdkWindowPrivate *)private->parent;
473 parent_private->children = g_list_prepend (parent_private->children, window);
475 private->drawable.xwindow = (HWND) anid;
476 GetClientRect ((HWND) anid, &rect);
478 point.y = rect.right;
479 ClientToScreen ((HWND) anid, &point);
480 if (parent != HWND_DESKTOP)
481 ScreenToClient (parent, &point);
482 private->x = point.x;
483 private->y = point.y;
484 private->drawable.width = rect.right - rect.left;
485 private->drawable.height = rect.bottom - rect.top;
486 private->resize_count = 0;
487 private->drawable.ref_count = 1;
488 private->drawable.window_type = GDK_WINDOW_FOREIGN;
489 private->drawable.destroyed = FALSE;
490 private->mapped = IsWindowVisible (private->drawable.xwindow);
491 private->guffaw_gravity = FALSE;
492 private->extension_events = 0;
493 private->extension_events_selected = FALSE;
495 private->drawable.colormap = NULL;
497 private->filters = NULL;
498 private->children = NULL;
500 window->user_data = NULL;
502 gdk_window_ref (window);
503 gdk_xid_table_insert (&private->drawable.xwindow, window);
508 /* Call this function when you want a window and all its children to
509 * disappear. When xdestroy is true, a request to destroy the XWindow
510 * is sent out. When it is false, it is assumed that the XWindow has
511 * been or will be destroyed by destroying some ancestor of this
515 gdk_window_internal_destroy (GdkWindow *window,
517 gboolean our_destroy)
519 GdkWindowPrivate *private;
520 GdkWindowPrivate *temp_private;
521 GdkWindow *temp_window;
525 g_return_if_fail (window != NULL);
527 private = (GdkWindowPrivate*) window;
529 GDK_NOTE (MISC, g_print ("gdk_window_internal_destroy %#x\n",
530 private->drawable.xwindow));
532 switch (private->drawable.window_type)
534 case GDK_WINDOW_TOPLEVEL:
535 case GDK_WINDOW_CHILD:
536 case GDK_WINDOW_DIALOG:
537 case GDK_WINDOW_TEMP:
538 case GDK_WINDOW_FOREIGN:
539 if (!private->drawable.destroyed)
543 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
544 if (parent_private->children)
545 parent_private->children = g_list_remove (parent_private->children, window);
548 if (GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_FOREIGN)
550 children = tmp = private->children;
551 private->children = NULL;
555 temp_window = tmp->data;
558 temp_private = (GdkWindowPrivate*) temp_window;
560 gdk_window_internal_destroy (temp_window, FALSE,
564 g_list_free (children);
567 if (private->extension_events != 0)
568 gdk_input_window_destroy (window);
570 if (private->filters)
572 tmp = private->filters;
580 g_list_free (private->filters);
581 private->filters = NULL;
584 if (private->drawable.window_type == GDK_WINDOW_FOREIGN)
586 if (our_destroy && (private->parent != NULL))
588 /* It's somebody elses window, but in our hierarchy,
589 * so reparent it to the root window, and then send
590 * it a delete event, as if we were a WM
592 gdk_window_hide (window);
593 gdk_window_reparent (window, NULL, 0, 0);
595 /* Is this too drastic? Many (most?) applications
596 * quit if any window receives WM_QUIT I think.
597 * OTOH, I don't think foreign windows are much
598 * used, so the question is maybe academic.
600 PostMessage (private->drawable.xwindow, WM_QUIT, 0, 0);
604 DestroyWindow (private->drawable.xwindow);
606 if (private->drawable.colormap)
607 gdk_colormap_unref (private->drawable.colormap);
609 private->mapped = FALSE;
610 private->drawable.destroyed = TRUE;
614 case GDK_WINDOW_ROOT:
615 g_error ("attempted to destroy root window");
618 case GDK_DRAWABLE_PIXMAP:
619 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
624 /* Like internal_destroy, but also destroys the reference created by
628 gdk_window_destroy (GdkWindow *window)
630 gdk_window_internal_destroy (window, TRUE, TRUE);
631 gdk_window_unref (window);
634 /* This function is called when the XWindow is really gone. */
637 gdk_window_destroy_notify (GdkWindow *window)
639 g_return_if_fail (window != NULL);
641 GDK_NOTE (EVENTS, g_print ("gdk_window_destroy_notify: %#x %d\n",
642 GDK_DRAWABLE_XID (window), GDK_DRAWABLE_DESTROYED (window)));
644 if (!GDK_DRAWABLE_DESTROYED (window))
646 if (GDK_DRAWABLE_TYPE(window) != GDK_WINDOW_FOREIGN)
647 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_DRAWABLE_XID (window));
649 gdk_window_internal_destroy (window, FALSE, FALSE);
652 gdk_xid_table_remove (GDK_DRAWABLE_XID (window));
653 gdk_window_unref (window);
657 gdk_window_ref (GdkWindow *window)
659 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
660 g_return_val_if_fail (window != NULL, NULL);
662 private->drawable.ref_count += 1;
664 GDK_NOTE (MISC, g_print ("gdk_window_ref %#x %d\n",
665 GDK_DRAWABLE_XID (window),
666 private->drawable.ref_count));
672 gdk_window_unref (GdkWindow *window)
674 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
675 g_return_if_fail (window != NULL);
677 private->drawable.ref_count -= 1;
679 GDK_NOTE (MISC, g_print ("gdk_window_unref %#x %d%s\n",
680 private->drawable.xwindow,
681 private->drawable.ref_count,
682 (private->drawable.ref_count == 0 ? " freeing" : "")));
684 if (private->drawable.ref_count == 0)
686 if (private->bg_type == GDK_WIN32_BG_PIXMAP
687 && private->bg_pixmap != NULL)
688 gdk_pixmap_unref (private->bg_pixmap);
690 if (!private->drawable.destroyed)
692 if (private->drawable.window_type == GDK_WINDOW_FOREIGN)
693 gdk_xid_table_remove (private->drawable.xwindow);
695 g_warning ("losing last reference to undestroyed window");
697 g_dataset_destroy (window);
703 gdk_window_show (GdkWindow *window)
705 GdkWindowPrivate *private;
707 g_return_if_fail (window != NULL);
709 private = (GdkWindowPrivate*) window;
710 if (!private->drawable.destroyed)
712 GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n",
713 private->drawable.xwindow));
715 private->mapped = TRUE;
716 if (private->drawable.window_type == GDK_WINDOW_TEMP)
718 ShowWindow (private->drawable.xwindow, SW_SHOWNOACTIVATE);
719 SetWindowPos (private->drawable.xwindow, HWND_TOPMOST, 0, 0, 0, 0,
720 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
722 ShowWindow (private->drawable.xwindow, SW_HIDE); /* Don't put on toolbar */
727 ShowWindow (private->drawable.xwindow, SW_SHOWNORMAL);
728 ShowWindow (private->drawable.xwindow, SW_RESTORE);
729 SetForegroundWindow (private->drawable.xwindow);
731 ShowOwnedPopups (private->drawable.xwindow, TRUE);
738 gdk_window_hide (GdkWindow *window)
740 GdkWindowPrivate *private;
742 g_return_if_fail (window != NULL);
744 private = (GdkWindowPrivate*) window;
745 if (!private->drawable.destroyed)
747 GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n",
748 private->drawable.xwindow));
750 private->mapped = FALSE;
751 if (private->drawable.window_type == GDK_WINDOW_TOPLEVEL)
752 ShowOwnedPopups (private->drawable.xwindow, FALSE);
754 ShowWindow (private->drawable.xwindow, SW_HIDE);
756 ShowWindow (private->drawable.xwindow, SW_MINIMIZE);
758 CloseWindow (private->drawable.xwindow);
764 gdk_window_withdraw (GdkWindow *window)
766 GdkWindowPrivate *private;
768 g_return_if_fail (window != NULL);
770 private = (GdkWindowPrivate*) window;
771 if (!private->drawable.destroyed)
773 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n",
774 private->drawable.xwindow));
776 gdk_window_hide (window); /* XXX */
781 gdk_window_move (GdkWindow *window,
785 GdkWindowPrivate *private;
787 g_return_if_fail (window != NULL);
789 private = (GdkWindowPrivate*) window;
790 if (!private->drawable.destroyed)
794 GDK_NOTE (MISC, g_print ("gdk_window_move: %#x +%d+%d\n",
795 private->drawable.xwindow, x, y));
797 GetClientRect (private->drawable.xwindow, &rect);
799 if (private->drawable.window_type != GDK_WINDOW_CHILD)
807 ClientToScreen (private->drawable.xwindow, &ptTL);
812 ptBR.y = rect.bottom;
813 ClientToScreen (private->drawable.xwindow, &ptBR);
814 rect.right = x + ptBR.x - ptTL.x;
815 rect.bottom = y + ptBR.y - ptTL.y;
817 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
818 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
819 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
820 g_warning ("gdk_window_move: AdjustWindowRectEx failed");
830 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
831 private->drawable.xwindow,
832 rect.right - rect.left, rect.bottom - rect.top,
834 if (!MoveWindow (private->drawable.xwindow,
835 x, y, rect.right - rect.left, rect.bottom - rect.top,
837 g_warning ("gdk_window_move: MoveWindow failed");
842 gdk_window_resize (GdkWindow *window,
846 GdkWindowPrivate *private;
848 g_return_if_fail (window != NULL);
850 if ((gint16) width < 1)
852 if ((gint16) height < 1)
855 private = (GdkWindowPrivate*) window;
857 if (!private->drawable.destroyed &&
858 ((private->resize_count > 0) ||
859 (private->drawable.width != (guint16) width) ||
860 (private->drawable.height != (guint16) height)))
864 GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
865 private->drawable.xwindow, width, height));
867 if (private->drawable.window_type != GDK_WINDOW_CHILD)
876 ClientToScreen (private->drawable.xwindow, &pt);
879 rect.right = pt.x + width;
880 rect.bottom = pt.y + height;
882 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
883 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
884 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
885 g_warning ("gdk_window_resize: AdjustWindowRectEx failed");
889 width = rect.right - rect.left;
890 height = rect.bottom - rect.top;
896 private->drawable.width = width;
897 private->drawable.height = height;
900 private->resize_count += 1;
902 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
903 private->drawable.xwindow, width, height, x, y));
904 if (!MoveWindow (private->drawable.xwindow,
907 g_warning ("gdk_window_resize: MoveWindow failed");
912 gdk_window_move_resize (GdkWindow *window,
918 GdkWindowPrivate *private;
920 g_return_if_fail (window != NULL);
922 if ((gint16) width < 1)
924 if ((gint16) height < 1)
927 private = (GdkWindowPrivate*) window;
928 if (!private->drawable.destroyed)
934 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
935 private->drawable.xwindow, width, height, x, y));
939 rect.right = x + width;
940 rect.bottom = y + height;
942 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
943 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
944 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
945 g_warning ("gdk_window_move_resize: AdjustWindowRectEx failed");
947 if (private->drawable.window_type == GDK_WINDOW_CHILD)
951 private->drawable.width = width;
952 private->drawable.height = height;
954 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
955 private->drawable.xwindow,
956 rect.right - rect.left, rect.bottom - rect.top,
957 rect.left, rect.top));
958 if (!MoveWindow (private->drawable.xwindow,
960 rect.right - rect.left, rect.bottom - rect.top,
962 g_warning ("gdk_window_move_resize: MoveWindow failed");
964 if (private->guffaw_gravity)
966 GList *tmp_list = private->children;
969 GdkWindowPrivate *child_private = tmp_list->data;
971 child_private->x -= x - private->x;
972 child_private->y -= y - private->y;
974 tmp_list = tmp_list->next;
982 gdk_window_reparent (GdkWindow *window,
983 GdkWindow *new_parent,
987 GdkWindowPrivate *window_private;
988 GdkWindowPrivate *parent_private;
989 GdkWindowPrivate *old_parent_private;
991 g_return_if_fail (window != NULL);
994 new_parent = (GdkWindow*) &gdk_root_parent;
996 window_private = (GdkWindowPrivate*) window;
997 old_parent_private = (GdkWindowPrivate*)window_private->parent;
998 parent_private = (GdkWindowPrivate*) new_parent;
1000 if (!window_private->drawable.destroyed && !parent_private->drawable.destroyed)
1002 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
1003 window_private->drawable.xwindow,
1004 parent_private->drawable.xwindow));
1005 if (!SetParent (window_private->drawable.xwindow, parent_private->drawable.xwindow))
1006 g_warning ("gdk_window_reparent: SetParent failed");
1008 if (!MoveWindow (window_private->drawable.xwindow,
1010 window_private->drawable.width, window_private->drawable.height,
1012 g_warning ("gdk_window_reparent: MoveWindow failed");
1015 window_private->parent = new_parent;
1017 if (old_parent_private)
1018 old_parent_private->children = g_list_remove (old_parent_private->children, window);
1020 if ((old_parent_private &&
1021 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1022 (!old_parent_private && parent_private->guffaw_gravity))
1023 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1025 parent_private->children = g_list_prepend (parent_private->children, window);
1029 gdk_window_clear (GdkWindow *window)
1031 g_return_if_fail (window != NULL);
1032 g_return_if_fail (GDK_IS_WINDOW (window));
1034 if (!GDK_DRAWABLE_DESTROYED (window))
1035 gdk_window_clear_area (window, 0, 0, -1, -1);
1040 gdk_window_clear_area (GdkWindow *window,
1046 g_return_if_fail (window != NULL);
1047 g_return_if_fail (GDK_IS_WINDOW (window));
1049 if (!GDK_DRAWABLE_DESTROYED (window))
1054 width = G_MAXSHORT/2; /* Yeah, right */
1056 height = G_MAXSHORT/2;
1057 GDK_NOTE (MISC, g_print ("gdk_window_clear_area: %#x %dx%d@+%d+%d\n",
1058 GDK_DRAWABLE_XID (window), width, height, x, y));
1059 hdc = GetDC (GDK_DRAWABLE_XID (window));
1060 IntersectClipRect (hdc, x, y, x + width, y + height);
1061 SendMessage (GDK_DRAWABLE_XID (window), WM_ERASEBKGND, (WPARAM) hdc, 0);
1062 ReleaseDC (GDK_DRAWABLE_XID (window), hdc);
1067 gdk_window_clear_area_e (GdkWindow *window,
1073 g_return_if_fail (window != NULL);
1074 g_return_if_fail (GDK_IS_WINDOW (window));
1076 if (!GDK_DRAWABLE_DESTROYED (window))
1080 GDK_NOTE (MISC, g_print ("gdk_window_clear_area_e: %#x %dx%d@+%d+%d\n",
1081 GDK_DRAWABLE_XID (window), width, height, x, y));
1084 rect.right = x + width;
1086 rect.bottom = y + height;
1087 if (!InvalidateRect (GDK_DRAWABLE_XID (window), &rect, TRUE))
1088 g_warning ("gdk_window_clear_area_e: InvalidateRect failed");
1089 UpdateWindow (GDK_DRAWABLE_XID (window));
1094 gdk_window_raise (GdkWindow *window)
1096 g_return_if_fail (window != NULL);
1097 g_return_if_fail (GDK_IS_WINDOW (window));
1099 if (!GDK_DRAWABLE_DESTROYED (window))
1101 GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n",
1102 GDK_DRAWABLE_XID (window)));
1104 if (!BringWindowToTop (GDK_DRAWABLE_XID (window)))
1105 g_warning ("gdk_window_raise: BringWindowToTop failed");
1110 gdk_window_lower (GdkWindow *window)
1112 g_return_if_fail (window != NULL);
1113 g_return_if_fail (GDK_IS_WINDOW (window));
1115 if (!GDK_DRAWABLE_DESTROYED (window))
1117 GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n",
1118 GDK_DRAWABLE_XID (window)));
1120 if (!SetWindowPos (GDK_DRAWABLE_XID (window), HWND_BOTTOM, 0, 0, 0, 0,
1121 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1122 g_warning ("gdk_window_lower: SetWindowPos failed");
1127 gdk_window_set_user_data (GdkWindow *window,
1130 g_return_if_fail (window != NULL);
1132 window->user_data = user_data;
1136 gdk_window_set_hints (GdkWindow *window,
1145 GdkWindowPrivate *private;
1146 WINDOWPLACEMENT size_hints;
1152 g_return_if_fail (window != NULL);
1153 g_return_if_fail (GDK_IS_WINDOW (window));
1155 if (GDK_DRAWABLE_DESTROYED (window))
1158 private = (GdkWindowPrivate*) window;
1160 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1161 private->drawable.xwindow,
1162 min_width, min_height, max_width, max_height,
1165 private->hint_flags = flags;
1166 size_hints.length = sizeof (size_hints);
1170 if (flags & GDK_HINT_POS)
1171 if (!GetWindowPlacement (private->drawable.xwindow, &size_hints))
1172 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1175 GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1176 " (%d,%d)--(%d,%d)\n",
1177 size_hints.rcNormalPosition.left,
1178 size_hints.rcNormalPosition.top,
1179 size_hints.rcNormalPosition.right,
1180 size_hints.rcNormalPosition.bottom));
1181 /* What are the corresponding window coordinates for client
1182 * area coordinates x, y
1186 rect.right = rect.left + 200; /* dummy */
1187 rect.bottom = rect.top + 200;
1188 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
1189 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
1190 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1191 size_hints.flags = 0;
1192 size_hints.showCmd = SW_SHOWNA;
1194 /* Set the normal position hint to that location, with unchanged
1197 diff = size_hints.rcNormalPosition.left - rect.left;
1198 size_hints.rcNormalPosition.left = rect.left;
1199 size_hints.rcNormalPosition.right -= diff;
1200 diff = size_hints.rcNormalPosition.top - rect.top;
1201 size_hints.rcNormalPosition.top = rect.top;
1202 size_hints.rcNormalPosition.bottom -= diff;
1203 GDK_NOTE (MISC, g_print ("...setting: (%d,%d)--(%d,%d)\n",
1204 size_hints.rcNormalPosition.left,
1205 size_hints.rcNormalPosition.top,
1206 size_hints.rcNormalPosition.right,
1207 size_hints.rcNormalPosition.bottom));
1208 if (!SetWindowPlacement (private->drawable.xwindow, &size_hints))
1209 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1210 private->hint_x = rect.left;
1211 private->hint_y = rect.top;
1214 if (flags & GDK_HINT_MIN_SIZE)
1218 rect.right = min_width;
1219 rect.bottom = min_height;
1220 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
1221 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
1222 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1223 private->hint_min_width = rect.right - rect.left;
1224 private->hint_min_height = rect.bottom - rect.top;
1226 /* Also chek if he current size of the window is in bounds. */
1227 GetClientRect (private->drawable.xwindow, &rect);
1228 if (rect.right < min_width && rect.bottom < min_height)
1229 gdk_window_resize (window, min_width, min_height);
1230 else if (rect.right < min_width)
1231 gdk_window_resize (window, min_width, rect.bottom);
1232 else if (rect.bottom < min_height)
1233 gdk_window_resize (window, rect.right, min_height);
1235 if (flags & GDK_HINT_MAX_SIZE)
1239 rect.right = max_width;
1240 rect.bottom = max_height;
1241 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
1242 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
1243 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1244 private->hint_max_width = rect.right - rect.left;
1245 private->hint_max_height = rect.bottom - rect.top;
1246 /* Again, check if the window is too large currently. */
1247 GetClientRect (private->drawable.xwindow, &rect);
1248 if (rect.right > max_width && rect.bottom > max_height)
1249 gdk_window_resize (window, max_width, max_height);
1250 else if (rect.right > max_width)
1251 gdk_window_resize (window, max_width, rect.bottom);
1252 else if (rect.bottom > max_height)
1253 gdk_window_resize (window, rect.right, max_height);
1259 gdk_window_set_geometry_hints (GdkWindow *window,
1260 GdkGeometry *geometry,
1261 GdkWindowHints geom_mask)
1263 GdkWindowPrivate *private;
1264 WINDOWPLACEMENT size_hints;
1270 g_return_if_fail (window != NULL);
1271 g_return_if_fail (GDK_IS_WINDOW (window));
1273 if (GDK_DRAWABLE_DESTROYED (window))
1276 private = (GdkWindowPrivate*) window;
1278 size_hints.length = sizeof (size_hints);
1280 private->hint_flags = geom_mask;
1282 if (geom_mask & GDK_HINT_POS)
1285 if (geom_mask & GDK_HINT_MIN_SIZE)
1289 rect.right = geometry->min_width;
1290 rect.bottom = geometry->min_height;
1291 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
1292 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
1293 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1294 private->hint_min_width = rect.right - rect.left;
1295 private->hint_min_height = rect.bottom - rect.top;
1297 /* Also check if he current size of the window is in bounds */
1298 GetClientRect (private->drawable.xwindow, &rect);
1299 if (rect.right < geometry->min_width
1300 && rect.bottom < geometry->min_height)
1301 gdk_window_resize (window, geometry->min_width, geometry->min_height);
1302 else if (rect.right < geometry->min_width)
1303 gdk_window_resize (window, geometry->min_width, rect.bottom);
1304 else if (rect.bottom < geometry->min_height)
1305 gdk_window_resize (window, rect.right, geometry->min_height);
1308 if (geom_mask & GDK_HINT_MAX_SIZE)
1312 rect.right = geometry->max_width;
1313 rect.bottom = geometry->max_height;
1314 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
1315 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
1316 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1317 private->hint_max_width = rect.right - rect.left;
1318 private->hint_max_height = rect.bottom - rect.top;
1320 /* Again, check if the window is too large currently. */
1321 GetClientRect (private->drawable.xwindow, &rect);
1322 if (rect.right > geometry->max_width
1323 && rect.bottom > geometry->max_height)
1324 gdk_window_resize (window, geometry->max_width, geometry->max_height);
1325 else if (rect.right > geometry->max_width)
1326 gdk_window_resize (window, geometry->max_width, rect.bottom);
1327 else if (rect.bottom > geometry->max_height)
1328 gdk_window_resize (window, rect.right, geometry->max_height);
1331 /* I don't know what to do when called with zero base_width and height. */
1332 if (geom_mask & GDK_HINT_BASE_SIZE
1333 && geometry->base_width > 0
1334 && geometry->base_height > 0)
1335 if (!GetWindowPlacement (private->drawable.xwindow, &size_hints))
1336 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1339 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1340 " rcNormalPosition: (%d,%d)--(%d,%d)\n",
1341 size_hints.rcNormalPosition.left,
1342 size_hints.rcNormalPosition.top,
1343 size_hints.rcNormalPosition.right,
1344 size_hints.rcNormalPosition.bottom));
1345 size_hints.rcNormalPosition.right =
1346 size_hints.rcNormalPosition.left + geometry->base_width;
1347 size_hints.rcNormalPosition.bottom =
1348 size_hints.rcNormalPosition.top + geometry->base_height;
1349 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
1350 size_hints.rcNormalPosition.left,
1351 size_hints.rcNormalPosition.top,
1352 size_hints.rcNormalPosition.right,
1353 size_hints.rcNormalPosition.bottom));
1354 if (!SetWindowPlacement (private->drawable.xwindow, &size_hints))
1355 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1358 if (geom_mask & GDK_HINT_RESIZE_INC)
1363 if (geom_mask & GDK_HINT_ASPECT)
1370 gdk_window_set_title (GdkWindow *window,
1373 g_return_if_fail (window != NULL);
1374 g_return_if_fail (GDK_IS_WINDOW (window));
1376 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
1377 GDK_DRAWABLE_XID (window), title));
1378 if (!GDK_DRAWABLE_DESTROYED (window))
1380 if (!SetWindowText (GDK_DRAWABLE_XID (window), title))
1381 g_warning ("gdk_window_set_title: SetWindowText failed");
1386 gdk_window_set_role (GdkWindow *window,
1389 g_return_if_fail (window != NULL);
1390 g_return_if_fail (GDK_IS_WINDOW (window));
1392 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1393 GDK_DRAWABLE_XID (window), (role ? role : "NULL")));
1398 gdk_window_set_transient_for (GdkWindow *window,
1401 g_return_if_fail (window != NULL);
1402 g_return_if_fail (GDK_IS_WINDOW (window));
1404 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1405 GDK_DRAWABLE_XID (window),
1406 GDK_DRAWABLE_XID (parent)));
1411 gdk_window_set_background (GdkWindow *window,
1414 GdkWindowPrivate *private;
1416 g_return_if_fail (window != NULL);
1417 g_return_if_fail (GDK_IS_WINDOW (window));
1419 private = (GdkWindowPrivate*) window;
1420 if (!GDK_DRAWABLE_DESTROYED (window))
1422 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1423 private->drawable.xwindow,
1424 gdk_color_to_string (color)));
1426 if (private->bg_type == GDK_WIN32_BG_PIXMAP)
1428 if (private->bg_pixmap != NULL)
1430 gdk_pixmap_unref (private->bg_pixmap);
1431 private->bg_pixmap = NULL;
1433 private->bg_type = GDK_WIN32_BG_NORMAL;
1435 private->bg_type = GDK_WIN32_BG_PIXEL;
1436 private->bg_pixel = *color;
1441 gdk_window_set_back_pixmap (GdkWindow *window,
1443 gint parent_relative)
1445 GdkWindowPrivate *private;
1447 g_return_if_fail (window != NULL);
1448 g_return_if_fail (GDK_IS_WINDOW (window));
1450 private = (GdkWindowPrivate*) window;
1452 if (!GDK_DRAWABLE_DESTROYED (window))
1454 if (private->bg_type == GDK_WIN32_BG_PIXMAP)
1456 if (private->bg_pixmap != NULL)
1458 gdk_pixmap_unref (private->bg_pixmap);
1459 private->bg_pixmap = NULL;
1461 private->bg_type = GDK_WIN32_BG_NORMAL;
1463 if (parent_relative)
1465 private->bg_type = GDK_WIN32_BG_PARENT_RELATIVE;
1473 /* We must cache the pixmap in the WindowPrivate and
1474 * paint it each time we get WM_ERASEBKGND
1476 private->bg_type = GDK_WIN32_BG_PIXMAP;
1477 private->bg_pixmap = pixmap;
1478 gdk_pixmap_ref (pixmap);
1484 gdk_window_set_cursor (GdkWindow *window,
1487 GdkWindowPrivate *window_private;
1488 GdkCursorPrivate *cursor_private;
1491 g_return_if_fail (window != NULL);
1492 g_return_if_fail (GDK_IS_WINDOW (window));
1494 window_private = (GdkWindowPrivate*) window;
1495 cursor_private = (GdkCursorPrivate*) cursor;
1497 if (!GDK_DRAWABLE_DESTROYED (window))
1500 xcursor = LoadCursor (NULL, IDC_ARROW);
1502 xcursor = cursor_private->xcursor;
1504 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1505 window_private->drawable.xwindow, xcursor));
1506 window_private->xcursor = xcursor;
1511 gdk_window_get_user_data (GdkWindow *window,
1514 g_return_if_fail (window != NULL);
1516 *data = window->user_data;
1520 gdk_window_get_geometry (GdkWindow *window,
1527 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1530 window = (GdkWindow*) &gdk_root_parent;
1532 if (!GDK_DRAWABLE_DESTROYED (window))
1536 if (!GetClientRect (GDK_DRAWABLE_XID (window), &rect))
1537 g_warning ("gdk_window_get_geometry: GetClientRect failed");
1544 *width = rect.right - rect.left;
1546 *height = rect.bottom - rect.top;
1548 *depth = gdk_drawable_get_visual (window)->depth;
1553 gdk_window_get_position (GdkWindow *window,
1557 GdkWindowPrivate *window_private;
1559 g_return_if_fail (window != NULL);
1560 g_return_if_fail (GDK_IS_WINDOW (window));
1562 window_private = (GdkWindowPrivate*) window;
1565 *x = window_private->x;
1567 *y = window_private->y;
1571 gdk_window_get_origin (GdkWindow *window,
1579 g_return_val_if_fail (window != NULL, 0);
1581 if (!GDK_DRAWABLE_DESTROYED (window))
1587 ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
1600 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
1601 GDK_DRAWABLE_XID (window), tx, ty));
1606 gdk_window_get_deskrelative_origin (GdkWindow *window,
1610 return gdk_window_get_origin (window, x, y);
1614 gdk_window_get_root_origin (GdkWindow *window,
1618 GdkWindowPrivate *private;
1621 g_return_if_fail (window != NULL);
1622 g_return_if_fail (GDK_IS_WINDOW (window));
1624 private = (GdkWindowPrivate*) window;
1629 if (GDK_DRAWABLE_DESTROYED (window))
1632 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1633 private = (GdkWindowPrivate*) private->parent;
1634 if (private->drawable.destroyed)
1639 ClientToScreen (private->drawable.xwindow, &pt);
1645 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%d+%d\n",
1646 GDK_DRAWABLE_XID (window),
1647 private->drawable.xwindow, pt.x, pt.y));
1651 gdk_window_get_pointer (GdkWindow *window,
1654 GdkModifierType *mask)
1656 GdkWindow *return_val;
1657 POINT pointc, point;
1660 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1663 window = (GdkWindow*) &gdk_root_parent;
1666 GetCursorPos (&pointc);
1668 ScreenToClient (GDK_DRAWABLE_XID (window), &point);
1675 hwnd = WindowFromPoint (point);
1677 ScreenToClient (hwnd, &point);
1680 hwndc = ChildWindowFromPoint (hwnd, point);
1681 ClientToScreen (hwnd, &point);
1682 ScreenToClient (hwndc, &point);
1683 } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1685 return_val = gdk_window_lookup (hwnd);
1691 GetKeyboardState (kbd);
1693 if (kbd[VK_SHIFT] & 0x80)
1694 *mask |= GDK_SHIFT_MASK;
1695 if (kbd[VK_CAPITAL] & 0x80)
1696 *mask |= GDK_LOCK_MASK;
1697 if (kbd[VK_CONTROL] & 0x80)
1698 *mask |= GDK_CONTROL_MASK;
1699 if (kbd[VK_MENU] & 0x80)
1700 *mask |= GDK_MOD1_MASK;
1701 if (kbd[VK_LBUTTON] & 0x80)
1702 *mask |= GDK_BUTTON1_MASK;
1703 if (kbd[VK_MBUTTON] & 0x80)
1704 *mask |= GDK_BUTTON2_MASK;
1705 if (kbd[VK_RBUTTON] & 0x80)
1706 *mask |= GDK_BUTTON3_MASK;
1713 gdk_window_at_pointer (gint *win_x,
1717 POINT point, pointc;
1721 GetCursorPos (&pointc);
1723 hwnd = WindowFromPoint (point);
1727 window = (GdkWindow *) &gdk_root_parent;
1735 ScreenToClient (hwnd, &point);
1738 hwndc = ChildWindowFromPoint (hwnd, point);
1739 ClientToScreen (hwnd, &point);
1740 ScreenToClient (hwndc, &point);
1741 } while (hwndc != hwnd && (hwnd = hwndc, 1));
1743 window = gdk_window_lookup (hwnd);
1745 if (window && (win_x || win_y))
1747 GetClientRect (hwnd, &rect);
1749 *win_x = point.x - rect.left;
1751 *win_y = point.y - rect.top;
1754 GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%d+%d %#x%s\n",
1755 point.x, point.y, hwnd,
1756 (window == NULL ? " NULL" : "")));
1762 gdk_window_get_parent (GdkWindow *window)
1764 g_return_val_if_fail (window != NULL, NULL);
1765 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1767 return ((GdkWindowPrivate*) window)->parent;
1771 gdk_window_get_toplevel (GdkWindow *window)
1773 g_return_val_if_fail (window != NULL, NULL);
1774 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1776 while (GDK_DRAWABLE_TYPE (window) == GDK_WINDOW_CHILD)
1777 window = ((GdkWindowPrivate*) window)->parent;
1783 gdk_window_get_children (GdkWindow *window)
1785 GdkWindowPrivate *private;
1788 g_return_val_if_fail (window != NULL, NULL);
1789 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1791 if (GDK_DRAWABLE_DESTROYED (window))
1795 g_warning ("gdk_window_get_children not implemented");
1802 gdk_window_get_events (GdkWindow *window)
1804 GdkWindowPrivate *private;
1806 g_return_val_if_fail (window != NULL, 0);
1807 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1809 private = (GdkWindowPrivate*) window;
1810 if (GDK_DRAWABLE_DESTROYED (window))
1813 return private->event_mask;
1817 gdk_window_set_events (GdkWindow *window,
1818 GdkEventMask event_mask)
1820 GdkWindowPrivate *private;
1822 g_return_if_fail (window != NULL);
1823 g_return_if_fail (GDK_IS_WINDOW (window));
1825 private = (GdkWindowPrivate*) window;
1826 if (GDK_DRAWABLE_DESTROYED (window))
1829 private->event_mask = event_mask;
1833 gdk_window_add_colormap_windows (GdkWindow *window)
1835 g_warning ("gdk_window_add_colormap_windows not implemented");
1839 gdk_window_shape_combine_mask (GdkWindow *window,
1843 g_return_if_fail (window != NULL);
1844 g_return_if_fail (GDK_IS_WINDOW (window));
1848 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
1849 GDK_DRAWABLE_XID (window)));
1850 SetWindowRgn (GDK_DRAWABLE_XID (window), NULL, TRUE);
1854 GdkDrawablePrivate *pixmap_private;
1860 /* Convert mask bitmap to region */
1861 pixmap_private = (GdkDrawablePrivate*) mask;
1862 hrgn = BitmapToRegion (pixmap_private->xwindow);
1864 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
1865 GDK_DRAWABLE_XID (window),
1866 pixmap_private->xwindow));
1868 /* SetWindowRgn wants window (not client) coordinates */
1869 dwStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
1870 dwExStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
1871 GetClientRect (GDK_DRAWABLE_XID (window), &rect);
1872 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1873 OffsetRgn (hrgn, -rect.left, -rect.top);
1875 OffsetRgn (hrgn, x, y);
1877 /* If this is a top-level window, add the title bar to the region */
1878 if (GDK_DRAWABLE_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1880 CombineRgn (hrgn, hrgn,
1881 CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
1885 SetWindowRgn (GDK_DRAWABLE_XID (window), hrgn, TRUE);
1890 gdk_window_add_filter (GdkWindow *window,
1891 GdkFilterFunc function,
1894 GdkWindowPrivate *private;
1896 GdkEventFilter *filter;
1898 g_return_if_fail (window != NULL);
1899 g_return_if_fail (GDK_IS_WINDOW (window));
1901 private = (GdkWindowPrivate*) window;
1902 if (private && GDK_DRAWABLE_DESTROYED (window))
1906 tmp_list = private->filters;
1908 tmp_list = gdk_default_filters;
1912 filter = (GdkEventFilter *)tmp_list->data;
1913 if ((filter->function == function) && (filter->data == data))
1915 tmp_list = tmp_list->next;
1918 filter = g_new (GdkEventFilter, 1);
1919 filter->function = function;
1920 filter->data = data;
1923 private->filters = g_list_append (private->filters, filter);
1925 gdk_default_filters = g_list_append (gdk_default_filters, filter);
1929 gdk_window_remove_filter (GdkWindow *window,
1930 GdkFilterFunc function,
1933 GdkWindowPrivate *private;
1934 GList *tmp_list, *node;
1935 GdkEventFilter *filter;
1937 g_return_if_fail (window != NULL);
1938 g_return_if_fail (GDK_IS_WINDOW (window));
1940 private = (GdkWindowPrivate*) window;
1943 tmp_list = private->filters;
1945 tmp_list = gdk_default_filters;
1949 filter = (GdkEventFilter *)tmp_list->data;
1951 tmp_list = tmp_list->next;
1953 if ((filter->function == function) && (filter->data == data))
1956 private->filters = g_list_remove_link (private->filters, node);
1958 gdk_default_filters = g_list_remove_link (gdk_default_filters, node);
1959 g_list_free_1 (node);
1968 gdk_window_set_override_redirect (GdkWindow *window,
1969 gboolean override_redirect)
1971 g_return_if_fail (window != NULL);
1972 g_return_if_fail (GDK_IS_WINDOW (window));
1974 g_warning ("gdk_window_set_override_redirect not implemented");
1978 gdk_window_set_icon (GdkWindow *window,
1979 GdkWindow *icon_window,
1983 g_return_if_fail (window != NULL);
1984 g_return_if_fail (GDK_IS_WINDOW (window));
1986 if (GDK_DRAWABLE_DESTROYED (window))
1989 g_warning ("gdk_window_set_icon not implemented");
1993 gdk_window_set_icon_name (GdkWindow *window,
1996 g_return_if_fail (window != NULL);
1997 g_return_if_fail (GDK_IS_WINDOW (window));
1999 if (GDK_DRAWABLE_DESTROYED (window))
2002 if (!SetWindowText (GDK_DRAWABLE_XID (window), name))
2003 g_warning ("gdk_window_set_icon_name: SetWindowText failed");
2007 gdk_window_set_group (GdkWindow *window,
2010 g_return_if_fail (window != NULL);
2011 g_return_if_fail (GDK_IS_WINDOW (window));
2012 g_return_if_fail (leader != NULL);
2013 g_return_if_fail (GDK_IS_WINDOW (leader));
2015 if (GDK_DRAWABLE_DESTROYED (window) || GDK_DRAWABLE_DESTROYED (leader))
2018 g_warning ("gdk_window_set_group not implemented");
2022 gdk_window_set_decorations (GdkWindow *window,
2023 GdkWMDecoration decorations)
2025 LONG style, exstyle;
2027 g_return_if_fail (window != NULL);
2028 g_return_if_fail (GDK_IS_WINDOW (window));
2030 style = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
2031 exstyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
2033 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2034 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
2036 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2038 if (decorations & GDK_DECOR_ALL)
2039 style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2040 if (decorations & GDK_DECOR_BORDER)
2041 style |= (WS_BORDER);
2042 if (decorations & GDK_DECOR_RESIZEH)
2043 style |= (WS_THICKFRAME);
2044 if (decorations & GDK_DECOR_TITLE)
2045 style |= (WS_CAPTION);
2046 if (decorations & GDK_DECOR_MENU)
2047 style |= (WS_SYSMENU);
2048 if (decorations & GDK_DECOR_MINIMIZE)
2049 style |= (WS_MINIMIZEBOX);
2050 if (decorations & GDK_DECOR_MAXIMIZE)
2051 style |= (WS_MAXIMIZEBOX);
2053 SetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE, style);
2057 gdk_window_set_functions (GdkWindow *window,
2058 GdkWMFunction functions)
2060 LONG style, exstyle;
2062 g_return_if_fail (window != NULL);
2063 g_return_if_fail (GDK_IS_WINDOW (window));
2065 style = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
2066 exstyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
2068 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2069 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
2072 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2074 if (functions & GDK_FUNC_ALL)
2075 style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2076 if (functions & GDK_FUNC_RESIZE)
2077 style |= (WS_THICKFRAME);
2078 if (functions & GDK_FUNC_MOVE)
2079 style |= (WS_THICKFRAME);
2080 if (functions & GDK_FUNC_MINIMIZE)
2081 style |= (WS_MINIMIZEBOX);
2082 if (functions & GDK_FUNC_MAXIMIZE)
2083 style |= (WS_MAXIMIZEBOX);
2085 SetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE, style);
2089 gdk_window_get_toplevels (void)
2091 GList *new_list = NULL;
2094 tmp_list = gdk_root_parent.children;
2097 new_list = g_list_prepend (new_list, tmp_list->data);
2098 tmp_list = tmp_list->next;
2105 * propagate the shapes from all child windows of a GDK window to the parent
2106 * window. Shamelessly ripped from Enlightenment's code
2112 QueryTree (HWND hwnd,
2122 child = GetWindow (hwnd, GW_CHILD);
2124 child = GetWindow (child, GW_HWNDNEXT);
2127 } while (child != NULL);
2131 *children = g_new (HWND, n);
2132 for (i = 0; i < n; i++)
2135 child = GetWindow (hwnd, GW_CHILD);
2137 child = GetWindow (child, GW_HWNDNEXT);
2138 *children[i] = child;
2144 gdk_propagate_shapes (HANDLE win,
2148 HRGN region, childRegion;
2153 SetRectEmpty (&emptyRect);
2154 region = CreateRectRgnIndirect (&emptyRect);
2156 GetWindowRgn (win, region);
2158 QueryTree (win, &list, &num);
2161 WINDOWPLACEMENT placement;
2163 placement.length = sizeof (WINDOWPLACEMENT);
2164 /* go through all child windows and combine regions */
2165 for (i = 0; i < num; i++)
2167 GetWindowPlacement (list[i], &placement);
2168 if (placement.showCmd = SW_SHOWNORMAL)
2170 childRegion = CreateRectRgnIndirect (&emptyRect);
2171 GetWindowRgn (list[i], childRegion);
2172 CombineRgn (region, region, childRegion, RGN_OR);
2173 DeleteObject (childRegion);
2176 SetWindowRgn (win, region, TRUE);
2179 DeleteObject (region);
2183 gdk_window_set_child_shapes (GdkWindow *window)
2185 g_return_if_fail (window != NULL);
2186 g_return_if_fail (GDK_IS_WINDOW (window));
2188 if (GDK_DRAWABLE_DESTROYED (window))
2191 gdk_propagate_shapes (GDK_DRAWABLE_XID (window), FALSE);
2195 gdk_window_merge_child_shapes (GdkWindow *window)
2197 g_return_if_fail (window != NULL);
2198 g_return_if_fail (GDK_IS_WINDOW (window));
2200 if (GDK_DRAWABLE_DESTROYED (window))
2203 gdk_propagate_shapes (GDK_DRAWABLE_XID (window), TRUE);
2206 /*************************************************************
2207 * gdk_window_is_visible:
2208 * Check if the given window is mapped.
2212 * is the window mapped
2213 *************************************************************/
2216 gdk_window_is_visible (GdkWindow *window)
2218 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2220 g_return_val_if_fail (window != NULL, FALSE);
2221 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2223 return private->mapped;
2226 /*************************************************************
2227 * gdk_window_is_viewable:
2228 * Check if the window and all ancestors of the window
2229 * are mapped. (This is not necessarily "viewable" in
2230 * the X sense, since we only check as far as we have
2231 * GDK window parents, not to the root window)
2235 * is the window viewable
2236 *************************************************************/
2239 gdk_window_is_viewable (GdkWindow *window)
2241 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2243 g_return_val_if_fail (window != NULL, FALSE);
2244 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2247 (private != &gdk_root_parent) &&
2248 (private->drawable.window_type != GDK_WINDOW_FOREIGN))
2250 if (!private->mapped)
2253 private = (GdkWindowPrivate *)private->parent;
2259 /* Support for windows that can be guffaw-scrolled
2260 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2264 gdk_window_gravity_works (void)
2266 enum { UNKNOWN, NO, YES };
2267 static gint gravity_works = UNKNOWN;
2269 if (gravity_works == UNKNOWN)
2276 attr.window_type = GDK_WINDOW_TEMP;
2277 attr.wclass = GDK_INPUT_OUTPUT;
2282 attr.event_mask = 0;
2284 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2286 attr.window_type = GDK_WINDOW_CHILD;
2287 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2289 gdk_window_set_static_win_gravity (child, TRUE);
2291 gdk_window_resize (parent, 100, 110);
2292 gdk_window_move (parent, 0, -10);
2293 gdk_window_move_resize (parent, 0, 0, 100, 100);
2295 gdk_window_resize (parent, 100, 110);
2296 gdk_window_move (parent, 0, -10);
2297 gdk_window_move_resize (parent, 0, 0, 100, 100);
2299 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2301 gdk_window_destroy (parent);
2302 gdk_window_destroy (child);
2304 gravity_works = ((y == -20) ? YES : NO);
2307 return (gravity_works == YES);
2311 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2313 g_return_if_fail (window != NULL);
2315 GDK_NOTE (MISC, g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2319 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2321 g_return_if_fail (window != NULL);
2324 g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2327 /*************************************************************
2328 * gdk_window_set_static_gravities:
2329 * Set the bit gravity of the given window to static,
2330 * and flag it so all children get static subwindow
2333 * window: window for which to set static gravity
2334 * use_static: Whether to turn static gravity on or off.
2336 * Does the XServer support static gravity?
2337 *************************************************************/
2340 gdk_window_set_static_gravities (GdkWindow *window,
2341 gboolean use_static)
2343 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2346 g_return_val_if_fail (window != NULL, FALSE);
2347 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2349 if (!use_static == !private->guffaw_gravity)
2352 if (use_static && !gdk_window_gravity_works ())
2355 private->guffaw_gravity = use_static;
2357 if (!GDK_DRAWABLE_DESTROYED (window))
2359 gdk_window_set_static_bit_gravity (window, use_static);
2361 tmp_list = private->children;
2364 gdk_window_set_static_win_gravity (window, use_static);
2366 tmp_list = tmp_list->next;