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 #ifdef MULTIPLE_WINDOW_CLASSES
148 Error: Not yet implemented!
151 wcl.cbSize = sizeof(WNDCLASSEX);
152 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
153 * on WM_SIZE and WM_MOVE. Flicker, Performance!
155 wcl.lpfnWndProc = gdk_WindowProc;
158 wcl.hInstance = gdk_ProgInstance;
160 /* initialize once! */
163 gchar sLoc [_MAX_PATH+1];
164 HINSTANCE hInst = GetModuleHandle(NULL);
166 if (0 != GetModuleFileName(hInst, sLoc, _MAX_PATH))
168 hAppIcon = ExtractIcon(hInst, sLoc, 0);
171 char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
173 hAppIcon = ExtractIcon(hInst, gdklibname, 0);
178 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
182 wcl.lpszMenuName = NULL;
185 /* initialize once per class */
186 #define ONCE_PER_CLASS() \
187 wcl.hIcon = CopyIcon (hAppIcon); \
188 wcl.hIconSm = CopyIcon (hAppIcon); \
189 wcl.hbrBackground = CreateSolidBrush( RGB(0,0,0)); \
190 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
194 case GDK_WINDOW_TOPLEVEL:
195 if (0 == klassTOPLEVEL)
197 wcl.lpszClassName = "gdkWindowToplevel";
200 klassTOPLEVEL = RegisterClassEx(&wcl);
202 klass = klassTOPLEVEL;
204 case GDK_WINDOW_CHILD:
207 wcl.lpszClassName = "gdkWindowChild";
209 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
211 klassCHILD = RegisterClassEx(&wcl);
215 case GDK_WINDOW_DIALOG:
216 if (0 == klassDIALOG)
218 wcl.lpszClassName = "gdkWindowDialog";
219 wcl.style |= CS_SAVEBITS;
221 klassDIALOG = RegisterClassEx(&wcl);
225 case GDK_WINDOW_TEMP:
228 wcl.lpszClassName = "gdkWindowTemp";
229 wcl.style |= CS_SAVEBITS;
231 klassTEMP = RegisterClassEx(&wcl);
235 case GDK_WINDOW_ROOT:
236 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
238 case GDK_WINDOW_PIXMAP:
239 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
244 } /* RegisterGdkClass */
248 gdk_window_new (GdkWindow *parent,
249 GdkWindowAttr *attributes,
250 gint attributes_mask)
253 GdkWindowPrivate *private;
254 GdkWindowPrivate *parent_private;
259 DWORD dwStyle, dwExStyle;
265 g_return_val_if_fail (attributes != NULL, NULL);
268 parent = (GdkWindow*) &gdk_root_parent;
270 parent_private = (GdkWindowPrivate*) parent;
271 if (parent_private->destroyed)
274 xparent = parent_private->xwindow;
276 private = g_new (GdkWindowPrivate, 1);
277 window = (GdkWindow*) private;
279 private->parent = parent;
281 private->destroyed = FALSE;
282 private->mapped = FALSE;
283 private->guffaw_gravity = FALSE;
284 private->resize_count = 0;
285 private->ref_count = 1;
287 private->x = (attributes_mask & GDK_WA_X) ? attributes->x : 0;
288 private->y = (attributes_mask & GDK_WA_Y) ? attributes->y : 0;
290 private->width = (attributes->width > 1) ? (attributes->width) : (1);
291 private->height = (attributes->height > 1) ? (attributes->height) : (1);
292 private->window_type = attributes->window_type;
293 private->extension_events = 0;
294 private->extension_events_selected = FALSE;
296 private->filters = NULL;
297 private->children = NULL;
299 window->user_data = NULL;
301 if (attributes_mask & GDK_WA_VISUAL)
302 visual = attributes->visual;
304 visual = gdk_visual_get_system ();
305 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
307 if (attributes_mask & GDK_WA_TITLE)
308 title = attributes->title;
310 title = g_get_prgname ();
312 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
313 private->bg_type = GDK_WIN32_BG_NORMAL;
314 private->hint_flags = 0;
315 private->xcursor = NULL;
317 if (parent_private && parent_private->guffaw_gravity)
322 if (attributes->wclass == GDK_INPUT_OUTPUT)
325 if (attributes_mask & GDK_WA_COLORMAP)
326 private->colormap = attributes->colormap;
328 private->colormap = gdk_colormap_get_system ();
332 dwExStyle = WS_EX_TRANSPARENT;
333 private->colormap = NULL;
334 private->bg_type = GDK_WIN32_BG_TRANSPARENT;
335 private->bg_pixmap = NULL;
338 if (attributes_mask & GDK_WA_X)
343 if (attributes_mask & GDK_WA_Y)
345 else if (attributes_mask & GDK_WA_X)
346 y = 100; /* ??? We must put it somewhere... */
348 y = 500; /* x is CW_USEDEFAULT, y doesn't matter then */
351 parent_private->children = g_list_prepend (parent_private->children, window);
353 switch (private->window_type)
355 case GDK_WINDOW_TOPLEVEL:
356 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
357 xparent = gdk_root_window;
359 case GDK_WINDOW_CHILD:
360 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
362 case GDK_WINDOW_DIALOG:
363 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
364 dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
365 xparent = gdk_root_window;
367 case GDK_WINDOW_TEMP:
368 dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
369 dwExStyle |= WS_EX_TOOLWINDOW;
371 case GDK_WINDOW_ROOT:
372 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
374 case GDK_WINDOW_PIXMAP:
375 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
379 klass = RegisterGdkClass (private->window_type);
381 g_error ("RegisterClassEx failed");
383 if (private->window_type != GDK_WINDOW_CHILD)
385 if (x == CW_USEDEFAULT)
396 rect.right = rect.left + private->width;
397 rect.bottom = rect.top + private->height;
399 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
400 g_warning ("gdk_window_new: AdjustWindowRectEx failed");
402 if (x != CW_USEDEFAULT)
407 width = rect.right - rect.left;
408 height = rect.bottom - rect.top;
412 width = private->width;
413 height = private->height;
417 CreateWindowEx (dwExStyle,
418 MAKEINTRESOURCE(klass),
428 g_print ("gdk_window_create: %s %s %#x %#x %dx%d@+%d+%d %#x = %#x\n",
429 (private->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
430 (private->window_type == GDK_WINDOW_CHILD ? "CHILD" :
431 (private->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
432 (private->window_type == GDK_WINDOW_TEMP ? "TEMP" :
437 width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
441 gdk_window_ref (window);
442 gdk_xid_table_insert (&private->xwindow, window);
444 if (private->colormap)
445 gdk_colormap_ref (private->colormap);
447 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
448 (attributes->cursor) :
455 gdk_window_foreign_new (guint32 anid)
458 GdkWindowPrivate *private;
459 GdkWindowPrivate *parent_private;
464 private = g_new (GdkWindowPrivate, 1);
465 window = (GdkWindow*) private;
467 parent = GetParent ((HWND) anid);
468 private->parent = gdk_xid_table_lookup (parent);
470 parent_private = (GdkWindowPrivate *)private->parent;
473 parent_private->children = g_list_prepend (parent_private->children, window);
475 private->xwindow = (HWND) anid;
476 GetClientRect ((HWND) anid, &rect);
478 point.y = rect.right;
479 ClientToScreen ((HWND) anid, &point);
480 if (parent != HWND_DESKTOP)
481 ScreenToClient (parent, &point);
482 private->x = point.x;
483 private->y = point.y;
484 private->width = rect.right - rect.left;
485 private->height = rect.bottom - rect.top;
486 private->resize_count = 0;
487 private->ref_count = 1;
488 private->window_type = GDK_WINDOW_FOREIGN;
489 private->destroyed = FALSE;
490 private->mapped = IsWindowVisible (private->xwindow);
491 private->guffaw_gravity = FALSE;
492 private->extension_events = 0;
493 private->extension_events_selected = FALSE;
495 private->colormap = NULL;
497 private->filters = NULL;
498 private->children = NULL;
500 window->user_data = NULL;
502 gdk_window_ref (window);
503 gdk_xid_table_insert (&private->xwindow, window);
508 /* Call this function when you want a window and all its children to
509 * disappear. When xdestroy is true, a request to destroy the XWindow
510 * is sent out. When it is false, it is assumed that the XWindow has
511 * been or will be destroyed by destroying some ancestor of this
515 gdk_window_internal_destroy (GdkWindow *window,
517 gboolean our_destroy)
519 GdkWindowPrivate *private;
520 GdkWindowPrivate *temp_private;
521 GdkWindow *temp_window;
525 g_return_if_fail (window != NULL);
527 private = (GdkWindowPrivate*) window;
529 GDK_NOTE (MISC, g_print ("gdk_window_internal_destroy %#x\n",
532 switch (private->window_type)
534 case GDK_WINDOW_TOPLEVEL:
535 case GDK_WINDOW_CHILD:
536 case GDK_WINDOW_DIALOG:
537 case GDK_WINDOW_TEMP:
538 case GDK_WINDOW_FOREIGN:
539 if (!private->destroyed)
543 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
544 if (parent_private->children)
545 parent_private->children = g_list_remove (parent_private->children, window);
548 if (private->window_type != GDK_WINDOW_FOREIGN)
550 children = tmp = private->children;
551 private->children = NULL;
555 temp_window = tmp->data;
558 temp_private = (GdkWindowPrivate*) temp_window;
560 gdk_window_internal_destroy (temp_window, FALSE,
564 g_list_free (children);
567 if (private->extension_events != 0)
568 gdk_input_window_destroy (window);
570 if (private->filters)
572 tmp = private->filters;
580 g_list_free (private->filters);
581 private->filters = NULL;
584 if (private->window_type == GDK_WINDOW_FOREIGN)
586 if (our_destroy && (private->parent != NULL))
588 /* It's somebody elses window, but in our hierarchy,
589 * so reparent it to the root window, and then send
590 * it a delete event, as if we were a WM
592 gdk_window_hide (window);
593 gdk_window_reparent (window, NULL, 0, 0);
595 /* Is this too drastic? Many (most?) applications
596 * quit if any window receives WM_QUIT I think.
597 * OTOH, I don't think foreign windows are much
598 * used, so the question is maybe academic.
600 PostMessage (private->xwindow, WM_QUIT, 0, 0);
604 DestroyWindow (private->xwindow);
606 if (private->colormap)
607 gdk_colormap_unref (private->colormap);
609 private->mapped = FALSE;
610 private->destroyed = TRUE;
614 case GDK_WINDOW_ROOT:
615 g_error ("attempted to destroy root window");
618 case GDK_WINDOW_PIXMAP:
619 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
624 /* Like internal_destroy, but also destroys the reference created by
628 gdk_window_destroy (GdkWindow *window)
630 gdk_window_internal_destroy (window, TRUE, TRUE);
631 gdk_window_unref (window);
634 /* This function is called when the XWindow is really gone. */
637 gdk_window_destroy_notify (GdkWindow *window)
639 GdkWindowPrivate *private;
641 g_return_if_fail (window != NULL);
643 private = (GdkWindowPrivate*) window;
645 GDK_NOTE (EVENTS, g_print ("gdk_window_destroy_notify: %#x %d\n",
646 private->xwindow, private->destroyed));
648 if (!private->destroyed)
650 if (private->window_type == GDK_WINDOW_FOREIGN)
651 gdk_window_internal_destroy (window, FALSE, FALSE);
653 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
656 gdk_xid_table_remove (private->xwindow);
657 gdk_window_unref (window);
661 gdk_window_ref (GdkWindow *window)
663 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
664 g_return_val_if_fail (window != NULL, NULL);
666 private->ref_count += 1;
668 GDK_NOTE (MISC, g_print ("gdk_window_ref %#x %d\n",
669 private->xwindow, private->ref_count));
675 gdk_window_unref (GdkWindow *window)
677 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
678 g_return_if_fail (window != NULL);
680 private->ref_count -= 1;
682 GDK_NOTE (MISC, g_print ("gdk_window_unref %#x %d%s\n",
683 private->xwindow, private->ref_count,
684 (private->ref_count == 0 ? " freeing" : "")));
686 if (private->ref_count == 0)
688 if (private->bg_type == GDK_WIN32_BG_PIXMAP && private->bg_pixmap != NULL)
689 gdk_pixmap_unref (private->bg_pixmap);
691 if (!private->destroyed)
693 if (private->window_type == GDK_WINDOW_FOREIGN)
694 gdk_xid_table_remove (private->xwindow);
696 g_warning ("losing last reference to undestroyed window");
698 g_dataset_destroy (window);
704 gdk_window_show (GdkWindow *window)
706 GdkWindowPrivate *private;
708 g_return_if_fail (window != NULL);
710 private = (GdkWindowPrivate*) window;
711 if (!private->destroyed)
713 GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n", private->xwindow));
715 private->mapped = TRUE;
716 if (private->window_type == GDK_WINDOW_TEMP)
718 ShowWindow (private->xwindow, SW_SHOWNOACTIVATE);
719 SetWindowPos (private->xwindow, HWND_TOPMOST, 0, 0, 0, 0,
720 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
722 ShowWindow (private->xwindow, SW_HIDE); /* Don't put on toolbar */
727 ShowWindow (private->xwindow, SW_SHOWNORMAL);
728 ShowWindow (private->xwindow, SW_RESTORE);
729 SetForegroundWindow (private->xwindow);
731 ShowOwnedPopups (private->xwindow, TRUE);
738 gdk_window_hide (GdkWindow *window)
740 GdkWindowPrivate *private;
742 g_return_if_fail (window != NULL);
744 private = (GdkWindowPrivate*) window;
745 if (!private->destroyed)
747 GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n", private->xwindow));
749 private->mapped = FALSE;
750 if (private->window_type == GDK_WINDOW_TOPLEVEL)
751 ShowOwnedPopups (private->xwindow, FALSE);
753 ShowWindow (private->xwindow, SW_HIDE);
755 ShowWindow (private->xwindow, SW_MINIMIZE);
757 CloseWindow (private->xwindow);
763 gdk_window_withdraw (GdkWindow *window)
765 GdkWindowPrivate *private;
767 g_return_if_fail (window != NULL);
769 private = (GdkWindowPrivate*) window;
770 if (!private->destroyed)
772 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n", private->xwindow));
774 gdk_window_hide (window); /* XXX */
779 gdk_window_move (GdkWindow *window,
783 GdkWindowPrivate *private;
785 g_return_if_fail (window != NULL);
787 private = (GdkWindowPrivate*) window;
788 if (!private->destroyed)
792 GDK_NOTE (MISC, g_print ("gdk_window_move: %#x +%d+%d\n",
793 private->xwindow, x, y));
795 GetClientRect (private->xwindow, &rect);
797 if (private->window_type != GDK_WINDOW_CHILD)
805 ClientToScreen (private->xwindow, &ptTL);
810 ptBR.y = rect.bottom;
811 ClientToScreen (private->xwindow, &ptBR);
812 rect.right = x + ptBR.x - ptTL.x;
813 rect.bottom = y + ptBR.y - ptTL.y;
815 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
816 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
817 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
818 g_warning ("gdk_window_move: AdjustWindowRectEx failed");
828 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
830 rect.right - rect.left, rect.bottom - rect.top,
832 if (!MoveWindow (private->xwindow,
833 x, y, rect.right - rect.left, rect.bottom - rect.top,
835 g_warning ("gdk_window_move: MoveWindow failed");
840 gdk_window_resize (GdkWindow *window,
844 GdkWindowPrivate *private;
846 g_return_if_fail (window != NULL);
848 if ((gint16) width < 1)
850 if ((gint16) height < 1)
853 private = (GdkWindowPrivate*) window;
855 if (!private->destroyed &&
856 ((private->resize_count > 0) ||
857 (private->width != (guint16) width) ||
858 (private->height != (guint16) height)))
862 GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
863 private->xwindow, width, height));
865 if (private->window_type != GDK_WINDOW_CHILD)
874 ClientToScreen (private->xwindow, &pt);
877 rect.right = pt.x + width;
878 rect.bottom = pt.y + height;
880 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
881 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
882 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
883 g_warning ("gdk_window_resize: AdjustWindowRectEx failed");
887 width = rect.right - rect.left;
888 height = rect.bottom - rect.top;
894 private->width = width;
895 private->height = height;
898 private->resize_count += 1;
900 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
901 private->xwindow, width, height, x, y));
902 if (!MoveWindow (private->xwindow,
905 g_warning ("gdk_window_resize: MoveWindow failed");
910 gdk_window_move_resize (GdkWindow *window,
916 GdkWindowPrivate *private;
918 g_return_if_fail (window != NULL);
920 if ((gint16) width < 1)
922 if ((gint16) height < 1)
925 private = (GdkWindowPrivate*) window;
926 if (!private->destroyed)
932 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
933 private->xwindow, width, height, x, y));
937 rect.right = x + width;
938 rect.bottom = y + height;
940 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
941 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
942 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
943 g_warning ("gdk_window_move_resize: AdjustWindowRectEx failed");
945 if (private->window_type == GDK_WINDOW_CHILD)
949 private->width = width;
950 private->height = height;
952 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
954 rect.right - rect.left, rect.bottom - rect.top,
955 rect.left, rect.top));
956 if (!MoveWindow (private->xwindow,
958 rect.right - rect.left, rect.bottom - rect.top,
960 g_warning ("gdk_window_move_resize: MoveWindow failed");
962 if (private->guffaw_gravity)
964 GList *tmp_list = private->children;
967 GdkWindowPrivate *child_private = tmp_list->data;
969 child_private->x -= x - private->x;
970 child_private->y -= y - private->y;
972 tmp_list = tmp_list->next;
980 gdk_window_reparent (GdkWindow *window,
981 GdkWindow *new_parent,
985 GdkWindowPrivate *window_private;
986 GdkWindowPrivate *parent_private;
987 GdkWindowPrivate *old_parent_private;
989 g_return_if_fail (window != NULL);
992 new_parent = (GdkWindow*) &gdk_root_parent;
994 window_private = (GdkWindowPrivate*) window;
995 old_parent_private = (GdkWindowPrivate*)window_private->parent;
996 parent_private = (GdkWindowPrivate*) new_parent;
998 if (!window_private->destroyed && !parent_private->destroyed)
1000 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
1001 window_private->xwindow,
1002 parent_private->xwindow));
1003 if (!SetParent (window_private->xwindow, parent_private->xwindow))
1004 g_warning ("gdk_window_reparent: SetParent failed");
1006 if (!MoveWindow (window_private->xwindow,
1008 window_private->width, window_private->height,
1010 g_warning ("gdk_window_reparent: MoveWindow failed");
1013 window_private->parent = new_parent;
1015 if (old_parent_private)
1016 old_parent_private->children = g_list_remove (old_parent_private->children, window);
1018 if ((old_parent_private &&
1019 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1020 (!old_parent_private && parent_private->guffaw_gravity))
1021 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1023 parent_private->children = g_list_prepend (parent_private->children, window);
1027 gdk_window_clear (GdkWindow *window)
1029 GdkWindowPrivate *private;
1031 g_return_if_fail (window != NULL);
1033 private = (GdkWindowPrivate*) window;
1035 if (!private->destroyed)
1037 gdk_window_clear_area (window, 0, 0, private->width, private->height);
1043 gdk_window_clear_area (GdkWindow *window,
1049 GdkWindowPrivate *private;
1051 g_return_if_fail (window != NULL);
1053 private = (GdkWindowPrivate*) window;
1055 if (!private->destroyed)
1060 width = G_MAXSHORT/2; /* Yeah, right */
1062 height = G_MAXSHORT/2;
1063 GDK_NOTE (MISC, g_print ("gdk_window_clear_area: %#x %dx%d@+%d+%d\n",
1064 private->xwindow, width, height, x, y));
1065 hdc = GetDC (private->xwindow);
1066 IntersectClipRect (hdc, x, y, x + width, y + height);
1067 SendMessage (private->xwindow, WM_ERASEBKGND, (WPARAM) hdc, 0);
1068 ReleaseDC (private->xwindow, hdc);
1073 gdk_window_clear_area_e (GdkWindow *window,
1079 GdkWindowPrivate *private;
1081 g_return_if_fail (window != NULL);
1083 private = (GdkWindowPrivate*) window;
1085 if (!private->destroyed)
1089 GDK_NOTE (MISC, g_print ("gdk_window_clear_area_e: %#x %dx%d@+%d+%d\n",
1090 private->xwindow, width, height, x, y));
1093 rect.right = x + width;
1095 rect.bottom = y + height;
1096 if (!InvalidateRect (private->xwindow, &rect, TRUE))
1097 g_warning ("gdk_window_clear_area_e: InvalidateRect failed");
1098 UpdateWindow (private->xwindow);
1103 gdk_window_copy_area (GdkWindow *window,
1107 GdkWindow *source_window,
1113 GdkWindowPrivate *src_private;
1114 GdkWindowPrivate *dest_private;
1115 GdkGCPrivate *gc_private;
1117 g_return_if_fail (window != NULL);
1118 g_return_if_fail (gc != NULL);
1120 if (source_window == NULL)
1121 source_window = window;
1123 src_private = (GdkWindowPrivate*) source_window;
1124 dest_private = (GdkWindowPrivate*) window;
1125 gc_private = (GdkGCPrivate*) gc;
1127 if (!src_private->destroyed && !dest_private->destroyed)
1129 HDC hdcDest, hdcSrc;
1131 if ((hdcDest = GetDC (dest_private->xwindow)) == NULL)
1132 g_warning ("gdk_window_copy_area: GetDC failed");
1134 if ((hdcSrc = GetDC (src_private->xwindow)) == NULL)
1135 g_warning ("gdk_window_copy_area: GetDC failed");
1137 if (!BitBlt (hdcDest, x, y, width, height, hdcSrc, source_x, source_y, SRCCOPY))
1138 g_warning ("gdk_window_copy_area: BitBlt failed");
1140 ReleaseDC (dest_private->xwindow, hdcDest);
1141 ReleaseDC (src_private->xwindow, hdcSrc);
1146 gdk_window_raise (GdkWindow *window)
1148 GdkWindowPrivate *private;
1150 g_return_if_fail (window != NULL);
1152 private = (GdkWindowPrivate*) window;
1154 if (!private->destroyed)
1156 GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n", private->xwindow));
1158 if (!BringWindowToTop (private->xwindow))
1159 g_warning ("gdk_window_raise: BringWindowToTop failed");
1164 gdk_window_lower (GdkWindow *window)
1166 GdkWindowPrivate *private;
1168 g_return_if_fail (window != NULL);
1170 private = (GdkWindowPrivate*) window;
1172 if (!private->destroyed)
1174 GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n", private->xwindow));
1176 if (!SetWindowPos (private->xwindow, HWND_BOTTOM, 0, 0, 0, 0,
1177 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1178 g_warning ("gdk_window_lower: SetWindowPos failed");
1183 gdk_window_set_user_data (GdkWindow *window,
1186 g_return_if_fail (window != NULL);
1188 window->user_data = user_data;
1192 gdk_window_set_hints (GdkWindow *window,
1201 GdkWindowPrivate *private;
1202 WINDOWPLACEMENT size_hints;
1208 g_return_if_fail (window != NULL);
1210 private = (GdkWindowPrivate*) window;
1211 if (private->destroyed)
1214 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1216 min_width, min_height, max_width, max_height,
1219 private->hint_flags = flags;
1220 size_hints.length = sizeof (size_hints);
1224 if (flags & GDK_HINT_POS)
1225 if (!GetWindowPlacement (private->xwindow, &size_hints))
1226 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1229 GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1230 " (%d,%d)--(%d,%d)\n",
1231 size_hints.rcNormalPosition.left,
1232 size_hints.rcNormalPosition.top,
1233 size_hints.rcNormalPosition.right,
1234 size_hints.rcNormalPosition.bottom));
1235 /* What are the corresponding window coordinates for client
1236 * area coordinates x, y
1240 rect.right = rect.left + 200; /* dummy */
1241 rect.bottom = rect.top + 200;
1242 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1243 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1244 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1245 size_hints.flags = 0;
1246 size_hints.showCmd = SW_SHOWNA;
1248 /* Set the normal position hint to that location, with unchanged
1251 diff = size_hints.rcNormalPosition.left - rect.left;
1252 size_hints.rcNormalPosition.left = rect.left;
1253 size_hints.rcNormalPosition.right -= diff;
1254 diff = size_hints.rcNormalPosition.top - rect.top;
1255 size_hints.rcNormalPosition.top = rect.top;
1256 size_hints.rcNormalPosition.bottom -= diff;
1257 GDK_NOTE (MISC, g_print ("...setting: (%d,%d)--(%d,%d)\n",
1258 size_hints.rcNormalPosition.left,
1259 size_hints.rcNormalPosition.top,
1260 size_hints.rcNormalPosition.right,
1261 size_hints.rcNormalPosition.bottom));
1262 if (!SetWindowPlacement (private->xwindow, &size_hints))
1263 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1264 private->hint_x = rect.left;
1265 private->hint_y = rect.top;
1268 if (flags & GDK_HINT_MIN_SIZE)
1272 rect.right = min_width;
1273 rect.bottom = min_height;
1274 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1275 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1276 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1277 private->hint_min_width = rect.right - rect.left;
1278 private->hint_min_height = rect.bottom - rect.top;
1280 /* Also chek if he current size of the window is in bounds. */
1281 GetClientRect (private->xwindow, &rect);
1282 if (rect.right < min_width && rect.bottom < min_height)
1283 gdk_window_resize (window, min_width, min_height);
1284 else if (rect.right < min_width)
1285 gdk_window_resize (window, min_width, rect.bottom);
1286 else if (rect.bottom < min_height)
1287 gdk_window_resize (window, rect.right, min_height);
1289 if (flags & GDK_HINT_MAX_SIZE)
1293 rect.right = max_width;
1294 rect.bottom = max_height;
1295 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1296 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1297 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1298 private->hint_max_width = rect.right - rect.left;
1299 private->hint_max_height = rect.bottom - rect.top;
1300 /* Again, check if the window is too large currently. */
1301 GetClientRect (private->xwindow, &rect);
1302 if (rect.right > max_width && rect.bottom > max_height)
1303 gdk_window_resize (window, max_width, max_height);
1304 else if (rect.right > max_width)
1305 gdk_window_resize (window, max_width, rect.bottom);
1306 else if (rect.bottom > max_height)
1307 gdk_window_resize (window, rect.right, max_height);
1313 gdk_window_set_geometry_hints (GdkWindow *window,
1314 GdkGeometry *geometry,
1315 GdkWindowHints geom_mask)
1317 GdkWindowPrivate *private;
1318 WINDOWPLACEMENT size_hints;
1324 g_return_if_fail (window != NULL);
1326 private = (GdkWindowPrivate*) window;
1327 if (private->destroyed)
1330 size_hints.length = sizeof (size_hints);
1332 private->hint_flags = geom_mask;
1334 if (geom_mask & GDK_HINT_POS)
1337 if (geom_mask & GDK_HINT_MIN_SIZE)
1341 rect.right = geometry->min_width;
1342 rect.bottom = geometry->min_height;
1343 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1344 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1345 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1346 private->hint_min_width = rect.right - rect.left;
1347 private->hint_min_height = rect.bottom - rect.top;
1349 /* Also check if he current size of the window is in bounds */
1350 GetClientRect (private->xwindow, &rect);
1351 if (rect.right < geometry->min_width
1352 && rect.bottom < geometry->min_height)
1353 gdk_window_resize (window, geometry->min_width, geometry->min_height);
1354 else if (rect.right < geometry->min_width)
1355 gdk_window_resize (window, geometry->min_width, rect.bottom);
1356 else if (rect.bottom < geometry->min_height)
1357 gdk_window_resize (window, rect.right, geometry->min_height);
1360 if (geom_mask & GDK_HINT_MAX_SIZE)
1364 rect.right = geometry->max_width;
1365 rect.bottom = geometry->max_height;
1366 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1367 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1368 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1369 private->hint_max_width = rect.right - rect.left;
1370 private->hint_max_height = rect.bottom - rect.top;
1372 /* Again, check if the window is too large currently. */
1373 GetClientRect (private->xwindow, &rect);
1374 if (rect.right > geometry->max_width
1375 && rect.bottom > geometry->max_height)
1376 gdk_window_resize (window, geometry->max_width, geometry->max_height);
1377 else if (rect.right > geometry->max_width)
1378 gdk_window_resize (window, geometry->max_width, rect.bottom);
1379 else if (rect.bottom > geometry->max_height)
1380 gdk_window_resize (window, rect.right, geometry->max_height);
1383 /* I don't know what to do when called with zero base_width and height. */
1384 if (geom_mask & GDK_HINT_BASE_SIZE
1385 && geometry->base_width > 0
1386 && geometry->base_height > 0)
1387 if (!GetWindowPlacement (private->xwindow, &size_hints))
1388 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1391 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1392 " rcNormalPosition: (%d,%d)--(%d,%d)\n",
1393 size_hints.rcNormalPosition.left,
1394 size_hints.rcNormalPosition.top,
1395 size_hints.rcNormalPosition.right,
1396 size_hints.rcNormalPosition.bottom));
1397 size_hints.rcNormalPosition.right =
1398 size_hints.rcNormalPosition.left + geometry->base_width;
1399 size_hints.rcNormalPosition.bottom =
1400 size_hints.rcNormalPosition.top + geometry->base_height;
1401 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
1402 size_hints.rcNormalPosition.left,
1403 size_hints.rcNormalPosition.top,
1404 size_hints.rcNormalPosition.right,
1405 size_hints.rcNormalPosition.bottom));
1406 if (!SetWindowPlacement (private->xwindow, &size_hints))
1407 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1410 if (geom_mask & GDK_HINT_RESIZE_INC)
1415 if (geom_mask & GDK_HINT_ASPECT)
1422 gdk_window_set_title (GdkWindow *window,
1425 GdkWindowPrivate *private;
1427 g_return_if_fail (window != NULL);
1429 private = (GdkWindowPrivate*) window;
1430 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
1431 private->xwindow, title));
1432 if (!private->destroyed)
1434 if (!SetWindowText (private->xwindow, title))
1435 g_warning ("gdk_window_set_title: SetWindowText failed");
1440 gdk_window_set_role (GdkWindow *window,
1443 GdkWindowPrivate *private;
1445 g_return_if_fail (window != NULL);
1447 private = (GdkWindowPrivate*) window;
1449 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1450 private->xwindow, (role ? role : "NULL")));
1455 gdk_window_set_transient_for (GdkWindow *window,
1458 GdkWindowPrivate *private;
1459 GdkWindowPrivate *parent_private;
1461 g_return_if_fail (window != NULL);
1463 private = (GdkWindowPrivate*) window;
1464 parent_private = (GdkWindowPrivate*) parent;
1466 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1467 private->xwindow, parent_private->xwindow));
1472 gdk_window_set_background (GdkWindow *window,
1475 GdkWindowPrivate *private;
1477 g_return_if_fail (window != NULL);
1479 private = (GdkWindowPrivate*) window;
1480 if (!private->destroyed)
1482 GdkColormapPrivate *colormap_private =
1483 (GdkColormapPrivate *) private->colormap;
1485 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1487 gdk_color_to_string (color)));
1489 if (private->bg_type == GDK_WIN32_BG_PIXMAP)
1491 if (private->bg_pixmap != NULL)
1493 gdk_pixmap_unref (private->bg_pixmap);
1494 private->bg_pixmap = NULL;
1496 private->bg_type = GDK_WIN32_BG_NORMAL;
1498 #ifdef MULTIPLE_WINDOW_CLASSES
1499 if (colormap_private != NULL
1500 && colormap_private->xcolormap->rc_palette)
1502 /* If we are on a palettized display we can't use the window
1503 * class background brush, but must handle WM_ERASEBKGND.
1504 * At least, I think so.
1507 private->bg_type = GDK_WIN32_BG_PIXEL;
1508 private->bg_pixel = *color;
1509 #ifdef MULTIPLE_WINDOW_CLASSES
1513 /* Non-palettized display; just set the window class background
1517 COLORREF background;
1519 background = RGB (color->red >> 8,
1523 if ((hbr = CreateSolidBrush (GetNearestColor (gdk_DC,
1524 background))) == NULL)
1526 g_warning ("gdk_window_set_background: CreateSolidBrush failed");
1530 oldbrush = (HGDIOBJ) GetClassLong (private->xwindow,
1533 if (SetClassLong (private->xwindow, GCL_HBRBACKGROUND,
1535 g_warning ("gdk_window_set_background: SetClassLong failed");
1537 if (!DeleteObject (oldbrush))
1538 g_warning ("gdk_window_set_background: DeleteObject failed");
1545 gdk_window_set_back_pixmap (GdkWindow *window,
1547 gint parent_relative)
1549 GdkWindowPrivate *window_private;
1550 #ifdef MULTIPLE_WINDOW_CLASSES
1551 GdkPixmapPrivate *pixmap_private;
1554 g_return_if_fail (window != NULL);
1556 window_private = (GdkWindowPrivate*) window;
1557 #ifdef MULTIPLE_WINDOW_CLASSES
1558 pixmap_private = (GdkPixmapPrivate*) pixmap;
1561 if (!window_private->destroyed)
1563 GdkColormapPrivate *colormap_private =
1564 (GdkColormapPrivate *) window_private->colormap;
1565 if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
1567 if (window_private->bg_pixmap != NULL)
1569 gdk_pixmap_unref (window_private->bg_pixmap);
1570 window_private->bg_pixmap = NULL;
1572 window_private->bg_type = GDK_WIN32_BG_NORMAL;
1574 if (parent_relative)
1576 window_private->bg_type = GDK_WIN32_BG_PARENT_RELATIVE;
1580 #ifdef MULTIPLE_WINDOW_CLASSES
1581 SetClassLong (window_private->xwindow, GCL_HBRBACKGROUND,
1582 (LONG) GetStockObject (BLACK_BRUSH));
1585 #ifdef MULTIPLE_WINDOW_CLASSES
1586 else if (colormap_private->xcolormap->rc_palette)
1588 /* Must do the background painting in the
1589 * WM_ERASEBKGND handler.
1591 window_private->bg_type = GDK_WIN32_BG_PIXMAP;
1592 window_private->bg_pixmap = pixmap;
1593 gdk_pixmap_ref (pixmap);
1595 else if (pixmap_private->width <= 8
1596 && pixmap_private->height <= 8)
1598 /* We can use small pixmaps directly as background brush */
1599 SetClassLong (window_private->xwindow, GCL_HBRBACKGROUND,
1600 (LONG) CreatePatternBrush (pixmap_private->xwindow));
1605 /* We must cache the pixmap in the WindowPrivate and
1606 * paint it each time we get WM_ERASEBKGND
1608 window_private->bg_type = GDK_WIN32_BG_PIXMAP;
1609 window_private->bg_pixmap = pixmap;
1610 gdk_pixmap_ref (pixmap);
1616 gdk_window_set_cursor (GdkWindow *window,
1619 GdkWindowPrivate *window_private;
1620 GdkCursorPrivate *cursor_private;
1623 g_return_if_fail (window != NULL);
1625 window_private = (GdkWindowPrivate*) window;
1626 cursor_private = (GdkCursorPrivate*) cursor;
1628 if (!window_private->destroyed)
1631 xcursor = LoadCursor (NULL, IDC_ARROW);
1633 xcursor = cursor_private->xcursor;
1635 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1636 window_private->xwindow, xcursor));
1637 #ifdef MULTIPLE_WINDOW_CLASSES
1638 if (!SetClassLong (window_private->xwindow, GCL_HCURSOR, (LONG) xcursor))
1639 g_warning ("gdk_window_set_cursor: SetClassLong failed");
1641 window_private->xcursor = xcursor;
1643 SetCursor (xcursor);
1648 gdk_window_set_colormap (GdkWindow *window,
1649 GdkColormap *colormap)
1651 GdkWindowPrivate *window_private;
1652 GdkColormapPrivate *colormap_private;
1654 g_return_if_fail (window != NULL);
1655 g_return_if_fail (colormap != NULL);
1657 window_private = (GdkWindowPrivate*) window;
1658 colormap_private = (GdkColormapPrivate*) colormap;
1660 if (!window_private->destroyed)
1663 GDK_NOTE (MISC, g_print ("gdk_window_set_colormap: %#x %#x\n",
1664 window_private->xwindow,
1665 colormap_private->xcolormap));
1666 if (window_private->colormap)
1667 gdk_colormap_unref (window_private->colormap);
1668 window_private->colormap = colormap;
1669 gdk_colormap_ref (window_private->colormap);
1671 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1672 gdk_window_add_colormap_windows (window);
1677 gdk_window_get_user_data (GdkWindow *window,
1680 g_return_if_fail (window != NULL);
1682 *data = window->user_data;
1686 gdk_window_get_geometry (GdkWindow *window,
1693 GdkWindowPrivate *window_private;
1696 window = (GdkWindow*) &gdk_root_parent;
1698 window_private = (GdkWindowPrivate*) window;
1700 if (!window_private->destroyed)
1704 if (!GetClientRect (window_private->xwindow, &rect))
1705 g_warning ("gdk_window_get_geometry: GetClientRect failed");
1712 *width = rect.right - rect.left;
1714 *height = rect.bottom - rect.top;
1716 *depth = gdk_window_get_visual (window)->depth;
1721 gdk_window_get_position (GdkWindow *window,
1725 GdkWindowPrivate *window_private;
1727 g_return_if_fail (window != NULL);
1729 window_private = (GdkWindowPrivate*) window;
1732 *x = window_private->x;
1734 *y = window_private->y;
1738 gdk_window_get_size (GdkWindow *window,
1742 GdkWindowPrivate *window_private;
1744 g_return_if_fail (window != NULL);
1746 window_private = (GdkWindowPrivate*) window;
1749 *width = window_private->width;
1751 *height = window_private->height;
1755 gdk_window_get_visual (GdkWindow *window)
1757 GdkWindowPrivate *window_private;
1759 g_return_val_if_fail (window != NULL, NULL);
1761 window_private = (GdkWindowPrivate*) window;
1762 /* Huh? ->parent is never set for a pixmap. We should just return
1763 * null immeditately. Well, do it then!
1765 if (window_private->window_type == GDK_WINDOW_PIXMAP)
1768 if (!window_private->destroyed)
1770 if (window_private->colormap == NULL)
1771 return gdk_visual_get_system (); /* XXX ??? */
1773 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1780 gdk_window_get_colormap (GdkWindow *window)
1782 GdkWindowPrivate *window_private;
1784 g_return_val_if_fail (window != NULL, NULL);
1785 window_private = (GdkWindowPrivate*) window;
1787 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1788 if (!window_private->destroyed)
1790 if (window_private->colormap == NULL)
1791 return gdk_colormap_get_system (); /* XXX ??? */
1793 return window_private->colormap;
1800 gdk_window_get_type (GdkWindow *window)
1802 GdkWindowPrivate *window_private;
1804 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1806 window_private = (GdkWindowPrivate*) window;
1807 return window_private->window_type;
1811 gdk_window_get_origin (GdkWindow *window,
1815 GdkWindowPrivate *private;
1820 g_return_val_if_fail (window != NULL, 0);
1822 private = (GdkWindowPrivate*) window;
1824 if (!private->destroyed)
1830 ClientToScreen (private->xwindow, &pt);
1843 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
1844 private->xwindow, tx, ty));
1849 gdk_window_get_deskrelative_origin (GdkWindow *window,
1853 return gdk_window_get_origin (window, x, y);
1857 gdk_window_get_root_origin (GdkWindow *window,
1861 GdkWindowPrivate *private;
1864 g_return_if_fail (window != NULL);
1866 private = (GdkWindowPrivate*) window;
1871 if (private->destroyed)
1874 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1875 private = (GdkWindowPrivate*) private->parent;
1876 if (private->destroyed)
1881 ClientToScreen (private->xwindow, &pt);
1887 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%d+%d\n",
1888 ((GdkWindowPrivate *) window)->xwindow,
1889 private->xwindow, pt.x, pt.y));
1893 gdk_window_get_pointer (GdkWindow *window,
1896 GdkModifierType *mask)
1898 GdkWindowPrivate *private;
1899 GdkWindow *return_val;
1900 POINT pointc, point;
1904 window = (GdkWindow*) &gdk_root_parent;
1906 private = (GdkWindowPrivate*) window;
1909 GetCursorPos (&pointc);
1911 ScreenToClient (private->xwindow, &point);
1918 hwnd = WindowFromPoint (point);
1920 ScreenToClient (hwnd, &point);
1923 hwndc = ChildWindowFromPoint (hwnd, point);
1924 ClientToScreen (hwnd, &point);
1925 ScreenToClient (hwndc, &point);
1926 } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1928 return_val = gdk_window_lookup (hwnd);
1934 GetKeyboardState (kbd);
1936 if (kbd[VK_SHIFT] & 0x80)
1937 *mask |= GDK_SHIFT_MASK;
1938 if (kbd[VK_CAPITAL] & 0x80)
1939 *mask |= GDK_LOCK_MASK;
1940 if (kbd[VK_CONTROL] & 0x80)
1941 *mask |= GDK_CONTROL_MASK;
1942 if (kbd[VK_MENU] & 0x80)
1943 *mask |= GDK_MOD1_MASK;
1944 if (kbd[VK_LBUTTON] & 0x80)
1945 *mask |= GDK_BUTTON1_MASK;
1946 if (kbd[VK_MBUTTON] & 0x80)
1947 *mask |= GDK_BUTTON2_MASK;
1948 if (kbd[VK_RBUTTON] & 0x80)
1949 *mask |= GDK_BUTTON3_MASK;
1956 gdk_window_at_pointer (gint *win_x,
1959 GdkWindowPrivate *private;
1961 POINT point, pointc;
1965 private = &gdk_root_parent;
1967 GetCursorPos (&pointc);
1969 hwnd = WindowFromPoint (point);
1973 window = (GdkWindow *) &gdk_root_parent;
1981 ScreenToClient (hwnd, &point);
1984 hwndc = ChildWindowFromPoint (hwnd, point);
1985 ClientToScreen (hwnd, &point);
1986 ScreenToClient (hwndc, &point);
1987 } while (hwndc != hwnd && (hwnd = hwndc, 1));
1989 window = gdk_window_lookup (hwnd);
1991 if (window && (win_x || win_y))
1993 GetClientRect (hwnd, &rect);
1995 *win_x = point.x - rect.left;
1997 *win_y = point.y - rect.top;
2000 GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%d+%d %#x%s\n",
2001 point.x, point.y, hwnd,
2002 (window == NULL ? " NULL" : "")));
2008 gdk_window_get_parent (GdkWindow *window)
2010 g_return_val_if_fail (window != NULL, NULL);
2012 return ((GdkWindowPrivate*) window)->parent;
2016 gdk_window_get_toplevel (GdkWindow *window)
2018 GdkWindowPrivate *private;
2020 g_return_val_if_fail (window != NULL, NULL);
2022 private = (GdkWindowPrivate*) window;
2024 while (private->window_type == GDK_WINDOW_CHILD)
2026 window = ((GdkWindowPrivate*) window)->parent;
2027 private = (GdkWindowPrivate*) window;
2034 gdk_window_get_children (GdkWindow *window)
2036 GdkWindowPrivate *private;
2039 g_return_val_if_fail (window != NULL, NULL);
2041 private = (GdkWindowPrivate*) window;
2042 if (private->destroyed)
2046 g_warning ("gdk_window_get_children ???");
2053 gdk_window_get_events (GdkWindow *window)
2055 GdkWindowPrivate *private;
2057 g_return_val_if_fail (window != NULL, 0);
2059 private = (GdkWindowPrivate*) window;
2060 if (private->destroyed)
2063 return private->event_mask;
2067 gdk_window_set_events (GdkWindow *window,
2068 GdkEventMask event_mask)
2070 GdkWindowPrivate *private;
2072 g_return_if_fail (window != NULL);
2074 private = (GdkWindowPrivate*) window;
2075 if (private->destroyed)
2078 private->event_mask = event_mask;
2082 gdk_window_add_colormap_windows (GdkWindow *window)
2084 g_warning ("gdk_window_add_colormap_windows not implemented"); /* XXX */
2088 * This needs the X11 shape extension.
2089 * If not available, shaped windows will look
2090 * ugly, but programs still work. Stefan Wille
2093 gdk_window_shape_combine_mask (GdkWindow *window,
2097 GdkWindowPrivate *window_private;
2099 g_return_if_fail (window != NULL);
2101 window_private = (GdkWindowPrivate*) window;
2105 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
2106 window_private->xwindow));
2107 SetWindowRgn (window_private->xwindow, NULL, TRUE);
2111 GdkPixmapPrivate *pixmap_private;
2117 /* Convert mask bitmap to region */
2118 pixmap_private = (GdkPixmapPrivate*) mask;
2119 hrgn = BitmapToRegion (pixmap_private->xwindow);
2121 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
2122 window_private->xwindow,
2123 pixmap_private->xwindow));
2125 /* SetWindowRgn wants window (not client) coordinates */
2126 dwStyle = GetWindowLong (window_private->xwindow, GWL_STYLE);
2127 dwExStyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2128 GetClientRect (window_private->xwindow, &rect);
2129 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
2130 OffsetRgn (hrgn, -rect.left, -rect.top);
2132 OffsetRgn (hrgn, x, y);
2134 /* If this is a top-level window, add the title bar to the region */
2135 if (window_private->window_type == GDK_WINDOW_TOPLEVEL)
2137 CombineRgn (hrgn, hrgn,
2138 CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
2142 SetWindowRgn (window_private->xwindow, hrgn, TRUE);
2147 gdk_window_add_filter (GdkWindow *window,
2148 GdkFilterFunc function,
2151 GdkWindowPrivate *private;
2153 GdkEventFilter *filter;
2155 private = (GdkWindowPrivate*) window;
2156 if (private && private->destroyed)
2160 tmp_list = private->filters;
2162 tmp_list = gdk_default_filters;
2166 filter = (GdkEventFilter *)tmp_list->data;
2167 if ((filter->function == function) && (filter->data == data))
2169 tmp_list = tmp_list->next;
2172 filter = g_new (GdkEventFilter, 1);
2173 filter->function = function;
2174 filter->data = data;
2177 private->filters = g_list_append (private->filters, filter);
2179 gdk_default_filters = g_list_append (gdk_default_filters, filter);
2183 gdk_window_remove_filter (GdkWindow *window,
2184 GdkFilterFunc function,
2187 GdkWindowPrivate *private;
2188 GList *tmp_list, *node;
2189 GdkEventFilter *filter;
2191 private = (GdkWindowPrivate*) window;
2194 tmp_list = private->filters;
2196 tmp_list = gdk_default_filters;
2200 filter = (GdkEventFilter *)tmp_list->data;
2202 tmp_list = tmp_list->next;
2204 if ((filter->function == function) && (filter->data == data))
2207 private->filters = g_list_remove_link (private->filters, node);
2209 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
2210 g_list_free_1 (node);
2219 gdk_window_set_override_redirect (GdkWindow *window,
2220 gboolean override_redirect)
2222 g_warning ("gdk_window_set_override_redirect not implemented"); /* XXX */
2226 gdk_window_set_icon (GdkWindow *window,
2227 GdkWindow *icon_window,
2231 g_warning ("gdk_window_set_icon not implemented"); /* XXX */
2235 gdk_window_set_icon_name (GdkWindow *window,
2238 GdkWindowPrivate *window_private;
2240 g_return_if_fail (window != NULL);
2241 window_private = (GdkWindowPrivate*) window;
2242 if (window_private->destroyed)
2245 if (!SetWindowText (window_private->xwindow, name))
2246 g_warning ("gdk_window_set_icon_name: SetWindowText failed");
2250 gdk_window_set_group (GdkWindow *window,
2253 g_warning ("gdk_window_set_group not implemented"); /* XXX */
2257 gdk_window_set_decorations (GdkWindow *window,
2258 GdkWMDecoration decorations)
2260 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2261 LONG style, exstyle;
2263 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2264 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2266 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2267 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
2269 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2271 if (decorations & GDK_DECOR_ALL)
2272 style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2273 if (decorations & GDK_DECOR_BORDER)
2274 style |= (WS_BORDER);
2275 if (decorations & GDK_DECOR_RESIZEH)
2276 style |= (WS_THICKFRAME);
2277 if (decorations & GDK_DECOR_TITLE)
2278 style |= (WS_CAPTION);
2279 if (decorations & GDK_DECOR_MENU)
2280 style |= (WS_SYSMENU);
2281 if (decorations & GDK_DECOR_MINIMIZE)
2282 style |= (WS_MINIMIZEBOX);
2283 if (decorations & GDK_DECOR_MAXIMIZE)
2284 style |= (WS_MAXIMIZEBOX);
2286 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2290 gdk_window_set_functions (GdkWindow *window,
2291 GdkWMFunction functions)
2293 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2294 LONG style, exstyle;
2296 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2297 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2299 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2300 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
2303 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2305 if (functions & GDK_FUNC_ALL)
2306 style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2307 if (functions & GDK_FUNC_RESIZE)
2308 style |= (WS_THICKFRAME);
2309 if (functions & GDK_FUNC_MOVE)
2310 style |= (WS_THICKFRAME);
2311 if (functions & GDK_FUNC_MINIMIZE)
2312 style |= (WS_MINIMIZEBOX);
2313 if (functions & GDK_FUNC_MAXIMIZE)
2314 style |= (WS_MAXIMIZEBOX);
2316 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2320 gdk_window_get_toplevels (void)
2322 GList *new_list = NULL;
2325 tmp_list = gdk_root_parent.children;
2328 new_list = g_list_prepend (new_list, tmp_list->data);
2329 tmp_list = tmp_list->next;
2336 * propagate the shapes from all child windows of a GDK window to the parent
2337 * window. Shamelessly ripped from Enlightenment's code
2343 QueryTree (HWND hwnd,
2353 child = GetWindow (hwnd, GW_CHILD);
2355 child = GetWindow (child, GW_HWNDNEXT);
2358 } while (child != NULL);
2362 *children = g_new (HWND, n);
2363 for (i = 0; i < n; i++)
2366 child = GetWindow (hwnd, GW_CHILD);
2368 child = GetWindow (child, GW_HWNDNEXT);
2369 *children[i] = child;
2375 gdk_propagate_shapes (HANDLE win,
2379 HRGN region, childRegion;
2384 SetRectEmpty (&emptyRect);
2385 region = CreateRectRgnIndirect (&emptyRect);
2387 GetWindowRgn (win, region);
2389 QueryTree (win, &list, &num);
2392 WINDOWPLACEMENT placement;
2394 placement.length = sizeof (WINDOWPLACEMENT);
2395 /* go through all child windows and combine regions */
2396 for (i = 0; i < num; i++)
2398 GetWindowPlacement (list[i], &placement);
2399 if (placement.showCmd = SW_SHOWNORMAL)
2401 childRegion = CreateRectRgnIndirect (&emptyRect);
2402 GetWindowRgn (list[i], childRegion);
2403 CombineRgn (region, region, childRegion, RGN_OR);
2404 DeleteObject (childRegion);
2407 SetWindowRgn (win, region, TRUE);
2410 DeleteObject (region);
2414 gdk_window_set_child_shapes (GdkWindow *window)
2416 GdkWindowPrivate *private;
2418 g_return_if_fail (window != NULL);
2420 private = (GdkWindowPrivate*) window;
2421 if (private->destroyed)
2424 gdk_propagate_shapes ( private->xwindow, FALSE);
2428 gdk_window_merge_child_shapes (GdkWindow *window)
2430 GdkWindowPrivate *private;
2432 g_return_if_fail (window != NULL);
2434 private = (GdkWindowPrivate*) window;
2435 if (private->destroyed)
2438 gdk_propagate_shapes (private->xwindow, TRUE);
2441 /*************************************************************
2442 * gdk_window_is_visible:
2443 * Check if the given window is mapped.
2447 * is the window mapped
2448 *************************************************************/
2451 gdk_window_is_visible (GdkWindow *window)
2453 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2455 g_return_val_if_fail (window != NULL, FALSE);
2457 return private->mapped;
2460 /*************************************************************
2461 * gdk_window_is_viewable:
2462 * Check if the window and all ancestors of the window
2463 * are mapped. (This is not necessarily "viewable" in
2464 * the X sense, since we only check as far as we have
2465 * GDK window parents, not to the root window)
2469 * is the window viewable
2470 *************************************************************/
2473 gdk_window_is_viewable (GdkWindow *window)
2475 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2477 g_return_val_if_fail (window != NULL, FALSE);
2480 (private != &gdk_root_parent) &&
2481 (private->window_type != GDK_WINDOW_FOREIGN))
2483 if (!private->mapped)
2486 private = (GdkWindowPrivate *)private->parent;
2493 gdk_drawable_set_data (GdkDrawable *drawable,
2496 GDestroyNotify destroy_func)
2498 g_dataset_set_data_full (drawable, key, data, destroy_func);
2502 /* Support for windows that can be guffaw-scrolled
2503 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2507 gdk_window_gravity_works (void)
2509 enum { UNKNOWN, NO, YES };
2510 static gint gravity_works = UNKNOWN;
2512 if (gravity_works == UNKNOWN)
2519 attr.window_type = GDK_WINDOW_TEMP;
2520 attr.wclass = GDK_INPUT_OUTPUT;
2525 attr.event_mask = 0;
2527 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2529 attr.window_type = GDK_WINDOW_CHILD;
2530 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2532 gdk_window_set_static_win_gravity (child, TRUE);
2534 gdk_window_resize (parent, 100, 110);
2535 gdk_window_move (parent, 0, -10);
2536 gdk_window_move_resize (parent, 0, 0, 100, 100);
2538 gdk_window_resize (parent, 100, 110);
2539 gdk_window_move (parent, 0, -10);
2540 gdk_window_move_resize (parent, 0, 0, 100, 100);
2542 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2544 gdk_window_destroy (parent);
2545 gdk_window_destroy (child);
2547 gravity_works = ((y == -20) ? YES : NO);
2550 return (gravity_works == YES);
2554 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2556 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2558 g_return_if_fail (window != NULL);
2561 g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2565 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2567 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2569 g_return_if_fail (window != NULL);
2572 g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2575 /*************************************************************
2576 * gdk_window_set_static_gravities:
2577 * Set the bit gravity of the given window to static,
2578 * and flag it so all children get static subwindow
2581 * window: window for which to set static gravity
2582 * use_static: Whether to turn static gravity on or off.
2584 * Does the XServer support static gravity?
2585 *************************************************************/
2588 gdk_window_set_static_gravities (GdkWindow *window,
2589 gboolean use_static)
2591 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2594 g_return_val_if_fail (window != NULL, FALSE);
2596 if (!use_static == !private->guffaw_gravity)
2599 if (use_static && !gdk_window_gravity_works ())
2602 private->guffaw_gravity = use_static;
2604 gdk_window_set_static_bit_gravity (window, use_static);
2606 tmp_list = private->children;
2609 gdk_window_set_static_win_gravity (window, use_static);
2611 tmp_list = tmp_list->next;