1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * Copyright (C) 1998-1999 Tor Lillqvist
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
33 #include "gdkevents.h"
34 #include "gdkpixmap.h"
35 #include "gdkwindow.h"
36 #include "gdkprivate.h"
37 #include "gdkinputprivate.h"
40 /* The Win API function AdjustWindowRect may return negative values
41 * resulting in obscured title bars. This helper function is coreccting it.
44 SafeAdjustWindowRectEx (RECT* lpRect,
49 if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
53 lpRect->right -= lpRect->left;
58 lpRect->bottom -= lpRect->top;
64 /* Forward declarations */
65 static gboolean gdk_window_gravity_works (void);
66 static void gdk_window_set_static_win_gravity (GdkWindow *window,
70 * The following fucntion by The Rasterman <raster@redhat.com>
71 * This function returns the X Window ID in which the x y location is in
72 * (x and y being relative to the root window), excluding any windows listed
73 * in the GList excludes (this is a list of X Window ID's - gpointer being
76 * This is primarily designed for internal gdk use - for DND for example
77 * when using a shaped icon window as the drag object - you exclude the
78 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
79 * You can get back an X Window ID as to what X Window ID is infact under
80 * those X,Y co-ordinates.
83 gdk_window_xid_at_coords (gint x,
89 gboolean warned = FALSE;
93 /* This is probably not correct, just a quick hack */
97 g_warning ("gdk_window_xid_at_coords probably not implemented correctly");
102 return WindowFromPoint (pt);
106 gdk_window_init (void)
112 SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
113 width = r.right - r.left;
114 height = r.bottom - r.top;
116 gdk_root_parent = g_new (GdkWindowPrivate, 1);
117 gdk_root_parent->drawable.xwindow = gdk_root_window;
118 gdk_root_parent->drawable.window_type = GDK_WINDOW_ROOT;
119 gdk_root_parent->drawable.drawable.user_data = NULL;
120 gdk_root_parent->drawable.width = width;
121 gdk_root_parent->drawable.height = height;
122 gdk_root_parent->drawable.ref_count = 1;
123 gdk_root_parent->drawable.colormap = NULL;
124 gdk_root_parent->children = NULL;
126 gdk_xid_table_insert (&gdk_root_window, gdk_root_parent);
130 * is a wrapper function for RegisterWindowClassEx.
131 * It creates at least one unique class for every
132 * GdkWindowType. If support for single window-specific icons
133 * is ever needed (e.g Dialog specific), every such window should
137 RegisterGdkClass(GdkWindowType wtype)
139 static ATOM klassTOPLEVEL = 0;
140 static ATOM klassDIALOG = 0;
141 static ATOM klassCHILD = 0;
142 static ATOM klassTEMP = 0;
143 static HICON hAppIcon = NULL;
144 static WNDCLASSEX wcl;
147 wcl.cbSize = sizeof(WNDCLASSEX);
148 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
149 * on WM_SIZE and WM_MOVE. Flicker, Performance!
151 wcl.lpfnWndProc = gdk_WindowProc;
154 wcl.hInstance = gdk_ProgInstance;
156 /* initialize once! */
159 gchar sLoc [_MAX_PATH+1];
160 HINSTANCE hInst = GetModuleHandle(NULL);
162 if (0 != GetModuleFileName(hInst, sLoc, _MAX_PATH))
164 hAppIcon = ExtractIcon(hInst, sLoc, 0);
167 char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
169 hAppIcon = ExtractIcon(hInst, gdklibname, 0);
174 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
178 wcl.lpszMenuName = NULL;
181 /* initialize once per class */
182 #define ONCE_PER_CLASS() \
183 wcl.hIcon = CopyIcon (hAppIcon); \
184 wcl.hIconSm = CopyIcon (hAppIcon); \
185 wcl.hbrBackground = CreateSolidBrush( RGB(0,0,0)); \
186 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
190 case GDK_WINDOW_TOPLEVEL:
191 if (0 == klassTOPLEVEL)
193 wcl.lpszClassName = "gdkWindowToplevel";
196 klassTOPLEVEL = RegisterClassEx(&wcl);
198 klass = klassTOPLEVEL;
200 case GDK_WINDOW_CHILD:
203 wcl.lpszClassName = "gdkWindowChild";
205 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
207 klassCHILD = RegisterClassEx(&wcl);
211 case GDK_WINDOW_DIALOG:
212 if (0 == klassDIALOG)
214 wcl.lpszClassName = "gdkWindowDialog";
215 wcl.style |= CS_SAVEBITS;
217 klassDIALOG = RegisterClassEx(&wcl);
221 case GDK_WINDOW_TEMP:
224 wcl.lpszClassName = "gdkWindowTemp";
225 wcl.style |= CS_SAVEBITS;
227 klassTEMP = RegisterClassEx(&wcl);
231 case GDK_WINDOW_ROOT:
232 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
234 case GDK_DRAWABLE_PIXMAP:
235 g_error ("cannot make windows of type GDK_DRAWABLE_PIXMAP (use gdk_pixmap_new)");
240 } /* RegisterGdkClass */
244 gdk_window_new (GdkWindow *parent,
245 GdkWindowAttr *attributes,
246 gint attributes_mask)
249 GdkWindowPrivate *private;
250 GdkWindowPrivate *parent_private;
255 DWORD dwStyle, dwExStyle;
266 g_return_val_if_fail (attributes != NULL, NULL);
269 parent = (GdkWindow*) gdk_root_parent;
271 parent_private = (GdkWindowPrivate*) parent;
272 if (GDK_DRAWABLE_DESTROYED (parent))
275 xparent = parent_private->drawable.xwindow;
277 private = g_new (GdkWindowPrivate, 1);
278 window = (GdkWindow*) private;
280 private->parent = parent;
282 private->drawable.destroyed = FALSE;
283 private->mapped = FALSE;
284 private->guffaw_gravity = FALSE;
285 private->resize_count = 0;
286 private->drawable.ref_count = 1;
288 private->x = (attributes_mask & GDK_WA_X) ? attributes->x : 0;
289 private->y = (attributes_mask & GDK_WA_Y) ? attributes->y : 0;
291 private->drawable.width = (attributes->width > 1) ? (attributes->width) : (1);
292 private->drawable.height = (attributes->height > 1) ? (attributes->height) : (1);
293 private->drawable.window_type = attributes->window_type;
294 private->extension_events = 0;
295 private->extension_events_selected = FALSE;
297 private->filters = NULL;
298 private->children = NULL;
300 window->user_data = NULL;
302 if (attributes_mask & GDK_WA_VISUAL)
303 visual = attributes->visual;
305 visual = gdk_visual_get_system ();
306 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
308 if (attributes_mask & GDK_WA_TITLE)
309 title = attributes->title;
311 title = g_get_prgname ();
313 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
314 private->bg_type = GDK_WIN32_BG_NORMAL;
315 private->hint_flags = 0;
316 private->xcursor = NULL;
318 if (parent_private && parent_private->guffaw_gravity)
323 if (attributes->wclass == GDK_INPUT_OUTPUT)
326 if (attributes_mask & GDK_WA_COLORMAP)
327 private->drawable.colormap = attributes->colormap;
329 private->drawable.colormap = gdk_colormap_get_system ();
333 dwExStyle = WS_EX_TRANSPARENT;
334 private->drawable.colormap = NULL;
335 private->bg_type = GDK_WIN32_BG_TRANSPARENT;
336 private->bg_pixmap = NULL;
339 if (attributes_mask & GDK_WA_X)
344 if (attributes_mask & GDK_WA_Y)
346 else if (attributes_mask & GDK_WA_X)
347 y = 100; /* ??? We must put it somewhere... */
349 y = 500; /* x is CW_USEDEFAULT, y doesn't matter then */
352 parent_private->children = g_list_prepend (parent_private->children, window);
354 switch (private->drawable.window_type)
356 case GDK_WINDOW_TOPLEVEL:
357 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
358 xparent = gdk_root_window;
360 case GDK_WINDOW_CHILD:
361 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
363 case GDK_WINDOW_DIALOG:
364 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
365 dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
366 xparent = gdk_root_window;
368 case GDK_WINDOW_TEMP:
369 dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
370 dwExStyle |= WS_EX_TOOLWINDOW;
372 case GDK_WINDOW_ROOT:
373 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
375 case GDK_DRAWABLE_PIXMAP:
376 g_error ("cannot make windows of type GDK_DRAWABLE_PIXMAP (use gdk_pixmap_new)");
380 klass = RegisterGdkClass (private->drawable.window_type);
382 g_error ("RegisterClassEx failed");
384 if (private->drawable.window_type != GDK_WINDOW_CHILD)
386 if (x == CW_USEDEFAULT)
397 rect.right = rect.left + private->drawable.width;
398 rect.bottom = rect.top + private->drawable.height;
400 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
401 g_warning ("gdk_window_new: AdjustWindowRectEx failed");
403 if (x != CW_USEDEFAULT)
408 width = rect.right - rect.left;
409 height = rect.bottom - rect.top;
413 width = private->drawable.width;
414 height = private->drawable.height;
418 private->input_locale = GetKeyboardLayout (0);
419 TranslateCharsetInfo ((DWORD FAR *) acp,
420 &private->charset_info,
423 titlelen = strlen (title);
424 wctitle = g_new (wchar_t, titlelen);
425 mbtitle = g_new (char, 3*titlelen + 1);
426 wlen = gdk_nmbstowchar_ts (wctitle, title, titlelen, titlelen);
427 WideCharToMultiByte (GetACP (), 0, wctitle, wlen,
428 mbtitle, 3*titlelen, NULL, NULL);
430 private->drawable.xwindow =
431 CreateWindowEx (dwExStyle,
432 MAKEINTRESOURCE(klass),
445 if (private->drawable.xwindow == NULL)
447 g_warning ("gdk_window_create: CreateWindowEx failed");
453 g_print ("gdk_window_create: %s %s %dx%d@+%d+%d %#x = %#x\n"
454 "...locale %#x codepage %d\n",
455 (private->drawable.window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
456 (private->drawable.window_type == GDK_WINDOW_CHILD ? "CHILD" :
457 (private->drawable.window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
458 (private->drawable.window_type == GDK_WINDOW_TEMP ? "TEMP" :
461 width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
463 private->drawable.xwindow,
464 private->input_locale,
465 private->charset_info.ciACP));
467 gdk_window_ref (window);
468 gdk_xid_table_insert (&private->drawable.xwindow, window);
470 if (private->drawable.colormap)
471 gdk_colormap_ref (private->drawable.colormap);
473 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
474 (attributes->cursor) :
481 gdk_window_foreign_new (guint32 anid)
484 GdkWindowPrivate *private;
485 GdkWindowPrivate *parent_private;
490 private = g_new (GdkWindowPrivate, 1);
491 window = (GdkWindow*) private;
493 parent = GetParent ((HWND) anid);
494 private->parent = gdk_xid_table_lookup (parent);
496 parent_private = (GdkWindowPrivate *)private->parent;
499 parent_private->children = g_list_prepend (parent_private->children, window);
501 private->drawable.xwindow = (HWND) anid;
502 GetClientRect ((HWND) anid, &rect);
504 point.y = rect.right;
505 ClientToScreen ((HWND) anid, &point);
506 if (parent != GetDesktopWindow ())
507 ScreenToClient (parent, &point);
508 private->x = point.x;
509 private->y = point.y;
510 private->drawable.width = rect.right - rect.left;
511 private->drawable.height = rect.bottom - rect.top;
512 private->resize_count = 0;
513 private->drawable.ref_count = 1;
514 private->drawable.window_type = GDK_WINDOW_FOREIGN;
515 private->drawable.destroyed = FALSE;
516 private->mapped = IsWindowVisible (private->drawable.xwindow);
517 private->guffaw_gravity = FALSE;
518 private->extension_events = 0;
519 private->extension_events_selected = FALSE;
521 private->drawable.colormap = NULL;
523 private->filters = NULL;
524 private->children = NULL;
526 window->user_data = NULL;
528 gdk_window_ref (window);
529 gdk_xid_table_insert (&private->drawable.xwindow, window);
534 /* Call this function when you want a window and all its children to
535 * disappear. When xdestroy is true, a request to destroy the XWindow
536 * is sent out. When it is false, it is assumed that the XWindow has
537 * been or will be destroyed by destroying some ancestor of this
541 gdk_window_internal_destroy (GdkWindow *window,
543 gboolean our_destroy)
545 GdkWindowPrivate *private;
546 GdkWindowPrivate *temp_private;
547 GdkWindow *temp_window;
551 g_return_if_fail (window != NULL);
553 private = (GdkWindowPrivate*) window;
555 GDK_NOTE (MISC, g_print ("gdk_window_internal_destroy %#x\n",
556 private->drawable.xwindow));
558 switch (private->drawable.window_type)
560 case GDK_WINDOW_TOPLEVEL:
561 case GDK_WINDOW_CHILD:
562 case GDK_WINDOW_DIALOG:
563 case GDK_WINDOW_TEMP:
564 case GDK_WINDOW_FOREIGN:
565 if (!private->drawable.destroyed)
569 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
570 if (parent_private->children)
571 parent_private->children = g_list_remove (parent_private->children, window);
574 if (GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_FOREIGN)
576 children = tmp = private->children;
577 private->children = NULL;
581 temp_window = tmp->data;
584 temp_private = (GdkWindowPrivate*) temp_window;
586 gdk_window_internal_destroy (temp_window, FALSE,
590 g_list_free (children);
593 if (private->extension_events != 0)
594 gdk_input_window_destroy (window);
596 if (private->filters)
598 tmp = private->filters;
606 g_list_free (private->filters);
607 private->filters = NULL;
610 if (private->drawable.window_type == GDK_WINDOW_FOREIGN)
612 if (our_destroy && (private->parent != NULL))
614 /* It's somebody elses window, but in our hierarchy,
615 * so reparent it to the root window, and then send
616 * it a delete event, as if we were a WM
618 gdk_window_hide (window);
619 gdk_window_reparent (window, NULL, 0, 0);
621 /* Is this too drastic? Many (most?) applications
622 * quit if any window receives WM_QUIT I think.
623 * OTOH, I don't think foreign windows are much
624 * used, so the question is maybe academic.
626 PostMessage (private->drawable.xwindow, WM_QUIT, 0, 0);
630 DestroyWindow (private->drawable.xwindow);
632 if (private->drawable.colormap)
633 gdk_colormap_unref (private->drawable.colormap);
635 private->mapped = FALSE;
636 private->drawable.destroyed = TRUE;
640 case GDK_WINDOW_ROOT:
641 g_error ("attempted to destroy root window");
644 case GDK_DRAWABLE_PIXMAP:
645 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
650 /* Like internal_destroy, but also destroys the reference created by
654 gdk_window_destroy (GdkWindow *window)
656 gdk_window_internal_destroy (window, TRUE, TRUE);
657 gdk_window_unref (window);
660 /* This function is called when the XWindow is really gone. */
663 gdk_window_destroy_notify (GdkWindow *window)
665 g_return_if_fail (window != NULL);
667 GDK_NOTE (EVENTS, g_print ("gdk_window_destroy_notify: %#x %d\n",
668 GDK_DRAWABLE_XID (window), GDK_DRAWABLE_DESTROYED (window)));
670 if (!GDK_DRAWABLE_DESTROYED (window))
672 if (GDK_DRAWABLE_TYPE(window) != GDK_WINDOW_FOREIGN)
673 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_DRAWABLE_XID (window));
675 gdk_window_internal_destroy (window, FALSE, FALSE);
678 gdk_xid_table_remove (GDK_DRAWABLE_XID (window));
679 gdk_window_unref (window);
683 gdk_window_ref (GdkWindow *window)
685 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
686 g_return_val_if_fail (window != NULL, NULL);
688 private->drawable.ref_count += 1;
690 GDK_NOTE (MISC, g_print ("gdk_window_ref %#x %d\n",
691 GDK_DRAWABLE_XID (window),
692 private->drawable.ref_count));
698 gdk_window_unref (GdkWindow *window)
700 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
701 g_return_if_fail (window != NULL);
703 private->drawable.ref_count -= 1;
705 GDK_NOTE (MISC, g_print ("gdk_window_unref %#x %d%s\n",
706 private->drawable.xwindow,
707 private->drawable.ref_count,
708 (private->drawable.ref_count == 0 ? " freeing" : "")));
710 if (private->drawable.ref_count == 0)
712 if (private->bg_type == GDK_WIN32_BG_PIXMAP
713 && private->bg_pixmap != NULL)
714 gdk_pixmap_unref (private->bg_pixmap);
716 if (!private->drawable.destroyed)
718 if (private->drawable.window_type == GDK_WINDOW_FOREIGN)
719 gdk_xid_table_remove (private->drawable.xwindow);
721 g_warning ("losing last reference to undestroyed window");
723 g_dataset_destroy (window);
729 gdk_window_show (GdkWindow *window)
731 GdkWindowPrivate *private;
733 g_return_if_fail (window != NULL);
735 private = (GdkWindowPrivate*) window;
736 if (!private->drawable.destroyed)
738 GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n",
739 private->drawable.xwindow));
741 private->mapped = TRUE;
742 if (private->drawable.window_type == GDK_WINDOW_TEMP)
744 ShowWindow (private->drawable.xwindow, SW_SHOWNOACTIVATE);
745 SetWindowPos (private->drawable.xwindow, HWND_TOPMOST, 0, 0, 0, 0,
746 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
748 ShowWindow (private->drawable.xwindow, SW_HIDE); /* Don't put on toolbar */
753 ShowWindow (private->drawable.xwindow, SW_SHOWNORMAL);
754 ShowWindow (private->drawable.xwindow, SW_RESTORE);
755 SetForegroundWindow (private->drawable.xwindow);
756 BringWindowToTop (private->drawable.xwindow);
758 ShowOwnedPopups (private->drawable.xwindow, TRUE);
765 gdk_window_hide (GdkWindow *window)
767 GdkWindowPrivate *private;
769 g_return_if_fail (window != NULL);
771 private = (GdkWindowPrivate*) window;
772 if (!private->drawable.destroyed)
774 GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n",
775 private->drawable.xwindow));
777 private->mapped = FALSE;
778 if (private->drawable.window_type == GDK_WINDOW_TOPLEVEL)
779 ShowOwnedPopups (private->drawable.xwindow, FALSE);
781 ShowWindow (private->drawable.xwindow, SW_HIDE);
783 ShowWindow (private->drawable.xwindow, SW_MINIMIZE);
785 CloseWindow (private->drawable.xwindow);
791 gdk_window_withdraw (GdkWindow *window)
793 GdkWindowPrivate *private;
795 g_return_if_fail (window != NULL);
797 private = (GdkWindowPrivate*) window;
798 if (!private->drawable.destroyed)
800 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n",
801 private->drawable.xwindow));
803 gdk_window_hide (window); /* XXX */
808 gdk_window_move (GdkWindow *window,
812 GdkWindowPrivate *private;
814 g_return_if_fail (window != NULL);
816 private = (GdkWindowPrivate*) window;
817 if (!private->drawable.destroyed)
821 GDK_NOTE (MISC, g_print ("gdk_window_move: %#x +%d+%d\n",
822 private->drawable.xwindow, x, y));
824 GetClientRect (private->drawable.xwindow, &rect);
826 if (private->drawable.window_type != GDK_WINDOW_CHILD)
834 ClientToScreen (private->drawable.xwindow, &ptTL);
839 ptBR.y = rect.bottom;
840 ClientToScreen (private->drawable.xwindow, &ptBR);
841 rect.right = x + ptBR.x - ptTL.x;
842 rect.bottom = y + ptBR.y - ptTL.y;
844 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
845 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
846 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
847 g_warning ("gdk_window_move: AdjustWindowRectEx failed");
857 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
858 private->drawable.xwindow,
859 rect.right - rect.left, rect.bottom - rect.top,
861 if (!MoveWindow (private->drawable.xwindow,
862 x, y, rect.right - rect.left, rect.bottom - rect.top,
864 g_warning ("gdk_window_move: MoveWindow failed");
869 gdk_window_resize (GdkWindow *window,
873 GdkWindowPrivate *private;
875 g_return_if_fail (window != NULL);
877 if ((gint16) width < 1)
879 if ((gint16) height < 1)
882 private = (GdkWindowPrivate*) window;
884 if (!private->drawable.destroyed &&
885 ((private->resize_count > 0) ||
886 (private->drawable.width != (guint16) width) ||
887 (private->drawable.height != (guint16) height)))
891 GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
892 private->drawable.xwindow, width, height));
894 if (private->drawable.window_type != GDK_WINDOW_CHILD)
903 ClientToScreen (private->drawable.xwindow, &pt);
906 rect.right = pt.x + width;
907 rect.bottom = pt.y + height;
909 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
910 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
911 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
912 g_warning ("gdk_window_resize: AdjustWindowRectEx failed");
916 width = rect.right - rect.left;
917 height = rect.bottom - rect.top;
923 private->drawable.width = width;
924 private->drawable.height = height;
927 private->resize_count += 1;
929 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
930 private->drawable.xwindow, width, height, x, y));
931 if (!MoveWindow (private->drawable.xwindow,
934 g_warning ("gdk_window_resize: MoveWindow failed");
939 gdk_window_move_resize (GdkWindow *window,
945 GdkWindowPrivate *private;
947 g_return_if_fail (window != NULL);
949 if ((gint16) width < 1)
951 if ((gint16) height < 1)
954 private = (GdkWindowPrivate*) window;
955 if (!private->drawable.destroyed)
961 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
962 private->drawable.xwindow, width, height, x, y));
966 rect.right = x + width;
967 rect.bottom = y + height;
969 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
970 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
971 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
972 g_warning ("gdk_window_move_resize: AdjustWindowRectEx failed");
974 if (private->drawable.window_type == GDK_WINDOW_CHILD)
978 private->drawable.width = width;
979 private->drawable.height = height;
981 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
982 private->drawable.xwindow,
983 rect.right - rect.left, rect.bottom - rect.top,
984 rect.left, rect.top));
985 if (!MoveWindow (private->drawable.xwindow,
987 rect.right - rect.left, rect.bottom - rect.top,
989 g_warning ("gdk_window_move_resize: MoveWindow failed");
991 if (private->guffaw_gravity)
993 GList *tmp_list = private->children;
996 GdkWindowPrivate *child_private = tmp_list->data;
998 child_private->x -= x - private->x;
999 child_private->y -= y - private->y;
1001 tmp_list = tmp_list->next;
1009 gdk_window_reparent (GdkWindow *window,
1010 GdkWindow *new_parent,
1014 GdkWindowPrivate *window_private;
1015 GdkWindowPrivate *parent_private;
1016 GdkWindowPrivate *old_parent_private;
1018 g_return_if_fail (window != NULL);
1021 new_parent = (GdkWindow*) gdk_root_parent;
1023 window_private = (GdkWindowPrivate*) window;
1024 old_parent_private = (GdkWindowPrivate*)window_private->parent;
1025 parent_private = (GdkWindowPrivate*) new_parent;
1027 if (!window_private->drawable.destroyed && !parent_private->drawable.destroyed)
1029 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
1030 window_private->drawable.xwindow,
1031 parent_private->drawable.xwindow));
1032 if (!SetParent (window_private->drawable.xwindow, parent_private->drawable.xwindow))
1033 g_warning ("gdk_window_reparent: SetParent failed");
1035 if (!MoveWindow (window_private->drawable.xwindow,
1037 window_private->drawable.width, window_private->drawable.height,
1039 g_warning ("gdk_window_reparent: MoveWindow failed");
1042 window_private->parent = new_parent;
1044 if (old_parent_private)
1045 old_parent_private->children = g_list_remove (old_parent_private->children, window);
1047 if ((old_parent_private &&
1048 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1049 (!old_parent_private && parent_private->guffaw_gravity))
1050 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1052 parent_private->children = g_list_prepend (parent_private->children, window);
1056 gdk_window_clear (GdkWindow *window)
1058 g_return_if_fail (window != NULL);
1059 g_return_if_fail (GDK_IS_WINDOW (window));
1061 if (!GDK_DRAWABLE_DESTROYED (window))
1062 gdk_window_clear_area (window, 0, 0, -1, -1);
1067 gdk_window_clear_area (GdkWindow *window,
1073 g_return_if_fail (window != NULL);
1074 g_return_if_fail (GDK_IS_WINDOW (window));
1076 if (!GDK_DRAWABLE_DESTROYED (window))
1081 width = G_MAXSHORT/2; /* Yeah, right */
1083 height = G_MAXSHORT/2;
1084 GDK_NOTE (MISC, g_print ("gdk_window_clear_area: %#x %dx%d@+%d+%d\n",
1085 GDK_DRAWABLE_XID (window), width, height, x, y));
1086 hdc = GetDC (GDK_DRAWABLE_XID (window));
1087 IntersectClipRect (hdc, x, y, x + width, y + height);
1088 SendMessage (GDK_DRAWABLE_XID (window), WM_ERASEBKGND, (WPARAM) hdc, 0);
1089 ReleaseDC (GDK_DRAWABLE_XID (window), hdc);
1094 gdk_window_clear_area_e (GdkWindow *window,
1100 g_return_if_fail (window != NULL);
1101 g_return_if_fail (GDK_IS_WINDOW (window));
1103 if (!GDK_DRAWABLE_DESTROYED (window))
1107 GDK_NOTE (MISC, g_print ("gdk_window_clear_area_e: %#x %dx%d@+%d+%d\n",
1108 GDK_DRAWABLE_XID (window), width, height, x, y));
1111 rect.right = x + width;
1113 rect.bottom = y + height;
1114 if (!InvalidateRect (GDK_DRAWABLE_XID (window), &rect, TRUE))
1115 g_warning ("gdk_window_clear_area_e: InvalidateRect failed");
1116 UpdateWindow (GDK_DRAWABLE_XID (window));
1121 gdk_window_raise (GdkWindow *window)
1123 g_return_if_fail (window != NULL);
1124 g_return_if_fail (GDK_IS_WINDOW (window));
1126 if (!GDK_DRAWABLE_DESTROYED (window))
1128 GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n",
1129 GDK_DRAWABLE_XID (window)));
1131 if (!BringWindowToTop (GDK_DRAWABLE_XID (window)))
1132 g_warning ("gdk_window_raise: BringWindowToTop failed");
1137 gdk_window_lower (GdkWindow *window)
1139 g_return_if_fail (window != NULL);
1140 g_return_if_fail (GDK_IS_WINDOW (window));
1142 if (!GDK_DRAWABLE_DESTROYED (window))
1144 GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n",
1145 GDK_DRAWABLE_XID (window)));
1147 if (!SetWindowPos (GDK_DRAWABLE_XID (window), HWND_BOTTOM, 0, 0, 0, 0,
1148 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1149 g_warning ("gdk_window_lower: SetWindowPos failed");
1154 gdk_window_set_user_data (GdkWindow *window,
1157 g_return_if_fail (window != NULL);
1159 window->user_data = user_data;
1163 gdk_window_set_hints (GdkWindow *window,
1172 GdkWindowPrivate *private;
1173 WINDOWPLACEMENT size_hints;
1179 g_return_if_fail (window != NULL);
1180 g_return_if_fail (GDK_IS_WINDOW (window));
1182 if (GDK_DRAWABLE_DESTROYED (window))
1185 private = (GdkWindowPrivate*) window;
1187 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1188 private->drawable.xwindow,
1189 min_width, min_height, max_width, max_height,
1192 private->hint_flags = flags;
1193 size_hints.length = sizeof (size_hints);
1197 if (flags & GDK_HINT_POS)
1198 if (!GetWindowPlacement (private->drawable.xwindow, &size_hints))
1199 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1202 GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1203 " (%d,%d)--(%d,%d)\n",
1204 size_hints.rcNormalPosition.left,
1205 size_hints.rcNormalPosition.top,
1206 size_hints.rcNormalPosition.right,
1207 size_hints.rcNormalPosition.bottom));
1208 /* What are the corresponding window coordinates for client
1209 * area coordinates x, y
1213 rect.right = rect.left + 200; /* dummy */
1214 rect.bottom = rect.top + 200;
1215 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
1216 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
1217 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1218 size_hints.flags = 0;
1219 size_hints.showCmd = SW_SHOWNA;
1221 /* Set the normal position hint to that location, with unchanged
1224 diff = size_hints.rcNormalPosition.left - rect.left;
1225 size_hints.rcNormalPosition.left = rect.left;
1226 size_hints.rcNormalPosition.right -= diff;
1227 diff = size_hints.rcNormalPosition.top - rect.top;
1228 size_hints.rcNormalPosition.top = rect.top;
1229 size_hints.rcNormalPosition.bottom -= diff;
1230 GDK_NOTE (MISC, g_print ("...setting: (%d,%d)--(%d,%d)\n",
1231 size_hints.rcNormalPosition.left,
1232 size_hints.rcNormalPosition.top,
1233 size_hints.rcNormalPosition.right,
1234 size_hints.rcNormalPosition.bottom));
1235 if (!SetWindowPlacement (private->drawable.xwindow, &size_hints))
1236 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1237 private->hint_x = rect.left;
1238 private->hint_y = rect.top;
1241 if (flags & GDK_HINT_MIN_SIZE)
1245 rect.right = min_width;
1246 rect.bottom = min_height;
1247 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
1248 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
1249 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1250 private->hint_min_width = rect.right - rect.left;
1251 private->hint_min_height = rect.bottom - rect.top;
1253 /* Also chek if he current size of the window is in bounds. */
1254 GetClientRect (private->drawable.xwindow, &rect);
1255 if (rect.right < min_width && rect.bottom < min_height)
1256 gdk_window_resize (window, min_width, min_height);
1257 else if (rect.right < min_width)
1258 gdk_window_resize (window, min_width, rect.bottom);
1259 else if (rect.bottom < min_height)
1260 gdk_window_resize (window, rect.right, min_height);
1262 if (flags & GDK_HINT_MAX_SIZE)
1266 rect.right = max_width;
1267 rect.bottom = max_height;
1268 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
1269 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
1270 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1271 private->hint_max_width = rect.right - rect.left;
1272 private->hint_max_height = rect.bottom - rect.top;
1273 /* Again, check if the window is too large currently. */
1274 GetClientRect (private->drawable.xwindow, &rect);
1275 if (rect.right > max_width && rect.bottom > max_height)
1276 gdk_window_resize (window, max_width, max_height);
1277 else if (rect.right > max_width)
1278 gdk_window_resize (window, max_width, rect.bottom);
1279 else if (rect.bottom > max_height)
1280 gdk_window_resize (window, rect.right, max_height);
1286 gdk_window_set_geometry_hints (GdkWindow *window,
1287 GdkGeometry *geometry,
1288 GdkWindowHints geom_mask)
1290 GdkWindowPrivate *private;
1291 WINDOWPLACEMENT size_hints;
1297 g_return_if_fail (window != NULL);
1298 g_return_if_fail (GDK_IS_WINDOW (window));
1300 if (GDK_DRAWABLE_DESTROYED (window))
1303 private = (GdkWindowPrivate*) window;
1305 size_hints.length = sizeof (size_hints);
1307 private->hint_flags = geom_mask;
1309 if (geom_mask & GDK_HINT_POS)
1312 if (geom_mask & GDK_HINT_MIN_SIZE)
1316 rect.right = geometry->min_width;
1317 rect.bottom = geometry->min_height;
1318 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
1319 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
1320 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1321 private->hint_min_width = rect.right - rect.left;
1322 private->hint_min_height = rect.bottom - rect.top;
1324 /* Also check if he current size of the window is in bounds */
1325 GetClientRect (private->drawable.xwindow, &rect);
1326 if (rect.right < geometry->min_width
1327 && rect.bottom < geometry->min_height)
1328 gdk_window_resize (window, geometry->min_width, geometry->min_height);
1329 else if (rect.right < geometry->min_width)
1330 gdk_window_resize (window, geometry->min_width, rect.bottom);
1331 else if (rect.bottom < geometry->min_height)
1332 gdk_window_resize (window, rect.right, geometry->min_height);
1335 if (geom_mask & GDK_HINT_MAX_SIZE)
1339 rect.right = geometry->max_width;
1340 rect.bottom = geometry->max_height;
1341 dwStyle = GetWindowLong (private->drawable.xwindow, GWL_STYLE);
1342 dwExStyle = GetWindowLong (private->drawable.xwindow, GWL_EXSTYLE);
1343 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1344 private->hint_max_width = rect.right - rect.left;
1345 private->hint_max_height = rect.bottom - rect.top;
1347 /* Again, check if the window is too large currently. */
1348 GetClientRect (private->drawable.xwindow, &rect);
1349 if (rect.right > geometry->max_width
1350 && rect.bottom > geometry->max_height)
1351 gdk_window_resize (window, geometry->max_width, geometry->max_height);
1352 else if (rect.right > geometry->max_width)
1353 gdk_window_resize (window, geometry->max_width, rect.bottom);
1354 else if (rect.bottom > geometry->max_height)
1355 gdk_window_resize (window, rect.right, geometry->max_height);
1358 /* I don't know what to do when called with zero base_width and height. */
1359 if (geom_mask & GDK_HINT_BASE_SIZE
1360 && geometry->base_width > 0
1361 && geometry->base_height > 0)
1362 if (!GetWindowPlacement (private->drawable.xwindow, &size_hints))
1363 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1366 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1367 " rcNormalPosition: (%d,%d)--(%d,%d)\n",
1368 size_hints.rcNormalPosition.left,
1369 size_hints.rcNormalPosition.top,
1370 size_hints.rcNormalPosition.right,
1371 size_hints.rcNormalPosition.bottom));
1372 size_hints.rcNormalPosition.right =
1373 size_hints.rcNormalPosition.left + geometry->base_width;
1374 size_hints.rcNormalPosition.bottom =
1375 size_hints.rcNormalPosition.top + geometry->base_height;
1376 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
1377 size_hints.rcNormalPosition.left,
1378 size_hints.rcNormalPosition.top,
1379 size_hints.rcNormalPosition.right,
1380 size_hints.rcNormalPosition.bottom));
1381 if (!SetWindowPlacement (private->drawable.xwindow, &size_hints))
1382 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1385 if (geom_mask & GDK_HINT_RESIZE_INC)
1390 if (geom_mask & GDK_HINT_ASPECT)
1397 gdk_window_set_title (GdkWindow *window,
1405 g_return_if_fail (window != NULL);
1406 g_return_if_fail (GDK_IS_WINDOW (window));
1408 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
1409 GDK_DRAWABLE_XID (window), title));
1410 if (!GDK_DRAWABLE_DESTROYED (window))
1412 /* As the title most is in UTF-8 we must translate it
1413 * to the system codepage.
1415 titlelen = strlen (title);
1416 wcstr = g_new (wchar_t, titlelen);
1417 mbstr = g_new (char, 3*titlelen + 1);
1418 wlen = gdk_nmbstowchar_ts (wcstr, title, titlelen, titlelen);
1419 WideCharToMultiByte (GetACP (), 0, wcstr, wlen,
1420 mbstr, 3*titlelen, NULL, NULL);
1422 if (!SetWindowText (GDK_DRAWABLE_XID (window), mbstr))
1423 g_warning ("gdk_window_set_title: SetWindowText failed");
1431 gdk_window_set_role (GdkWindow *window,
1434 g_return_if_fail (window != NULL);
1435 g_return_if_fail (GDK_IS_WINDOW (window));
1437 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1438 GDK_DRAWABLE_XID (window), (role ? role : "NULL")));
1443 gdk_window_set_transient_for (GdkWindow *window,
1446 g_return_if_fail (window != NULL);
1447 g_return_if_fail (GDK_IS_WINDOW (window));
1449 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1450 GDK_DRAWABLE_XID (window),
1451 GDK_DRAWABLE_XID (parent)));
1456 gdk_window_set_background (GdkWindow *window,
1459 GdkWindowPrivate *private;
1461 g_return_if_fail (window != NULL);
1462 g_return_if_fail (GDK_IS_WINDOW (window));
1464 private = (GdkWindowPrivate*) window;
1465 if (!GDK_DRAWABLE_DESTROYED (window))
1467 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1468 private->drawable.xwindow,
1469 gdk_color_to_string (color)));
1471 if (private->bg_type == GDK_WIN32_BG_PIXMAP)
1473 if (private->bg_pixmap != NULL)
1475 gdk_pixmap_unref (private->bg_pixmap);
1476 private->bg_pixmap = NULL;
1478 private->bg_type = GDK_WIN32_BG_NORMAL;
1480 private->bg_type = GDK_WIN32_BG_PIXEL;
1481 private->bg_pixel = *color;
1486 gdk_window_set_back_pixmap (GdkWindow *window,
1488 gint parent_relative)
1490 GdkWindowPrivate *private;
1492 g_return_if_fail (window != NULL);
1493 g_return_if_fail (GDK_IS_WINDOW (window));
1495 private = (GdkWindowPrivate*) window;
1497 if (!GDK_DRAWABLE_DESTROYED (window))
1499 if (private->bg_type == GDK_WIN32_BG_PIXMAP)
1501 if (private->bg_pixmap != NULL)
1503 gdk_pixmap_unref (private->bg_pixmap);
1504 private->bg_pixmap = NULL;
1506 private->bg_type = GDK_WIN32_BG_NORMAL;
1508 if (parent_relative)
1510 private->bg_type = GDK_WIN32_BG_PARENT_RELATIVE;
1518 /* We must cache the pixmap in the WindowPrivate and
1519 * paint it each time we get WM_ERASEBKGND
1521 private->bg_type = GDK_WIN32_BG_PIXMAP;
1522 private->bg_pixmap = pixmap;
1523 gdk_pixmap_ref (pixmap);
1529 gdk_window_set_cursor (GdkWindow *window,
1532 GdkWindowPrivate *window_private;
1533 GdkCursorPrivate *cursor_private;
1536 g_return_if_fail (window != NULL);
1537 g_return_if_fail (GDK_IS_WINDOW (window));
1539 window_private = (GdkWindowPrivate*) window;
1540 cursor_private = (GdkCursorPrivate*) cursor;
1542 if (!GDK_DRAWABLE_DESTROYED (window))
1545 xcursor = LoadCursor (NULL, IDC_ARROW);
1547 xcursor = cursor_private->xcursor;
1549 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1550 window_private->drawable.xwindow, xcursor));
1551 window_private->xcursor = xcursor;
1556 gdk_window_get_user_data (GdkWindow *window,
1559 g_return_if_fail (window != NULL);
1561 *data = window->user_data;
1565 gdk_window_get_geometry (GdkWindow *window,
1572 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1575 window = (GdkWindow*) gdk_root_parent;
1577 if (!GDK_DRAWABLE_DESTROYED (window))
1581 if (!GetClientRect (GDK_DRAWABLE_XID (window), &rect))
1582 g_warning ("gdk_window_get_geometry: GetClientRect failed");
1589 *width = rect.right - rect.left;
1591 *height = rect.bottom - rect.top;
1593 *depth = gdk_drawable_get_visual (window)->depth;
1598 gdk_window_get_position (GdkWindow *window,
1602 GdkWindowPrivate *window_private;
1604 g_return_if_fail (window != NULL);
1605 g_return_if_fail (GDK_IS_WINDOW (window));
1607 window_private = (GdkWindowPrivate*) window;
1610 *x = window_private->x;
1612 *y = window_private->y;
1616 gdk_window_get_origin (GdkWindow *window,
1624 g_return_val_if_fail (window != NULL, 0);
1626 if (!GDK_DRAWABLE_DESTROYED (window))
1632 ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
1645 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
1646 GDK_DRAWABLE_XID (window), tx, ty));
1651 gdk_window_get_deskrelative_origin (GdkWindow *window,
1655 return gdk_window_get_origin (window, x, y);
1659 gdk_window_get_root_origin (GdkWindow *window,
1663 GdkWindowPrivate *private;
1666 g_return_if_fail (window != NULL);
1667 g_return_if_fail (GDK_IS_WINDOW (window));
1669 private = (GdkWindowPrivate*) window;
1674 if (GDK_DRAWABLE_DESTROYED (window))
1677 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1678 private = (GdkWindowPrivate*) private->parent;
1679 if (private->drawable.destroyed)
1684 ClientToScreen (private->drawable.xwindow, &pt);
1690 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%d+%d\n",
1691 GDK_DRAWABLE_XID (window),
1692 private->drawable.xwindow, pt.x, pt.y));
1696 gdk_window_get_pointer (GdkWindow *window,
1699 GdkModifierType *mask)
1701 GdkWindow *return_val;
1702 POINT pointc, point;
1705 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1708 window = (GdkWindow*) gdk_root_parent;
1711 GetCursorPos (&pointc);
1713 ScreenToClient (GDK_DRAWABLE_XID (window), &point);
1720 hwnd = WindowFromPoint (point);
1722 ScreenToClient (hwnd, &point);
1725 hwndc = ChildWindowFromPoint (hwnd, point);
1726 ClientToScreen (hwnd, &point);
1727 ScreenToClient (hwndc, &point);
1728 } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1730 return_val = gdk_window_lookup (hwnd);
1736 GetKeyboardState (kbd);
1738 if (kbd[VK_SHIFT] & 0x80)
1739 *mask |= GDK_SHIFT_MASK;
1740 if (kbd[VK_CAPITAL] & 0x80)
1741 *mask |= GDK_LOCK_MASK;
1742 if (kbd[VK_CONTROL] & 0x80)
1743 *mask |= GDK_CONTROL_MASK;
1744 if (kbd[VK_MENU] & 0x80)
1745 *mask |= GDK_MOD1_MASK;
1746 if (kbd[VK_LBUTTON] & 0x80)
1747 *mask |= GDK_BUTTON1_MASK;
1748 if (kbd[VK_MBUTTON] & 0x80)
1749 *mask |= GDK_BUTTON2_MASK;
1750 if (kbd[VK_RBUTTON] & 0x80)
1751 *mask |= GDK_BUTTON3_MASK;
1758 gdk_window_at_pointer (gint *win_x,
1762 POINT point, pointc;
1766 GetCursorPos (&pointc);
1768 hwnd = WindowFromPoint (point);
1772 window = (GdkWindow *) gdk_root_parent;
1780 ScreenToClient (hwnd, &point);
1783 hwndc = ChildWindowFromPoint (hwnd, point);
1784 ClientToScreen (hwnd, &point);
1785 ScreenToClient (hwndc, &point);
1786 } while (hwndc != hwnd && (hwnd = hwndc, 1));
1788 window = gdk_window_lookup (hwnd);
1790 if (window && (win_x || win_y))
1792 GetClientRect (hwnd, &rect);
1794 *win_x = point.x - rect.left;
1796 *win_y = point.y - rect.top;
1799 GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%d+%d %#x%s\n",
1800 point.x, point.y, hwnd,
1801 (window == NULL ? " NULL" : "")));
1807 gdk_window_get_parent (GdkWindow *window)
1809 g_return_val_if_fail (window != NULL, NULL);
1810 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1812 return ((GdkWindowPrivate*) window)->parent;
1816 gdk_window_get_toplevel (GdkWindow *window)
1818 g_return_val_if_fail (window != NULL, NULL);
1819 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1821 while (GDK_DRAWABLE_TYPE (window) == GDK_WINDOW_CHILD)
1822 window = ((GdkWindowPrivate*) window)->parent;
1828 gdk_window_get_children (GdkWindow *window)
1830 GdkWindowPrivate *private;
1833 g_return_val_if_fail (window != NULL, NULL);
1834 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1836 if (GDK_DRAWABLE_DESTROYED (window))
1840 g_warning ("gdk_window_get_children not implemented");
1847 gdk_window_get_events (GdkWindow *window)
1849 GdkWindowPrivate *private;
1851 g_return_val_if_fail (window != NULL, 0);
1852 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1854 private = (GdkWindowPrivate*) window;
1855 if (GDK_DRAWABLE_DESTROYED (window))
1858 return private->event_mask;
1862 gdk_window_set_events (GdkWindow *window,
1863 GdkEventMask event_mask)
1865 GdkWindowPrivate *private;
1867 g_return_if_fail (window != NULL);
1868 g_return_if_fail (GDK_IS_WINDOW (window));
1870 private = (GdkWindowPrivate*) window;
1871 if (GDK_DRAWABLE_DESTROYED (window))
1874 private->event_mask = event_mask;
1878 gdk_window_add_colormap_windows (GdkWindow *window)
1880 g_warning ("gdk_window_add_colormap_windows not implemented");
1884 gdk_window_shape_combine_mask (GdkWindow *window,
1888 g_return_if_fail (window != NULL);
1889 g_return_if_fail (GDK_IS_WINDOW (window));
1893 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
1894 GDK_DRAWABLE_XID (window)));
1895 SetWindowRgn (GDK_DRAWABLE_XID (window), NULL, TRUE);
1899 GdkDrawablePrivate *pixmap_private;
1905 /* Convert mask bitmap to region */
1906 pixmap_private = (GdkDrawablePrivate*) mask;
1907 hrgn = BitmapToRegion (pixmap_private->xwindow);
1909 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
1910 GDK_DRAWABLE_XID (window),
1911 pixmap_private->xwindow));
1913 /* SetWindowRgn wants window (not client) coordinates */
1914 dwStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
1915 dwExStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
1916 GetClientRect (GDK_DRAWABLE_XID (window), &rect);
1917 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1918 OffsetRgn (hrgn, -rect.left, -rect.top);
1920 OffsetRgn (hrgn, x, y);
1922 /* If this is a top-level window, add the title bar to the region */
1923 if (GDK_DRAWABLE_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1925 CombineRgn (hrgn, hrgn,
1926 CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
1930 SetWindowRgn (GDK_DRAWABLE_XID (window), hrgn, TRUE);
1935 gdk_window_add_filter (GdkWindow *window,
1936 GdkFilterFunc function,
1939 GdkWindowPrivate *private;
1941 GdkEventFilter *filter;
1943 g_return_if_fail (window != NULL);
1944 g_return_if_fail (GDK_IS_WINDOW (window));
1946 private = (GdkWindowPrivate*) window;
1947 if (private && GDK_DRAWABLE_DESTROYED (window))
1950 tmp_list = private->filters;
1954 filter = (GdkEventFilter *)tmp_list->data;
1955 if ((filter->function == function) && (filter->data == data))
1957 tmp_list = tmp_list->next;
1960 filter = g_new (GdkEventFilter, 1);
1961 filter->function = function;
1962 filter->data = data;
1964 private->filters = g_list_append (private->filters, filter);
1968 gdk_window_remove_filter (GdkWindow *window,
1969 GdkFilterFunc function,
1972 GdkWindowPrivate *private;
1973 GList *tmp_list, *node;
1974 GdkEventFilter *filter;
1976 g_return_if_fail (window != NULL);
1977 g_return_if_fail (GDK_IS_WINDOW (window));
1979 private = (GdkWindowPrivate*) window;
1981 tmp_list = private->filters;
1985 filter = (GdkEventFilter *)tmp_list->data;
1987 tmp_list = tmp_list->next;
1989 if ((filter->function == function) && (filter->data == data))
1991 private->filters = g_list_remove_link (private->filters, node);
1993 g_list_free_1 (node);
2002 gdk_window_set_override_redirect (GdkWindow *window,
2003 gboolean override_redirect)
2005 g_return_if_fail (window != NULL);
2006 g_return_if_fail (GDK_IS_WINDOW (window));
2008 g_warning ("gdk_window_set_override_redirect not implemented");
2012 gdk_window_set_icon (GdkWindow *window,
2013 GdkWindow *icon_window,
2017 g_return_if_fail (window != NULL);
2018 g_return_if_fail (GDK_IS_WINDOW (window));
2020 if (GDK_DRAWABLE_DESTROYED (window))
2023 g_warning ("gdk_window_set_icon not implemented");
2027 gdk_window_set_icon_name (GdkWindow *window,
2030 g_return_if_fail (window != NULL);
2031 g_return_if_fail (GDK_IS_WINDOW (window));
2033 if (GDK_DRAWABLE_DESTROYED (window))
2036 if (!SetWindowText (GDK_DRAWABLE_XID (window), name))
2037 g_warning ("gdk_window_set_icon_name: SetWindowText failed");
2041 gdk_window_set_group (GdkWindow *window,
2044 g_return_if_fail (window != NULL);
2045 g_return_if_fail (GDK_IS_WINDOW (window));
2046 g_return_if_fail (leader != NULL);
2047 g_return_if_fail (GDK_IS_WINDOW (leader));
2049 if (GDK_DRAWABLE_DESTROYED (window) || GDK_DRAWABLE_DESTROYED (leader))
2052 g_warning ("gdk_window_set_group not implemented");
2056 gdk_window_set_decorations (GdkWindow *window,
2057 GdkWMDecoration decorations)
2059 LONG style, exstyle;
2061 g_return_if_fail (window != NULL);
2062 g_return_if_fail (GDK_IS_WINDOW (window));
2064 style = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
2065 exstyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
2067 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2068 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
2070 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2072 if (decorations & GDK_DECOR_ALL)
2073 style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2074 if (decorations & GDK_DECOR_BORDER)
2075 style |= (WS_BORDER);
2076 if (decorations & GDK_DECOR_RESIZEH)
2077 style |= (WS_THICKFRAME);
2078 if (decorations & GDK_DECOR_TITLE)
2079 style |= (WS_CAPTION);
2080 if (decorations & GDK_DECOR_MENU)
2081 style |= (WS_SYSMENU);
2082 if (decorations & GDK_DECOR_MINIMIZE)
2083 style |= (WS_MINIMIZEBOX);
2084 if (decorations & GDK_DECOR_MAXIMIZE)
2085 style |= (WS_MAXIMIZEBOX);
2087 SetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE, style);
2091 gdk_window_set_functions (GdkWindow *window,
2092 GdkWMFunction functions)
2094 LONG style, exstyle;
2096 g_return_if_fail (window != NULL);
2097 g_return_if_fail (GDK_IS_WINDOW (window));
2099 style = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
2100 exstyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
2102 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2103 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
2106 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2108 if (functions & GDK_FUNC_ALL)
2109 style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2110 if (functions & GDK_FUNC_RESIZE)
2111 style |= (WS_THICKFRAME);
2112 if (functions & GDK_FUNC_MOVE)
2113 style |= (WS_THICKFRAME);
2114 if (functions & GDK_FUNC_MINIMIZE)
2115 style |= (WS_MINIMIZEBOX);
2116 if (functions & GDK_FUNC_MAXIMIZE)
2117 style |= (WS_MAXIMIZEBOX);
2119 SetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE, style);
2123 gdk_window_get_toplevels (void)
2125 GList *new_list = NULL;
2128 tmp_list = gdk_root_parent->children;
2131 new_list = g_list_prepend (new_list, tmp_list->data);
2132 tmp_list = tmp_list->next;
2139 * propagate the shapes from all child windows of a GDK window to the parent
2140 * window. Shamelessly ripped from Enlightenment's code
2146 QueryTree (HWND hwnd,
2156 child = GetWindow (hwnd, GW_CHILD);
2158 child = GetWindow (child, GW_HWNDNEXT);
2161 } while (child != NULL);
2165 *children = g_new (HWND, n);
2166 for (i = 0; i < n; i++)
2169 child = GetWindow (hwnd, GW_CHILD);
2171 child = GetWindow (child, GW_HWNDNEXT);
2172 *children[i] = child;
2178 gdk_propagate_shapes (HANDLE win,
2182 HRGN region, childRegion;
2187 SetRectEmpty (&emptyRect);
2188 region = CreateRectRgnIndirect (&emptyRect);
2190 GetWindowRgn (win, region);
2192 QueryTree (win, &list, &num);
2195 WINDOWPLACEMENT placement;
2197 placement.length = sizeof (WINDOWPLACEMENT);
2198 /* go through all child windows and combine regions */
2199 for (i = 0; i < num; i++)
2201 GetWindowPlacement (list[i], &placement);
2202 if (placement.showCmd = SW_SHOWNORMAL)
2204 childRegion = CreateRectRgnIndirect (&emptyRect);
2205 GetWindowRgn (list[i], childRegion);
2206 CombineRgn (region, region, childRegion, RGN_OR);
2207 DeleteObject (childRegion);
2210 SetWindowRgn (win, region, TRUE);
2213 DeleteObject (region);
2217 gdk_window_set_child_shapes (GdkWindow *window)
2219 g_return_if_fail (window != NULL);
2220 g_return_if_fail (GDK_IS_WINDOW (window));
2222 if (GDK_DRAWABLE_DESTROYED (window))
2225 gdk_propagate_shapes (GDK_DRAWABLE_XID (window), FALSE);
2229 gdk_window_merge_child_shapes (GdkWindow *window)
2231 g_return_if_fail (window != NULL);
2232 g_return_if_fail (GDK_IS_WINDOW (window));
2234 if (GDK_DRAWABLE_DESTROYED (window))
2237 gdk_propagate_shapes (GDK_DRAWABLE_XID (window), TRUE);
2240 /*************************************************************
2241 * gdk_window_is_visible:
2242 * Check if the given window is mapped.
2246 * is the window mapped
2247 *************************************************************/
2250 gdk_window_is_visible (GdkWindow *window)
2252 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2254 g_return_val_if_fail (window != NULL, FALSE);
2255 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2257 return private->mapped;
2260 /*************************************************************
2261 * gdk_window_is_viewable:
2262 * Check if the window and all ancestors of the window
2263 * are mapped. (This is not necessarily "viewable" in
2264 * the X sense, since we only check as far as we have
2265 * GDK window parents, not to the root window)
2269 * is the window viewable
2270 *************************************************************/
2273 gdk_window_is_viewable (GdkWindow *window)
2275 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2277 g_return_val_if_fail (window != NULL, FALSE);
2278 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2281 (private != gdk_root_parent) &&
2282 (private->drawable.window_type != GDK_WINDOW_FOREIGN))
2284 if (!private->mapped)
2287 private = (GdkWindowPrivate *)private->parent;
2293 /* Support for windows that can be guffaw-scrolled
2294 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2298 gdk_window_gravity_works (void)
2300 enum { UNKNOWN, NO, YES };
2301 static gint gravity_works = UNKNOWN;
2303 if (gravity_works == UNKNOWN)
2310 attr.window_type = GDK_WINDOW_TEMP;
2311 attr.wclass = GDK_INPUT_OUTPUT;
2316 attr.event_mask = 0;
2318 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2320 attr.window_type = GDK_WINDOW_CHILD;
2321 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2323 gdk_window_set_static_win_gravity (child, TRUE);
2325 gdk_window_resize (parent, 100, 110);
2326 gdk_window_move (parent, 0, -10);
2327 gdk_window_move_resize (parent, 0, 0, 100, 100);
2329 gdk_window_resize (parent, 100, 110);
2330 gdk_window_move (parent, 0, -10);
2331 gdk_window_move_resize (parent, 0, 0, 100, 100);
2333 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2335 gdk_window_destroy (parent);
2336 gdk_window_destroy (child);
2338 gravity_works = ((y == -20) ? YES : NO);
2341 return (gravity_works == YES);
2345 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2347 g_return_if_fail (window != NULL);
2349 GDK_NOTE (MISC, g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2353 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2355 g_return_if_fail (window != NULL);
2358 g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2361 /*************************************************************
2362 * gdk_window_set_static_gravities:
2363 * Set the bit gravity of the given window to static,
2364 * and flag it so all children get static subwindow
2367 * window: window for which to set static gravity
2368 * use_static: Whether to turn static gravity on or off.
2370 * Does the XServer support static gravity?
2371 *************************************************************/
2374 gdk_window_set_static_gravities (GdkWindow *window,
2375 gboolean use_static)
2377 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2380 g_return_val_if_fail (window != NULL, FALSE);
2381 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2383 if (!use_static == !private->guffaw_gravity)
2386 if (use_static && !gdk_window_gravity_works ())
2389 private->guffaw_gravity = use_static;
2391 if (!GDK_DRAWABLE_DESTROYED (window))
2393 gdk_window_set_static_bit_gravity (window, use_static);
2395 tmp_list = private->children;
2398 gdk_window_set_static_win_gravity (window, use_static);
2400 tmp_list = tmp_list->next;