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"
35 /* The Win API function AdjustWindowRect may return negative values
36 * resulting in obscured title bars. This helper function is coreccting it.
39 SafeAdjustWindowRectEx (RECT* lpRect,
44 if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
48 lpRect->right -= lpRect->left;
53 lpRect->bottom -= lpRect->top;
59 /* Forward declarations */
60 static gboolean gdk_window_gravity_works (void);
61 static void gdk_window_set_static_win_gravity (GdkWindow *window,
65 * The following fucntion by The Rasterman <raster@redhat.com>
66 * This function returns the X Window ID in which the x y location is in
67 * (x and y being relative to the root window), excluding any windows listed
68 * in the GList excludes (this is a list of X Window ID's - gpointer being
71 * This is primarily designed for internal gdk use - for DND for example
72 * when using a shaped icon window as the drag object - you exclude the
73 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
74 * You can get back an X Window ID as to what X Window ID is infact under
75 * those X,Y co-ordinates.
78 gdk_window_xid_at_coords (gint x,
84 gboolean warned = FALSE;
88 /* This is probably not correct, just a quick hack */
92 g_warning ("gdk_window_xid_at_coords probably not implemented correctly");
97 return WindowFromPoint (pt);
101 gdk_window_init (void)
106 width = GetSystemMetrics (SM_CXSCREEN);
107 height = GetSystemMetrics (SM_CYSCREEN);
109 { RECT r; /* //HB: don't obscure tray window (task bar) */
110 SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
111 width = r.right - r.left;
112 height = r.bottom - r.top;
116 gdk_root_parent.xwindow = gdk_root_window;
117 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
118 gdk_root_parent.window.user_data = NULL;
119 gdk_root_parent.width = width;
120 gdk_root_parent.height = height;
121 gdk_root_parent.children = NULL;
122 gdk_root_parent.colormap = NULL;
123 gdk_root_parent.ref_count = 1;
125 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
129 gdk_window_new (GdkWindow *parent,
130 GdkWindowAttr *attributes,
131 gint attributes_mask)
134 GdkWindowPrivate *private;
135 GdkWindowPrivate *parent_private;
139 #ifdef MULTIPLE_WINDOW_CLASSES
142 char wcl_name_buf[20];
143 static int wcl_cnt = 0;
145 static WNDCLASSEX wcl;
146 static ATOM klass = 0;
148 static HICON hAppIcon = NULL;
149 DWORD dwStyle, dwExStyle;
155 g_return_val_if_fail (attributes != NULL, NULL);
158 parent = (GdkWindow*) &gdk_root_parent;
160 parent_private = (GdkWindowPrivate*) parent;
161 if (parent_private->destroyed)
164 xparent = parent_private->xwindow;
166 private = g_new (GdkWindowPrivate, 1);
167 window = (GdkWindow*) private;
169 private->parent = parent;
171 private->destroyed = FALSE;
172 private->mapped = FALSE;
173 private->guffaw_gravity = FALSE;
174 private->resize_count = 0;
175 private->ref_count = 1;
177 private->x = (attributes_mask & GDK_WA_X) ? attributes->x : 0;
178 private->y = (attributes_mask & GDK_WA_Y) ? attributes->y : 0;
180 private->width = (attributes->width > 1) ? (attributes->width) : (1);
181 private->height = (attributes->height > 1) ? (attributes->height) : (1);
182 private->window_type = attributes->window_type;
183 private->extension_events = 0;
184 private->extension_events_selected = FALSE;
186 private->filters = NULL;
187 private->children = NULL;
189 window->user_data = NULL;
191 if (attributes_mask & GDK_WA_VISUAL)
192 visual = attributes->visual;
194 visual = gdk_visual_get_system ();
195 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
197 if (attributes_mask & GDK_WA_TITLE)
198 title = attributes->title;
200 title = g_get_prgname ();
202 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
203 private->bg_type = GDK_WIN32_BG_NORMAL;
204 private->hint_flags = 0;
206 #ifndef MULTIPLE_WINDOW_CLASSES
210 wcl.cbSize = sizeof (WNDCLASSEX);
212 wcl.style = CS_HREDRAW | CS_VREDRAW;
216 wcl.lpfnWndProc = gdk_WindowProc;
219 wcl.hInstance = gdk_ProgInstance;
220 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
222 #if 0 /* tml: orig -> generates SetClassLong errors in set background */
223 wcl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
224 wcl.hbrBackground = NULL;
226 /* initialize once! */
229 gchar sLoc [_MAX_PATH+1];
230 HINSTANCE hInst = GetModuleHandle(NULL);
232 if (0 != GetModuleFileName(hInst, sLoc, _MAX_PATH))
234 hAppIcon = ExtractIcon(hInst, sLoc, 0);
237 char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
239 hAppIcon = ExtractIcon(hInst, gdklibname, 0);
244 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
247 wcl.hIcon = CopyIcon (hAppIcon);
248 wcl.hIconSm = CopyIcon (hAppIcon);
249 /* HB: starting with black to have something to release ... */
250 wcl.hbrBackground = CreateSolidBrush( RGB(0,0,0));
253 wcl.lpszMenuName = NULL;
254 #ifdef MULTIPLE_WINDOW_CLASSES
255 sprintf (wcl_name_buf, "gdk-wcl-%d", wcl_cnt++);
256 wcl.lpszClassName = g_strdup (wcl_name_buf);
257 /* wcl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); */
259 wcl.lpszClassName = "GDK-window-class";
260 klass = RegisterClassEx (&wcl);
262 g_error ("RegisterClassEx failed");
265 private->xcursor = NULL;
268 if (parent_private && parent_private->guffaw_gravity)
273 if (attributes->wclass == GDK_INPUT_OUTPUT)
276 if (attributes_mask & GDK_WA_COLORMAP)
277 private->colormap = attributes->colormap;
279 private->colormap = gdk_colormap_get_system ();
283 dwExStyle = WS_EX_TRANSPARENT;
284 private->colormap = NULL;
285 private->bg_type = GDK_WIN32_BG_TRANSPARENT;
286 private->bg_pixmap = NULL;
289 if (attributes_mask & GDK_WA_X)
294 if (attributes_mask & GDK_WA_Y)
296 else if (attributes_mask & GDK_WA_X)
297 y = 100; /* ??? We must put it somewhere... */
299 y = 500; /* x is CW_USEDEFAULT, y doesn't matter then */
302 parent_private->children = g_list_prepend (parent_private->children, window);
304 switch (private->window_type)
306 case GDK_WINDOW_TOPLEVEL:
307 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
308 xparent = gdk_root_window;
310 case GDK_WINDOW_CHILD:
311 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
313 case GDK_WINDOW_DIALOG:
314 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
315 xparent = gdk_root_window;
317 case GDK_WINDOW_TEMP:
318 dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
319 #ifdef MULTIPLE_WINDOW_CLASSES
320 wcl.style |= CS_SAVEBITS;
322 dwExStyle |= WS_EX_TOOLWINDOW;
324 case GDK_WINDOW_ROOT:
325 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
327 case GDK_WINDOW_PIXMAP:
328 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
332 #ifdef MULTIPLE_WINDOW_CLASSES
333 klass = RegisterClassEx (&wcl);
335 g_error ("RegisterClassEx failed");
338 if (private->window_type != GDK_WINDOW_CHILD)
340 if (x == CW_USEDEFAULT)
351 rect.right = rect.left + private->width;
352 rect.bottom = rect.top + private->height;
354 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
355 g_warning ("gdk_window_new: AdjustWindowRectEx failed");
357 if (x != CW_USEDEFAULT)
362 width = rect.right - rect.left;
363 height = rect.bottom - rect.top;
367 width = private->width;
368 height = private->height;
372 CreateWindowEx (dwExStyle,
383 g_print ("gdk_window_create: %s %s %#x %#x %dx%d@+%d+%d %#x = %#x\n",
384 (private->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
385 (private->window_type == GDK_WINDOW_CHILD ? "CHILD" :
386 (private->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
387 (private->window_type == GDK_WINDOW_TEMP ? "TEMP" :
392 width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
396 gdk_window_ref (window);
397 gdk_xid_table_insert (&private->xwindow, window);
399 if (private->colormap)
400 gdk_colormap_ref (private->colormap);
402 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
403 (attributes->cursor) :
410 gdk_window_foreign_new (guint32 anid)
413 GdkWindowPrivate *private;
414 GdkWindowPrivate *parent_private;
419 private = g_new (GdkWindowPrivate, 1);
420 window = (GdkWindow*) private;
422 parent = GetParent ((HWND) anid);
423 private->parent = gdk_xid_table_lookup (parent);
425 parent_private = (GdkWindowPrivate *)private->parent;
428 parent_private->children = g_list_prepend (parent_private->children, window);
430 private->xwindow = (HWND) anid;
431 GetClientRect ((HWND) anid, &rect);
433 point.y = rect.right;
434 ClientToScreen ((HWND) anid, &point);
435 if (parent != HWND_DESKTOP)
436 ScreenToClient (parent, &point);
437 private->x = point.x;
438 private->y = point.y;
439 private->width = rect.right - rect.left;
440 private->height = rect.bottom - rect.top;
441 private->resize_count = 0;
442 private->ref_count = 1;
443 private->window_type = GDK_WINDOW_FOREIGN;
444 private->destroyed = FALSE;
445 private->mapped = IsWindowVisible (private->xwindow);
446 private->guffaw_gravity = FALSE;
447 private->extension_events = 0;
448 private->extension_events_selected = FALSE;
450 private->colormap = NULL;
452 private->filters = NULL;
453 private->children = NULL;
455 window->user_data = NULL;
457 gdk_window_ref (window);
458 gdk_xid_table_insert (&private->xwindow, window);
463 /* Call this function when you want a window and all its children to
464 * disappear. When xdestroy is true, a request to destroy the XWindow
465 * is sent out. When it is false, it is assumed that the XWindow has
466 * been or will be destroyed by destroying some ancestor of this
470 gdk_window_internal_destroy (GdkWindow *window,
472 gboolean our_destroy)
474 GdkWindowPrivate *private;
475 GdkWindowPrivate *temp_private;
476 GdkWindow *temp_window;
480 g_return_if_fail (window != NULL);
482 private = (GdkWindowPrivate*) window;
484 GDK_NOTE (MISC, g_print ("gdk_window_internal_destroy %#x\n",
487 switch (private->window_type)
489 case GDK_WINDOW_TOPLEVEL:
490 case GDK_WINDOW_CHILD:
491 case GDK_WINDOW_DIALOG:
492 case GDK_WINDOW_TEMP:
493 case GDK_WINDOW_FOREIGN:
494 if (!private->destroyed)
498 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
499 if (parent_private->children)
500 parent_private->children = g_list_remove (parent_private->children, window);
503 if (private->window_type != GDK_WINDOW_FOREIGN)
505 children = tmp = private->children;
506 private->children = NULL;
510 temp_window = tmp->data;
513 temp_private = (GdkWindowPrivate*) temp_window;
515 gdk_window_internal_destroy (temp_window, FALSE,
519 g_list_free (children);
522 if (private->extension_events != 0)
523 gdk_input_window_destroy (window);
525 if (private->filters)
527 tmp = private->filters;
535 g_list_free (private->filters);
536 private->filters = NULL;
539 if (private->window_type == GDK_WINDOW_FOREIGN)
541 if (our_destroy && (private->parent != NULL))
543 /* It's somebody elses window, but in our hierarchy,
544 * so reparent it to the root window, and then send
545 * it a delete event, as if we were a WM
547 gdk_window_hide (window);
548 gdk_window_reparent (window, NULL, 0, 0);
550 /* Is this too drastic? Many (most?) applications
551 * quit if any window receives WM_QUIT I think.
552 * OTOH, I don't think foreign windows are much
553 * used, so the question is maybe academic.
555 PostMessage (private->xwindow, WM_QUIT, 0, 0);
559 DestroyWindow (private->xwindow);
561 if (private->colormap)
562 gdk_colormap_unref (private->colormap);
564 private->mapped = FALSE;
565 private->destroyed = TRUE;
569 case GDK_WINDOW_ROOT:
570 g_error ("attempted to destroy root window");
573 case GDK_WINDOW_PIXMAP:
574 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
579 /* Like internal_destroy, but also destroys the reference created by
583 gdk_window_destroy (GdkWindow *window)
585 gdk_window_internal_destroy (window, TRUE, TRUE);
586 gdk_window_unref (window);
589 /* This function is called when the XWindow is really gone. */
592 gdk_window_destroy_notify (GdkWindow *window)
594 GdkWindowPrivate *private;
596 g_return_if_fail (window != NULL);
598 private = (GdkWindowPrivate*) window;
600 GDK_NOTE (EVENTS, g_print ("gdk_window_destroy_notify: %#x %d\n",
601 private->xwindow, private->destroyed));
603 if (!private->destroyed)
605 if (private->window_type == GDK_WINDOW_FOREIGN)
606 gdk_window_internal_destroy (window, FALSE, FALSE);
608 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
611 gdk_xid_table_remove (private->xwindow);
612 gdk_window_unref (window);
616 gdk_window_ref (GdkWindow *window)
618 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
619 g_return_val_if_fail (window != NULL, NULL);
621 private->ref_count += 1;
623 GDK_NOTE (MISC, g_print ("gdk_window_ref %#x %d\n",
624 private->xwindow, private->ref_count));
630 gdk_window_unref (GdkWindow *window)
632 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
633 g_return_if_fail (window != NULL);
635 private->ref_count -= 1;
637 GDK_NOTE (MISC, g_print ("gdk_window_unref %#x %d%s\n",
638 private->xwindow, private->ref_count,
639 (private->ref_count == 0 ? " freeing" : "")));
641 if (private->ref_count == 0)
643 if (private->bg_type == GDK_WIN32_BG_PIXMAP && private->bg_pixmap != NULL)
644 gdk_pixmap_unref (private->bg_pixmap);
646 if (!private->destroyed)
648 if (private->window_type == GDK_WINDOW_FOREIGN)
649 gdk_xid_table_remove (private->xwindow);
651 g_warning ("losing last reference to undestroyed window");
653 g_dataset_destroy (window);
659 gdk_window_show (GdkWindow *window)
661 GdkWindowPrivate *private;
663 g_return_if_fail (window != NULL);
665 private = (GdkWindowPrivate*) window;
666 if (!private->destroyed)
668 GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n", private->xwindow));
670 private->mapped = TRUE;
671 if (private->window_type == GDK_WINDOW_TEMP)
673 ShowWindow (private->xwindow, SW_SHOWNOACTIVATE);
674 SetWindowPos (private->xwindow, HWND_TOPMOST, 0, 0, 0, 0,
675 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
677 ShowWindow (private->xwindow, SW_HIDE); /* Don't put on toolbar */
682 ShowWindow (private->xwindow, SW_SHOWNORMAL);
683 ShowWindow (private->xwindow, SW_RESTORE);
684 SetForegroundWindow (private->xwindow);
686 ShowOwnedPopups (private->xwindow, TRUE);
693 gdk_window_hide (GdkWindow *window)
695 GdkWindowPrivate *private;
697 g_return_if_fail (window != NULL);
699 private = (GdkWindowPrivate*) window;
700 if (!private->destroyed)
702 GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n", private->xwindow));
704 private->mapped = FALSE;
705 if (private->window_type == GDK_WINDOW_TOPLEVEL)
706 ShowOwnedPopups (private->xwindow, FALSE);
708 ShowWindow (private->xwindow, SW_HIDE);
710 ShowWindow (private->xwindow, SW_MINIMIZE);
712 CloseWindow (private->xwindow);
718 gdk_window_withdraw (GdkWindow *window)
720 GdkWindowPrivate *private;
722 g_return_if_fail (window != NULL);
724 private = (GdkWindowPrivate*) window;
725 if (!private->destroyed)
727 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n", private->xwindow));
729 gdk_window_hide (window); /* XXX */
734 gdk_window_move (GdkWindow *window,
738 GdkWindowPrivate *private;
740 g_return_if_fail (window != NULL);
742 private = (GdkWindowPrivate*) window;
743 if (!private->destroyed)
747 GDK_NOTE (MISC, g_print ("gdk_window_move: %#x +%d+%d\n",
748 private->xwindow, x, y));
750 GetClientRect (private->xwindow, &rect);
752 if (private->window_type != GDK_WINDOW_CHILD)
760 ClientToScreen (private->xwindow, &ptTL);
765 ptBR.y = rect.bottom;
766 ClientToScreen (private->xwindow, &ptBR);
767 rect.right = x + ptBR.x - ptTL.x;
768 rect.bottom = y + ptBR.y - ptTL.y;
770 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
771 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
772 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
773 g_warning ("gdk_window_move: AdjustWindowRectEx failed");
783 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
785 rect.right - rect.left, rect.bottom - rect.top,
787 if (!MoveWindow (private->xwindow,
788 x, y, rect.right - rect.left, rect.bottom - rect.top,
790 g_warning ("gdk_window_move: MoveWindow failed");
795 gdk_window_resize (GdkWindow *window,
799 GdkWindowPrivate *private;
801 g_return_if_fail (window != NULL);
803 if ((gint16) width < 1)
805 if ((gint16) height < 1)
808 private = (GdkWindowPrivate*) window;
810 if (!private->destroyed &&
811 ((private->resize_count > 0) ||
812 (private->width != (guint16) width) ||
813 (private->height != (guint16) height)))
817 GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
818 private->xwindow, width, height));
820 if (private->window_type != GDK_WINDOW_CHILD)
829 ClientToScreen (private->xwindow, &pt);
832 rect.right = pt.x + width;
833 rect.bottom = pt.y + height;
835 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
836 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
837 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
838 g_warning ("gdk_window_resize: AdjustWindowRectEx failed");
842 width = rect.right - rect.left;
843 height = rect.bottom - rect.top;
849 private->width = width;
850 private->height = height;
853 private->resize_count += 1;
855 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
856 private->xwindow, width, height, x, y));
857 if (!MoveWindow (private->xwindow,
860 g_warning ("gdk_window_resize: MoveWindow failed");
865 gdk_window_move_resize (GdkWindow *window,
871 GdkWindowPrivate *private;
873 g_return_if_fail (window != NULL);
875 if ((gint16) width < 1)
877 if ((gint16) height < 1)
880 private = (GdkWindowPrivate*) window;
881 if (!private->destroyed)
887 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
888 private->xwindow, width, height, x, y));
892 rect.right = x + width;
893 rect.bottom = y + height;
895 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
896 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
897 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
898 g_warning ("gdk_window_move_resize: AdjustWindowRectEx failed");
900 if (private->window_type == GDK_WINDOW_CHILD)
904 private->width = width;
905 private->height = height;
907 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
909 rect.right - rect.left, rect.bottom - rect.top,
910 rect.left, rect.top));
911 if (!MoveWindow (private->xwindow,
913 rect.right - rect.left, rect.bottom - rect.top,
915 g_warning ("gdk_window_move_resize: MoveWindow failed");
917 if (private->guffaw_gravity)
919 GList *tmp_list = private->children;
922 GdkWindowPrivate *child_private = tmp_list->data;
924 child_private->x -= x - private->x;
925 child_private->y -= y - private->y;
927 tmp_list = tmp_list->next;
935 gdk_window_reparent (GdkWindow *window,
936 GdkWindow *new_parent,
940 GdkWindowPrivate *window_private;
941 GdkWindowPrivate *parent_private;
942 GdkWindowPrivate *old_parent_private;
944 g_return_if_fail (window != NULL);
947 new_parent = (GdkWindow*) &gdk_root_parent;
949 window_private = (GdkWindowPrivate*) window;
950 old_parent_private = (GdkWindowPrivate*)window_private->parent;
951 parent_private = (GdkWindowPrivate*) new_parent;
953 if (!window_private->destroyed && !parent_private->destroyed)
955 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
956 window_private->xwindow,
957 parent_private->xwindow));
958 if (!SetParent (window_private->xwindow, parent_private->xwindow))
959 g_warning ("gdk_window_reparent: SetParent failed");
961 if (!MoveWindow (window_private->xwindow,
963 window_private->width, window_private->height,
965 g_warning ("gdk_window_reparent: MoveWindow failed");
968 window_private->parent = new_parent;
970 if (old_parent_private)
971 old_parent_private->children = g_list_remove (old_parent_private->children, window);
973 if ((old_parent_private &&
974 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
975 (!old_parent_private && parent_private->guffaw_gravity))
976 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
978 parent_private->children = g_list_prepend (parent_private->children, window);
982 gdk_window_clear (GdkWindow *window)
984 GdkWindowPrivate *private;
986 g_return_if_fail (window != NULL);
988 private = (GdkWindowPrivate*) window;
990 if (!private->destroyed)
992 gdk_window_clear_area (window, 0, 0, private->width, private->height);
998 gdk_window_clear_area (GdkWindow *window,
1004 GdkWindowPrivate *private;
1006 g_return_if_fail (window != NULL);
1008 private = (GdkWindowPrivate*) window;
1010 if (!private->destroyed)
1015 width = G_MAXSHORT/2; /* Yeah, right */
1017 height = G_MAXSHORT/2;
1018 GDK_NOTE (MISC, g_print ("gdk_window_clear_area: %#x %dx%d@+%d+%d\n",
1019 private->xwindow, width, height, x, y));
1020 hdc = GetDC (private->xwindow);
1021 IntersectClipRect (hdc, x, y, x + width, y + height);
1022 SendMessage (private->xwindow, WM_ERASEBKGND, (WPARAM) hdc, 0);
1023 ReleaseDC (private->xwindow, hdc);
1028 gdk_window_clear_area_e (GdkWindow *window,
1034 GdkWindowPrivate *private;
1036 g_return_if_fail (window != NULL);
1038 private = (GdkWindowPrivate*) window;
1040 if (!private->destroyed)
1044 GDK_NOTE (MISC, g_print ("gdk_window_clear_area_e: %#x %dx%d@+%d+%d\n",
1045 private->xwindow, width, height, x, y));
1048 rect.right = x + width;
1050 rect.bottom = y + height;
1051 if (!InvalidateRect (private->xwindow, &rect, TRUE))
1052 g_warning ("gdk_window_clear_area_e: InvalidateRect failed");
1053 UpdateWindow (private->xwindow);
1058 gdk_window_copy_area (GdkWindow *window,
1062 GdkWindow *source_window,
1068 GdkWindowPrivate *src_private;
1069 GdkWindowPrivate *dest_private;
1070 GdkGCPrivate *gc_private;
1072 g_return_if_fail (window != NULL);
1073 g_return_if_fail (gc != NULL);
1075 if (source_window == NULL)
1076 source_window = window;
1078 src_private = (GdkWindowPrivate*) source_window;
1079 dest_private = (GdkWindowPrivate*) window;
1080 gc_private = (GdkGCPrivate*) gc;
1082 if (!src_private->destroyed && !dest_private->destroyed)
1084 HDC hdcDest, hdcSrc;
1086 if ((hdcDest = GetDC (dest_private->xwindow)) == NULL)
1087 g_warning ("gdk_window_copy_area: GetDC failed");
1089 if ((hdcSrc = GetDC (src_private->xwindow)) == NULL)
1090 g_warning ("gdk_window_copy_area: GetDC failed");
1092 if (!BitBlt (hdcDest, x, y, width, height, hdcSrc, source_x, source_y, SRCCOPY))
1093 g_warning ("gdk_window_copy_area: BitBlt failed");
1095 ReleaseDC (dest_private->xwindow, hdcDest);
1096 ReleaseDC (src_private->xwindow, hdcSrc);
1101 gdk_window_raise (GdkWindow *window)
1103 GdkWindowPrivate *private;
1105 g_return_if_fail (window != NULL);
1107 private = (GdkWindowPrivate*) window;
1109 if (!private->destroyed)
1111 GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n", private->xwindow));
1113 if (!BringWindowToTop (private->xwindow))
1114 g_warning ("gdk_window_raise: BringWindowToTop failed");
1119 gdk_window_lower (GdkWindow *window)
1121 GdkWindowPrivate *private;
1123 g_return_if_fail (window != NULL);
1125 private = (GdkWindowPrivate*) window;
1127 if (!private->destroyed)
1129 GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n", private->xwindow));
1131 if (!SetWindowPos (private->xwindow, HWND_BOTTOM, 0, 0, 0, 0,
1132 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1133 g_warning ("gdk_window_lower: SetWindowPos failed");
1138 gdk_window_set_user_data (GdkWindow *window,
1141 g_return_if_fail (window != NULL);
1143 window->user_data = user_data;
1147 gdk_window_set_hints (GdkWindow *window,
1156 GdkWindowPrivate *private;
1157 WINDOWPLACEMENT size_hints;
1163 g_return_if_fail (window != NULL);
1165 private = (GdkWindowPrivate*) window;
1166 if (private->destroyed)
1169 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1171 min_width, min_height, max_width, max_height,
1174 private->hint_flags = flags;
1175 size_hints.length = sizeof (size_hints);
1179 if (flags & GDK_HINT_POS)
1180 if (!GetWindowPlacement (private->xwindow, &size_hints))
1181 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1184 GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1185 " (%d,%d)--(%d,%d)\n",
1186 size_hints.rcNormalPosition.left,
1187 size_hints.rcNormalPosition.top,
1188 size_hints.rcNormalPosition.right,
1189 size_hints.rcNormalPosition.bottom));
1190 /* What are the corresponding window coordinates for client
1191 * area coordinates x, y
1195 rect.right = rect.left + 200; /* dummy */
1196 rect.bottom = rect.top + 200;
1197 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1198 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1199 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1200 size_hints.flags = 0;
1201 size_hints.showCmd = SW_SHOWNA;
1203 /* Set the normal position hint to that location, with unchanged
1206 diff = size_hints.rcNormalPosition.left - rect.left;
1207 size_hints.rcNormalPosition.left = rect.left;
1208 size_hints.rcNormalPosition.right -= diff;
1209 diff = size_hints.rcNormalPosition.top - rect.top;
1210 size_hints.rcNormalPosition.top = rect.top;
1211 size_hints.rcNormalPosition.bottom -= diff;
1212 GDK_NOTE (MISC, g_print ("...setting: (%d,%d)--(%d,%d)\n",
1213 size_hints.rcNormalPosition.left,
1214 size_hints.rcNormalPosition.top,
1215 size_hints.rcNormalPosition.right,
1216 size_hints.rcNormalPosition.bottom));
1217 if (!SetWindowPlacement (private->xwindow, &size_hints))
1218 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1219 private->hint_x = rect.left;
1220 private->hint_y = rect.top;
1223 if (flags & GDK_HINT_MIN_SIZE)
1227 rect.right = min_width;
1228 rect.bottom = min_height;
1229 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1230 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1231 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1232 private->hint_min_width = rect.right - rect.left;
1233 private->hint_min_height = rect.bottom - rect.top;
1235 /* Also chek if he current size of the window is in bounds. */
1236 GetClientRect (private->xwindow, &rect);
1237 if (rect.right < min_width && rect.bottom < min_height)
1238 gdk_window_resize (window, min_width, min_height);
1239 else if (rect.right < min_width)
1240 gdk_window_resize (window, min_width, rect.bottom);
1241 else if (rect.bottom < min_height)
1242 gdk_window_resize (window, rect.right, min_height);
1244 if (flags & GDK_HINT_MAX_SIZE)
1248 rect.right = max_width;
1249 rect.bottom = max_height;
1250 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1251 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1252 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1253 private->hint_max_width = rect.right - rect.left;
1254 private->hint_max_height = rect.bottom - rect.top;
1255 /* Again, check if the window is too large currently. */
1256 GetClientRect (private->xwindow, &rect);
1257 if (rect.right > max_width && rect.bottom > max_height)
1258 gdk_window_resize (window, max_width, max_height);
1259 else if (rect.right > max_width)
1260 gdk_window_resize (window, max_width, rect.bottom);
1261 else if (rect.bottom > max_height)
1262 gdk_window_resize (window, rect.right, max_height);
1268 gdk_window_set_geometry_hints (GdkWindow *window,
1269 GdkGeometry *geometry,
1270 GdkWindowHints geom_mask)
1272 GdkWindowPrivate *private;
1273 WINDOWPLACEMENT size_hints;
1279 g_return_if_fail (window != NULL);
1281 private = (GdkWindowPrivate*) window;
1282 if (private->destroyed)
1285 size_hints.length = sizeof (size_hints);
1287 private->hint_flags = geom_mask;
1289 if (geom_mask & GDK_HINT_POS)
1292 if (geom_mask & GDK_HINT_MIN_SIZE)
1296 rect.right = geometry->min_width;
1297 rect.bottom = geometry->min_height;
1298 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1299 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1300 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1301 private->hint_min_width = rect.right - rect.left;
1302 private->hint_min_height = rect.bottom - rect.top;
1304 /* Also check if he current size of the window is in bounds */
1305 GetClientRect (private->xwindow, &rect);
1306 if (rect.right < geometry->min_width
1307 && rect.bottom < geometry->min_height)
1308 gdk_window_resize (window, geometry->min_width, geometry->min_height);
1309 else if (rect.right < geometry->min_width)
1310 gdk_window_resize (window, geometry->min_width, rect.bottom);
1311 else if (rect.bottom < geometry->min_height)
1312 gdk_window_resize (window, rect.right, geometry->min_height);
1315 if (geom_mask & GDK_HINT_MAX_SIZE)
1319 rect.right = geometry->max_width;
1320 rect.bottom = geometry->max_height;
1321 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1322 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1323 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1324 private->hint_max_width = rect.right - rect.left;
1325 private->hint_max_height = rect.bottom - rect.top;
1327 /* Again, check if the window is too large currently. */
1328 GetClientRect (private->xwindow, &rect);
1329 if (rect.right > geometry->max_width
1330 && rect.bottom > geometry->max_height)
1331 gdk_window_resize (window, geometry->max_width, geometry->max_height);
1332 else if (rect.right > geometry->max_width)
1333 gdk_window_resize (window, geometry->max_width, rect.bottom);
1334 else if (rect.bottom > geometry->max_height)
1335 gdk_window_resize (window, rect.right, geometry->max_height);
1338 /* I don't know what to do when called with zero base_width and height. */
1339 if (geom_mask & GDK_HINT_BASE_SIZE
1340 && geometry->base_width > 0
1341 && geometry->base_height > 0)
1342 if (!GetWindowPlacement (private->xwindow, &size_hints))
1343 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1346 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1347 " rcNormalPosition: (%d,%d)--(%d,%d)\n",
1348 size_hints.rcNormalPosition.left,
1349 size_hints.rcNormalPosition.top,
1350 size_hints.rcNormalPosition.right,
1351 size_hints.rcNormalPosition.bottom));
1352 size_hints.rcNormalPosition.right =
1353 size_hints.rcNormalPosition.left + geometry->base_width;
1354 size_hints.rcNormalPosition.bottom =
1355 size_hints.rcNormalPosition.top + geometry->base_height;
1356 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
1357 size_hints.rcNormalPosition.left,
1358 size_hints.rcNormalPosition.top,
1359 size_hints.rcNormalPosition.right,
1360 size_hints.rcNormalPosition.bottom));
1361 if (!SetWindowPlacement (private->xwindow, &size_hints))
1362 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1365 if (geom_mask & GDK_HINT_RESIZE_INC)
1370 if (geom_mask & GDK_HINT_ASPECT)
1377 gdk_window_set_title (GdkWindow *window,
1380 GdkWindowPrivate *private;
1382 g_return_if_fail (window != NULL);
1384 private = (GdkWindowPrivate*) window;
1385 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
1386 private->xwindow, title));
1387 if (!private->destroyed)
1389 if (!SetWindowText (private->xwindow, title))
1390 g_warning ("gdk_window_set_title: SetWindowText failed");
1395 gdk_window_set_role (GdkWindow *window,
1398 GdkWindowPrivate *private;
1400 g_return_if_fail (window != NULL);
1402 private = (GdkWindowPrivate*) window;
1404 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1405 private->xwindow, (role ? role : "NULL")));
1410 gdk_window_set_transient_for (GdkWindow *window,
1413 GdkWindowPrivate *private;
1414 GdkWindowPrivate *parent_private;
1416 g_return_if_fail (window != NULL);
1418 private = (GdkWindowPrivate*) window;
1419 parent_private = (GdkWindowPrivate*) parent;
1421 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1422 private->xwindow, parent_private->xwindow));
1427 gdk_window_set_background (GdkWindow *window,
1430 GdkWindowPrivate *private;
1432 g_return_if_fail (window != NULL);
1434 private = (GdkWindowPrivate*) window;
1435 if (!private->destroyed)
1437 GdkColormapPrivate *colormap_private =
1438 (GdkColormapPrivate *) private->colormap;
1440 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1442 gdk_color_to_string (color)));
1444 if (private->bg_type == GDK_WIN32_BG_PIXMAP)
1446 if (private->bg_pixmap != NULL)
1448 gdk_pixmap_unref (private->bg_pixmap);
1449 private->bg_pixmap = NULL;
1451 private->bg_type = GDK_WIN32_BG_NORMAL;
1453 #ifdef MULTIPLE_WINDOW_CLASSES
1454 if (colormap_private != NULL
1455 && colormap_private->xcolormap->rc_palette)
1457 /* If we are on a palettized display we can't use the window
1458 * class background brush, but must handle WM_ERASEBKGND.
1459 * At least, I think so.
1462 private->bg_type = GDK_WIN32_BG_PIXEL;
1463 private->bg_pixel = *color;
1464 #ifdef MULTIPLE_WINDOW_CLASSES
1468 /* Non-palettized display; just set the window class background
1472 COLORREF background;
1474 background = RGB (color->red >> 8,
1478 if ((hbr = CreateSolidBrush (GetNearestColor (gdk_DC,
1479 background))) == NULL)
1481 g_warning ("gdk_window_set_background: CreateSolidBrush failed");
1485 oldbrush = (HGDIOBJ) GetClassLong (private->xwindow,
1488 if (SetClassLong (private->xwindow, GCL_HBRBACKGROUND,
1490 g_warning ("gdk_window_set_background: SetClassLong failed");
1492 if (!DeleteObject (oldbrush))
1493 g_warning ("gdk_window_set_background: DeleteObject failed");
1500 gdk_window_set_back_pixmap (GdkWindow *window,
1502 gint parent_relative)
1504 GdkWindowPrivate *window_private;
1505 #ifdef MULTIPLE_WINDOW_CLASSES
1506 GdkPixmapPrivate *pixmap_private;
1509 g_return_if_fail (window != NULL);
1511 window_private = (GdkWindowPrivate*) window;
1512 #ifdef MULTIPLE_WINDOW_CLASSES
1513 pixmap_private = (GdkPixmapPrivate*) pixmap;
1516 if (!window_private->destroyed)
1518 GdkColormapPrivate *colormap_private =
1519 (GdkColormapPrivate *) window_private->colormap;
1520 if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
1522 if (window_private->bg_pixmap != NULL)
1524 gdk_pixmap_unref (window_private->bg_pixmap);
1525 window_private->bg_pixmap = NULL;
1527 window_private->bg_type = GDK_WIN32_BG_NORMAL;
1529 if (parent_relative)
1531 window_private->bg_type = GDK_WIN32_BG_PARENT_RELATIVE;
1535 #ifdef MULTIPLE_WINDOW_CLASSES
1536 SetClassLong (window_private->xwindow, GCL_HBRBACKGROUND,
1537 (LONG) GetStockObject (BLACK_BRUSH));
1540 #ifdef MULTIPLE_WINDOW_CLASSES
1541 else if (colormap_private->xcolormap->rc_palette)
1543 /* Must do the background painting in the
1544 * WM_ERASEBKGND handler.
1546 window_private->bg_type = GDK_WIN32_BG_PIXMAP;
1547 window_private->bg_pixmap = pixmap;
1548 gdk_pixmap_ref (pixmap);
1550 else if (pixmap_private->width <= 8
1551 && pixmap_private->height <= 8)
1553 /* We can use small pixmaps directly as background brush */
1554 SetClassLong (window_private->xwindow, GCL_HBRBACKGROUND,
1555 (LONG) CreatePatternBrush (pixmap_private->xwindow));
1560 /* We must cache the pixmap in the WindowPrivate and
1561 * paint it each time we get WM_ERASEBKGND
1563 window_private->bg_type = GDK_WIN32_BG_PIXMAP;
1564 window_private->bg_pixmap = pixmap;
1565 gdk_pixmap_ref (pixmap);
1571 gdk_window_set_cursor (GdkWindow *window,
1574 GdkWindowPrivate *window_private;
1575 GdkCursorPrivate *cursor_private;
1578 g_return_if_fail (window != NULL);
1580 window_private = (GdkWindowPrivate*) window;
1581 cursor_private = (GdkCursorPrivate*) cursor;
1583 if (!window_private->destroyed)
1586 xcursor = LoadCursor (NULL, IDC_ARROW);
1588 xcursor = cursor_private->xcursor;
1590 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1591 window_private->xwindow, xcursor));
1592 #ifdef MULTIPLE_WINDOW_CLASSES
1593 if (!SetClassLong (window_private->xwindow, GCL_HCURSOR, (LONG) xcursor))
1594 g_warning ("gdk_window_set_cursor: SetClassLong failed");
1596 window_private->xcursor = xcursor;
1598 SetCursor (xcursor);
1603 gdk_window_set_colormap (GdkWindow *window,
1604 GdkColormap *colormap)
1606 GdkWindowPrivate *window_private;
1607 GdkColormapPrivate *colormap_private;
1609 g_return_if_fail (window != NULL);
1610 g_return_if_fail (colormap != NULL);
1612 window_private = (GdkWindowPrivate*) window;
1613 colormap_private = (GdkColormapPrivate*) colormap;
1615 if (!window_private->destroyed)
1618 GDK_NOTE (MISC, g_print ("gdk_window_set_colormap: %#x %#x\n",
1619 window_private->xwindow,
1620 colormap_private->xcolormap));
1621 if (window_private->colormap)
1622 gdk_colormap_unref (window_private->colormap);
1623 window_private->colormap = colormap;
1624 gdk_colormap_ref (window_private->colormap);
1626 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1627 gdk_window_add_colormap_windows (window);
1632 gdk_window_get_user_data (GdkWindow *window,
1635 g_return_if_fail (window != NULL);
1637 *data = window->user_data;
1641 gdk_window_get_geometry (GdkWindow *window,
1648 GdkWindowPrivate *window_private;
1651 window = (GdkWindow*) &gdk_root_parent;
1653 window_private = (GdkWindowPrivate*) window;
1655 if (!window_private->destroyed)
1659 if (!GetClientRect (window_private->xwindow, &rect))
1660 g_warning ("gdk_window_get_geometry: GetClientRect failed");
1667 *width = rect.right - rect.left;
1669 *height = rect.bottom - rect.top;
1671 *depth = gdk_window_get_visual (window)->depth;
1676 gdk_window_get_position (GdkWindow *window,
1680 GdkWindowPrivate *window_private;
1682 g_return_if_fail (window != NULL);
1684 window_private = (GdkWindowPrivate*) window;
1687 *x = window_private->x;
1689 *y = window_private->y;
1693 gdk_window_get_size (GdkWindow *window,
1697 GdkWindowPrivate *window_private;
1699 g_return_if_fail (window != NULL);
1701 window_private = (GdkWindowPrivate*) window;
1704 *width = window_private->width;
1706 *height = window_private->height;
1710 gdk_window_get_visual (GdkWindow *window)
1712 GdkWindowPrivate *window_private;
1714 g_return_val_if_fail (window != NULL, NULL);
1716 window_private = (GdkWindowPrivate*) window;
1717 /* Huh? ->parent is never set for a pixmap. We should just return
1718 * null immeditately. Well, do it then!
1720 if (window_private->window_type == GDK_WINDOW_PIXMAP)
1723 if (!window_private->destroyed)
1725 if (window_private->colormap == NULL)
1726 return gdk_visual_get_system (); /* XXX ??? */
1728 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1735 gdk_window_get_colormap (GdkWindow *window)
1737 GdkWindowPrivate *window_private;
1739 g_return_val_if_fail (window != NULL, NULL);
1740 window_private = (GdkWindowPrivate*) window;
1742 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1743 if (!window_private->destroyed)
1745 if (window_private->colormap == NULL)
1746 return gdk_colormap_get_system (); /* XXX ??? */
1748 return window_private->colormap;
1755 gdk_window_get_type (GdkWindow *window)
1757 GdkWindowPrivate *window_private;
1759 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1761 window_private = (GdkWindowPrivate*) window;
1762 return window_private->window_type;
1766 gdk_window_get_origin (GdkWindow *window,
1770 GdkWindowPrivate *private;
1775 g_return_val_if_fail (window != NULL, 0);
1777 private = (GdkWindowPrivate*) window;
1779 if (!private->destroyed)
1785 ClientToScreen (private->xwindow, &pt);
1798 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
1799 private->xwindow, tx, ty));
1804 gdk_window_get_deskrelative_origin (GdkWindow *window,
1808 return gdk_window_get_origin (window, x, y);
1812 gdk_window_get_root_origin (GdkWindow *window,
1816 GdkWindowPrivate *private;
1819 g_return_if_fail (window != NULL);
1821 private = (GdkWindowPrivate*) window;
1826 if (private->destroyed)
1829 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1830 private = (GdkWindowPrivate*) private->parent;
1831 if (private->destroyed)
1836 ClientToScreen (private->xwindow, &pt);
1842 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%d+%d\n",
1843 ((GdkWindowPrivate *) window)->xwindow,
1844 private->xwindow, pt.x, pt.y));
1848 gdk_window_get_pointer (GdkWindow *window,
1851 GdkModifierType *mask)
1853 GdkWindowPrivate *private;
1854 GdkWindow *return_val;
1855 POINT pointc, point;
1859 window = (GdkWindow*) &gdk_root_parent;
1861 private = (GdkWindowPrivate*) window;
1864 GetCursorPos (&pointc);
1866 ScreenToClient (private->xwindow, &point);
1873 hwnd = WindowFromPoint (point);
1875 ScreenToClient (hwnd, &point);
1878 hwndc = ChildWindowFromPoint (hwnd, point);
1879 ClientToScreen (hwnd, &point);
1880 ScreenToClient (hwndc, &point);
1881 } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1883 return_val = gdk_window_lookup (hwnd);
1889 GetKeyboardState (kbd);
1891 if (kbd[VK_SHIFT] & 0x80)
1892 *mask |= GDK_SHIFT_MASK;
1893 if (kbd[VK_CAPITAL] & 0x80)
1894 *mask |= GDK_LOCK_MASK;
1895 if (kbd[VK_CONTROL] & 0x80)
1896 *mask |= GDK_CONTROL_MASK;
1897 if (kbd[VK_MENU] & 0x80)
1898 *mask |= GDK_MOD1_MASK;
1899 if (kbd[VK_LBUTTON] & 0x80)
1900 *mask |= GDK_BUTTON1_MASK;
1901 if (kbd[VK_MBUTTON] & 0x80)
1902 *mask |= GDK_BUTTON2_MASK;
1903 if (kbd[VK_RBUTTON] & 0x80)
1904 *mask |= GDK_BUTTON3_MASK;
1911 gdk_window_at_pointer (gint *win_x,
1914 GdkWindowPrivate *private;
1916 POINT point, pointc;
1920 private = &gdk_root_parent;
1922 GetCursorPos (&pointc);
1924 hwnd = WindowFromPoint (point);
1928 window = (GdkWindow *) &gdk_root_parent;
1936 ScreenToClient (hwnd, &point);
1939 hwndc = ChildWindowFromPoint (hwnd, point);
1940 ClientToScreen (hwnd, &point);
1941 ScreenToClient (hwndc, &point);
1942 } while (hwndc != hwnd && (hwnd = hwndc, 1));
1944 window = gdk_window_lookup (hwnd);
1946 if (window && (win_x || win_y))
1948 GetClientRect (hwnd, &rect);
1950 *win_x = point.x - rect.left;
1952 *win_y = point.y - rect.top;
1955 GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%d+%d %#x%s\n",
1956 point.x, point.y, hwnd,
1957 (window == NULL ? " NULL" : "")));
1963 gdk_window_get_parent (GdkWindow *window)
1965 g_return_val_if_fail (window != NULL, NULL);
1967 return ((GdkWindowPrivate*) window)->parent;
1971 gdk_window_get_toplevel (GdkWindow *window)
1973 GdkWindowPrivate *private;
1975 g_return_val_if_fail (window != NULL, NULL);
1977 private = (GdkWindowPrivate*) window;
1979 while (private->window_type == GDK_WINDOW_CHILD)
1981 window = ((GdkWindowPrivate*) window)->parent;
1982 private = (GdkWindowPrivate*) window;
1989 gdk_window_get_children (GdkWindow *window)
1991 GdkWindowPrivate *private;
1994 g_return_val_if_fail (window != NULL, NULL);
1996 private = (GdkWindowPrivate*) window;
1997 if (private->destroyed)
2001 g_warning ("gdk_window_get_children ???");
2008 gdk_window_get_events (GdkWindow *window)
2010 GdkWindowPrivate *private;
2012 g_return_val_if_fail (window != NULL, 0);
2014 private = (GdkWindowPrivate*) window;
2015 if (private->destroyed)
2018 return private->event_mask;
2022 gdk_window_set_events (GdkWindow *window,
2023 GdkEventMask event_mask)
2025 GdkWindowPrivate *private;
2027 g_return_if_fail (window != NULL);
2029 private = (GdkWindowPrivate*) window;
2030 if (private->destroyed)
2033 private->event_mask = event_mask;
2037 gdk_window_add_colormap_windows (GdkWindow *window)
2039 g_warning ("gdk_window_add_colormap_windows not implemented"); /* XXX */
2043 * This needs the X11 shape extension.
2044 * If not available, shaped windows will look
2045 * ugly, but programs still work. Stefan Wille
2048 gdk_window_shape_combine_mask (GdkWindow *window,
2052 GdkWindowPrivate *window_private;
2054 g_return_if_fail (window != NULL);
2056 window_private = (GdkWindowPrivate*) window;
2060 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
2061 window_private->xwindow));
2062 SetWindowRgn (window_private->xwindow, NULL, TRUE);
2066 GdkPixmapPrivate *pixmap_private;
2072 /* Convert mask bitmap to region */
2073 pixmap_private = (GdkPixmapPrivate*) mask;
2074 hrgn = BitmapToRegion (pixmap_private->xwindow);
2076 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
2077 window_private->xwindow,
2078 pixmap_private->xwindow));
2080 /* SetWindowRgn wants window (not client) coordinates */
2081 dwStyle = GetWindowLong (window_private->xwindow, GWL_STYLE);
2082 dwExStyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2083 GetClientRect (window_private->xwindow, &rect);
2084 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
2085 OffsetRgn (hrgn, -rect.left, -rect.top);
2087 OffsetRgn (hrgn, x, y);
2089 /* If this is a top-level window, add the title bar to the region */
2090 if (window_private->window_type == GDK_WINDOW_TOPLEVEL)
2092 CombineRgn (hrgn, hrgn,
2093 CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
2097 SetWindowRgn (window_private->xwindow, hrgn, TRUE);
2102 gdk_window_add_filter (GdkWindow *window,
2103 GdkFilterFunc function,
2106 GdkWindowPrivate *private;
2108 GdkEventFilter *filter;
2110 private = (GdkWindowPrivate*) window;
2111 if (private && private->destroyed)
2115 tmp_list = private->filters;
2117 tmp_list = gdk_default_filters;
2121 filter = (GdkEventFilter *)tmp_list->data;
2122 if ((filter->function == function) && (filter->data == data))
2124 tmp_list = tmp_list->next;
2127 filter = g_new (GdkEventFilter, 1);
2128 filter->function = function;
2129 filter->data = data;
2132 private->filters = g_list_append (private->filters, filter);
2134 gdk_default_filters = g_list_append (gdk_default_filters, filter);
2138 gdk_window_remove_filter (GdkWindow *window,
2139 GdkFilterFunc function,
2142 GdkWindowPrivate *private;
2143 GList *tmp_list, *node;
2144 GdkEventFilter *filter;
2146 private = (GdkWindowPrivate*) window;
2149 tmp_list = private->filters;
2151 tmp_list = gdk_default_filters;
2155 filter = (GdkEventFilter *)tmp_list->data;
2157 tmp_list = tmp_list->next;
2159 if ((filter->function == function) && (filter->data == data))
2162 private->filters = g_list_remove_link (private->filters, node);
2164 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
2165 g_list_free_1 (node);
2174 gdk_window_set_override_redirect (GdkWindow *window,
2175 gboolean override_redirect)
2177 g_warning ("gdk_window_set_override_redirect not implemented"); /* XXX */
2181 gdk_window_set_icon (GdkWindow *window,
2182 GdkWindow *icon_window,
2186 g_warning ("gdk_window_set_icon not implemented"); /* XXX */
2190 gdk_window_set_icon_name (GdkWindow *window,
2193 GdkWindowPrivate *window_private;
2195 g_return_if_fail (window != NULL);
2196 window_private = (GdkWindowPrivate*) window;
2197 if (window_private->destroyed)
2200 if (!SetWindowText (window_private->xwindow, name))
2201 g_warning ("gdk_window_set_icon_name: SetWindowText failed");
2205 gdk_window_set_group (GdkWindow *window,
2208 g_warning ("gdk_window_set_group not implemented"); /* XXX */
2212 gdk_window_set_decorations (GdkWindow *window,
2213 GdkWMDecoration decorations)
2215 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2216 LONG style, exstyle;
2218 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2219 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2221 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2222 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
2224 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2226 if (decorations & GDK_DECOR_ALL)
2227 style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2228 if (decorations & GDK_DECOR_BORDER)
2229 style |= (WS_BORDER);
2230 if (decorations & GDK_DECOR_RESIZEH)
2231 style |= (WS_THICKFRAME);
2232 if (decorations & GDK_DECOR_TITLE)
2233 style |= (WS_CAPTION);
2234 if (decorations & GDK_DECOR_MENU)
2235 style |= (WS_SYSMENU);
2236 if (decorations & GDK_DECOR_MINIMIZE)
2237 style |= (WS_MINIMIZEBOX);
2238 if (decorations & GDK_DECOR_MAXIMIZE)
2239 style |= (WS_MAXIMIZEBOX);
2241 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2245 gdk_window_set_functions (GdkWindow *window,
2246 GdkWMFunction functions)
2248 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2249 LONG style, exstyle;
2251 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2252 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2254 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2255 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
2258 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2260 if (functions & GDK_FUNC_ALL)
2261 style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2262 if (functions & GDK_FUNC_RESIZE)
2263 style |= (WS_THICKFRAME);
2264 if (functions & GDK_FUNC_MOVE)
2265 style |= (WS_THICKFRAME);
2266 if (functions & GDK_FUNC_MINIMIZE)
2267 style |= (WS_MINIMIZEBOX);
2268 if (functions & GDK_FUNC_MAXIMIZE)
2269 style |= (WS_MAXIMIZEBOX);
2271 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2275 gdk_window_get_toplevels (void)
2277 GList *new_list = NULL;
2280 tmp_list = gdk_root_parent.children;
2283 new_list = g_list_prepend (new_list, tmp_list->data);
2284 tmp_list = tmp_list->next;
2291 * propagate the shapes from all child windows of a GDK window to the parent
2292 * window. Shamelessly ripped from Enlightenment's code
2298 QueryTree (HWND hwnd,
2308 child = GetWindow (hwnd, GW_CHILD);
2310 child = GetWindow (child, GW_HWNDNEXT);
2313 } while (child != NULL);
2317 *children = g_new (HWND, n);
2318 for (i = 0; i < n; i++)
2321 child = GetWindow (hwnd, GW_CHILD);
2323 child = GetWindow (child, GW_HWNDNEXT);
2324 *children[i] = child;
2330 gdk_propagate_shapes (HANDLE win,
2334 HRGN region, childRegion;
2339 SetRectEmpty (&emptyRect);
2340 region = CreateRectRgnIndirect (&emptyRect);
2342 GetWindowRgn (win, region);
2344 QueryTree (win, &list, &num);
2347 WINDOWPLACEMENT placement;
2349 placement.length = sizeof (WINDOWPLACEMENT);
2350 /* go through all child windows and combine regions */
2351 for (i = 0; i < num; i++)
2353 GetWindowPlacement (list[i], &placement);
2354 if (placement.showCmd = SW_SHOWNORMAL)
2356 childRegion = CreateRectRgnIndirect (&emptyRect);
2357 GetWindowRgn (list[i], childRegion);
2358 CombineRgn (region, region, childRegion, RGN_OR);
2359 DeleteObject (childRegion);
2362 SetWindowRgn (win, region, TRUE);
2365 DeleteObject (region);
2369 gdk_window_set_child_shapes (GdkWindow *window)
2371 GdkWindowPrivate *private;
2373 g_return_if_fail (window != NULL);
2375 private = (GdkWindowPrivate*) window;
2376 if (private->destroyed)
2379 gdk_propagate_shapes ( private->xwindow, FALSE);
2383 gdk_window_merge_child_shapes (GdkWindow *window)
2385 GdkWindowPrivate *private;
2387 g_return_if_fail (window != NULL);
2389 private = (GdkWindowPrivate*) window;
2390 if (private->destroyed)
2393 gdk_propagate_shapes (private->xwindow, TRUE);
2396 /*************************************************************
2397 * gdk_window_is_visible:
2398 * Check if the given window is mapped.
2402 * is the window mapped
2403 *************************************************************/
2406 gdk_window_is_visible (GdkWindow *window)
2408 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2410 g_return_val_if_fail (window != NULL, FALSE);
2412 return private->mapped;
2415 /*************************************************************
2416 * gdk_window_is_viewable:
2417 * Check if the window and all ancestors of the window
2418 * are mapped. (This is not necessarily "viewable" in
2419 * the X sense, since we only check as far as we have
2420 * GDK window parents, not to the root window)
2424 * is the window viewable
2425 *************************************************************/
2428 gdk_window_is_viewable (GdkWindow *window)
2430 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2432 g_return_val_if_fail (window != NULL, FALSE);
2435 (private != &gdk_root_parent) &&
2436 (private->window_type != GDK_WINDOW_FOREIGN))
2438 if (!private->mapped)
2441 private = (GdkWindowPrivate *)private->parent;
2448 gdk_drawable_set_data (GdkDrawable *drawable,
2451 GDestroyNotify destroy_func)
2453 g_dataset_set_data_full (drawable, key, data, destroy_func);
2457 /* Support for windows that can be guffaw-scrolled
2458 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2462 gdk_window_gravity_works (void)
2464 enum { UNKNOWN, NO, YES };
2465 static gint gravity_works = UNKNOWN;
2467 if (gravity_works == UNKNOWN)
2474 attr.window_type = GDK_WINDOW_TEMP;
2475 attr.wclass = GDK_INPUT_OUTPUT;
2480 attr.event_mask = 0;
2482 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2484 attr.window_type = GDK_WINDOW_CHILD;
2485 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2487 gdk_window_set_static_win_gravity (child, TRUE);
2489 gdk_window_resize (parent, 100, 110);
2490 gdk_window_move (parent, 0, -10);
2491 gdk_window_move_resize (parent, 0, 0, 100, 100);
2493 gdk_window_resize (parent, 100, 110);
2494 gdk_window_move (parent, 0, -10);
2495 gdk_window_move_resize (parent, 0, 0, 100, 100);
2497 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2499 gdk_window_destroy (parent);
2500 gdk_window_destroy (child);
2502 gravity_works = ((y == -20) ? YES : NO);
2505 return (gravity_works == YES);
2509 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2511 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2513 g_return_if_fail (window != NULL);
2516 g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2520 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2522 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2524 g_return_if_fail (window != NULL);
2527 g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2530 /*************************************************************
2531 * gdk_window_set_static_gravities:
2532 * Set the bit gravity of the given window to static,
2533 * and flag it so all children get static subwindow
2536 * window: window for which to set static gravity
2537 * use_static: Whether to turn static gravity on or off.
2539 * Does the XServer support static gravity?
2540 *************************************************************/
2543 gdk_window_set_static_gravities (GdkWindow *window,
2544 gboolean use_static)
2546 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2549 g_return_val_if_fail (window != NULL, FALSE);
2551 if (!use_static == !private->guffaw_gravity)
2554 if (use_static && !gdk_window_gravity_works ())
2557 private->guffaw_gravity = use_static;
2559 gdk_window_set_static_bit_gravity (window, use_static);
2561 tmp_list = private->children;
2564 gdk_window_set_static_win_gravity (window, use_static);
2566 tmp_list = tmp_list->next;