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 gdk_window_new (GdkWindow *parent,
131 GdkWindowAttr *attributes,
132 gint attributes_mask)
135 GdkWindowPrivate *private;
136 GdkWindowPrivate *parent_private;
140 #ifdef MULTIPLE_WINDOW_CLASSES
143 char wcl_name_buf[20];
144 static int wcl_cnt = 0;
146 static WNDCLASSEX wcl;
147 static ATOM klass = 0;
149 static HICON hAppIcon = NULL;
150 DWORD dwStyle, dwExStyle;
156 g_return_val_if_fail (attributes != NULL, NULL);
159 parent = (GdkWindow*) &gdk_root_parent;
161 parent_private = (GdkWindowPrivate*) parent;
162 if (parent_private->destroyed)
165 xparent = parent_private->xwindow;
167 private = g_new (GdkWindowPrivate, 1);
168 window = (GdkWindow*) private;
170 private->parent = parent;
172 private->destroyed = FALSE;
173 private->mapped = FALSE;
174 private->guffaw_gravity = FALSE;
175 private->resize_count = 0;
176 private->ref_count = 1;
178 private->x = (attributes_mask & GDK_WA_X) ? attributes->x : 0;
179 private->y = (attributes_mask & GDK_WA_Y) ? attributes->y : 0;
181 private->width = (attributes->width > 1) ? (attributes->width) : (1);
182 private->height = (attributes->height > 1) ? (attributes->height) : (1);
183 private->window_type = attributes->window_type;
184 private->extension_events = 0;
185 private->extension_events_selected = FALSE;
187 private->filters = NULL;
188 private->children = NULL;
190 window->user_data = NULL;
192 if (attributes_mask & GDK_WA_VISUAL)
193 visual = attributes->visual;
195 visual = gdk_visual_get_system ();
196 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
198 if (attributes_mask & GDK_WA_TITLE)
199 title = attributes->title;
201 title = g_get_prgname ();
203 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
204 private->bg_type = GDK_WIN32_BG_NORMAL;
205 private->hint_flags = 0;
207 #ifndef MULTIPLE_WINDOW_CLASSES
211 wcl.cbSize = sizeof (WNDCLASSEX);
213 wcl.style = CS_HREDRAW | CS_VREDRAW;
217 wcl.lpfnWndProc = gdk_WindowProc;
220 wcl.hInstance = gdk_ProgInstance;
221 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
223 #if 0 /* tml: orig -> generates SetClassLong errors in set background */
224 wcl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
225 wcl.hbrBackground = NULL;
227 /* initialize once! */
230 gchar sLoc [_MAX_PATH+1];
231 HINSTANCE hInst = GetModuleHandle(NULL);
233 if (0 != GetModuleFileName(hInst, sLoc, _MAX_PATH))
235 hAppIcon = ExtractIcon(hInst, sLoc, 0);
238 char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
240 hAppIcon = ExtractIcon(hInst, gdklibname, 0);
245 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
248 wcl.hIcon = CopyIcon (hAppIcon);
249 wcl.hIconSm = CopyIcon (hAppIcon);
250 /* HB: starting with black to have something to release ... */
251 wcl.hbrBackground = CreateSolidBrush( RGB(0,0,0));
254 wcl.lpszMenuName = NULL;
255 #ifdef MULTIPLE_WINDOW_CLASSES
256 sprintf (wcl_name_buf, "gdk-wcl-%d", wcl_cnt++);
257 wcl.lpszClassName = g_strdup (wcl_name_buf);
258 /* wcl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); */
260 wcl.lpszClassName = "GDK-window-class";
261 klass = RegisterClassEx (&wcl);
263 g_error ("RegisterClassEx failed");
266 private->xcursor = NULL;
269 if (parent_private && parent_private->guffaw_gravity)
274 if (attributes->wclass == GDK_INPUT_OUTPUT)
277 if (attributes_mask & GDK_WA_COLORMAP)
278 private->colormap = attributes->colormap;
280 private->colormap = gdk_colormap_get_system ();
284 dwExStyle = WS_EX_TRANSPARENT;
285 private->colormap = NULL;
286 private->bg_type = GDK_WIN32_BG_TRANSPARENT;
287 private->bg_pixmap = NULL;
290 if (attributes_mask & GDK_WA_X)
295 if (attributes_mask & GDK_WA_Y)
297 else if (attributes_mask & GDK_WA_X)
298 y = 100; /* ??? We must put it somewhere... */
300 y = 500; /* x is CW_USEDEFAULT, y doesn't matter then */
303 parent_private->children = g_list_prepend (parent_private->children, window);
305 switch (private->window_type)
307 case GDK_WINDOW_TOPLEVEL:
308 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
309 xparent = gdk_root_window;
311 case GDK_WINDOW_CHILD:
312 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
314 case GDK_WINDOW_DIALOG:
315 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
316 xparent = gdk_root_window;
318 case GDK_WINDOW_TEMP:
319 dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
320 #ifdef MULTIPLE_WINDOW_CLASSES
321 wcl.style |= CS_SAVEBITS;
323 dwExStyle |= WS_EX_TOOLWINDOW;
325 case GDK_WINDOW_ROOT:
326 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
328 case GDK_WINDOW_PIXMAP:
329 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
333 #ifdef MULTIPLE_WINDOW_CLASSES
334 klass = RegisterClassEx (&wcl);
336 g_error ("RegisterClassEx failed");
339 if (private->window_type != GDK_WINDOW_CHILD)
341 if (x == CW_USEDEFAULT)
352 rect.right = rect.left + private->width;
353 rect.bottom = rect.top + private->height;
355 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
356 g_warning ("gdk_window_new: AdjustWindowRectEx failed");
358 if (x != CW_USEDEFAULT)
363 width = rect.right - rect.left;
364 height = rect.bottom - rect.top;
368 width = private->width;
369 height = private->height;
373 CreateWindowEx (dwExStyle,
384 g_print ("gdk_window_create: %s %s %#x %#x %dx%d@+%d+%d %#x = %#x\n",
385 (private->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
386 (private->window_type == GDK_WINDOW_CHILD ? "CHILD" :
387 (private->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
388 (private->window_type == GDK_WINDOW_TEMP ? "TEMP" :
393 width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
397 gdk_window_ref (window);
398 gdk_xid_table_insert (&private->xwindow, window);
400 if (private->colormap)
401 gdk_colormap_ref (private->colormap);
403 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
404 (attributes->cursor) :
411 gdk_window_foreign_new (guint32 anid)
414 GdkWindowPrivate *private;
415 GdkWindowPrivate *parent_private;
420 private = g_new (GdkWindowPrivate, 1);
421 window = (GdkWindow*) private;
423 parent = GetParent ((HWND) anid);
424 private->parent = gdk_xid_table_lookup (parent);
426 parent_private = (GdkWindowPrivate *)private->parent;
429 parent_private->children = g_list_prepend (parent_private->children, window);
431 private->xwindow = (HWND) anid;
432 GetClientRect ((HWND) anid, &rect);
434 point.y = rect.right;
435 ClientToScreen ((HWND) anid, &point);
436 if (parent != HWND_DESKTOP)
437 ScreenToClient (parent, &point);
438 private->x = point.x;
439 private->y = point.y;
440 private->width = rect.right - rect.left;
441 private->height = rect.bottom - rect.top;
442 private->resize_count = 0;
443 private->ref_count = 1;
444 private->window_type = GDK_WINDOW_FOREIGN;
445 private->destroyed = FALSE;
446 private->mapped = IsWindowVisible (private->xwindow);
447 private->guffaw_gravity = FALSE;
448 private->extension_events = 0;
449 private->extension_events_selected = FALSE;
451 private->colormap = NULL;
453 private->filters = NULL;
454 private->children = NULL;
456 window->user_data = NULL;
458 gdk_window_ref (window);
459 gdk_xid_table_insert (&private->xwindow, window);
464 /* Call this function when you want a window and all its children to
465 * disappear. When xdestroy is true, a request to destroy the XWindow
466 * is sent out. When it is false, it is assumed that the XWindow has
467 * been or will be destroyed by destroying some ancestor of this
471 gdk_window_internal_destroy (GdkWindow *window,
473 gboolean our_destroy)
475 GdkWindowPrivate *private;
476 GdkWindowPrivate *temp_private;
477 GdkWindow *temp_window;
481 g_return_if_fail (window != NULL);
483 private = (GdkWindowPrivate*) window;
485 GDK_NOTE (MISC, g_print ("gdk_window_internal_destroy %#x\n",
488 switch (private->window_type)
490 case GDK_WINDOW_TOPLEVEL:
491 case GDK_WINDOW_CHILD:
492 case GDK_WINDOW_DIALOG:
493 case GDK_WINDOW_TEMP:
494 case GDK_WINDOW_FOREIGN:
495 if (!private->destroyed)
499 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
500 if (parent_private->children)
501 parent_private->children = g_list_remove (parent_private->children, window);
504 if (private->window_type != GDK_WINDOW_FOREIGN)
506 children = tmp = private->children;
507 private->children = NULL;
511 temp_window = tmp->data;
514 temp_private = (GdkWindowPrivate*) temp_window;
516 gdk_window_internal_destroy (temp_window, FALSE,
520 g_list_free (children);
523 if (private->extension_events != 0)
524 gdk_input_window_destroy (window);
526 if (private->filters)
528 tmp = private->filters;
536 g_list_free (private->filters);
537 private->filters = NULL;
540 if (private->window_type == GDK_WINDOW_FOREIGN)
542 if (our_destroy && (private->parent != NULL))
544 /* It's somebody elses window, but in our hierarchy,
545 * so reparent it to the root window, and then send
546 * it a delete event, as if we were a WM
548 gdk_window_hide (window);
549 gdk_window_reparent (window, NULL, 0, 0);
551 /* Is this too drastic? Many (most?) applications
552 * quit if any window receives WM_QUIT I think.
553 * OTOH, I don't think foreign windows are much
554 * used, so the question is maybe academic.
556 PostMessage (private->xwindow, WM_QUIT, 0, 0);
560 DestroyWindow (private->xwindow);
562 if (private->colormap)
563 gdk_colormap_unref (private->colormap);
565 private->mapped = FALSE;
566 private->destroyed = TRUE;
570 case GDK_WINDOW_ROOT:
571 g_error ("attempted to destroy root window");
574 case GDK_WINDOW_PIXMAP:
575 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
580 /* Like internal_destroy, but also destroys the reference created by
584 gdk_window_destroy (GdkWindow *window)
586 gdk_window_internal_destroy (window, TRUE, TRUE);
587 gdk_window_unref (window);
590 /* This function is called when the XWindow is really gone. */
593 gdk_window_destroy_notify (GdkWindow *window)
595 GdkWindowPrivate *private;
597 g_return_if_fail (window != NULL);
599 private = (GdkWindowPrivate*) window;
601 GDK_NOTE (EVENTS, g_print ("gdk_window_destroy_notify: %#x %d\n",
602 private->xwindow, private->destroyed));
604 if (!private->destroyed)
606 if (private->window_type == GDK_WINDOW_FOREIGN)
607 gdk_window_internal_destroy (window, FALSE, FALSE);
609 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
612 gdk_xid_table_remove (private->xwindow);
613 gdk_window_unref (window);
617 gdk_window_ref (GdkWindow *window)
619 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
620 g_return_val_if_fail (window != NULL, NULL);
622 private->ref_count += 1;
624 GDK_NOTE (MISC, g_print ("gdk_window_ref %#x %d\n",
625 private->xwindow, private->ref_count));
631 gdk_window_unref (GdkWindow *window)
633 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
634 g_return_if_fail (window != NULL);
636 private->ref_count -= 1;
638 GDK_NOTE (MISC, g_print ("gdk_window_unref %#x %d%s\n",
639 private->xwindow, private->ref_count,
640 (private->ref_count == 0 ? " freeing" : "")));
642 if (private->ref_count == 0)
644 if (private->bg_type == GDK_WIN32_BG_PIXMAP && private->bg_pixmap != NULL)
645 gdk_pixmap_unref (private->bg_pixmap);
647 if (!private->destroyed)
649 if (private->window_type == GDK_WINDOW_FOREIGN)
650 gdk_xid_table_remove (private->xwindow);
652 g_warning ("losing last reference to undestroyed window");
654 g_dataset_destroy (window);
660 gdk_window_show (GdkWindow *window)
662 GdkWindowPrivate *private;
664 g_return_if_fail (window != NULL);
666 private = (GdkWindowPrivate*) window;
667 if (!private->destroyed)
669 GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n", private->xwindow));
671 private->mapped = TRUE;
672 if (private->window_type == GDK_WINDOW_TEMP)
674 ShowWindow (private->xwindow, SW_SHOWNOACTIVATE);
675 SetWindowPos (private->xwindow, HWND_TOPMOST, 0, 0, 0, 0,
676 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
678 ShowWindow (private->xwindow, SW_HIDE); /* Don't put on toolbar */
683 ShowWindow (private->xwindow, SW_SHOWNORMAL);
684 ShowWindow (private->xwindow, SW_RESTORE);
685 SetForegroundWindow (private->xwindow);
687 ShowOwnedPopups (private->xwindow, TRUE);
694 gdk_window_hide (GdkWindow *window)
696 GdkWindowPrivate *private;
698 g_return_if_fail (window != NULL);
700 private = (GdkWindowPrivate*) window;
701 if (!private->destroyed)
703 GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n", private->xwindow));
705 private->mapped = FALSE;
706 if (private->window_type == GDK_WINDOW_TOPLEVEL)
707 ShowOwnedPopups (private->xwindow, FALSE);
709 ShowWindow (private->xwindow, SW_HIDE);
711 ShowWindow (private->xwindow, SW_MINIMIZE);
713 CloseWindow (private->xwindow);
719 gdk_window_withdraw (GdkWindow *window)
721 GdkWindowPrivate *private;
723 g_return_if_fail (window != NULL);
725 private = (GdkWindowPrivate*) window;
726 if (!private->destroyed)
728 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n", private->xwindow));
730 gdk_window_hide (window); /* XXX */
735 gdk_window_move (GdkWindow *window,
739 GdkWindowPrivate *private;
741 g_return_if_fail (window != NULL);
743 private = (GdkWindowPrivate*) window;
744 if (!private->destroyed)
748 GDK_NOTE (MISC, g_print ("gdk_window_move: %#x +%d+%d\n",
749 private->xwindow, x, y));
751 GetClientRect (private->xwindow, &rect);
753 if (private->window_type != GDK_WINDOW_CHILD)
761 ClientToScreen (private->xwindow, &ptTL);
766 ptBR.y = rect.bottom;
767 ClientToScreen (private->xwindow, &ptBR);
768 rect.right = x + ptBR.x - ptTL.x;
769 rect.bottom = y + ptBR.y - ptTL.y;
771 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
772 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
773 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
774 g_warning ("gdk_window_move: AdjustWindowRectEx failed");
784 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
786 rect.right - rect.left, rect.bottom - rect.top,
788 if (!MoveWindow (private->xwindow,
789 x, y, rect.right - rect.left, rect.bottom - rect.top,
791 g_warning ("gdk_window_move: MoveWindow failed");
796 gdk_window_resize (GdkWindow *window,
800 GdkWindowPrivate *private;
802 g_return_if_fail (window != NULL);
804 if ((gint16) width < 1)
806 if ((gint16) height < 1)
809 private = (GdkWindowPrivate*) window;
811 if (!private->destroyed &&
812 ((private->resize_count > 0) ||
813 (private->width != (guint16) width) ||
814 (private->height != (guint16) height)))
818 GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
819 private->xwindow, width, height));
821 if (private->window_type != GDK_WINDOW_CHILD)
830 ClientToScreen (private->xwindow, &pt);
833 rect.right = pt.x + width;
834 rect.bottom = pt.y + height;
836 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
837 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
838 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
839 g_warning ("gdk_window_resize: AdjustWindowRectEx failed");
843 width = rect.right - rect.left;
844 height = rect.bottom - rect.top;
850 private->width = width;
851 private->height = height;
854 private->resize_count += 1;
856 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
857 private->xwindow, width, height, x, y));
858 if (!MoveWindow (private->xwindow,
861 g_warning ("gdk_window_resize: MoveWindow failed");
866 gdk_window_move_resize (GdkWindow *window,
872 GdkWindowPrivate *private;
874 g_return_if_fail (window != NULL);
876 if ((gint16) width < 1)
878 if ((gint16) height < 1)
881 private = (GdkWindowPrivate*) window;
882 if (!private->destroyed)
888 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
889 private->xwindow, width, height, x, y));
893 rect.right = x + width;
894 rect.bottom = y + height;
896 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
897 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
898 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
899 g_warning ("gdk_window_move_resize: AdjustWindowRectEx failed");
901 if (private->window_type == GDK_WINDOW_CHILD)
905 private->width = width;
906 private->height = height;
908 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
910 rect.right - rect.left, rect.bottom - rect.top,
911 rect.left, rect.top));
912 if (!MoveWindow (private->xwindow,
914 rect.right - rect.left, rect.bottom - rect.top,
916 g_warning ("gdk_window_move_resize: MoveWindow failed");
918 if (private->guffaw_gravity)
920 GList *tmp_list = private->children;
923 GdkWindowPrivate *child_private = tmp_list->data;
925 child_private->x -= x - private->x;
926 child_private->y -= y - private->y;
928 tmp_list = tmp_list->next;
936 gdk_window_reparent (GdkWindow *window,
937 GdkWindow *new_parent,
941 GdkWindowPrivate *window_private;
942 GdkWindowPrivate *parent_private;
943 GdkWindowPrivate *old_parent_private;
945 g_return_if_fail (window != NULL);
948 new_parent = (GdkWindow*) &gdk_root_parent;
950 window_private = (GdkWindowPrivate*) window;
951 old_parent_private = (GdkWindowPrivate*)window_private->parent;
952 parent_private = (GdkWindowPrivate*) new_parent;
954 if (!window_private->destroyed && !parent_private->destroyed)
956 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
957 window_private->xwindow,
958 parent_private->xwindow));
959 if (!SetParent (window_private->xwindow, parent_private->xwindow))
960 g_warning ("gdk_window_reparent: SetParent failed");
962 if (!MoveWindow (window_private->xwindow,
964 window_private->width, window_private->height,
966 g_warning ("gdk_window_reparent: MoveWindow failed");
969 window_private->parent = new_parent;
971 if (old_parent_private)
972 old_parent_private->children = g_list_remove (old_parent_private->children, window);
974 if ((old_parent_private &&
975 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
976 (!old_parent_private && parent_private->guffaw_gravity))
977 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
979 parent_private->children = g_list_prepend (parent_private->children, window);
983 gdk_window_clear (GdkWindow *window)
985 GdkWindowPrivate *private;
987 g_return_if_fail (window != NULL);
989 private = (GdkWindowPrivate*) window;
991 if (!private->destroyed)
993 gdk_window_clear_area (window, 0, 0, private->width, private->height);
999 gdk_window_clear_area (GdkWindow *window,
1005 GdkWindowPrivate *private;
1007 g_return_if_fail (window != NULL);
1009 private = (GdkWindowPrivate*) window;
1011 if (!private->destroyed)
1016 width = G_MAXSHORT/2; /* Yeah, right */
1018 height = G_MAXSHORT/2;
1019 GDK_NOTE (MISC, g_print ("gdk_window_clear_area: %#x %dx%d@+%d+%d\n",
1020 private->xwindow, width, height, x, y));
1021 hdc = GetDC (private->xwindow);
1022 IntersectClipRect (hdc, x, y, x + width, y + height);
1023 SendMessage (private->xwindow, WM_ERASEBKGND, (WPARAM) hdc, 0);
1024 ReleaseDC (private->xwindow, hdc);
1029 gdk_window_clear_area_e (GdkWindow *window,
1035 GdkWindowPrivate *private;
1037 g_return_if_fail (window != NULL);
1039 private = (GdkWindowPrivate*) window;
1041 if (!private->destroyed)
1045 GDK_NOTE (MISC, g_print ("gdk_window_clear_area_e: %#x %dx%d@+%d+%d\n",
1046 private->xwindow, width, height, x, y));
1049 rect.right = x + width;
1051 rect.bottom = y + height;
1052 if (!InvalidateRect (private->xwindow, &rect, TRUE))
1053 g_warning ("gdk_window_clear_area_e: InvalidateRect failed");
1054 UpdateWindow (private->xwindow);
1059 gdk_window_copy_area (GdkWindow *window,
1063 GdkWindow *source_window,
1069 GdkWindowPrivate *src_private;
1070 GdkWindowPrivate *dest_private;
1071 GdkGCPrivate *gc_private;
1073 g_return_if_fail (window != NULL);
1074 g_return_if_fail (gc != NULL);
1076 if (source_window == NULL)
1077 source_window = window;
1079 src_private = (GdkWindowPrivate*) source_window;
1080 dest_private = (GdkWindowPrivate*) window;
1081 gc_private = (GdkGCPrivate*) gc;
1083 if (!src_private->destroyed && !dest_private->destroyed)
1085 HDC hdcDest, hdcSrc;
1087 if ((hdcDest = GetDC (dest_private->xwindow)) == NULL)
1088 g_warning ("gdk_window_copy_area: GetDC failed");
1090 if ((hdcSrc = GetDC (src_private->xwindow)) == NULL)
1091 g_warning ("gdk_window_copy_area: GetDC failed");
1093 if (!BitBlt (hdcDest, x, y, width, height, hdcSrc, source_x, source_y, SRCCOPY))
1094 g_warning ("gdk_window_copy_area: BitBlt failed");
1096 ReleaseDC (dest_private->xwindow, hdcDest);
1097 ReleaseDC (src_private->xwindow, hdcSrc);
1102 gdk_window_raise (GdkWindow *window)
1104 GdkWindowPrivate *private;
1106 g_return_if_fail (window != NULL);
1108 private = (GdkWindowPrivate*) window;
1110 if (!private->destroyed)
1112 GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n", private->xwindow));
1114 if (!BringWindowToTop (private->xwindow))
1115 g_warning ("gdk_window_raise: BringWindowToTop failed");
1120 gdk_window_lower (GdkWindow *window)
1122 GdkWindowPrivate *private;
1124 g_return_if_fail (window != NULL);
1126 private = (GdkWindowPrivate*) window;
1128 if (!private->destroyed)
1130 GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n", private->xwindow));
1132 if (!SetWindowPos (private->xwindow, HWND_BOTTOM, 0, 0, 0, 0,
1133 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1134 g_warning ("gdk_window_lower: SetWindowPos failed");
1139 gdk_window_set_user_data (GdkWindow *window,
1142 g_return_if_fail (window != NULL);
1144 window->user_data = user_data;
1148 gdk_window_set_hints (GdkWindow *window,
1157 GdkWindowPrivate *private;
1158 WINDOWPLACEMENT size_hints;
1164 g_return_if_fail (window != NULL);
1166 private = (GdkWindowPrivate*) window;
1167 if (private->destroyed)
1170 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1172 min_width, min_height, max_width, max_height,
1175 private->hint_flags = flags;
1176 size_hints.length = sizeof (size_hints);
1180 if (flags & GDK_HINT_POS)
1181 if (!GetWindowPlacement (private->xwindow, &size_hints))
1182 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1185 GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1186 " (%d,%d)--(%d,%d)\n",
1187 size_hints.rcNormalPosition.left,
1188 size_hints.rcNormalPosition.top,
1189 size_hints.rcNormalPosition.right,
1190 size_hints.rcNormalPosition.bottom));
1191 /* What are the corresponding window coordinates for client
1192 * area coordinates x, y
1196 rect.right = rect.left + 200; /* dummy */
1197 rect.bottom = rect.top + 200;
1198 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1199 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1200 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1201 size_hints.flags = 0;
1202 size_hints.showCmd = SW_SHOWNA;
1204 /* Set the normal position hint to that location, with unchanged
1207 diff = size_hints.rcNormalPosition.left - rect.left;
1208 size_hints.rcNormalPosition.left = rect.left;
1209 size_hints.rcNormalPosition.right -= diff;
1210 diff = size_hints.rcNormalPosition.top - rect.top;
1211 size_hints.rcNormalPosition.top = rect.top;
1212 size_hints.rcNormalPosition.bottom -= diff;
1213 GDK_NOTE (MISC, g_print ("...setting: (%d,%d)--(%d,%d)\n",
1214 size_hints.rcNormalPosition.left,
1215 size_hints.rcNormalPosition.top,
1216 size_hints.rcNormalPosition.right,
1217 size_hints.rcNormalPosition.bottom));
1218 if (!SetWindowPlacement (private->xwindow, &size_hints))
1219 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1220 private->hint_x = rect.left;
1221 private->hint_y = rect.top;
1224 if (flags & GDK_HINT_MIN_SIZE)
1228 rect.right = min_width;
1229 rect.bottom = min_height;
1230 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1231 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1232 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1233 private->hint_min_width = rect.right - rect.left;
1234 private->hint_min_height = rect.bottom - rect.top;
1236 /* Also chek if he current size of the window is in bounds. */
1237 GetClientRect (private->xwindow, &rect);
1238 if (rect.right < min_width && rect.bottom < min_height)
1239 gdk_window_resize (window, min_width, min_height);
1240 else if (rect.right < min_width)
1241 gdk_window_resize (window, min_width, rect.bottom);
1242 else if (rect.bottom < min_height)
1243 gdk_window_resize (window, rect.right, min_height);
1245 if (flags & GDK_HINT_MAX_SIZE)
1249 rect.right = max_width;
1250 rect.bottom = max_height;
1251 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1252 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1253 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1254 private->hint_max_width = rect.right - rect.left;
1255 private->hint_max_height = rect.bottom - rect.top;
1256 /* Again, check if the window is too large currently. */
1257 GetClientRect (private->xwindow, &rect);
1258 if (rect.right > max_width && rect.bottom > max_height)
1259 gdk_window_resize (window, max_width, max_height);
1260 else if (rect.right > max_width)
1261 gdk_window_resize (window, max_width, rect.bottom);
1262 else if (rect.bottom > max_height)
1263 gdk_window_resize (window, rect.right, max_height);
1269 gdk_window_set_geometry_hints (GdkWindow *window,
1270 GdkGeometry *geometry,
1271 GdkWindowHints geom_mask)
1273 GdkWindowPrivate *private;
1274 WINDOWPLACEMENT size_hints;
1280 g_return_if_fail (window != NULL);
1282 private = (GdkWindowPrivate*) window;
1283 if (private->destroyed)
1286 size_hints.length = sizeof (size_hints);
1288 private->hint_flags = geom_mask;
1290 if (geom_mask & GDK_HINT_POS)
1293 if (geom_mask & GDK_HINT_MIN_SIZE)
1297 rect.right = geometry->min_width;
1298 rect.bottom = geometry->min_height;
1299 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1300 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1301 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1302 private->hint_min_width = rect.right - rect.left;
1303 private->hint_min_height = rect.bottom - rect.top;
1305 /* Also check if he current size of the window is in bounds */
1306 GetClientRect (private->xwindow, &rect);
1307 if (rect.right < geometry->min_width
1308 && rect.bottom < geometry->min_height)
1309 gdk_window_resize (window, geometry->min_width, geometry->min_height);
1310 else if (rect.right < geometry->min_width)
1311 gdk_window_resize (window, geometry->min_width, rect.bottom);
1312 else if (rect.bottom < geometry->min_height)
1313 gdk_window_resize (window, rect.right, geometry->min_height);
1316 if (geom_mask & GDK_HINT_MAX_SIZE)
1320 rect.right = geometry->max_width;
1321 rect.bottom = geometry->max_height;
1322 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1323 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1324 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1325 private->hint_max_width = rect.right - rect.left;
1326 private->hint_max_height = rect.bottom - rect.top;
1328 /* Again, check if the window is too large currently. */
1329 GetClientRect (private->xwindow, &rect);
1330 if (rect.right > geometry->max_width
1331 && rect.bottom > geometry->max_height)
1332 gdk_window_resize (window, geometry->max_width, geometry->max_height);
1333 else if (rect.right > geometry->max_width)
1334 gdk_window_resize (window, geometry->max_width, rect.bottom);
1335 else if (rect.bottom > geometry->max_height)
1336 gdk_window_resize (window, rect.right, geometry->max_height);
1339 /* I don't know what to do when called with zero base_width and height. */
1340 if (geom_mask & GDK_HINT_BASE_SIZE
1341 && geometry->base_width > 0
1342 && geometry->base_height > 0)
1343 if (!GetWindowPlacement (private->xwindow, &size_hints))
1344 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1347 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1348 " rcNormalPosition: (%d,%d)--(%d,%d)\n",
1349 size_hints.rcNormalPosition.left,
1350 size_hints.rcNormalPosition.top,
1351 size_hints.rcNormalPosition.right,
1352 size_hints.rcNormalPosition.bottom));
1353 size_hints.rcNormalPosition.right =
1354 size_hints.rcNormalPosition.left + geometry->base_width;
1355 size_hints.rcNormalPosition.bottom =
1356 size_hints.rcNormalPosition.top + geometry->base_height;
1357 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
1358 size_hints.rcNormalPosition.left,
1359 size_hints.rcNormalPosition.top,
1360 size_hints.rcNormalPosition.right,
1361 size_hints.rcNormalPosition.bottom));
1362 if (!SetWindowPlacement (private->xwindow, &size_hints))
1363 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1366 if (geom_mask & GDK_HINT_RESIZE_INC)
1371 if (geom_mask & GDK_HINT_ASPECT)
1378 gdk_window_set_title (GdkWindow *window,
1381 GdkWindowPrivate *private;
1383 g_return_if_fail (window != NULL);
1385 private = (GdkWindowPrivate*) window;
1386 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
1387 private->xwindow, title));
1388 if (!private->destroyed)
1390 if (!SetWindowText (private->xwindow, title))
1391 g_warning ("gdk_window_set_title: SetWindowText failed");
1396 gdk_window_set_role (GdkWindow *window,
1399 GdkWindowPrivate *private;
1401 g_return_if_fail (window != NULL);
1403 private = (GdkWindowPrivate*) window;
1405 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1406 private->xwindow, (role ? role : "NULL")));
1411 gdk_window_set_transient_for (GdkWindow *window,
1414 GdkWindowPrivate *private;
1415 GdkWindowPrivate *parent_private;
1417 g_return_if_fail (window != NULL);
1419 private = (GdkWindowPrivate*) window;
1420 parent_private = (GdkWindowPrivate*) parent;
1422 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1423 private->xwindow, parent_private->xwindow));
1428 gdk_window_set_background (GdkWindow *window,
1431 GdkWindowPrivate *private;
1433 g_return_if_fail (window != NULL);
1435 private = (GdkWindowPrivate*) window;
1436 if (!private->destroyed)
1438 GdkColormapPrivate *colormap_private =
1439 (GdkColormapPrivate *) private->colormap;
1441 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1443 gdk_color_to_string (color)));
1445 if (private->bg_type == GDK_WIN32_BG_PIXMAP)
1447 if (private->bg_pixmap != NULL)
1449 gdk_pixmap_unref (private->bg_pixmap);
1450 private->bg_pixmap = NULL;
1452 private->bg_type = GDK_WIN32_BG_NORMAL;
1454 #ifdef MULTIPLE_WINDOW_CLASSES
1455 if (colormap_private != NULL
1456 && colormap_private->xcolormap->rc_palette)
1458 /* If we are on a palettized display we can't use the window
1459 * class background brush, but must handle WM_ERASEBKGND.
1460 * At least, I think so.
1463 private->bg_type = GDK_WIN32_BG_PIXEL;
1464 private->bg_pixel = *color;
1465 #ifdef MULTIPLE_WINDOW_CLASSES
1469 /* Non-palettized display; just set the window class background
1473 COLORREF background;
1475 background = RGB (color->red >> 8,
1479 if ((hbr = CreateSolidBrush (GetNearestColor (gdk_DC,
1480 background))) == NULL)
1482 g_warning ("gdk_window_set_background: CreateSolidBrush failed");
1486 oldbrush = (HGDIOBJ) GetClassLong (private->xwindow,
1489 if (SetClassLong (private->xwindow, GCL_HBRBACKGROUND,
1491 g_warning ("gdk_window_set_background: SetClassLong failed");
1493 if (!DeleteObject (oldbrush))
1494 g_warning ("gdk_window_set_background: DeleteObject failed");
1501 gdk_window_set_back_pixmap (GdkWindow *window,
1503 gint parent_relative)
1505 GdkWindowPrivate *window_private;
1506 #ifdef MULTIPLE_WINDOW_CLASSES
1507 GdkPixmapPrivate *pixmap_private;
1510 g_return_if_fail (window != NULL);
1512 window_private = (GdkWindowPrivate*) window;
1513 #ifdef MULTIPLE_WINDOW_CLASSES
1514 pixmap_private = (GdkPixmapPrivate*) pixmap;
1517 if (!window_private->destroyed)
1519 GdkColormapPrivate *colormap_private =
1520 (GdkColormapPrivate *) window_private->colormap;
1521 if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
1523 if (window_private->bg_pixmap != NULL)
1525 gdk_pixmap_unref (window_private->bg_pixmap);
1526 window_private->bg_pixmap = NULL;
1528 window_private->bg_type = GDK_WIN32_BG_NORMAL;
1530 if (parent_relative)
1532 window_private->bg_type = GDK_WIN32_BG_PARENT_RELATIVE;
1536 #ifdef MULTIPLE_WINDOW_CLASSES
1537 SetClassLong (window_private->xwindow, GCL_HBRBACKGROUND,
1538 (LONG) GetStockObject (BLACK_BRUSH));
1541 #ifdef MULTIPLE_WINDOW_CLASSES
1542 else if (colormap_private->xcolormap->rc_palette)
1544 /* Must do the background painting in the
1545 * WM_ERASEBKGND handler.
1547 window_private->bg_type = GDK_WIN32_BG_PIXMAP;
1548 window_private->bg_pixmap = pixmap;
1549 gdk_pixmap_ref (pixmap);
1551 else if (pixmap_private->width <= 8
1552 && pixmap_private->height <= 8)
1554 /* We can use small pixmaps directly as background brush */
1555 SetClassLong (window_private->xwindow, GCL_HBRBACKGROUND,
1556 (LONG) CreatePatternBrush (pixmap_private->xwindow));
1561 /* We must cache the pixmap in the WindowPrivate and
1562 * paint it each time we get WM_ERASEBKGND
1564 window_private->bg_type = GDK_WIN32_BG_PIXMAP;
1565 window_private->bg_pixmap = pixmap;
1566 gdk_pixmap_ref (pixmap);
1572 gdk_window_set_cursor (GdkWindow *window,
1575 GdkWindowPrivate *window_private;
1576 GdkCursorPrivate *cursor_private;
1579 g_return_if_fail (window != NULL);
1581 window_private = (GdkWindowPrivate*) window;
1582 cursor_private = (GdkCursorPrivate*) cursor;
1584 if (!window_private->destroyed)
1587 xcursor = LoadCursor (NULL, IDC_ARROW);
1589 xcursor = cursor_private->xcursor;
1591 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1592 window_private->xwindow, xcursor));
1593 #ifdef MULTIPLE_WINDOW_CLASSES
1594 if (!SetClassLong (window_private->xwindow, GCL_HCURSOR, (LONG) xcursor))
1595 g_warning ("gdk_window_set_cursor: SetClassLong failed");
1597 window_private->xcursor = xcursor;
1599 SetCursor (xcursor);
1604 gdk_window_set_colormap (GdkWindow *window,
1605 GdkColormap *colormap)
1607 GdkWindowPrivate *window_private;
1608 GdkColormapPrivate *colormap_private;
1610 g_return_if_fail (window != NULL);
1611 g_return_if_fail (colormap != NULL);
1613 window_private = (GdkWindowPrivate*) window;
1614 colormap_private = (GdkColormapPrivate*) colormap;
1616 if (!window_private->destroyed)
1619 GDK_NOTE (MISC, g_print ("gdk_window_set_colormap: %#x %#x\n",
1620 window_private->xwindow,
1621 colormap_private->xcolormap));
1622 if (window_private->colormap)
1623 gdk_colormap_unref (window_private->colormap);
1624 window_private->colormap = colormap;
1625 gdk_colormap_ref (window_private->colormap);
1627 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1628 gdk_window_add_colormap_windows (window);
1633 gdk_window_get_user_data (GdkWindow *window,
1636 g_return_if_fail (window != NULL);
1638 *data = window->user_data;
1642 gdk_window_get_geometry (GdkWindow *window,
1649 GdkWindowPrivate *window_private;
1652 window = (GdkWindow*) &gdk_root_parent;
1654 window_private = (GdkWindowPrivate*) window;
1656 if (!window_private->destroyed)
1660 if (!GetClientRect (window_private->xwindow, &rect))
1661 g_warning ("gdk_window_get_geometry: GetClientRect failed");
1668 *width = rect.right - rect.left;
1670 *height = rect.bottom - rect.top;
1672 *depth = gdk_window_get_visual (window)->depth;
1677 gdk_window_get_position (GdkWindow *window,
1681 GdkWindowPrivate *window_private;
1683 g_return_if_fail (window != NULL);
1685 window_private = (GdkWindowPrivate*) window;
1688 *x = window_private->x;
1690 *y = window_private->y;
1694 gdk_window_get_size (GdkWindow *window,
1698 GdkWindowPrivate *window_private;
1700 g_return_if_fail (window != NULL);
1702 window_private = (GdkWindowPrivate*) window;
1705 *width = window_private->width;
1707 *height = window_private->height;
1711 gdk_window_get_visual (GdkWindow *window)
1713 GdkWindowPrivate *window_private;
1715 g_return_val_if_fail (window != NULL, NULL);
1717 window_private = (GdkWindowPrivate*) window;
1718 /* Huh? ->parent is never set for a pixmap. We should just return
1719 * null immeditately. Well, do it then!
1721 if (window_private->window_type == GDK_WINDOW_PIXMAP)
1724 if (!window_private->destroyed)
1726 if (window_private->colormap == NULL)
1727 return gdk_visual_get_system (); /* XXX ??? */
1729 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1736 gdk_window_get_colormap (GdkWindow *window)
1738 GdkWindowPrivate *window_private;
1740 g_return_val_if_fail (window != NULL, NULL);
1741 window_private = (GdkWindowPrivate*) window;
1743 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1744 if (!window_private->destroyed)
1746 if (window_private->colormap == NULL)
1747 return gdk_colormap_get_system (); /* XXX ??? */
1749 return window_private->colormap;
1756 gdk_window_get_type (GdkWindow *window)
1758 GdkWindowPrivate *window_private;
1760 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1762 window_private = (GdkWindowPrivate*) window;
1763 return window_private->window_type;
1767 gdk_window_get_origin (GdkWindow *window,
1771 GdkWindowPrivate *private;
1776 g_return_val_if_fail (window != NULL, 0);
1778 private = (GdkWindowPrivate*) window;
1780 if (!private->destroyed)
1786 ClientToScreen (private->xwindow, &pt);
1799 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
1800 private->xwindow, tx, ty));
1805 gdk_window_get_deskrelative_origin (GdkWindow *window,
1809 return gdk_window_get_origin (window, x, y);
1813 gdk_window_get_root_origin (GdkWindow *window,
1817 GdkWindowPrivate *private;
1820 g_return_if_fail (window != NULL);
1822 private = (GdkWindowPrivate*) window;
1827 if (private->destroyed)
1830 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1831 private = (GdkWindowPrivate*) private->parent;
1832 if (private->destroyed)
1837 ClientToScreen (private->xwindow, &pt);
1843 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%d+%d\n",
1844 ((GdkWindowPrivate *) window)->xwindow,
1845 private->xwindow, pt.x, pt.y));
1849 gdk_window_get_pointer (GdkWindow *window,
1852 GdkModifierType *mask)
1854 GdkWindowPrivate *private;
1855 GdkWindow *return_val;
1856 POINT pointc, point;
1860 window = (GdkWindow*) &gdk_root_parent;
1862 private = (GdkWindowPrivate*) window;
1865 GetCursorPos (&pointc);
1867 ScreenToClient (private->xwindow, &point);
1874 hwnd = WindowFromPoint (point);
1876 ScreenToClient (hwnd, &point);
1879 hwndc = ChildWindowFromPoint (hwnd, point);
1880 ClientToScreen (hwnd, &point);
1881 ScreenToClient (hwndc, &point);
1882 } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1884 return_val = gdk_window_lookup (hwnd);
1890 GetKeyboardState (kbd);
1892 if (kbd[VK_SHIFT] & 0x80)
1893 *mask |= GDK_SHIFT_MASK;
1894 if (kbd[VK_CAPITAL] & 0x80)
1895 *mask |= GDK_LOCK_MASK;
1896 if (kbd[VK_CONTROL] & 0x80)
1897 *mask |= GDK_CONTROL_MASK;
1898 if (kbd[VK_MENU] & 0x80)
1899 *mask |= GDK_MOD1_MASK;
1900 if (kbd[VK_LBUTTON] & 0x80)
1901 *mask |= GDK_BUTTON1_MASK;
1902 if (kbd[VK_MBUTTON] & 0x80)
1903 *mask |= GDK_BUTTON2_MASK;
1904 if (kbd[VK_RBUTTON] & 0x80)
1905 *mask |= GDK_BUTTON3_MASK;
1912 gdk_window_at_pointer (gint *win_x,
1915 GdkWindowPrivate *private;
1917 POINT point, pointc;
1921 private = &gdk_root_parent;
1923 GetCursorPos (&pointc);
1925 hwnd = WindowFromPoint (point);
1929 window = (GdkWindow *) &gdk_root_parent;
1937 ScreenToClient (hwnd, &point);
1940 hwndc = ChildWindowFromPoint (hwnd, point);
1941 ClientToScreen (hwnd, &point);
1942 ScreenToClient (hwndc, &point);
1943 } while (hwndc != hwnd && (hwnd = hwndc, 1));
1945 window = gdk_window_lookup (hwnd);
1947 if (window && (win_x || win_y))
1949 GetClientRect (hwnd, &rect);
1951 *win_x = point.x - rect.left;
1953 *win_y = point.y - rect.top;
1956 GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%d+%d %#x%s\n",
1957 point.x, point.y, hwnd,
1958 (window == NULL ? " NULL" : "")));
1964 gdk_window_get_parent (GdkWindow *window)
1966 g_return_val_if_fail (window != NULL, NULL);
1968 return ((GdkWindowPrivate*) window)->parent;
1972 gdk_window_get_toplevel (GdkWindow *window)
1974 GdkWindowPrivate *private;
1976 g_return_val_if_fail (window != NULL, NULL);
1978 private = (GdkWindowPrivate*) window;
1980 while (private->window_type == GDK_WINDOW_CHILD)
1982 window = ((GdkWindowPrivate*) window)->parent;
1983 private = (GdkWindowPrivate*) window;
1990 gdk_window_get_children (GdkWindow *window)
1992 GdkWindowPrivate *private;
1995 g_return_val_if_fail (window != NULL, NULL);
1997 private = (GdkWindowPrivate*) window;
1998 if (private->destroyed)
2002 g_warning ("gdk_window_get_children ???");
2009 gdk_window_get_events (GdkWindow *window)
2011 GdkWindowPrivate *private;
2013 g_return_val_if_fail (window != NULL, 0);
2015 private = (GdkWindowPrivate*) window;
2016 if (private->destroyed)
2019 return private->event_mask;
2023 gdk_window_set_events (GdkWindow *window,
2024 GdkEventMask event_mask)
2026 GdkWindowPrivate *private;
2028 g_return_if_fail (window != NULL);
2030 private = (GdkWindowPrivate*) window;
2031 if (private->destroyed)
2034 private->event_mask = event_mask;
2038 gdk_window_add_colormap_windows (GdkWindow *window)
2040 g_warning ("gdk_window_add_colormap_windows not implemented"); /* XXX */
2044 * This needs the X11 shape extension.
2045 * If not available, shaped windows will look
2046 * ugly, but programs still work. Stefan Wille
2049 gdk_window_shape_combine_mask (GdkWindow *window,
2053 GdkWindowPrivate *window_private;
2055 g_return_if_fail (window != NULL);
2057 window_private = (GdkWindowPrivate*) window;
2061 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
2062 window_private->xwindow));
2063 SetWindowRgn (window_private->xwindow, NULL, TRUE);
2067 GdkPixmapPrivate *pixmap_private;
2073 /* Convert mask bitmap to region */
2074 pixmap_private = (GdkPixmapPrivate*) mask;
2075 hrgn = BitmapToRegion (pixmap_private->xwindow);
2077 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
2078 window_private->xwindow,
2079 pixmap_private->xwindow));
2081 /* SetWindowRgn wants window (not client) coordinates */
2082 dwStyle = GetWindowLong (window_private->xwindow, GWL_STYLE);
2083 dwExStyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2084 GetClientRect (window_private->xwindow, &rect);
2085 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
2086 OffsetRgn (hrgn, -rect.left, -rect.top);
2088 OffsetRgn (hrgn, x, y);
2090 /* If this is a top-level window, add the title bar to the region */
2091 if (window_private->window_type == GDK_WINDOW_TOPLEVEL)
2093 CombineRgn (hrgn, hrgn,
2094 CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
2098 SetWindowRgn (window_private->xwindow, hrgn, TRUE);
2103 gdk_window_add_filter (GdkWindow *window,
2104 GdkFilterFunc function,
2107 GdkWindowPrivate *private;
2109 GdkEventFilter *filter;
2111 private = (GdkWindowPrivate*) window;
2112 if (private && private->destroyed)
2116 tmp_list = private->filters;
2118 tmp_list = gdk_default_filters;
2122 filter = (GdkEventFilter *)tmp_list->data;
2123 if ((filter->function == function) && (filter->data == data))
2125 tmp_list = tmp_list->next;
2128 filter = g_new (GdkEventFilter, 1);
2129 filter->function = function;
2130 filter->data = data;
2133 private->filters = g_list_append (private->filters, filter);
2135 gdk_default_filters = g_list_append (gdk_default_filters, filter);
2139 gdk_window_remove_filter (GdkWindow *window,
2140 GdkFilterFunc function,
2143 GdkWindowPrivate *private;
2144 GList *tmp_list, *node;
2145 GdkEventFilter *filter;
2147 private = (GdkWindowPrivate*) window;
2150 tmp_list = private->filters;
2152 tmp_list = gdk_default_filters;
2156 filter = (GdkEventFilter *)tmp_list->data;
2158 tmp_list = tmp_list->next;
2160 if ((filter->function == function) && (filter->data == data))
2163 private->filters = g_list_remove_link (private->filters, node);
2165 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
2166 g_list_free_1 (node);
2175 gdk_window_set_override_redirect (GdkWindow *window,
2176 gboolean override_redirect)
2178 g_warning ("gdk_window_set_override_redirect not implemented"); /* XXX */
2182 gdk_window_set_icon (GdkWindow *window,
2183 GdkWindow *icon_window,
2187 g_warning ("gdk_window_set_icon not implemented"); /* XXX */
2191 gdk_window_set_icon_name (GdkWindow *window,
2194 GdkWindowPrivate *window_private;
2196 g_return_if_fail (window != NULL);
2197 window_private = (GdkWindowPrivate*) window;
2198 if (window_private->destroyed)
2201 if (!SetWindowText (window_private->xwindow, name))
2202 g_warning ("gdk_window_set_icon_name: SetWindowText failed");
2206 gdk_window_set_group (GdkWindow *window,
2209 g_warning ("gdk_window_set_group not implemented"); /* XXX */
2213 gdk_window_set_decorations (GdkWindow *window,
2214 GdkWMDecoration decorations)
2216 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2217 LONG style, exstyle;
2219 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2220 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2222 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2223 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
2225 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2227 if (decorations & GDK_DECOR_ALL)
2228 style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2229 if (decorations & GDK_DECOR_BORDER)
2230 style |= (WS_BORDER);
2231 if (decorations & GDK_DECOR_RESIZEH)
2232 style |= (WS_THICKFRAME);
2233 if (decorations & GDK_DECOR_TITLE)
2234 style |= (WS_CAPTION);
2235 if (decorations & GDK_DECOR_MENU)
2236 style |= (WS_SYSMENU);
2237 if (decorations & GDK_DECOR_MINIMIZE)
2238 style |= (WS_MINIMIZEBOX);
2239 if (decorations & GDK_DECOR_MAXIMIZE)
2240 style |= (WS_MAXIMIZEBOX);
2242 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2246 gdk_window_set_functions (GdkWindow *window,
2247 GdkWMFunction functions)
2249 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2250 LONG style, exstyle;
2252 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2253 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2255 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2256 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
2259 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2261 if (functions & GDK_FUNC_ALL)
2262 style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2263 if (functions & GDK_FUNC_RESIZE)
2264 style |= (WS_THICKFRAME);
2265 if (functions & GDK_FUNC_MOVE)
2266 style |= (WS_THICKFRAME);
2267 if (functions & GDK_FUNC_MINIMIZE)
2268 style |= (WS_MINIMIZEBOX);
2269 if (functions & GDK_FUNC_MAXIMIZE)
2270 style |= (WS_MAXIMIZEBOX);
2272 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2276 gdk_window_get_toplevels (void)
2278 GList *new_list = NULL;
2281 tmp_list = gdk_root_parent.children;
2284 new_list = g_list_prepend (new_list, tmp_list->data);
2285 tmp_list = tmp_list->next;
2292 * propagate the shapes from all child windows of a GDK window to the parent
2293 * window. Shamelessly ripped from Enlightenment's code
2299 QueryTree (HWND hwnd,
2309 child = GetWindow (hwnd, GW_CHILD);
2311 child = GetWindow (child, GW_HWNDNEXT);
2314 } while (child != NULL);
2318 *children = g_new (HWND, n);
2319 for (i = 0; i < n; i++)
2322 child = GetWindow (hwnd, GW_CHILD);
2324 child = GetWindow (child, GW_HWNDNEXT);
2325 *children[i] = child;
2331 gdk_propagate_shapes (HANDLE win,
2335 HRGN region, childRegion;
2340 SetRectEmpty (&emptyRect);
2341 region = CreateRectRgnIndirect (&emptyRect);
2343 GetWindowRgn (win, region);
2345 QueryTree (win, &list, &num);
2348 WINDOWPLACEMENT placement;
2350 placement.length = sizeof (WINDOWPLACEMENT);
2351 /* go through all child windows and combine regions */
2352 for (i = 0; i < num; i++)
2354 GetWindowPlacement (list[i], &placement);
2355 if (placement.showCmd = SW_SHOWNORMAL)
2357 childRegion = CreateRectRgnIndirect (&emptyRect);
2358 GetWindowRgn (list[i], childRegion);
2359 CombineRgn (region, region, childRegion, RGN_OR);
2360 DeleteObject (childRegion);
2363 SetWindowRgn (win, region, TRUE);
2366 DeleteObject (region);
2370 gdk_window_set_child_shapes (GdkWindow *window)
2372 GdkWindowPrivate *private;
2374 g_return_if_fail (window != NULL);
2376 private = (GdkWindowPrivate*) window;
2377 if (private->destroyed)
2380 gdk_propagate_shapes ( private->xwindow, FALSE);
2384 gdk_window_merge_child_shapes (GdkWindow *window)
2386 GdkWindowPrivate *private;
2388 g_return_if_fail (window != NULL);
2390 private = (GdkWindowPrivate*) window;
2391 if (private->destroyed)
2394 gdk_propagate_shapes (private->xwindow, TRUE);
2397 /*************************************************************
2398 * gdk_window_is_visible:
2399 * Check if the given window is mapped.
2403 * is the window mapped
2404 *************************************************************/
2407 gdk_window_is_visible (GdkWindow *window)
2409 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2411 g_return_val_if_fail (window != NULL, FALSE);
2413 return private->mapped;
2416 /*************************************************************
2417 * gdk_window_is_viewable:
2418 * Check if the window and all ancestors of the window
2419 * are mapped. (This is not necessarily "viewable" in
2420 * the X sense, since we only check as far as we have
2421 * GDK window parents, not to the root window)
2425 * is the window viewable
2426 *************************************************************/
2429 gdk_window_is_viewable (GdkWindow *window)
2431 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2433 g_return_val_if_fail (window != NULL, FALSE);
2436 (private != &gdk_root_parent) &&
2437 (private->window_type != GDK_WINDOW_FOREIGN))
2439 if (!private->mapped)
2442 private = (GdkWindowPrivate *)private->parent;
2449 gdk_drawable_set_data (GdkDrawable *drawable,
2452 GDestroyNotify destroy_func)
2454 g_dataset_set_data_full (drawable, key, data, destroy_func);
2458 /* Support for windows that can be guffaw-scrolled
2459 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2463 gdk_window_gravity_works (void)
2465 enum { UNKNOWN, NO, YES };
2466 static gint gravity_works = UNKNOWN;
2468 if (gravity_works == UNKNOWN)
2475 attr.window_type = GDK_WINDOW_TEMP;
2476 attr.wclass = GDK_INPUT_OUTPUT;
2481 attr.event_mask = 0;
2483 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2485 attr.window_type = GDK_WINDOW_CHILD;
2486 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2488 gdk_window_set_static_win_gravity (child, TRUE);
2490 gdk_window_resize (parent, 100, 110);
2491 gdk_window_move (parent, 0, -10);
2492 gdk_window_move_resize (parent, 0, 0, 100, 100);
2494 gdk_window_resize (parent, 100, 110);
2495 gdk_window_move (parent, 0, -10);
2496 gdk_window_move_resize (parent, 0, 0, 100, 100);
2498 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2500 gdk_window_destroy (parent);
2501 gdk_window_destroy (child);
2503 gravity_works = ((y == -20) ? YES : NO);
2506 return (gravity_works == YES);
2510 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2512 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2514 g_return_if_fail (window != NULL);
2517 g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2521 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2523 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2525 g_return_if_fail (window != NULL);
2528 g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2531 /*************************************************************
2532 * gdk_window_set_static_gravities:
2533 * Set the bit gravity of the given window to static,
2534 * and flag it so all children get static subwindow
2537 * window: window for which to set static gravity
2538 * use_static: Whether to turn static gravity on or off.
2540 * Does the XServer support static gravity?
2541 *************************************************************/
2544 gdk_window_set_static_gravities (GdkWindow *window,
2545 gboolean use_static)
2547 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2550 g_return_val_if_fail (window != NULL, FALSE);
2552 if (!use_static == !private->guffaw_gravity)
2555 if (use_static && !gdk_window_gravity_works ())
2558 private->guffaw_gravity = use_static;
2560 gdk_window_set_static_bit_gravity (window, use_static);
2562 tmp_list = private->children;
2565 gdk_window_set_static_win_gravity (window, use_static);
2567 tmp_list = tmp_list->next;