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 "gdkwindow.h"
35 #include "gdkprivate.h"
36 #include "gdkinputprivate.h"
38 /* The Win API function AdjustWindowRect may return negative values
39 * resulting in obscured title bars. This helper function is coreccting it.
42 SafeAdjustWindowRectEx (RECT* lpRect,
47 if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
51 lpRect->right -= lpRect->left;
56 lpRect->bottom -= lpRect->top;
62 /* Forward declarations */
63 static gboolean gdk_window_gravity_works (void);
64 static void gdk_window_set_static_win_gravity (GdkWindow *window,
68 * The following fucntion by The Rasterman <raster@redhat.com>
69 * This function returns the X Window ID in which the x y location is in
70 * (x and y being relative to the root window), excluding any windows listed
71 * in the GList excludes (this is a list of X Window ID's - gpointer being
74 * This is primarily designed for internal gdk use - for DND for example
75 * when using a shaped icon window as the drag object - you exclude the
76 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
77 * You can get back an X Window ID as to what X Window ID is infact under
78 * those X,Y co-ordinates.
81 gdk_window_xid_at_coords (gint x,
87 gboolean warned = FALSE;
91 /* This is probably not correct, just a quick hack */
95 g_warning ("gdk_window_xid_at_coords probably not implemented correctly");
100 return WindowFromPoint (pt);
104 gdk_window_init (void)
109 width = GetSystemMetrics (SM_CXSCREEN);
110 height = GetSystemMetrics (SM_CYSCREEN);
112 { RECT r; /* //HB: don't obscure tray window (task bar) */
113 SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
114 width = r.right - r.left;
115 height = r.bottom - r.top;
119 gdk_root_parent.xwindow = gdk_root_window;
120 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
121 gdk_root_parent.window.user_data = NULL;
122 gdk_root_parent.width = width;
123 gdk_root_parent.height = height;
124 gdk_root_parent.children = NULL;
125 gdk_root_parent.colormap = NULL;
126 gdk_root_parent.ref_count = 1;
128 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
132 * is a wrapper function for RegisterWindowClassEx.
133 * It creates at least one unique class for every
134 * GdkWindowType. If support for single window-specific icons
135 * is ever needed (e.g Dialog specific), every such window should
139 RegisterGdkClass(GdkWindowType wtype)
141 static ATOM klassTOPLEVEL = 0;
142 static ATOM klassDIALOG = 0;
143 static ATOM klassCHILD = 0;
144 static ATOM klassTEMP = 0;
145 static HICON hAppIcon = NULL;
146 static WNDCLASSEX wcl;
149 wcl.cbSize = sizeof(WNDCLASSEX);
150 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
151 * on WM_SIZE and WM_MOVE. Flicker, Performance!
153 wcl.lpfnWndProc = gdk_WindowProc;
156 wcl.hInstance = gdk_ProgInstance;
158 /* initialize once! */
161 gchar sLoc [_MAX_PATH+1];
162 HINSTANCE hInst = GetModuleHandle(NULL);
164 if (0 != GetModuleFileName(hInst, sLoc, _MAX_PATH))
166 hAppIcon = ExtractIcon(hInst, sLoc, 0);
169 char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
171 hAppIcon = ExtractIcon(hInst, gdklibname, 0);
176 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
180 wcl.lpszMenuName = NULL;
183 /* initialize once per class */
184 #define ONCE_PER_CLASS() \
185 wcl.hIcon = CopyIcon (hAppIcon); \
186 wcl.hIconSm = CopyIcon (hAppIcon); \
187 wcl.hbrBackground = CreateSolidBrush( RGB(0,0,0)); \
188 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
192 case GDK_WINDOW_TOPLEVEL:
193 if (0 == klassTOPLEVEL)
195 wcl.lpszClassName = "gdkWindowToplevel";
198 klassTOPLEVEL = RegisterClassEx(&wcl);
200 klass = klassTOPLEVEL;
202 case GDK_WINDOW_CHILD:
205 wcl.lpszClassName = "gdkWindowChild";
207 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
209 klassCHILD = RegisterClassEx(&wcl);
213 case GDK_WINDOW_DIALOG:
214 if (0 == klassDIALOG)
216 wcl.lpszClassName = "gdkWindowDialog";
217 wcl.style |= CS_SAVEBITS;
219 klassDIALOG = RegisterClassEx(&wcl);
223 case GDK_WINDOW_TEMP:
226 wcl.lpszClassName = "gdkWindowTemp";
227 wcl.style |= CS_SAVEBITS;
229 klassTEMP = RegisterClassEx(&wcl);
233 case GDK_WINDOW_ROOT:
234 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
236 case GDK_WINDOW_PIXMAP:
237 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
242 } /* RegisterGdkClass */
246 gdk_window_new (GdkWindow *parent,
247 GdkWindowAttr *attributes,
248 gint attributes_mask)
251 GdkWindowPrivate *private;
252 GdkWindowPrivate *parent_private;
257 DWORD dwStyle, dwExStyle;
263 g_return_val_if_fail (attributes != NULL, NULL);
266 parent = (GdkWindow*) &gdk_root_parent;
268 parent_private = (GdkWindowPrivate*) parent;
269 if (parent_private->destroyed)
272 xparent = parent_private->xwindow;
274 private = g_new (GdkWindowPrivate, 1);
275 window = (GdkWindow*) private;
277 private->parent = parent;
279 private->destroyed = FALSE;
280 private->mapped = FALSE;
281 private->guffaw_gravity = FALSE;
282 private->resize_count = 0;
283 private->ref_count = 1;
285 private->x = (attributes_mask & GDK_WA_X) ? attributes->x : 0;
286 private->y = (attributes_mask & GDK_WA_Y) ? attributes->y : 0;
288 private->width = (attributes->width > 1) ? (attributes->width) : (1);
289 private->height = (attributes->height > 1) ? (attributes->height) : (1);
290 private->window_type = attributes->window_type;
291 private->extension_events = 0;
292 private->extension_events_selected = FALSE;
294 private->filters = NULL;
295 private->children = NULL;
297 window->user_data = NULL;
299 if (attributes_mask & GDK_WA_VISUAL)
300 visual = attributes->visual;
302 visual = gdk_visual_get_system ();
303 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
305 if (attributes_mask & GDK_WA_TITLE)
306 title = attributes->title;
308 title = g_get_prgname ();
310 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
311 private->bg_type = GDK_WIN32_BG_NORMAL;
312 private->hint_flags = 0;
313 private->xcursor = NULL;
315 if (parent_private && parent_private->guffaw_gravity)
320 if (attributes->wclass == GDK_INPUT_OUTPUT)
323 if (attributes_mask & GDK_WA_COLORMAP)
324 private->colormap = attributes->colormap;
326 private->colormap = gdk_colormap_get_system ();
330 dwExStyle = WS_EX_TRANSPARENT;
331 private->colormap = NULL;
332 private->bg_type = GDK_WIN32_BG_TRANSPARENT;
333 private->bg_pixmap = NULL;
336 if (attributes_mask & GDK_WA_X)
341 if (attributes_mask & GDK_WA_Y)
343 else if (attributes_mask & GDK_WA_X)
344 y = 100; /* ??? We must put it somewhere... */
346 y = 500; /* x is CW_USEDEFAULT, y doesn't matter then */
349 parent_private->children = g_list_prepend (parent_private->children, window);
351 switch (private->window_type)
353 case GDK_WINDOW_TOPLEVEL:
354 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
355 xparent = gdk_root_window;
357 case GDK_WINDOW_CHILD:
358 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
360 case GDK_WINDOW_DIALOG:
361 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
362 dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
363 xparent = gdk_root_window;
365 case GDK_WINDOW_TEMP:
366 dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
367 dwExStyle |= WS_EX_TOOLWINDOW;
369 case GDK_WINDOW_ROOT:
370 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
372 case GDK_WINDOW_PIXMAP:
373 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
377 klass = RegisterGdkClass (private->window_type);
379 g_error ("RegisterClassEx failed");
381 if (private->window_type != GDK_WINDOW_CHILD)
383 if (x == CW_USEDEFAULT)
394 rect.right = rect.left + private->width;
395 rect.bottom = rect.top + private->height;
397 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
398 g_warning ("gdk_window_new: AdjustWindowRectEx failed");
400 if (x != CW_USEDEFAULT)
405 width = rect.right - rect.left;
406 height = rect.bottom - rect.top;
410 width = private->width;
411 height = private->height;
415 CreateWindowEx (dwExStyle,
416 MAKEINTRESOURCE(klass),
426 g_print ("gdk_window_create: %s %s %#x %#x %dx%d@+%d+%d %#x = %#x\n",
427 (private->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
428 (private->window_type == GDK_WINDOW_CHILD ? "CHILD" :
429 (private->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
430 (private->window_type == GDK_WINDOW_TEMP ? "TEMP" :
435 width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
439 gdk_window_ref (window);
440 gdk_xid_table_insert (&private->xwindow, window);
442 if (private->colormap)
443 gdk_colormap_ref (private->colormap);
445 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
446 (attributes->cursor) :
453 gdk_window_foreign_new (guint32 anid)
456 GdkWindowPrivate *private;
457 GdkWindowPrivate *parent_private;
462 private = g_new (GdkWindowPrivate, 1);
463 window = (GdkWindow*) private;
465 parent = GetParent ((HWND) anid);
466 private->parent = gdk_xid_table_lookup (parent);
468 parent_private = (GdkWindowPrivate *)private->parent;
471 parent_private->children = g_list_prepend (parent_private->children, window);
473 private->xwindow = (HWND) anid;
474 GetClientRect ((HWND) anid, &rect);
476 point.y = rect.right;
477 ClientToScreen ((HWND) anid, &point);
478 if (parent != HWND_DESKTOP)
479 ScreenToClient (parent, &point);
480 private->x = point.x;
481 private->y = point.y;
482 private->width = rect.right - rect.left;
483 private->height = rect.bottom - rect.top;
484 private->resize_count = 0;
485 private->ref_count = 1;
486 private->window_type = GDK_WINDOW_FOREIGN;
487 private->destroyed = FALSE;
488 private->mapped = IsWindowVisible (private->xwindow);
489 private->guffaw_gravity = FALSE;
490 private->extension_events = 0;
491 private->extension_events_selected = FALSE;
493 private->colormap = NULL;
495 private->filters = NULL;
496 private->children = NULL;
498 window->user_data = NULL;
500 gdk_window_ref (window);
501 gdk_xid_table_insert (&private->xwindow, window);
506 /* Call this function when you want a window and all its children to
507 * disappear. When xdestroy is true, a request to destroy the XWindow
508 * is sent out. When it is false, it is assumed that the XWindow has
509 * been or will be destroyed by destroying some ancestor of this
513 gdk_window_internal_destroy (GdkWindow *window,
515 gboolean our_destroy)
517 GdkWindowPrivate *private;
518 GdkWindowPrivate *temp_private;
519 GdkWindow *temp_window;
523 g_return_if_fail (window != NULL);
525 private = (GdkWindowPrivate*) window;
527 GDK_NOTE (MISC, g_print ("gdk_window_internal_destroy %#x\n",
530 switch (private->window_type)
532 case GDK_WINDOW_TOPLEVEL:
533 case GDK_WINDOW_CHILD:
534 case GDK_WINDOW_DIALOG:
535 case GDK_WINDOW_TEMP:
536 case GDK_WINDOW_FOREIGN:
537 if (!private->destroyed)
541 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
542 if (parent_private->children)
543 parent_private->children = g_list_remove (parent_private->children, window);
546 if (private->window_type != GDK_WINDOW_FOREIGN)
548 children = tmp = private->children;
549 private->children = NULL;
553 temp_window = tmp->data;
556 temp_private = (GdkWindowPrivate*) temp_window;
558 gdk_window_internal_destroy (temp_window, FALSE,
562 g_list_free (children);
565 if (private->extension_events != 0)
566 gdk_input_window_destroy (window);
568 if (private->filters)
570 tmp = private->filters;
578 g_list_free (private->filters);
579 private->filters = NULL;
582 if (private->window_type == GDK_WINDOW_FOREIGN)
584 if (our_destroy && (private->parent != NULL))
586 /* It's somebody elses window, but in our hierarchy,
587 * so reparent it to the root window, and then send
588 * it a delete event, as if we were a WM
590 gdk_window_hide (window);
591 gdk_window_reparent (window, NULL, 0, 0);
593 /* Is this too drastic? Many (most?) applications
594 * quit if any window receives WM_QUIT I think.
595 * OTOH, I don't think foreign windows are much
596 * used, so the question is maybe academic.
598 PostMessage (private->xwindow, WM_QUIT, 0, 0);
602 DestroyWindow (private->xwindow);
604 if (private->colormap)
605 gdk_colormap_unref (private->colormap);
607 private->mapped = FALSE;
608 private->destroyed = TRUE;
612 case GDK_WINDOW_ROOT:
613 g_error ("attempted to destroy root window");
616 case GDK_WINDOW_PIXMAP:
617 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
622 /* Like internal_destroy, but also destroys the reference created by
626 gdk_window_destroy (GdkWindow *window)
628 gdk_window_internal_destroy (window, TRUE, TRUE);
629 gdk_window_unref (window);
632 /* This function is called when the XWindow is really gone. */
635 gdk_window_destroy_notify (GdkWindow *window)
637 GdkWindowPrivate *private;
639 g_return_if_fail (window != NULL);
641 private = (GdkWindowPrivate*) window;
643 GDK_NOTE (EVENTS, g_print ("gdk_window_destroy_notify: %#x %d\n",
644 private->xwindow, private->destroyed));
646 if (!private->destroyed)
648 if (private->window_type == GDK_WINDOW_FOREIGN)
649 gdk_window_internal_destroy (window, FALSE, FALSE);
651 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
654 gdk_xid_table_remove (private->xwindow);
655 gdk_window_unref (window);
659 gdk_window_ref (GdkWindow *window)
661 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
662 g_return_val_if_fail (window != NULL, NULL);
664 private->ref_count += 1;
666 GDK_NOTE (MISC, g_print ("gdk_window_ref %#x %d\n",
667 private->xwindow, private->ref_count));
673 gdk_window_unref (GdkWindow *window)
675 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
676 g_return_if_fail (window != NULL);
678 private->ref_count -= 1;
680 GDK_NOTE (MISC, g_print ("gdk_window_unref %#x %d%s\n",
681 private->xwindow, private->ref_count,
682 (private->ref_count == 0 ? " freeing" : "")));
684 if (private->ref_count == 0)
686 if (private->bg_type == GDK_WIN32_BG_PIXMAP && private->bg_pixmap != NULL)
687 gdk_pixmap_unref (private->bg_pixmap);
689 if (!private->destroyed)
691 if (private->window_type == GDK_WINDOW_FOREIGN)
692 gdk_xid_table_remove (private->xwindow);
694 g_warning ("losing last reference to undestroyed window");
696 g_dataset_destroy (window);
702 gdk_window_show (GdkWindow *window)
704 GdkWindowPrivate *private;
706 g_return_if_fail (window != NULL);
708 private = (GdkWindowPrivate*) window;
709 if (!private->destroyed)
711 GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n", private->xwindow));
713 private->mapped = TRUE;
714 if (private->window_type == GDK_WINDOW_TEMP)
716 ShowWindow (private->xwindow, SW_SHOWNOACTIVATE);
717 SetWindowPos (private->xwindow, HWND_TOPMOST, 0, 0, 0, 0,
718 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
720 ShowWindow (private->xwindow, SW_HIDE); /* Don't put on toolbar */
725 ShowWindow (private->xwindow, SW_SHOWNORMAL);
726 ShowWindow (private->xwindow, SW_RESTORE);
727 SetForegroundWindow (private->xwindow);
729 ShowOwnedPopups (private->xwindow, TRUE);
736 gdk_window_hide (GdkWindow *window)
738 GdkWindowPrivate *private;
740 g_return_if_fail (window != NULL);
742 private = (GdkWindowPrivate*) window;
743 if (!private->destroyed)
745 GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n", private->xwindow));
747 private->mapped = FALSE;
748 if (private->window_type == GDK_WINDOW_TOPLEVEL)
749 ShowOwnedPopups (private->xwindow, FALSE);
751 ShowWindow (private->xwindow, SW_HIDE);
753 ShowWindow (private->xwindow, SW_MINIMIZE);
755 CloseWindow (private->xwindow);
761 gdk_window_withdraw (GdkWindow *window)
763 GdkWindowPrivate *private;
765 g_return_if_fail (window != NULL);
767 private = (GdkWindowPrivate*) window;
768 if (!private->destroyed)
770 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n", private->xwindow));
772 gdk_window_hide (window); /* XXX */
777 gdk_window_move (GdkWindow *window,
781 GdkWindowPrivate *private;
783 g_return_if_fail (window != NULL);
785 private = (GdkWindowPrivate*) window;
786 if (!private->destroyed)
790 GDK_NOTE (MISC, g_print ("gdk_window_move: %#x +%d+%d\n",
791 private->xwindow, x, y));
793 GetClientRect (private->xwindow, &rect);
795 if (private->window_type != GDK_WINDOW_CHILD)
803 ClientToScreen (private->xwindow, &ptTL);
808 ptBR.y = rect.bottom;
809 ClientToScreen (private->xwindow, &ptBR);
810 rect.right = x + ptBR.x - ptTL.x;
811 rect.bottom = y + ptBR.y - ptTL.y;
813 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
814 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
815 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
816 g_warning ("gdk_window_move: AdjustWindowRectEx failed");
826 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
828 rect.right - rect.left, rect.bottom - rect.top,
830 if (!MoveWindow (private->xwindow,
831 x, y, rect.right - rect.left, rect.bottom - rect.top,
833 g_warning ("gdk_window_move: MoveWindow failed");
838 gdk_window_resize (GdkWindow *window,
842 GdkWindowPrivate *private;
844 g_return_if_fail (window != NULL);
846 if ((gint16) width < 1)
848 if ((gint16) height < 1)
851 private = (GdkWindowPrivate*) window;
853 if (!private->destroyed &&
854 ((private->resize_count > 0) ||
855 (private->width != (guint16) width) ||
856 (private->height != (guint16) height)))
860 GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
861 private->xwindow, width, height));
863 if (private->window_type != GDK_WINDOW_CHILD)
872 ClientToScreen (private->xwindow, &pt);
875 rect.right = pt.x + width;
876 rect.bottom = pt.y + height;
878 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
879 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
880 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
881 g_warning ("gdk_window_resize: AdjustWindowRectEx failed");
885 width = rect.right - rect.left;
886 height = rect.bottom - rect.top;
892 private->width = width;
893 private->height = height;
896 private->resize_count += 1;
898 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
899 private->xwindow, width, height, x, y));
900 if (!MoveWindow (private->xwindow,
903 g_warning ("gdk_window_resize: MoveWindow failed");
908 gdk_window_move_resize (GdkWindow *window,
914 GdkWindowPrivate *private;
916 g_return_if_fail (window != NULL);
918 if ((gint16) width < 1)
920 if ((gint16) height < 1)
923 private = (GdkWindowPrivate*) window;
924 if (!private->destroyed)
930 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
931 private->xwindow, width, height, x, y));
935 rect.right = x + width;
936 rect.bottom = y + height;
938 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
939 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
940 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
941 g_warning ("gdk_window_move_resize: AdjustWindowRectEx failed");
943 if (private->window_type == GDK_WINDOW_CHILD)
947 private->width = width;
948 private->height = height;
950 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
952 rect.right - rect.left, rect.bottom - rect.top,
953 rect.left, rect.top));
954 if (!MoveWindow (private->xwindow,
956 rect.right - rect.left, rect.bottom - rect.top,
958 g_warning ("gdk_window_move_resize: MoveWindow failed");
960 if (private->guffaw_gravity)
962 GList *tmp_list = private->children;
965 GdkWindowPrivate *child_private = tmp_list->data;
967 child_private->x -= x - private->x;
968 child_private->y -= y - private->y;
970 tmp_list = tmp_list->next;
978 gdk_window_reparent (GdkWindow *window,
979 GdkWindow *new_parent,
983 GdkWindowPrivate *window_private;
984 GdkWindowPrivate *parent_private;
985 GdkWindowPrivate *old_parent_private;
987 g_return_if_fail (window != NULL);
990 new_parent = (GdkWindow*) &gdk_root_parent;
992 window_private = (GdkWindowPrivate*) window;
993 old_parent_private = (GdkWindowPrivate*)window_private->parent;
994 parent_private = (GdkWindowPrivate*) new_parent;
996 if (!window_private->destroyed && !parent_private->destroyed)
998 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
999 window_private->xwindow,
1000 parent_private->xwindow));
1001 if (!SetParent (window_private->xwindow, parent_private->xwindow))
1002 g_warning ("gdk_window_reparent: SetParent failed");
1004 if (!MoveWindow (window_private->xwindow,
1006 window_private->width, window_private->height,
1008 g_warning ("gdk_window_reparent: MoveWindow failed");
1011 window_private->parent = new_parent;
1013 if (old_parent_private)
1014 old_parent_private->children = g_list_remove (old_parent_private->children, window);
1016 if ((old_parent_private &&
1017 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1018 (!old_parent_private && parent_private->guffaw_gravity))
1019 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1021 parent_private->children = g_list_prepend (parent_private->children, window);
1025 gdk_window_clear (GdkWindow *window)
1027 GdkWindowPrivate *private;
1029 g_return_if_fail (window != NULL);
1031 private = (GdkWindowPrivate*) window;
1033 if (!private->destroyed)
1035 gdk_window_clear_area (window, 0, 0, private->width, private->height);
1041 gdk_window_clear_area (GdkWindow *window,
1047 GdkWindowPrivate *private;
1049 g_return_if_fail (window != NULL);
1051 private = (GdkWindowPrivate*) window;
1053 if (!private->destroyed)
1058 width = G_MAXSHORT/2; /* Yeah, right */
1060 height = G_MAXSHORT/2;
1061 GDK_NOTE (MISC, g_print ("gdk_window_clear_area: %#x %dx%d@+%d+%d\n",
1062 private->xwindow, width, height, x, y));
1063 hdc = GetDC (private->xwindow);
1064 IntersectClipRect (hdc, x, y, x + width, y + height);
1065 SendMessage (private->xwindow, WM_ERASEBKGND, (WPARAM) hdc, 0);
1066 ReleaseDC (private->xwindow, hdc);
1071 gdk_window_clear_area_e (GdkWindow *window,
1077 GdkWindowPrivate *private;
1079 g_return_if_fail (window != NULL);
1081 private = (GdkWindowPrivate*) window;
1083 if (!private->destroyed)
1087 GDK_NOTE (MISC, g_print ("gdk_window_clear_area_e: %#x %dx%d@+%d+%d\n",
1088 private->xwindow, width, height, x, y));
1091 rect.right = x + width;
1093 rect.bottom = y + height;
1094 if (!InvalidateRect (private->xwindow, &rect, TRUE))
1095 g_warning ("gdk_window_clear_area_e: InvalidateRect failed");
1096 UpdateWindow (private->xwindow);
1101 gdk_window_copy_area (GdkWindow *window,
1105 GdkWindow *source_window,
1111 GdkWindowPrivate *src_private;
1112 GdkWindowPrivate *dest_private;
1113 GdkGCPrivate *gc_private;
1115 g_return_if_fail (window != NULL);
1116 g_return_if_fail (gc != NULL);
1118 if (source_window == NULL)
1119 source_window = window;
1121 src_private = (GdkWindowPrivate*) source_window;
1122 dest_private = (GdkWindowPrivate*) window;
1123 gc_private = (GdkGCPrivate*) gc;
1125 if (!src_private->destroyed && !dest_private->destroyed)
1127 HDC hdcDest, hdcSrc;
1129 if ((hdcDest = GetDC (dest_private->xwindow)) == NULL)
1130 g_warning ("gdk_window_copy_area: GetDC failed");
1132 if ((hdcSrc = GetDC (src_private->xwindow)) == NULL)
1133 g_warning ("gdk_window_copy_area: GetDC failed");
1135 if (!BitBlt (hdcDest, x, y, width, height, hdcSrc, source_x, source_y, SRCCOPY))
1136 g_warning ("gdk_window_copy_area: BitBlt failed");
1138 ReleaseDC (dest_private->xwindow, hdcDest);
1139 ReleaseDC (src_private->xwindow, hdcSrc);
1144 gdk_window_raise (GdkWindow *window)
1146 GdkWindowPrivate *private;
1148 g_return_if_fail (window != NULL);
1150 private = (GdkWindowPrivate*) window;
1152 if (!private->destroyed)
1154 GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n", private->xwindow));
1156 if (!BringWindowToTop (private->xwindow))
1157 g_warning ("gdk_window_raise: BringWindowToTop failed");
1162 gdk_window_lower (GdkWindow *window)
1164 GdkWindowPrivate *private;
1166 g_return_if_fail (window != NULL);
1168 private = (GdkWindowPrivate*) window;
1170 if (!private->destroyed)
1172 GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n", private->xwindow));
1174 if (!SetWindowPos (private->xwindow, HWND_BOTTOM, 0, 0, 0, 0,
1175 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1176 g_warning ("gdk_window_lower: SetWindowPos failed");
1181 gdk_window_set_user_data (GdkWindow *window,
1184 g_return_if_fail (window != NULL);
1186 window->user_data = user_data;
1190 gdk_window_set_hints (GdkWindow *window,
1199 GdkWindowPrivate *private;
1200 WINDOWPLACEMENT size_hints;
1206 g_return_if_fail (window != NULL);
1208 private = (GdkWindowPrivate*) window;
1209 if (private->destroyed)
1212 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1214 min_width, min_height, max_width, max_height,
1217 private->hint_flags = flags;
1218 size_hints.length = sizeof (size_hints);
1222 if (flags & GDK_HINT_POS)
1223 if (!GetWindowPlacement (private->xwindow, &size_hints))
1224 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1227 GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1228 " (%d,%d)--(%d,%d)\n",
1229 size_hints.rcNormalPosition.left,
1230 size_hints.rcNormalPosition.top,
1231 size_hints.rcNormalPosition.right,
1232 size_hints.rcNormalPosition.bottom));
1233 /* What are the corresponding window coordinates for client
1234 * area coordinates x, y
1238 rect.right = rect.left + 200; /* dummy */
1239 rect.bottom = rect.top + 200;
1240 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1241 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1242 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1243 size_hints.flags = 0;
1244 size_hints.showCmd = SW_SHOWNA;
1246 /* Set the normal position hint to that location, with unchanged
1249 diff = size_hints.rcNormalPosition.left - rect.left;
1250 size_hints.rcNormalPosition.left = rect.left;
1251 size_hints.rcNormalPosition.right -= diff;
1252 diff = size_hints.rcNormalPosition.top - rect.top;
1253 size_hints.rcNormalPosition.top = rect.top;
1254 size_hints.rcNormalPosition.bottom -= diff;
1255 GDK_NOTE (MISC, g_print ("...setting: (%d,%d)--(%d,%d)\n",
1256 size_hints.rcNormalPosition.left,
1257 size_hints.rcNormalPosition.top,
1258 size_hints.rcNormalPosition.right,
1259 size_hints.rcNormalPosition.bottom));
1260 if (!SetWindowPlacement (private->xwindow, &size_hints))
1261 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1262 private->hint_x = rect.left;
1263 private->hint_y = rect.top;
1266 if (flags & GDK_HINT_MIN_SIZE)
1270 rect.right = min_width;
1271 rect.bottom = min_height;
1272 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1273 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1274 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1275 private->hint_min_width = rect.right - rect.left;
1276 private->hint_min_height = rect.bottom - rect.top;
1278 /* Also chek if he current size of the window is in bounds. */
1279 GetClientRect (private->xwindow, &rect);
1280 if (rect.right < min_width && rect.bottom < min_height)
1281 gdk_window_resize (window, min_width, min_height);
1282 else if (rect.right < min_width)
1283 gdk_window_resize (window, min_width, rect.bottom);
1284 else if (rect.bottom < min_height)
1285 gdk_window_resize (window, rect.right, min_height);
1287 if (flags & GDK_HINT_MAX_SIZE)
1291 rect.right = max_width;
1292 rect.bottom = max_height;
1293 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1294 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1295 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1296 private->hint_max_width = rect.right - rect.left;
1297 private->hint_max_height = rect.bottom - rect.top;
1298 /* Again, check if the window is too large currently. */
1299 GetClientRect (private->xwindow, &rect);
1300 if (rect.right > max_width && rect.bottom > max_height)
1301 gdk_window_resize (window, max_width, max_height);
1302 else if (rect.right > max_width)
1303 gdk_window_resize (window, max_width, rect.bottom);
1304 else if (rect.bottom > max_height)
1305 gdk_window_resize (window, rect.right, max_height);
1311 gdk_window_set_geometry_hints (GdkWindow *window,
1312 GdkGeometry *geometry,
1313 GdkWindowHints geom_mask)
1315 GdkWindowPrivate *private;
1316 WINDOWPLACEMENT size_hints;
1322 g_return_if_fail (window != NULL);
1324 private = (GdkWindowPrivate*) window;
1325 if (private->destroyed)
1328 size_hints.length = sizeof (size_hints);
1330 private->hint_flags = geom_mask;
1332 if (geom_mask & GDK_HINT_POS)
1335 if (geom_mask & GDK_HINT_MIN_SIZE)
1339 rect.right = geometry->min_width;
1340 rect.bottom = geometry->min_height;
1341 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1342 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1343 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1344 private->hint_min_width = rect.right - rect.left;
1345 private->hint_min_height = rect.bottom - rect.top;
1347 /* Also check if he current size of the window is in bounds */
1348 GetClientRect (private->xwindow, &rect);
1349 if (rect.right < geometry->min_width
1350 && rect.bottom < geometry->min_height)
1351 gdk_window_resize (window, geometry->min_width, geometry->min_height);
1352 else if (rect.right < geometry->min_width)
1353 gdk_window_resize (window, geometry->min_width, rect.bottom);
1354 else if (rect.bottom < geometry->min_height)
1355 gdk_window_resize (window, rect.right, geometry->min_height);
1358 if (geom_mask & GDK_HINT_MAX_SIZE)
1362 rect.right = geometry->max_width;
1363 rect.bottom = geometry->max_height;
1364 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1365 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1366 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1367 private->hint_max_width = rect.right - rect.left;
1368 private->hint_max_height = rect.bottom - rect.top;
1370 /* Again, check if the window is too large currently. */
1371 GetClientRect (private->xwindow, &rect);
1372 if (rect.right > geometry->max_width
1373 && rect.bottom > geometry->max_height)
1374 gdk_window_resize (window, geometry->max_width, geometry->max_height);
1375 else if (rect.right > geometry->max_width)
1376 gdk_window_resize (window, geometry->max_width, rect.bottom);
1377 else if (rect.bottom > geometry->max_height)
1378 gdk_window_resize (window, rect.right, geometry->max_height);
1381 /* I don't know what to do when called with zero base_width and height. */
1382 if (geom_mask & GDK_HINT_BASE_SIZE
1383 && geometry->base_width > 0
1384 && geometry->base_height > 0)
1385 if (!GetWindowPlacement (private->xwindow, &size_hints))
1386 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1389 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1390 " rcNormalPosition: (%d,%d)--(%d,%d)\n",
1391 size_hints.rcNormalPosition.left,
1392 size_hints.rcNormalPosition.top,
1393 size_hints.rcNormalPosition.right,
1394 size_hints.rcNormalPosition.bottom));
1395 size_hints.rcNormalPosition.right =
1396 size_hints.rcNormalPosition.left + geometry->base_width;
1397 size_hints.rcNormalPosition.bottom =
1398 size_hints.rcNormalPosition.top + geometry->base_height;
1399 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
1400 size_hints.rcNormalPosition.left,
1401 size_hints.rcNormalPosition.top,
1402 size_hints.rcNormalPosition.right,
1403 size_hints.rcNormalPosition.bottom));
1404 if (!SetWindowPlacement (private->xwindow, &size_hints))
1405 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1408 if (geom_mask & GDK_HINT_RESIZE_INC)
1413 if (geom_mask & GDK_HINT_ASPECT)
1420 gdk_window_set_title (GdkWindow *window,
1423 GdkWindowPrivate *private;
1425 g_return_if_fail (window != NULL);
1427 private = (GdkWindowPrivate*) window;
1428 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
1429 private->xwindow, title));
1430 if (!private->destroyed)
1432 if (!SetWindowText (private->xwindow, title))
1433 g_warning ("gdk_window_set_title: SetWindowText failed");
1438 gdk_window_set_role (GdkWindow *window,
1441 GdkWindowPrivate *private;
1443 g_return_if_fail (window != NULL);
1445 private = (GdkWindowPrivate*) window;
1447 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1448 private->xwindow, (role ? role : "NULL")));
1453 gdk_window_set_transient_for (GdkWindow *window,
1456 GdkWindowPrivate *private;
1457 GdkWindowPrivate *parent_private;
1459 g_return_if_fail (window != NULL);
1461 private = (GdkWindowPrivate*) window;
1462 parent_private = (GdkWindowPrivate*) parent;
1464 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1465 private->xwindow, parent_private->xwindow));
1470 gdk_window_set_background (GdkWindow *window,
1473 GdkWindowPrivate *private;
1475 g_return_if_fail (window != NULL);
1477 private = (GdkWindowPrivate*) window;
1478 if (!private->destroyed)
1480 GdkColormapPrivate *colormap_private =
1481 (GdkColormapPrivate *) private->colormap;
1483 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1485 gdk_color_to_string (color)));
1487 if (private->bg_type == GDK_WIN32_BG_PIXMAP)
1489 if (private->bg_pixmap != NULL)
1491 gdk_pixmap_unref (private->bg_pixmap);
1492 private->bg_pixmap = NULL;
1494 private->bg_type = GDK_WIN32_BG_NORMAL;
1496 private->bg_type = GDK_WIN32_BG_PIXEL;
1497 private->bg_pixel = *color;
1502 gdk_window_set_back_pixmap (GdkWindow *window,
1504 gint parent_relative)
1506 GdkWindowPrivate *window_private;
1508 g_return_if_fail (window != NULL);
1510 window_private = (GdkWindowPrivate*) window;
1512 if (!window_private->destroyed)
1514 GdkColormapPrivate *colormap_private =
1515 (GdkColormapPrivate *) window_private->colormap;
1516 if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
1518 if (window_private->bg_pixmap != NULL)
1520 gdk_pixmap_unref (window_private->bg_pixmap);
1521 window_private->bg_pixmap = NULL;
1523 window_private->bg_type = GDK_WIN32_BG_NORMAL;
1525 if (parent_relative)
1527 window_private->bg_type = GDK_WIN32_BG_PARENT_RELATIVE;
1535 /* We must cache the pixmap in the WindowPrivate and
1536 * paint it each time we get WM_ERASEBKGND
1538 window_private->bg_type = GDK_WIN32_BG_PIXMAP;
1539 window_private->bg_pixmap = pixmap;
1540 gdk_pixmap_ref (pixmap);
1546 gdk_window_set_cursor (GdkWindow *window,
1549 GdkWindowPrivate *window_private;
1550 GdkCursorPrivate *cursor_private;
1553 g_return_if_fail (window != NULL);
1555 window_private = (GdkWindowPrivate*) window;
1556 cursor_private = (GdkCursorPrivate*) cursor;
1558 if (!window_private->destroyed)
1561 xcursor = LoadCursor (NULL, IDC_ARROW);
1563 xcursor = cursor_private->xcursor;
1565 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1566 window_private->xwindow, xcursor));
1567 window_private->xcursor = xcursor;
1568 SetCursor (xcursor);
1573 gdk_window_set_colormap (GdkWindow *window,
1574 GdkColormap *colormap)
1576 GdkWindowPrivate *window_private;
1577 GdkColormapPrivate *colormap_private;
1579 g_return_if_fail (window != NULL);
1580 g_return_if_fail (colormap != NULL);
1582 window_private = (GdkWindowPrivate*) window;
1583 colormap_private = (GdkColormapPrivate*) colormap;
1585 if (!window_private->destroyed)
1588 GDK_NOTE (MISC, g_print ("gdk_window_set_colormap: %#x %#x\n",
1589 window_private->xwindow,
1590 colormap_private->xcolormap));
1591 if (window_private->colormap)
1592 gdk_colormap_unref (window_private->colormap);
1593 window_private->colormap = colormap;
1594 gdk_colormap_ref (window_private->colormap);
1596 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1597 gdk_window_add_colormap_windows (window);
1602 gdk_window_get_user_data (GdkWindow *window,
1605 g_return_if_fail (window != NULL);
1607 *data = window->user_data;
1611 gdk_window_get_geometry (GdkWindow *window,
1618 GdkWindowPrivate *window_private;
1621 window = (GdkWindow*) &gdk_root_parent;
1623 window_private = (GdkWindowPrivate*) window;
1625 if (!window_private->destroyed)
1629 if (!GetClientRect (window_private->xwindow, &rect))
1630 g_warning ("gdk_window_get_geometry: GetClientRect failed");
1637 *width = rect.right - rect.left;
1639 *height = rect.bottom - rect.top;
1641 *depth = gdk_window_get_visual (window)->depth;
1646 gdk_window_get_position (GdkWindow *window,
1650 GdkWindowPrivate *window_private;
1652 g_return_if_fail (window != NULL);
1654 window_private = (GdkWindowPrivate*) window;
1657 *x = window_private->x;
1659 *y = window_private->y;
1663 gdk_window_get_size (GdkWindow *window,
1667 GdkWindowPrivate *window_private;
1669 g_return_if_fail (window != NULL);
1671 window_private = (GdkWindowPrivate*) window;
1674 *width = window_private->width;
1676 *height = window_private->height;
1680 gdk_window_get_visual (GdkWindow *window)
1682 GdkWindowPrivate *window_private;
1684 g_return_val_if_fail (window != NULL, NULL);
1686 window_private = (GdkWindowPrivate*) window;
1687 /* Huh? ->parent is never set for a pixmap. We should just return
1688 * null immeditately. Well, do it then!
1690 if (window_private->window_type == GDK_WINDOW_PIXMAP)
1693 if (!window_private->destroyed)
1695 if (window_private->colormap == NULL)
1696 return gdk_visual_get_system (); /* XXX ??? */
1698 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1705 gdk_window_get_colormap (GdkWindow *window)
1707 GdkWindowPrivate *window_private;
1709 g_return_val_if_fail (window != NULL, NULL);
1710 window_private = (GdkWindowPrivate*) window;
1712 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1713 if (!window_private->destroyed)
1715 if (window_private->colormap == NULL)
1716 return gdk_colormap_get_system (); /* XXX ??? */
1718 return window_private->colormap;
1725 gdk_window_get_type (GdkWindow *window)
1727 GdkWindowPrivate *window_private;
1729 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1731 window_private = (GdkWindowPrivate*) window;
1732 return window_private->window_type;
1736 gdk_window_get_origin (GdkWindow *window,
1740 GdkWindowPrivate *private;
1745 g_return_val_if_fail (window != NULL, 0);
1747 private = (GdkWindowPrivate*) window;
1749 if (!private->destroyed)
1755 ClientToScreen (private->xwindow, &pt);
1768 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
1769 private->xwindow, tx, ty));
1774 gdk_window_get_deskrelative_origin (GdkWindow *window,
1778 return gdk_window_get_origin (window, x, y);
1782 gdk_window_get_root_origin (GdkWindow *window,
1786 GdkWindowPrivate *private;
1789 g_return_if_fail (window != NULL);
1791 private = (GdkWindowPrivate*) window;
1796 if (private->destroyed)
1799 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1800 private = (GdkWindowPrivate*) private->parent;
1801 if (private->destroyed)
1806 ClientToScreen (private->xwindow, &pt);
1812 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%d+%d\n",
1813 ((GdkWindowPrivate *) window)->xwindow,
1814 private->xwindow, pt.x, pt.y));
1818 gdk_window_get_pointer (GdkWindow *window,
1821 GdkModifierType *mask)
1823 GdkWindowPrivate *private;
1824 GdkWindow *return_val;
1825 POINT pointc, point;
1829 window = (GdkWindow*) &gdk_root_parent;
1831 private = (GdkWindowPrivate*) window;
1834 GetCursorPos (&pointc);
1836 ScreenToClient (private->xwindow, &point);
1843 hwnd = WindowFromPoint (point);
1845 ScreenToClient (hwnd, &point);
1848 hwndc = ChildWindowFromPoint (hwnd, point);
1849 ClientToScreen (hwnd, &point);
1850 ScreenToClient (hwndc, &point);
1851 } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1853 return_val = gdk_window_lookup (hwnd);
1859 GetKeyboardState (kbd);
1861 if (kbd[VK_SHIFT] & 0x80)
1862 *mask |= GDK_SHIFT_MASK;
1863 if (kbd[VK_CAPITAL] & 0x80)
1864 *mask |= GDK_LOCK_MASK;
1865 if (kbd[VK_CONTROL] & 0x80)
1866 *mask |= GDK_CONTROL_MASK;
1867 if (kbd[VK_MENU] & 0x80)
1868 *mask |= GDK_MOD1_MASK;
1869 if (kbd[VK_LBUTTON] & 0x80)
1870 *mask |= GDK_BUTTON1_MASK;
1871 if (kbd[VK_MBUTTON] & 0x80)
1872 *mask |= GDK_BUTTON2_MASK;
1873 if (kbd[VK_RBUTTON] & 0x80)
1874 *mask |= GDK_BUTTON3_MASK;
1881 gdk_window_at_pointer (gint *win_x,
1884 GdkWindowPrivate *private;
1886 POINT point, pointc;
1890 private = &gdk_root_parent;
1892 GetCursorPos (&pointc);
1894 hwnd = WindowFromPoint (point);
1898 window = (GdkWindow *) &gdk_root_parent;
1906 ScreenToClient (hwnd, &point);
1909 hwndc = ChildWindowFromPoint (hwnd, point);
1910 ClientToScreen (hwnd, &point);
1911 ScreenToClient (hwndc, &point);
1912 } while (hwndc != hwnd && (hwnd = hwndc, 1));
1914 window = gdk_window_lookup (hwnd);
1916 if (window && (win_x || win_y))
1918 GetClientRect (hwnd, &rect);
1920 *win_x = point.x - rect.left;
1922 *win_y = point.y - rect.top;
1925 GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%d+%d %#x%s\n",
1926 point.x, point.y, hwnd,
1927 (window == NULL ? " NULL" : "")));
1933 gdk_window_get_parent (GdkWindow *window)
1935 g_return_val_if_fail (window != NULL, NULL);
1937 return ((GdkWindowPrivate*) window)->parent;
1941 gdk_window_get_toplevel (GdkWindow *window)
1943 GdkWindowPrivate *private;
1945 g_return_val_if_fail (window != NULL, NULL);
1947 private = (GdkWindowPrivate*) window;
1949 while (private->window_type == GDK_WINDOW_CHILD)
1951 window = ((GdkWindowPrivate*) window)->parent;
1952 private = (GdkWindowPrivate*) window;
1959 gdk_window_get_children (GdkWindow *window)
1961 GdkWindowPrivate *private;
1964 g_return_val_if_fail (window != NULL, NULL);
1966 private = (GdkWindowPrivate*) window;
1967 if (private->destroyed)
1971 g_warning ("gdk_window_get_children ???");
1978 gdk_window_get_events (GdkWindow *window)
1980 GdkWindowPrivate *private;
1982 g_return_val_if_fail (window != NULL, 0);
1984 private = (GdkWindowPrivate*) window;
1985 if (private->destroyed)
1988 return private->event_mask;
1992 gdk_window_set_events (GdkWindow *window,
1993 GdkEventMask event_mask)
1995 GdkWindowPrivate *private;
1997 g_return_if_fail (window != NULL);
1999 private = (GdkWindowPrivate*) window;
2000 if (private->destroyed)
2003 private->event_mask = event_mask;
2007 gdk_window_add_colormap_windows (GdkWindow *window)
2009 g_warning ("gdk_window_add_colormap_windows not implemented"); /* XXX */
2013 * This needs the X11 shape extension.
2014 * If not available, shaped windows will look
2015 * ugly, but programs still work. Stefan Wille
2018 gdk_window_shape_combine_mask (GdkWindow *window,
2022 GdkWindowPrivate *window_private;
2024 g_return_if_fail (window != NULL);
2026 window_private = (GdkWindowPrivate*) window;
2030 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
2031 window_private->xwindow));
2032 SetWindowRgn (window_private->xwindow, NULL, TRUE);
2036 GdkPixmapPrivate *pixmap_private;
2042 /* Convert mask bitmap to region */
2043 pixmap_private = (GdkPixmapPrivate*) mask;
2044 hrgn = BitmapToRegion (pixmap_private->xwindow);
2046 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
2047 window_private->xwindow,
2048 pixmap_private->xwindow));
2050 /* SetWindowRgn wants window (not client) coordinates */
2051 dwStyle = GetWindowLong (window_private->xwindow, GWL_STYLE);
2052 dwExStyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2053 GetClientRect (window_private->xwindow, &rect);
2054 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
2055 OffsetRgn (hrgn, -rect.left, -rect.top);
2057 OffsetRgn (hrgn, x, y);
2059 /* If this is a top-level window, add the title bar to the region */
2060 if (window_private->window_type == GDK_WINDOW_TOPLEVEL)
2062 CombineRgn (hrgn, hrgn,
2063 CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
2067 SetWindowRgn (window_private->xwindow, hrgn, TRUE);
2072 gdk_window_add_filter (GdkWindow *window,
2073 GdkFilterFunc function,
2076 GdkWindowPrivate *private;
2078 GdkEventFilter *filter;
2080 private = (GdkWindowPrivate*) window;
2081 if (private && private->destroyed)
2085 tmp_list = private->filters;
2087 tmp_list = gdk_default_filters;
2091 filter = (GdkEventFilter *)tmp_list->data;
2092 if ((filter->function == function) && (filter->data == data))
2094 tmp_list = tmp_list->next;
2097 filter = g_new (GdkEventFilter, 1);
2098 filter->function = function;
2099 filter->data = data;
2102 private->filters = g_list_append (private->filters, filter);
2104 gdk_default_filters = g_list_append (gdk_default_filters, filter);
2108 gdk_window_remove_filter (GdkWindow *window,
2109 GdkFilterFunc function,
2112 GdkWindowPrivate *private;
2113 GList *tmp_list, *node;
2114 GdkEventFilter *filter;
2116 private = (GdkWindowPrivate*) window;
2119 tmp_list = private->filters;
2121 tmp_list = gdk_default_filters;
2125 filter = (GdkEventFilter *)tmp_list->data;
2127 tmp_list = tmp_list->next;
2129 if ((filter->function == function) && (filter->data == data))
2132 private->filters = g_list_remove_link (private->filters, node);
2134 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
2135 g_list_free_1 (node);
2144 gdk_window_set_override_redirect (GdkWindow *window,
2145 gboolean override_redirect)
2147 g_warning ("gdk_window_set_override_redirect not implemented"); /* XXX */
2151 gdk_window_set_icon (GdkWindow *window,
2152 GdkWindow *icon_window,
2156 g_warning ("gdk_window_set_icon not implemented"); /* XXX */
2160 gdk_window_set_icon_name (GdkWindow *window,
2163 GdkWindowPrivate *window_private;
2165 g_return_if_fail (window != NULL);
2166 window_private = (GdkWindowPrivate*) window;
2167 if (window_private->destroyed)
2170 if (!SetWindowText (window_private->xwindow, name))
2171 g_warning ("gdk_window_set_icon_name: SetWindowText failed");
2175 gdk_window_set_group (GdkWindow *window,
2178 g_warning ("gdk_window_set_group not implemented"); /* XXX */
2182 gdk_window_set_decorations (GdkWindow *window,
2183 GdkWMDecoration decorations)
2185 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2186 LONG style, exstyle;
2188 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2189 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2191 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2192 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
2194 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2196 if (decorations & GDK_DECOR_ALL)
2197 style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2198 if (decorations & GDK_DECOR_BORDER)
2199 style |= (WS_BORDER);
2200 if (decorations & GDK_DECOR_RESIZEH)
2201 style |= (WS_THICKFRAME);
2202 if (decorations & GDK_DECOR_TITLE)
2203 style |= (WS_CAPTION);
2204 if (decorations & GDK_DECOR_MENU)
2205 style |= (WS_SYSMENU);
2206 if (decorations & GDK_DECOR_MINIMIZE)
2207 style |= (WS_MINIMIZEBOX);
2208 if (decorations & GDK_DECOR_MAXIMIZE)
2209 style |= (WS_MAXIMIZEBOX);
2211 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2215 gdk_window_set_functions (GdkWindow *window,
2216 GdkWMFunction functions)
2218 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2219 LONG style, exstyle;
2221 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2222 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2224 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2225 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
2228 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2230 if (functions & GDK_FUNC_ALL)
2231 style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2232 if (functions & GDK_FUNC_RESIZE)
2233 style |= (WS_THICKFRAME);
2234 if (functions & GDK_FUNC_MOVE)
2235 style |= (WS_THICKFRAME);
2236 if (functions & GDK_FUNC_MINIMIZE)
2237 style |= (WS_MINIMIZEBOX);
2238 if (functions & GDK_FUNC_MAXIMIZE)
2239 style |= (WS_MAXIMIZEBOX);
2241 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2245 gdk_window_get_toplevels (void)
2247 GList *new_list = NULL;
2250 tmp_list = gdk_root_parent.children;
2253 new_list = g_list_prepend (new_list, tmp_list->data);
2254 tmp_list = tmp_list->next;
2261 * propagate the shapes from all child windows of a GDK window to the parent
2262 * window. Shamelessly ripped from Enlightenment's code
2268 QueryTree (HWND hwnd,
2278 child = GetWindow (hwnd, GW_CHILD);
2280 child = GetWindow (child, GW_HWNDNEXT);
2283 } while (child != NULL);
2287 *children = g_new (HWND, n);
2288 for (i = 0; i < n; i++)
2291 child = GetWindow (hwnd, GW_CHILD);
2293 child = GetWindow (child, GW_HWNDNEXT);
2294 *children[i] = child;
2300 gdk_propagate_shapes (HANDLE win,
2304 HRGN region, childRegion;
2309 SetRectEmpty (&emptyRect);
2310 region = CreateRectRgnIndirect (&emptyRect);
2312 GetWindowRgn (win, region);
2314 QueryTree (win, &list, &num);
2317 WINDOWPLACEMENT placement;
2319 placement.length = sizeof (WINDOWPLACEMENT);
2320 /* go through all child windows and combine regions */
2321 for (i = 0; i < num; i++)
2323 GetWindowPlacement (list[i], &placement);
2324 if (placement.showCmd = SW_SHOWNORMAL)
2326 childRegion = CreateRectRgnIndirect (&emptyRect);
2327 GetWindowRgn (list[i], childRegion);
2328 CombineRgn (region, region, childRegion, RGN_OR);
2329 DeleteObject (childRegion);
2332 SetWindowRgn (win, region, TRUE);
2335 DeleteObject (region);
2339 gdk_window_set_child_shapes (GdkWindow *window)
2341 GdkWindowPrivate *private;
2343 g_return_if_fail (window != NULL);
2345 private = (GdkWindowPrivate*) window;
2346 if (private->destroyed)
2349 gdk_propagate_shapes ( private->xwindow, FALSE);
2353 gdk_window_merge_child_shapes (GdkWindow *window)
2355 GdkWindowPrivate *private;
2357 g_return_if_fail (window != NULL);
2359 private = (GdkWindowPrivate*) window;
2360 if (private->destroyed)
2363 gdk_propagate_shapes (private->xwindow, TRUE);
2366 /*************************************************************
2367 * gdk_window_is_visible:
2368 * Check if the given window is mapped.
2372 * is the window mapped
2373 *************************************************************/
2376 gdk_window_is_visible (GdkWindow *window)
2378 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2380 g_return_val_if_fail (window != NULL, FALSE);
2382 return private->mapped;
2385 /*************************************************************
2386 * gdk_window_is_viewable:
2387 * Check if the window and all ancestors of the window
2388 * are mapped. (This is not necessarily "viewable" in
2389 * the X sense, since we only check as far as we have
2390 * GDK window parents, not to the root window)
2394 * is the window viewable
2395 *************************************************************/
2398 gdk_window_is_viewable (GdkWindow *window)
2400 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2402 g_return_val_if_fail (window != NULL, FALSE);
2405 (private != &gdk_root_parent) &&
2406 (private->window_type != GDK_WINDOW_FOREIGN))
2408 if (!private->mapped)
2411 private = (GdkWindowPrivate *)private->parent;
2418 gdk_drawable_set_data (GdkDrawable *drawable,
2421 GDestroyNotify destroy_func)
2423 g_dataset_set_data_full (drawable, key, data, destroy_func);
2427 /* Support for windows that can be guffaw-scrolled
2428 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2432 gdk_window_gravity_works (void)
2434 enum { UNKNOWN, NO, YES };
2435 static gint gravity_works = UNKNOWN;
2437 if (gravity_works == UNKNOWN)
2444 attr.window_type = GDK_WINDOW_TEMP;
2445 attr.wclass = GDK_INPUT_OUTPUT;
2450 attr.event_mask = 0;
2452 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2454 attr.window_type = GDK_WINDOW_CHILD;
2455 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2457 gdk_window_set_static_win_gravity (child, TRUE);
2459 gdk_window_resize (parent, 100, 110);
2460 gdk_window_move (parent, 0, -10);
2461 gdk_window_move_resize (parent, 0, 0, 100, 100);
2463 gdk_window_resize (parent, 100, 110);
2464 gdk_window_move (parent, 0, -10);
2465 gdk_window_move_resize (parent, 0, 0, 100, 100);
2467 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2469 gdk_window_destroy (parent);
2470 gdk_window_destroy (child);
2472 gravity_works = ((y == -20) ? YES : NO);
2475 return (gravity_works == YES);
2479 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2481 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2483 g_return_if_fail (window != NULL);
2486 g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2490 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2492 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2494 g_return_if_fail (window != NULL);
2497 g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2500 /*************************************************************
2501 * gdk_window_set_static_gravities:
2502 * Set the bit gravity of the given window to static,
2503 * and flag it so all children get static subwindow
2506 * window: window for which to set static gravity
2507 * use_static: Whether to turn static gravity on or off.
2509 * Does the XServer support static gravity?
2510 *************************************************************/
2513 gdk_window_set_static_gravities (GdkWindow *window,
2514 gboolean use_static)
2516 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2519 g_return_val_if_fail (window != NULL, FALSE);
2521 if (!use_static == !private->guffaw_gravity)
2524 if (use_static && !gdk_window_gravity_works ())
2527 private->guffaw_gravity = use_static;
2529 gdk_window_set_static_bit_gravity (window, use_static);
2531 tmp_list = private->children;
2534 gdk_window_set_static_win_gravity (window, use_static);
2536 tmp_list = tmp_list->next;