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 "gdkprivate.h"
36 /* The Win API function AdjustWindowRect may return negative values
37 * resulting in obscured title bars. This helper function is coreccting it.
40 SafeAdjustWindowRectEx (RECT* lpRect,
45 if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
49 lpRect->right -= lpRect->left;
54 lpRect->bottom -= lpRect->top;
60 /* Forward declarations */
61 static gboolean gdk_window_gravity_works (void);
62 static void gdk_window_set_static_win_gravity (GdkWindow *window,
66 * The following fucntion by The Rasterman <raster@redhat.com>
67 * This function returns the X Window ID in which the x y location is in
68 * (x and y being relative to the root window), excluding any windows listed
69 * in the GList excludes (this is a list of X Window ID's - gpointer being
72 * This is primarily designed for internal gdk use - for DND for example
73 * when using a shaped icon window as the drag object - you exclude the
74 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
75 * You can get back an X Window ID as to what X Window ID is infact under
76 * those X,Y co-ordinates.
79 gdk_window_xid_at_coords (gint x,
85 gboolean warned = FALSE;
89 /* This is probably not correct, just a quick hack */
93 g_warning ("gdk_window_xid_at_coords probably not implemented correctly");
98 return WindowFromPoint (pt);
102 gdk_window_init (void)
107 width = GetSystemMetrics (SM_CXSCREEN);
108 height = GetSystemMetrics (SM_CYSCREEN);
110 { RECT r; /* //HB: don't obscure tray window (task bar) */
111 SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
112 width = r.right - r.left;
113 height = r.bottom - r.top;
117 gdk_root_parent.xwindow = gdk_root_window;
118 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
119 gdk_root_parent.window.user_data = NULL;
120 gdk_root_parent.width = width;
121 gdk_root_parent.height = height;
122 gdk_root_parent.children = NULL;
123 gdk_root_parent.colormap = NULL;
124 gdk_root_parent.ref_count = 1;
126 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
130 * is a wrapper function for RegisterWindowClassEx.
131 * It creates at least one unique class for every
132 * GdkWindowType. If support for single window-specific icons
133 * is ever needed (e.g Dialog specific), every such window should
137 RegisterGdkClass(GdkWindowType wtype)
139 static ATOM klassTOPLEVEL = 0;
140 static ATOM klassDIALOG = 0;
141 static ATOM klassCHILD = 0;
142 static ATOM klassTEMP = 0;
143 static HICON hAppIcon = NULL;
144 static WNDCLASSEX wcl;
147 wcl.cbSize = sizeof(WNDCLASSEX);
148 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
149 * on WM_SIZE and WM_MOVE. Flicker, Performance!
151 wcl.lpfnWndProc = gdk_WindowProc;
154 wcl.hInstance = gdk_ProgInstance;
156 /* initialize once! */
159 gchar sLoc [_MAX_PATH+1];
160 HINSTANCE hInst = GetModuleHandle(NULL);
162 if (0 != GetModuleFileName(hInst, sLoc, _MAX_PATH))
164 hAppIcon = ExtractIcon(hInst, sLoc, 0);
167 char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
169 hAppIcon = ExtractIcon(hInst, gdklibname, 0);
174 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
178 wcl.lpszMenuName = NULL;
181 /* initialize once per class */
182 #define ONCE_PER_CLASS() \
183 wcl.hIcon = CopyIcon (hAppIcon); \
184 wcl.hIconSm = CopyIcon (hAppIcon); \
185 wcl.hbrBackground = CreateSolidBrush( RGB(0,0,0)); \
186 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
190 case GDK_WINDOW_TOPLEVEL:
191 if (0 == klassTOPLEVEL)
193 wcl.lpszClassName = "gdkWindowToplevel";
196 klassTOPLEVEL = RegisterClassEx(&wcl);
198 klass = klassTOPLEVEL;
200 case GDK_WINDOW_CHILD:
203 wcl.lpszClassName = "gdkWindowChild";
205 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
207 klassCHILD = RegisterClassEx(&wcl);
211 case GDK_WINDOW_DIALOG:
212 if (0 == klassDIALOG)
214 wcl.lpszClassName = "gdkWindowDialog";
215 wcl.style |= CS_SAVEBITS;
217 klassDIALOG = RegisterClassEx(&wcl);
221 case GDK_WINDOW_TEMP:
224 wcl.lpszClassName = "gdkWindowTemp";
225 wcl.style |= CS_SAVEBITS;
227 klassTEMP = RegisterClassEx(&wcl);
231 case GDK_WINDOW_ROOT:
232 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
234 case GDK_WINDOW_PIXMAP:
235 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
240 } /* RegisterGdkClass */
244 gdk_window_new (GdkWindow *parent,
245 GdkWindowAttr *attributes,
246 gint attributes_mask)
249 GdkWindowPrivate *private;
250 GdkWindowPrivate *parent_private;
255 DWORD dwStyle, dwExStyle;
261 g_return_val_if_fail (attributes != NULL, NULL);
264 parent = (GdkWindow*) &gdk_root_parent;
266 parent_private = (GdkWindowPrivate*) parent;
267 if (parent_private->destroyed)
270 xparent = parent_private->xwindow;
272 private = g_new (GdkWindowPrivate, 1);
273 window = (GdkWindow*) private;
275 private->parent = parent;
277 private->destroyed = FALSE;
278 private->mapped = FALSE;
279 private->guffaw_gravity = FALSE;
280 private->resize_count = 0;
281 private->ref_count = 1;
283 private->x = (attributes_mask & GDK_WA_X) ? attributes->x : 0;
284 private->y = (attributes_mask & GDK_WA_Y) ? attributes->y : 0;
286 private->width = (attributes->width > 1) ? (attributes->width) : (1);
287 private->height = (attributes->height > 1) ? (attributes->height) : (1);
288 private->window_type = attributes->window_type;
289 private->extension_events = 0;
290 private->extension_events_selected = FALSE;
292 private->filters = NULL;
293 private->children = NULL;
295 window->user_data = NULL;
297 if (attributes_mask & GDK_WA_VISUAL)
298 visual = attributes->visual;
300 visual = gdk_visual_get_system ();
301 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
303 if (attributes_mask & GDK_WA_TITLE)
304 title = attributes->title;
306 title = g_get_prgname ();
308 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
309 private->bg_type = GDK_WIN32_BG_NORMAL;
310 private->hint_flags = 0;
311 private->xcursor = NULL;
313 if (parent_private && parent_private->guffaw_gravity)
318 if (attributes->wclass == GDK_INPUT_OUTPUT)
321 if (attributes_mask & GDK_WA_COLORMAP)
322 private->colormap = attributes->colormap;
324 private->colormap = gdk_colormap_get_system ();
328 dwExStyle = WS_EX_TRANSPARENT;
329 private->colormap = NULL;
330 private->bg_type = GDK_WIN32_BG_TRANSPARENT;
331 private->bg_pixmap = NULL;
334 if (attributes_mask & GDK_WA_X)
339 if (attributes_mask & GDK_WA_Y)
341 else if (attributes_mask & GDK_WA_X)
342 y = 100; /* ??? We must put it somewhere... */
344 y = 500; /* x is CW_USEDEFAULT, y doesn't matter then */
347 parent_private->children = g_list_prepend (parent_private->children, window);
349 switch (private->window_type)
351 case GDK_WINDOW_TOPLEVEL:
352 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
353 xparent = gdk_root_window;
355 case GDK_WINDOW_CHILD:
356 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
358 case GDK_WINDOW_DIALOG:
359 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
360 dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
361 xparent = gdk_root_window;
363 case GDK_WINDOW_TEMP:
364 dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
365 dwExStyle |= WS_EX_TOOLWINDOW;
367 case GDK_WINDOW_ROOT:
368 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
370 case GDK_WINDOW_PIXMAP:
371 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
375 klass = RegisterGdkClass (private->window_type);
377 g_error ("RegisterClassEx failed");
379 if (private->window_type != GDK_WINDOW_CHILD)
381 if (x == CW_USEDEFAULT)
392 rect.right = rect.left + private->width;
393 rect.bottom = rect.top + private->height;
395 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
396 g_warning ("gdk_window_new: AdjustWindowRectEx failed");
398 if (x != CW_USEDEFAULT)
403 width = rect.right - rect.left;
404 height = rect.bottom - rect.top;
408 width = private->width;
409 height = private->height;
413 CreateWindowEx (dwExStyle,
414 MAKEINTRESOURCE(klass),
424 g_print ("gdk_window_create: %s %s %#x %#x %dx%d@+%d+%d %#x = %#x\n",
425 (private->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
426 (private->window_type == GDK_WINDOW_CHILD ? "CHILD" :
427 (private->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
428 (private->window_type == GDK_WINDOW_TEMP ? "TEMP" :
433 width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
437 gdk_window_ref (window);
438 gdk_xid_table_insert (&private->xwindow, window);
440 if (private->colormap)
441 gdk_colormap_ref (private->colormap);
443 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
444 (attributes->cursor) :
451 gdk_window_foreign_new (guint32 anid)
454 GdkWindowPrivate *private;
455 GdkWindowPrivate *parent_private;
460 private = g_new (GdkWindowPrivate, 1);
461 window = (GdkWindow*) private;
463 parent = GetParent ((HWND) anid);
464 private->parent = gdk_xid_table_lookup (parent);
466 parent_private = (GdkWindowPrivate *)private->parent;
469 parent_private->children = g_list_prepend (parent_private->children, window);
471 private->xwindow = (HWND) anid;
472 GetClientRect ((HWND) anid, &rect);
474 point.y = rect.right;
475 ClientToScreen ((HWND) anid, &point);
476 if (parent != HWND_DESKTOP)
477 ScreenToClient (parent, &point);
478 private->x = point.x;
479 private->y = point.y;
480 private->width = rect.right - rect.left;
481 private->height = rect.bottom - rect.top;
482 private->resize_count = 0;
483 private->ref_count = 1;
484 private->window_type = GDK_WINDOW_FOREIGN;
485 private->destroyed = FALSE;
486 private->mapped = IsWindowVisible (private->xwindow);
487 private->guffaw_gravity = FALSE;
488 private->extension_events = 0;
489 private->extension_events_selected = FALSE;
491 private->colormap = NULL;
493 private->filters = NULL;
494 private->children = NULL;
496 window->user_data = NULL;
498 gdk_window_ref (window);
499 gdk_xid_table_insert (&private->xwindow, window);
504 /* Call this function when you want a window and all its children to
505 * disappear. When xdestroy is true, a request to destroy the XWindow
506 * is sent out. When it is false, it is assumed that the XWindow has
507 * been or will be destroyed by destroying some ancestor of this
511 gdk_window_internal_destroy (GdkWindow *window,
513 gboolean our_destroy)
515 GdkWindowPrivate *private;
516 GdkWindowPrivate *temp_private;
517 GdkWindow *temp_window;
521 g_return_if_fail (window != NULL);
523 private = (GdkWindowPrivate*) window;
525 GDK_NOTE (MISC, g_print ("gdk_window_internal_destroy %#x\n",
528 switch (private->window_type)
530 case GDK_WINDOW_TOPLEVEL:
531 case GDK_WINDOW_CHILD:
532 case GDK_WINDOW_DIALOG:
533 case GDK_WINDOW_TEMP:
534 case GDK_WINDOW_FOREIGN:
535 if (!private->destroyed)
539 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
540 if (parent_private->children)
541 parent_private->children = g_list_remove (parent_private->children, window);
544 if (private->window_type != GDK_WINDOW_FOREIGN)
546 children = tmp = private->children;
547 private->children = NULL;
551 temp_window = tmp->data;
554 temp_private = (GdkWindowPrivate*) temp_window;
556 gdk_window_internal_destroy (temp_window, FALSE,
560 g_list_free (children);
563 if (private->extension_events != 0)
564 gdk_input_window_destroy (window);
566 if (private->filters)
568 tmp = private->filters;
576 g_list_free (private->filters);
577 private->filters = NULL;
580 if (private->window_type == GDK_WINDOW_FOREIGN)
582 if (our_destroy && (private->parent != NULL))
584 /* It's somebody elses window, but in our hierarchy,
585 * so reparent it to the root window, and then send
586 * it a delete event, as if we were a WM
588 gdk_window_hide (window);
589 gdk_window_reparent (window, NULL, 0, 0);
591 /* Is this too drastic? Many (most?) applications
592 * quit if any window receives WM_QUIT I think.
593 * OTOH, I don't think foreign windows are much
594 * used, so the question is maybe academic.
596 PostMessage (private->xwindow, WM_QUIT, 0, 0);
600 DestroyWindow (private->xwindow);
602 if (private->colormap)
603 gdk_colormap_unref (private->colormap);
605 private->mapped = FALSE;
606 private->destroyed = TRUE;
610 case GDK_WINDOW_ROOT:
611 g_error ("attempted to destroy root window");
614 case GDK_WINDOW_PIXMAP:
615 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
620 /* Like internal_destroy, but also destroys the reference created by
624 gdk_window_destroy (GdkWindow *window)
626 gdk_window_internal_destroy (window, TRUE, TRUE);
627 gdk_window_unref (window);
630 /* This function is called when the XWindow is really gone. */
633 gdk_window_destroy_notify (GdkWindow *window)
635 GdkWindowPrivate *private;
637 g_return_if_fail (window != NULL);
639 private = (GdkWindowPrivate*) window;
641 GDK_NOTE (EVENTS, g_print ("gdk_window_destroy_notify: %#x %d\n",
642 private->xwindow, private->destroyed));
644 if (!private->destroyed)
646 if (private->window_type == GDK_WINDOW_FOREIGN)
647 gdk_window_internal_destroy (window, FALSE, FALSE);
649 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
652 gdk_xid_table_remove (private->xwindow);
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->ref_count += 1;
664 GDK_NOTE (MISC, g_print ("gdk_window_ref %#x %d\n",
665 private->xwindow, private->ref_count));
671 gdk_window_unref (GdkWindow *window)
673 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
674 g_return_if_fail (window != NULL);
676 private->ref_count -= 1;
678 GDK_NOTE (MISC, g_print ("gdk_window_unref %#x %d%s\n",
679 private->xwindow, private->ref_count,
680 (private->ref_count == 0 ? " freeing" : "")));
682 if (private->ref_count == 0)
684 if (private->bg_type == GDK_WIN32_BG_PIXMAP && private->bg_pixmap != NULL)
685 gdk_pixmap_unref (private->bg_pixmap);
687 if (!private->destroyed)
689 if (private->window_type == GDK_WINDOW_FOREIGN)
690 gdk_xid_table_remove (private->xwindow);
692 g_warning ("losing last reference to undestroyed window");
694 g_dataset_destroy (window);
700 gdk_window_show (GdkWindow *window)
702 GdkWindowPrivate *private;
704 g_return_if_fail (window != NULL);
706 private = (GdkWindowPrivate*) window;
707 if (!private->destroyed)
709 GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n", private->xwindow));
711 private->mapped = TRUE;
712 if (private->window_type == GDK_WINDOW_TEMP)
714 ShowWindow (private->xwindow, SW_SHOWNOACTIVATE);
715 SetWindowPos (private->xwindow, HWND_TOPMOST, 0, 0, 0, 0,
716 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
718 ShowWindow (private->xwindow, SW_HIDE); /* Don't put on toolbar */
723 ShowWindow (private->xwindow, SW_SHOWNORMAL);
724 ShowWindow (private->xwindow, SW_RESTORE);
725 SetForegroundWindow (private->xwindow);
727 ShowOwnedPopups (private->xwindow, TRUE);
734 gdk_window_hide (GdkWindow *window)
736 GdkWindowPrivate *private;
738 g_return_if_fail (window != NULL);
740 private = (GdkWindowPrivate*) window;
741 if (!private->destroyed)
743 GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n", private->xwindow));
745 private->mapped = FALSE;
746 if (private->window_type == GDK_WINDOW_TOPLEVEL)
747 ShowOwnedPopups (private->xwindow, FALSE);
749 ShowWindow (private->xwindow, SW_HIDE);
751 ShowWindow (private->xwindow, SW_MINIMIZE);
753 CloseWindow (private->xwindow);
759 gdk_window_withdraw (GdkWindow *window)
761 GdkWindowPrivate *private;
763 g_return_if_fail (window != NULL);
765 private = (GdkWindowPrivate*) window;
766 if (!private->destroyed)
768 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n", private->xwindow));
770 gdk_window_hide (window); /* XXX */
775 gdk_window_move (GdkWindow *window,
779 GdkWindowPrivate *private;
781 g_return_if_fail (window != NULL);
783 private = (GdkWindowPrivate*) window;
784 if (!private->destroyed)
788 GDK_NOTE (MISC, g_print ("gdk_window_move: %#x +%d+%d\n",
789 private->xwindow, x, y));
791 GetClientRect (private->xwindow, &rect);
793 if (private->window_type != GDK_WINDOW_CHILD)
801 ClientToScreen (private->xwindow, &ptTL);
806 ptBR.y = rect.bottom;
807 ClientToScreen (private->xwindow, &ptBR);
808 rect.right = x + ptBR.x - ptTL.x;
809 rect.bottom = y + ptBR.y - ptTL.y;
811 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
812 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
813 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
814 g_warning ("gdk_window_move: AdjustWindowRectEx failed");
824 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
826 rect.right - rect.left, rect.bottom - rect.top,
828 if (!MoveWindow (private->xwindow,
829 x, y, rect.right - rect.left, rect.bottom - rect.top,
831 g_warning ("gdk_window_move: MoveWindow failed");
836 gdk_window_resize (GdkWindow *window,
840 GdkWindowPrivate *private;
842 g_return_if_fail (window != NULL);
844 if ((gint16) width < 1)
846 if ((gint16) height < 1)
849 private = (GdkWindowPrivate*) window;
851 if (!private->destroyed &&
852 ((private->resize_count > 0) ||
853 (private->width != (guint16) width) ||
854 (private->height != (guint16) height)))
858 GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
859 private->xwindow, width, height));
861 if (private->window_type != GDK_WINDOW_CHILD)
870 ClientToScreen (private->xwindow, &pt);
873 rect.right = pt.x + width;
874 rect.bottom = pt.y + height;
876 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
877 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
878 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
879 g_warning ("gdk_window_resize: AdjustWindowRectEx failed");
883 width = rect.right - rect.left;
884 height = rect.bottom - rect.top;
890 private->width = width;
891 private->height = height;
894 private->resize_count += 1;
896 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
897 private->xwindow, width, height, x, y));
898 if (!MoveWindow (private->xwindow,
901 g_warning ("gdk_window_resize: MoveWindow failed");
906 gdk_window_move_resize (GdkWindow *window,
912 GdkWindowPrivate *private;
914 g_return_if_fail (window != NULL);
916 if ((gint16) width < 1)
918 if ((gint16) height < 1)
921 private = (GdkWindowPrivate*) window;
922 if (!private->destroyed)
928 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
929 private->xwindow, width, height, x, y));
933 rect.right = x + width;
934 rect.bottom = y + height;
936 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
937 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
938 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
939 g_warning ("gdk_window_move_resize: AdjustWindowRectEx failed");
941 if (private->window_type == GDK_WINDOW_CHILD)
945 private->width = width;
946 private->height = height;
948 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
950 rect.right - rect.left, rect.bottom - rect.top,
951 rect.left, rect.top));
952 if (!MoveWindow (private->xwindow,
954 rect.right - rect.left, rect.bottom - rect.top,
956 g_warning ("gdk_window_move_resize: MoveWindow failed");
958 if (private->guffaw_gravity)
960 GList *tmp_list = private->children;
963 GdkWindowPrivate *child_private = tmp_list->data;
965 child_private->x -= x - private->x;
966 child_private->y -= y - private->y;
968 tmp_list = tmp_list->next;
976 gdk_window_reparent (GdkWindow *window,
977 GdkWindow *new_parent,
981 GdkWindowPrivate *window_private;
982 GdkWindowPrivate *parent_private;
983 GdkWindowPrivate *old_parent_private;
985 g_return_if_fail (window != NULL);
988 new_parent = (GdkWindow*) &gdk_root_parent;
990 window_private = (GdkWindowPrivate*) window;
991 old_parent_private = (GdkWindowPrivate*)window_private->parent;
992 parent_private = (GdkWindowPrivate*) new_parent;
994 if (!window_private->destroyed && !parent_private->destroyed)
996 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
997 window_private->xwindow,
998 parent_private->xwindow));
999 if (!SetParent (window_private->xwindow, parent_private->xwindow))
1000 g_warning ("gdk_window_reparent: SetParent failed");
1002 if (!MoveWindow (window_private->xwindow,
1004 window_private->width, window_private->height,
1006 g_warning ("gdk_window_reparent: MoveWindow failed");
1009 window_private->parent = new_parent;
1011 if (old_parent_private)
1012 old_parent_private->children = g_list_remove (old_parent_private->children, window);
1014 if ((old_parent_private &&
1015 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1016 (!old_parent_private && parent_private->guffaw_gravity))
1017 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1019 parent_private->children = g_list_prepend (parent_private->children, window);
1023 gdk_window_clear (GdkWindow *window)
1025 GdkWindowPrivate *private;
1027 g_return_if_fail (window != NULL);
1029 private = (GdkWindowPrivate*) window;
1031 if (!private->destroyed)
1033 gdk_window_clear_area (window, 0, 0, private->width, private->height);
1039 gdk_window_clear_area (GdkWindow *window,
1045 GdkWindowPrivate *private;
1047 g_return_if_fail (window != NULL);
1049 private = (GdkWindowPrivate*) window;
1051 if (!private->destroyed)
1056 width = G_MAXSHORT/2; /* Yeah, right */
1058 height = G_MAXSHORT/2;
1059 GDK_NOTE (MISC, g_print ("gdk_window_clear_area: %#x %dx%d@+%d+%d\n",
1060 private->xwindow, width, height, x, y));
1061 hdc = GetDC (private->xwindow);
1062 IntersectClipRect (hdc, x, y, x + width, y + height);
1063 SendMessage (private->xwindow, WM_ERASEBKGND, (WPARAM) hdc, 0);
1064 ReleaseDC (private->xwindow, hdc);
1069 gdk_window_clear_area_e (GdkWindow *window,
1075 GdkWindowPrivate *private;
1077 g_return_if_fail (window != NULL);
1079 private = (GdkWindowPrivate*) window;
1081 if (!private->destroyed)
1085 GDK_NOTE (MISC, g_print ("gdk_window_clear_area_e: %#x %dx%d@+%d+%d\n",
1086 private->xwindow, width, height, x, y));
1089 rect.right = x + width;
1091 rect.bottom = y + height;
1092 if (!InvalidateRect (private->xwindow, &rect, TRUE))
1093 g_warning ("gdk_window_clear_area_e: InvalidateRect failed");
1094 UpdateWindow (private->xwindow);
1099 gdk_window_copy_area (GdkWindow *window,
1103 GdkWindow *source_window,
1109 GdkWindowPrivate *src_private;
1110 GdkWindowPrivate *dest_private;
1111 GdkGCPrivate *gc_private;
1113 g_return_if_fail (window != NULL);
1114 g_return_if_fail (gc != NULL);
1116 if (source_window == NULL)
1117 source_window = window;
1119 src_private = (GdkWindowPrivate*) source_window;
1120 dest_private = (GdkWindowPrivate*) window;
1121 gc_private = (GdkGCPrivate*) gc;
1123 if (!src_private->destroyed && !dest_private->destroyed)
1125 HDC hdcDest, hdcSrc;
1127 if ((hdcDest = GetDC (dest_private->xwindow)) == NULL)
1128 g_warning ("gdk_window_copy_area: GetDC failed");
1130 if ((hdcSrc = GetDC (src_private->xwindow)) == NULL)
1131 g_warning ("gdk_window_copy_area: GetDC failed");
1133 if (!BitBlt (hdcDest, x, y, width, height, hdcSrc, source_x, source_y, SRCCOPY))
1134 g_warning ("gdk_window_copy_area: BitBlt failed");
1136 ReleaseDC (dest_private->xwindow, hdcDest);
1137 ReleaseDC (src_private->xwindow, hdcSrc);
1142 gdk_window_raise (GdkWindow *window)
1144 GdkWindowPrivate *private;
1146 g_return_if_fail (window != NULL);
1148 private = (GdkWindowPrivate*) window;
1150 if (!private->destroyed)
1152 GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n", private->xwindow));
1154 if (!BringWindowToTop (private->xwindow))
1155 g_warning ("gdk_window_raise: BringWindowToTop failed");
1160 gdk_window_lower (GdkWindow *window)
1162 GdkWindowPrivate *private;
1164 g_return_if_fail (window != NULL);
1166 private = (GdkWindowPrivate*) window;
1168 if (!private->destroyed)
1170 GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n", private->xwindow));
1172 if (!SetWindowPos (private->xwindow, HWND_BOTTOM, 0, 0, 0, 0,
1173 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1174 g_warning ("gdk_window_lower: SetWindowPos failed");
1179 gdk_window_set_user_data (GdkWindow *window,
1182 g_return_if_fail (window != NULL);
1184 window->user_data = user_data;
1188 gdk_window_set_hints (GdkWindow *window,
1197 GdkWindowPrivate *private;
1198 WINDOWPLACEMENT size_hints;
1204 g_return_if_fail (window != NULL);
1206 private = (GdkWindowPrivate*) window;
1207 if (private->destroyed)
1210 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1212 min_width, min_height, max_width, max_height,
1215 private->hint_flags = flags;
1216 size_hints.length = sizeof (size_hints);
1220 if (flags & GDK_HINT_POS)
1221 if (!GetWindowPlacement (private->xwindow, &size_hints))
1222 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1225 GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1226 " (%d,%d)--(%d,%d)\n",
1227 size_hints.rcNormalPosition.left,
1228 size_hints.rcNormalPosition.top,
1229 size_hints.rcNormalPosition.right,
1230 size_hints.rcNormalPosition.bottom));
1231 /* What are the corresponding window coordinates for client
1232 * area coordinates x, y
1236 rect.right = rect.left + 200; /* dummy */
1237 rect.bottom = rect.top + 200;
1238 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1239 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1240 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1241 size_hints.flags = 0;
1242 size_hints.showCmd = SW_SHOWNA;
1244 /* Set the normal position hint to that location, with unchanged
1247 diff = size_hints.rcNormalPosition.left - rect.left;
1248 size_hints.rcNormalPosition.left = rect.left;
1249 size_hints.rcNormalPosition.right -= diff;
1250 diff = size_hints.rcNormalPosition.top - rect.top;
1251 size_hints.rcNormalPosition.top = rect.top;
1252 size_hints.rcNormalPosition.bottom -= diff;
1253 GDK_NOTE (MISC, g_print ("...setting: (%d,%d)--(%d,%d)\n",
1254 size_hints.rcNormalPosition.left,
1255 size_hints.rcNormalPosition.top,
1256 size_hints.rcNormalPosition.right,
1257 size_hints.rcNormalPosition.bottom));
1258 if (!SetWindowPlacement (private->xwindow, &size_hints))
1259 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1260 private->hint_x = rect.left;
1261 private->hint_y = rect.top;
1264 if (flags & GDK_HINT_MIN_SIZE)
1268 rect.right = min_width;
1269 rect.bottom = min_height;
1270 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1271 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1272 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1273 private->hint_min_width = rect.right - rect.left;
1274 private->hint_min_height = rect.bottom - rect.top;
1276 /* Also chek if he current size of the window is in bounds. */
1277 GetClientRect (private->xwindow, &rect);
1278 if (rect.right < min_width && rect.bottom < min_height)
1279 gdk_window_resize (window, min_width, min_height);
1280 else if (rect.right < min_width)
1281 gdk_window_resize (window, min_width, rect.bottom);
1282 else if (rect.bottom < min_height)
1283 gdk_window_resize (window, rect.right, min_height);
1285 if (flags & GDK_HINT_MAX_SIZE)
1289 rect.right = max_width;
1290 rect.bottom = max_height;
1291 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1292 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1293 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1294 private->hint_max_width = rect.right - rect.left;
1295 private->hint_max_height = rect.bottom - rect.top;
1296 /* Again, check if the window is too large currently. */
1297 GetClientRect (private->xwindow, &rect);
1298 if (rect.right > max_width && rect.bottom > max_height)
1299 gdk_window_resize (window, max_width, max_height);
1300 else if (rect.right > max_width)
1301 gdk_window_resize (window, max_width, rect.bottom);
1302 else if (rect.bottom > max_height)
1303 gdk_window_resize (window, rect.right, max_height);
1309 gdk_window_set_geometry_hints (GdkWindow *window,
1310 GdkGeometry *geometry,
1311 GdkWindowHints geom_mask)
1313 GdkWindowPrivate *private;
1314 WINDOWPLACEMENT size_hints;
1320 g_return_if_fail (window != NULL);
1322 private = (GdkWindowPrivate*) window;
1323 if (private->destroyed)
1326 size_hints.length = sizeof (size_hints);
1328 private->hint_flags = geom_mask;
1330 if (geom_mask & GDK_HINT_POS)
1333 if (geom_mask & GDK_HINT_MIN_SIZE)
1337 rect.right = geometry->min_width;
1338 rect.bottom = geometry->min_height;
1339 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1340 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1341 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1342 private->hint_min_width = rect.right - rect.left;
1343 private->hint_min_height = rect.bottom - rect.top;
1345 /* Also check if he current size of the window is in bounds */
1346 GetClientRect (private->xwindow, &rect);
1347 if (rect.right < geometry->min_width
1348 && rect.bottom < geometry->min_height)
1349 gdk_window_resize (window, geometry->min_width, geometry->min_height);
1350 else if (rect.right < geometry->min_width)
1351 gdk_window_resize (window, geometry->min_width, rect.bottom);
1352 else if (rect.bottom < geometry->min_height)
1353 gdk_window_resize (window, rect.right, geometry->min_height);
1356 if (geom_mask & GDK_HINT_MAX_SIZE)
1360 rect.right = geometry->max_width;
1361 rect.bottom = geometry->max_height;
1362 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1363 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1364 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1365 private->hint_max_width = rect.right - rect.left;
1366 private->hint_max_height = rect.bottom - rect.top;
1368 /* Again, check if the window is too large currently. */
1369 GetClientRect (private->xwindow, &rect);
1370 if (rect.right > geometry->max_width
1371 && rect.bottom > geometry->max_height)
1372 gdk_window_resize (window, geometry->max_width, geometry->max_height);
1373 else if (rect.right > geometry->max_width)
1374 gdk_window_resize (window, geometry->max_width, rect.bottom);
1375 else if (rect.bottom > geometry->max_height)
1376 gdk_window_resize (window, rect.right, geometry->max_height);
1379 /* I don't know what to do when called with zero base_width and height. */
1380 if (geom_mask & GDK_HINT_BASE_SIZE
1381 && geometry->base_width > 0
1382 && geometry->base_height > 0)
1383 if (!GetWindowPlacement (private->xwindow, &size_hints))
1384 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1387 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1388 " rcNormalPosition: (%d,%d)--(%d,%d)\n",
1389 size_hints.rcNormalPosition.left,
1390 size_hints.rcNormalPosition.top,
1391 size_hints.rcNormalPosition.right,
1392 size_hints.rcNormalPosition.bottom));
1393 size_hints.rcNormalPosition.right =
1394 size_hints.rcNormalPosition.left + geometry->base_width;
1395 size_hints.rcNormalPosition.bottom =
1396 size_hints.rcNormalPosition.top + geometry->base_height;
1397 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
1398 size_hints.rcNormalPosition.left,
1399 size_hints.rcNormalPosition.top,
1400 size_hints.rcNormalPosition.right,
1401 size_hints.rcNormalPosition.bottom));
1402 if (!SetWindowPlacement (private->xwindow, &size_hints))
1403 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1406 if (geom_mask & GDK_HINT_RESIZE_INC)
1411 if (geom_mask & GDK_HINT_ASPECT)
1418 gdk_window_set_title (GdkWindow *window,
1421 GdkWindowPrivate *private;
1423 g_return_if_fail (window != NULL);
1425 private = (GdkWindowPrivate*) window;
1426 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
1427 private->xwindow, title));
1428 if (!private->destroyed)
1430 if (!SetWindowText (private->xwindow, title))
1431 g_warning ("gdk_window_set_title: SetWindowText failed");
1436 gdk_window_set_role (GdkWindow *window,
1439 GdkWindowPrivate *private;
1441 g_return_if_fail (window != NULL);
1443 private = (GdkWindowPrivate*) window;
1445 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1446 private->xwindow, (role ? role : "NULL")));
1451 gdk_window_set_transient_for (GdkWindow *window,
1454 GdkWindowPrivate *private;
1455 GdkWindowPrivate *parent_private;
1457 g_return_if_fail (window != NULL);
1459 private = (GdkWindowPrivate*) window;
1460 parent_private = (GdkWindowPrivate*) parent;
1462 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1463 private->xwindow, parent_private->xwindow));
1468 gdk_window_set_background (GdkWindow *window,
1471 GdkWindowPrivate *private;
1473 g_return_if_fail (window != NULL);
1475 private = (GdkWindowPrivate*) window;
1476 if (!private->destroyed)
1478 GdkColormapPrivate *colormap_private =
1479 (GdkColormapPrivate *) private->colormap;
1481 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1483 gdk_color_to_string (color)));
1485 if (private->bg_type == GDK_WIN32_BG_PIXMAP)
1487 if (private->bg_pixmap != NULL)
1489 gdk_pixmap_unref (private->bg_pixmap);
1490 private->bg_pixmap = NULL;
1492 private->bg_type = GDK_WIN32_BG_NORMAL;
1494 private->bg_type = GDK_WIN32_BG_PIXEL;
1495 private->bg_pixel = *color;
1500 gdk_window_set_back_pixmap (GdkWindow *window,
1502 gint parent_relative)
1504 GdkWindowPrivate *window_private;
1506 g_return_if_fail (window != NULL);
1508 window_private = (GdkWindowPrivate*) window;
1510 if (!window_private->destroyed)
1512 GdkColormapPrivate *colormap_private =
1513 (GdkColormapPrivate *) window_private->colormap;
1514 if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
1516 if (window_private->bg_pixmap != NULL)
1518 gdk_pixmap_unref (window_private->bg_pixmap);
1519 window_private->bg_pixmap = NULL;
1521 window_private->bg_type = GDK_WIN32_BG_NORMAL;
1523 if (parent_relative)
1525 window_private->bg_type = GDK_WIN32_BG_PARENT_RELATIVE;
1533 /* We must cache the pixmap in the WindowPrivate and
1534 * paint it each time we get WM_ERASEBKGND
1536 window_private->bg_type = GDK_WIN32_BG_PIXMAP;
1537 window_private->bg_pixmap = pixmap;
1538 gdk_pixmap_ref (pixmap);
1544 gdk_window_set_cursor (GdkWindow *window,
1547 GdkWindowPrivate *window_private;
1548 GdkCursorPrivate *cursor_private;
1551 g_return_if_fail (window != NULL);
1553 window_private = (GdkWindowPrivate*) window;
1554 cursor_private = (GdkCursorPrivate*) cursor;
1556 if (!window_private->destroyed)
1559 xcursor = LoadCursor (NULL, IDC_ARROW);
1561 xcursor = cursor_private->xcursor;
1563 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1564 window_private->xwindow, xcursor));
1565 window_private->xcursor = xcursor;
1566 SetCursor (xcursor);
1571 gdk_window_set_colormap (GdkWindow *window,
1572 GdkColormap *colormap)
1574 GdkWindowPrivate *window_private;
1575 GdkColormapPrivate *colormap_private;
1577 g_return_if_fail (window != NULL);
1578 g_return_if_fail (colormap != NULL);
1580 window_private = (GdkWindowPrivate*) window;
1581 colormap_private = (GdkColormapPrivate*) colormap;
1583 if (!window_private->destroyed)
1586 GDK_NOTE (MISC, g_print ("gdk_window_set_colormap: %#x %#x\n",
1587 window_private->xwindow,
1588 colormap_private->xcolormap));
1589 if (window_private->colormap)
1590 gdk_colormap_unref (window_private->colormap);
1591 window_private->colormap = colormap;
1592 gdk_colormap_ref (window_private->colormap);
1594 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1595 gdk_window_add_colormap_windows (window);
1600 gdk_window_get_user_data (GdkWindow *window,
1603 g_return_if_fail (window != NULL);
1605 *data = window->user_data;
1609 gdk_window_get_geometry (GdkWindow *window,
1616 GdkWindowPrivate *window_private;
1619 window = (GdkWindow*) &gdk_root_parent;
1621 window_private = (GdkWindowPrivate*) window;
1623 if (!window_private->destroyed)
1627 if (!GetClientRect (window_private->xwindow, &rect))
1628 g_warning ("gdk_window_get_geometry: GetClientRect failed");
1635 *width = rect.right - rect.left;
1637 *height = rect.bottom - rect.top;
1639 *depth = gdk_window_get_visual (window)->depth;
1644 gdk_window_get_position (GdkWindow *window,
1648 GdkWindowPrivate *window_private;
1650 g_return_if_fail (window != NULL);
1652 window_private = (GdkWindowPrivate*) window;
1655 *x = window_private->x;
1657 *y = window_private->y;
1661 gdk_window_get_size (GdkWindow *window,
1665 GdkWindowPrivate *window_private;
1667 g_return_if_fail (window != NULL);
1669 window_private = (GdkWindowPrivate*) window;
1672 *width = window_private->width;
1674 *height = window_private->height;
1678 gdk_window_get_visual (GdkWindow *window)
1680 GdkWindowPrivate *window_private;
1682 g_return_val_if_fail (window != NULL, NULL);
1684 window_private = (GdkWindowPrivate*) window;
1685 /* Huh? ->parent is never set for a pixmap. We should just return
1686 * null immeditately. Well, do it then!
1688 if (window_private->window_type == GDK_WINDOW_PIXMAP)
1691 if (!window_private->destroyed)
1693 if (window_private->colormap == NULL)
1694 return gdk_visual_get_system (); /* XXX ??? */
1696 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1703 gdk_window_get_colormap (GdkWindow *window)
1705 GdkWindowPrivate *window_private;
1707 g_return_val_if_fail (window != NULL, NULL);
1708 window_private = (GdkWindowPrivate*) window;
1710 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1711 if (!window_private->destroyed)
1713 if (window_private->colormap == NULL)
1714 return gdk_colormap_get_system (); /* XXX ??? */
1716 return window_private->colormap;
1723 gdk_window_get_type (GdkWindow *window)
1725 GdkWindowPrivate *window_private;
1727 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1729 window_private = (GdkWindowPrivate*) window;
1730 return window_private->window_type;
1734 gdk_window_get_origin (GdkWindow *window,
1738 GdkWindowPrivate *private;
1743 g_return_val_if_fail (window != NULL, 0);
1745 private = (GdkWindowPrivate*) window;
1747 if (!private->destroyed)
1753 ClientToScreen (private->xwindow, &pt);
1766 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
1767 private->xwindow, tx, ty));
1772 gdk_window_get_deskrelative_origin (GdkWindow *window,
1776 return gdk_window_get_origin (window, x, y);
1780 gdk_window_get_root_origin (GdkWindow *window,
1784 GdkWindowPrivate *private;
1787 g_return_if_fail (window != NULL);
1789 private = (GdkWindowPrivate*) window;
1794 if (private->destroyed)
1797 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1798 private = (GdkWindowPrivate*) private->parent;
1799 if (private->destroyed)
1804 ClientToScreen (private->xwindow, &pt);
1810 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%d+%d\n",
1811 ((GdkWindowPrivate *) window)->xwindow,
1812 private->xwindow, pt.x, pt.y));
1816 gdk_window_get_pointer (GdkWindow *window,
1819 GdkModifierType *mask)
1821 GdkWindowPrivate *private;
1822 GdkWindow *return_val;
1823 POINT pointc, point;
1827 window = (GdkWindow*) &gdk_root_parent;
1829 private = (GdkWindowPrivate*) window;
1832 GetCursorPos (&pointc);
1834 ScreenToClient (private->xwindow, &point);
1841 hwnd = WindowFromPoint (point);
1843 ScreenToClient (hwnd, &point);
1846 hwndc = ChildWindowFromPoint (hwnd, point);
1847 ClientToScreen (hwnd, &point);
1848 ScreenToClient (hwndc, &point);
1849 } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1851 return_val = gdk_window_lookup (hwnd);
1857 GetKeyboardState (kbd);
1859 if (kbd[VK_SHIFT] & 0x80)
1860 *mask |= GDK_SHIFT_MASK;
1861 if (kbd[VK_CAPITAL] & 0x80)
1862 *mask |= GDK_LOCK_MASK;
1863 if (kbd[VK_CONTROL] & 0x80)
1864 *mask |= GDK_CONTROL_MASK;
1865 if (kbd[VK_MENU] & 0x80)
1866 *mask |= GDK_MOD1_MASK;
1867 if (kbd[VK_LBUTTON] & 0x80)
1868 *mask |= GDK_BUTTON1_MASK;
1869 if (kbd[VK_MBUTTON] & 0x80)
1870 *mask |= GDK_BUTTON2_MASK;
1871 if (kbd[VK_RBUTTON] & 0x80)
1872 *mask |= GDK_BUTTON3_MASK;
1879 gdk_window_at_pointer (gint *win_x,
1882 GdkWindowPrivate *private;
1884 POINT point, pointc;
1888 private = &gdk_root_parent;
1890 GetCursorPos (&pointc);
1892 hwnd = WindowFromPoint (point);
1896 window = (GdkWindow *) &gdk_root_parent;
1904 ScreenToClient (hwnd, &point);
1907 hwndc = ChildWindowFromPoint (hwnd, point);
1908 ClientToScreen (hwnd, &point);
1909 ScreenToClient (hwndc, &point);
1910 } while (hwndc != hwnd && (hwnd = hwndc, 1));
1912 window = gdk_window_lookup (hwnd);
1914 if (window && (win_x || win_y))
1916 GetClientRect (hwnd, &rect);
1918 *win_x = point.x - rect.left;
1920 *win_y = point.y - rect.top;
1923 GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%d+%d %#x%s\n",
1924 point.x, point.y, hwnd,
1925 (window == NULL ? " NULL" : "")));
1931 gdk_window_get_parent (GdkWindow *window)
1933 g_return_val_if_fail (window != NULL, NULL);
1935 return ((GdkWindowPrivate*) window)->parent;
1939 gdk_window_get_toplevel (GdkWindow *window)
1941 GdkWindowPrivate *private;
1943 g_return_val_if_fail (window != NULL, NULL);
1945 private = (GdkWindowPrivate*) window;
1947 while (private->window_type == GDK_WINDOW_CHILD)
1949 window = ((GdkWindowPrivate*) window)->parent;
1950 private = (GdkWindowPrivate*) window;
1957 gdk_window_get_children (GdkWindow *window)
1959 GdkWindowPrivate *private;
1962 g_return_val_if_fail (window != NULL, NULL);
1964 private = (GdkWindowPrivate*) window;
1965 if (private->destroyed)
1969 g_warning ("gdk_window_get_children ???");
1976 gdk_window_get_events (GdkWindow *window)
1978 GdkWindowPrivate *private;
1980 g_return_val_if_fail (window != NULL, 0);
1982 private = (GdkWindowPrivate*) window;
1983 if (private->destroyed)
1986 return private->event_mask;
1990 gdk_window_set_events (GdkWindow *window,
1991 GdkEventMask event_mask)
1993 GdkWindowPrivate *private;
1995 g_return_if_fail (window != NULL);
1997 private = (GdkWindowPrivate*) window;
1998 if (private->destroyed)
2001 private->event_mask = event_mask;
2005 gdk_window_add_colormap_windows (GdkWindow *window)
2007 g_warning ("gdk_window_add_colormap_windows not implemented"); /* XXX */
2011 * This needs the X11 shape extension.
2012 * If not available, shaped windows will look
2013 * ugly, but programs still work. Stefan Wille
2016 gdk_window_shape_combine_mask (GdkWindow *window,
2020 GdkWindowPrivate *window_private;
2022 g_return_if_fail (window != NULL);
2024 window_private = (GdkWindowPrivate*) window;
2028 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
2029 window_private->xwindow));
2030 SetWindowRgn (window_private->xwindow, NULL, TRUE);
2034 GdkPixmapPrivate *pixmap_private;
2040 /* Convert mask bitmap to region */
2041 pixmap_private = (GdkPixmapPrivate*) mask;
2042 hrgn = BitmapToRegion (pixmap_private->xwindow);
2044 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
2045 window_private->xwindow,
2046 pixmap_private->xwindow));
2048 /* SetWindowRgn wants window (not client) coordinates */
2049 dwStyle = GetWindowLong (window_private->xwindow, GWL_STYLE);
2050 dwExStyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2051 GetClientRect (window_private->xwindow, &rect);
2052 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
2053 OffsetRgn (hrgn, -rect.left, -rect.top);
2055 OffsetRgn (hrgn, x, y);
2057 /* If this is a top-level window, add the title bar to the region */
2058 if (window_private->window_type == GDK_WINDOW_TOPLEVEL)
2060 CombineRgn (hrgn, hrgn,
2061 CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
2065 SetWindowRgn (window_private->xwindow, hrgn, TRUE);
2070 gdk_window_add_filter (GdkWindow *window,
2071 GdkFilterFunc function,
2074 GdkWindowPrivate *private;
2076 GdkEventFilter *filter;
2078 private = (GdkWindowPrivate*) window;
2079 if (private && private->destroyed)
2083 tmp_list = private->filters;
2085 tmp_list = gdk_default_filters;
2089 filter = (GdkEventFilter *)tmp_list->data;
2090 if ((filter->function == function) && (filter->data == data))
2092 tmp_list = tmp_list->next;
2095 filter = g_new (GdkEventFilter, 1);
2096 filter->function = function;
2097 filter->data = data;
2100 private->filters = g_list_append (private->filters, filter);
2102 gdk_default_filters = g_list_append (gdk_default_filters, filter);
2106 gdk_window_remove_filter (GdkWindow *window,
2107 GdkFilterFunc function,
2110 GdkWindowPrivate *private;
2111 GList *tmp_list, *node;
2112 GdkEventFilter *filter;
2114 private = (GdkWindowPrivate*) window;
2117 tmp_list = private->filters;
2119 tmp_list = gdk_default_filters;
2123 filter = (GdkEventFilter *)tmp_list->data;
2125 tmp_list = tmp_list->next;
2127 if ((filter->function == function) && (filter->data == data))
2130 private->filters = g_list_remove_link (private->filters, node);
2132 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
2133 g_list_free_1 (node);
2142 gdk_window_set_override_redirect (GdkWindow *window,
2143 gboolean override_redirect)
2145 g_warning ("gdk_window_set_override_redirect not implemented"); /* XXX */
2149 gdk_window_set_icon (GdkWindow *window,
2150 GdkWindow *icon_window,
2154 g_warning ("gdk_window_set_icon not implemented"); /* XXX */
2158 gdk_window_set_icon_name (GdkWindow *window,
2161 GdkWindowPrivate *window_private;
2163 g_return_if_fail (window != NULL);
2164 window_private = (GdkWindowPrivate*) window;
2165 if (window_private->destroyed)
2168 if (!SetWindowText (window_private->xwindow, name))
2169 g_warning ("gdk_window_set_icon_name: SetWindowText failed");
2173 gdk_window_set_group (GdkWindow *window,
2176 g_warning ("gdk_window_set_group not implemented"); /* XXX */
2180 gdk_window_set_decorations (GdkWindow *window,
2181 GdkWMDecoration decorations)
2183 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2184 LONG style, exstyle;
2186 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2187 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2189 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2190 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
2192 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2194 if (decorations & GDK_DECOR_ALL)
2195 style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2196 if (decorations & GDK_DECOR_BORDER)
2197 style |= (WS_BORDER);
2198 if (decorations & GDK_DECOR_RESIZEH)
2199 style |= (WS_THICKFRAME);
2200 if (decorations & GDK_DECOR_TITLE)
2201 style |= (WS_CAPTION);
2202 if (decorations & GDK_DECOR_MENU)
2203 style |= (WS_SYSMENU);
2204 if (decorations & GDK_DECOR_MINIMIZE)
2205 style |= (WS_MINIMIZEBOX);
2206 if (decorations & GDK_DECOR_MAXIMIZE)
2207 style |= (WS_MAXIMIZEBOX);
2209 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2213 gdk_window_set_functions (GdkWindow *window,
2214 GdkWMFunction functions)
2216 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2217 LONG style, exstyle;
2219 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2220 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2222 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2223 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
2226 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2228 if (functions & GDK_FUNC_ALL)
2229 style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2230 if (functions & GDK_FUNC_RESIZE)
2231 style |= (WS_THICKFRAME);
2232 if (functions & GDK_FUNC_MOVE)
2233 style |= (WS_THICKFRAME);
2234 if (functions & GDK_FUNC_MINIMIZE)
2235 style |= (WS_MINIMIZEBOX);
2236 if (functions & GDK_FUNC_MAXIMIZE)
2237 style |= (WS_MAXIMIZEBOX);
2239 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2243 gdk_window_get_toplevels (void)
2245 GList *new_list = NULL;
2248 tmp_list = gdk_root_parent.children;
2251 new_list = g_list_prepend (new_list, tmp_list->data);
2252 tmp_list = tmp_list->next;
2259 * propagate the shapes from all child windows of a GDK window to the parent
2260 * window. Shamelessly ripped from Enlightenment's code
2266 QueryTree (HWND hwnd,
2276 child = GetWindow (hwnd, GW_CHILD);
2278 child = GetWindow (child, GW_HWNDNEXT);
2281 } while (child != NULL);
2285 *children = g_new (HWND, n);
2286 for (i = 0; i < n; i++)
2289 child = GetWindow (hwnd, GW_CHILD);
2291 child = GetWindow (child, GW_HWNDNEXT);
2292 *children[i] = child;
2298 gdk_propagate_shapes (HANDLE win,
2302 HRGN region, childRegion;
2307 SetRectEmpty (&emptyRect);
2308 region = CreateRectRgnIndirect (&emptyRect);
2310 GetWindowRgn (win, region);
2312 QueryTree (win, &list, &num);
2315 WINDOWPLACEMENT placement;
2317 placement.length = sizeof (WINDOWPLACEMENT);
2318 /* go through all child windows and combine regions */
2319 for (i = 0; i < num; i++)
2321 GetWindowPlacement (list[i], &placement);
2322 if (placement.showCmd = SW_SHOWNORMAL)
2324 childRegion = CreateRectRgnIndirect (&emptyRect);
2325 GetWindowRgn (list[i], childRegion);
2326 CombineRgn (region, region, childRegion, RGN_OR);
2327 DeleteObject (childRegion);
2330 SetWindowRgn (win, region, TRUE);
2333 DeleteObject (region);
2337 gdk_window_set_child_shapes (GdkWindow *window)
2339 GdkWindowPrivate *private;
2341 g_return_if_fail (window != NULL);
2343 private = (GdkWindowPrivate*) window;
2344 if (private->destroyed)
2347 gdk_propagate_shapes ( private->xwindow, FALSE);
2351 gdk_window_merge_child_shapes (GdkWindow *window)
2353 GdkWindowPrivate *private;
2355 g_return_if_fail (window != NULL);
2357 private = (GdkWindowPrivate*) window;
2358 if (private->destroyed)
2361 gdk_propagate_shapes (private->xwindow, TRUE);
2364 /*************************************************************
2365 * gdk_window_is_visible:
2366 * Check if the given window is mapped.
2370 * is the window mapped
2371 *************************************************************/
2374 gdk_window_is_visible (GdkWindow *window)
2376 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2378 g_return_val_if_fail (window != NULL, FALSE);
2380 return private->mapped;
2383 /*************************************************************
2384 * gdk_window_is_viewable:
2385 * Check if the window and all ancestors of the window
2386 * are mapped. (This is not necessarily "viewable" in
2387 * the X sense, since we only check as far as we have
2388 * GDK window parents, not to the root window)
2392 * is the window viewable
2393 *************************************************************/
2396 gdk_window_is_viewable (GdkWindow *window)
2398 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2400 g_return_val_if_fail (window != NULL, FALSE);
2403 (private != &gdk_root_parent) &&
2404 (private->window_type != GDK_WINDOW_FOREIGN))
2406 if (!private->mapped)
2409 private = (GdkWindowPrivate *)private->parent;
2416 gdk_drawable_set_data (GdkDrawable *drawable,
2419 GDestroyNotify destroy_func)
2421 g_dataset_set_data_full (drawable, key, data, destroy_func);
2425 /* Support for windows that can be guffaw-scrolled
2426 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2430 gdk_window_gravity_works (void)
2432 enum { UNKNOWN, NO, YES };
2433 static gint gravity_works = UNKNOWN;
2435 if (gravity_works == UNKNOWN)
2442 attr.window_type = GDK_WINDOW_TEMP;
2443 attr.wclass = GDK_INPUT_OUTPUT;
2448 attr.event_mask = 0;
2450 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2452 attr.window_type = GDK_WINDOW_CHILD;
2453 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2455 gdk_window_set_static_win_gravity (child, TRUE);
2457 gdk_window_resize (parent, 100, 110);
2458 gdk_window_move (parent, 0, -10);
2459 gdk_window_move_resize (parent, 0, 0, 100, 100);
2461 gdk_window_resize (parent, 100, 110);
2462 gdk_window_move (parent, 0, -10);
2463 gdk_window_move_resize (parent, 0, 0, 100, 100);
2465 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2467 gdk_window_destroy (parent);
2468 gdk_window_destroy (child);
2470 gravity_works = ((y == -20) ? YES : NO);
2473 return (gravity_works == YES);
2477 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2479 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2481 g_return_if_fail (window != NULL);
2484 g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2488 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2490 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2492 g_return_if_fail (window != NULL);
2495 g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2498 /*************************************************************
2499 * gdk_window_set_static_gravities:
2500 * Set the bit gravity of the given window to static,
2501 * and flag it so all children get static subwindow
2504 * window: window for which to set static gravity
2505 * use_static: Whether to turn static gravity on or off.
2507 * Does the XServer support static gravity?
2508 *************************************************************/
2511 gdk_window_set_static_gravities (GdkWindow *window,
2512 gboolean use_static)
2514 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2517 g_return_val_if_fail (window != NULL, FALSE);
2519 if (!use_static == !private->guffaw_gravity)
2522 if (use_static && !gdk_window_gravity_works ())
2525 private->guffaw_gravity = use_static;
2527 gdk_window_set_static_bit_gravity (window, use_static);
2529 tmp_list = private->children;
2532 gdk_window_set_static_win_gravity (window, use_static);
2534 tmp_list = tmp_list->next;