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 "gdkinternals.h"
37 #include "gdkprivate.h"
38 #include "gdkprivate-win32.h"
39 #include "gdkinputprivate.h"
42 static gboolean gdk_window_gravity_works (void);
43 static void gdk_window_set_static_win_gravity (GdkWindow *window,
46 /* The Win API function AdjustWindowRect may return negative values
47 * resulting in obscured title bars. This helper function is coreccting it.
50 SafeAdjustWindowRectEx (RECT* lpRect,
55 if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
57 WIN32_API_FAILED ("AdjustWindowRectEx");
62 lpRect->right -= lpRect->left;
67 lpRect->bottom -= lpRect->top;
73 GdkDrawableClass _gdk_windowing_window_class;
76 gdk_win32_window_destroy (GdkDrawable *drawable)
78 if (!GDK_DRAWABLE_DESTROYED (drawable))
80 if (GDK_DRAWABLE_TYPE (drawable) != GDK_WINDOW_FOREIGN)
82 g_warning ("losing last reference to undestroyed window");
83 _gdk_window_destroy (drawable, FALSE);
86 /* We use TRUE here, to keep us from actually calling
87 * DestroyWindow() on the window
89 _gdk_window_destroy (drawable, TRUE);
91 gdk_xid_table_remove (GDK_DRAWABLE_XID (drawable));
94 if (GDK_WINDOW_WIN32DATA (drawable)->xcursor != NULL)
95 DestroyCursor (GDK_WINDOW_WIN32DATA (drawable)->xcursor);
97 g_free (GDK_DRAWABLE_WIN32DATA (drawable));
101 gdk_win32_window_alloc (void)
104 GdkWindowPrivate *private;
106 static gboolean initialized = FALSE;
112 _gdk_windowing_window_class = _gdk_win32_drawable_class;
113 _gdk_win32_drawable_class.destroy = gdk_win32_window_destroy;
116 window = _gdk_window_alloc ();
117 private = (GdkWindowPrivate *) window;
119 private->drawable.klass = &_gdk_windowing_window_class;
120 private->drawable.klass_data = g_new (GdkWindowWin32Data, 1);
122 GDK_WINDOW_WIN32DATA (window)->event_mask = 0;
123 GDK_WINDOW_WIN32DATA (window)->bg_type = GDK_WIN32_BG_NORMAL;
124 GDK_WINDOW_WIN32DATA (window)->xcursor = NULL;
125 GDK_WINDOW_WIN32DATA (window)->hint_flags = 0;
126 GDK_WINDOW_WIN32DATA (window)->extension_events_selected = FALSE;
128 GDK_WINDOW_WIN32DATA (window)->input_locale = GetKeyboardLayout (0);
129 TranslateCharsetInfo ((DWORD FAR *) GetACP (),
130 &GDK_WINDOW_WIN32DATA (window)->charset_info,
137 gdk_window_init (void)
139 GdkWindowPrivate *private;
144 SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
145 width = r.right - r.left;
146 height = r.bottom - r.top;
148 gdk_parent_root = gdk_win32_window_alloc ();
149 private = (GdkWindowPrivate *) gdk_parent_root;
151 GDK_DRAWABLE_WIN32DATA (gdk_parent_root)->xid = gdk_root_window;
152 private->drawable.window_type = GDK_WINDOW_ROOT;
153 private->drawable.width = width;
154 private->drawable.height = height;
156 gdk_xid_table_insert (&gdk_root_window, gdk_parent_root);
160 * is a wrapper function for RegisterWindowClassEx.
161 * It creates at least one unique class for every
162 * GdkWindowType. If support for single window-specific icons
163 * is ever needed (e.g Dialog specific), every such window should
167 RegisterGdkClass (GdkDrawableType wtype)
169 static ATOM klassTOPLEVEL = 0;
170 static ATOM klassDIALOG = 0;
171 static ATOM klassCHILD = 0;
172 static ATOM klassTEMP = 0;
173 static HICON hAppIcon = NULL;
174 static WNDCLASSEX wcl;
177 wcl.cbSize = sizeof(WNDCLASSEX);
178 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
179 * on WM_SIZE and WM_MOVE. Flicker, Performance!
181 wcl.lpfnWndProc = gdk_WindowProc;
184 wcl.hInstance = gdk_ProgInstance;
186 /* initialize once! */
189 gchar sLoc [_MAX_PATH+1];
191 if (0 != GetModuleFileName(gdk_ProgInstance, sLoc, _MAX_PATH))
193 hAppIcon = ExtractIcon(gdk_ProgInstance, sLoc, 0);
196 char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
198 hAppIcon = ExtractIcon(gdk_ProgInstance, gdklibname, 0);
203 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
207 wcl.lpszMenuName = NULL;
210 /* initialize once per class */
211 #define ONCE_PER_CLASS() \
212 wcl.hIcon = CopyIcon (hAppIcon); \
213 wcl.hIconSm = CopyIcon (hAppIcon); \
214 wcl.hbrBackground = CreateSolidBrush( RGB(0,0,0)); \
215 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
219 case GDK_WINDOW_TOPLEVEL:
220 if (0 == klassTOPLEVEL)
222 wcl.lpszClassName = "gdkWindowToplevel";
225 klassTOPLEVEL = RegisterClassEx(&wcl);
227 klass = klassTOPLEVEL;
229 case GDK_WINDOW_CHILD:
232 wcl.lpszClassName = "gdkWindowChild";
234 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
236 klassCHILD = RegisterClassEx(&wcl);
240 case GDK_WINDOW_DIALOG:
241 if (0 == klassDIALOG)
243 wcl.lpszClassName = "gdkWindowDialog";
244 wcl.style |= CS_SAVEBITS;
246 klassDIALOG = RegisterClassEx(&wcl);
250 case GDK_WINDOW_TEMP:
253 wcl.lpszClassName = "gdkWindowTemp";
254 wcl.style |= CS_SAVEBITS;
256 klassTEMP = RegisterClassEx(&wcl);
260 case GDK_WINDOW_ROOT:
261 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
263 case GDK_DRAWABLE_PIXMAP:
264 g_error ("cannot make windows of type GDK_DRAWABLE_PIXMAP (use gdk_pixmap_new)");
270 WIN32_API_FAILED ("RegisterClassEx");
271 g_error ("That is a fatal error");
277 gdk_window_new (GdkWindow *parent,
278 GdkWindowAttr *attributes,
279 gint attributes_mask)
282 GdkWindowPrivate *private;
283 GdkWindowPrivate *parent_private;
288 DWORD dwStyle, dwExStyle;
298 g_return_val_if_fail (attributes != NULL, NULL);
301 parent = gdk_parent_root;
303 parent_private = (GdkWindowPrivate*) parent;
304 if (GDK_DRAWABLE_DESTROYED (parent))
307 xparent = GDK_DRAWABLE_XID (parent);
309 window = gdk_win32_window_alloc ();
310 private = (GdkWindowPrivate *)window;
312 private->parent = parent;
314 private->x = (attributes_mask & GDK_WA_X) ? attributes->x : 0;
315 private->y = (attributes_mask & GDK_WA_Y) ? attributes->y : 0;
317 private->drawable.width = (attributes->width > 1) ? (attributes->width) : (1);
318 private->drawable.height = (attributes->height > 1) ? (attributes->height) : (1);
319 private->drawable.window_type = attributes->window_type;
320 GDK_WINDOW_WIN32DATA (window)->extension_events_selected = FALSE;
322 if (attributes_mask & GDK_WA_VISUAL)
323 visual = attributes->visual;
325 visual = gdk_visual_get_system ();
326 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
328 if (attributes_mask & GDK_WA_TITLE)
329 title = attributes->title;
331 title = g_get_prgname ();
333 title = "GDK client window";
335 GDK_WINDOW_WIN32DATA (window)->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
337 if (parent_private && parent_private->guffaw_gravity)
342 if (attributes->wclass == GDK_INPUT_OUTPUT)
345 if (attributes_mask & GDK_WA_COLORMAP)
346 private->drawable.colormap = attributes->colormap;
348 private->drawable.colormap = gdk_colormap_get_system ();
352 dwExStyle = WS_EX_TRANSPARENT;
353 private->drawable.colormap = NULL;
354 GDK_WINDOW_WIN32DATA (window)->bg_type = GDK_WIN32_BG_TRANSPARENT;
355 GDK_WINDOW_WIN32DATA (window)->bg_pixmap = NULL;
358 if (attributes_mask & GDK_WA_X)
363 if (attributes_mask & GDK_WA_Y)
365 else if (attributes_mask & GDK_WA_X)
366 y = 100; /* ??? We must put it somewhere... */
368 y = 500; /* x is CW_USEDEFAULT, y doesn't matter then */
371 parent_private->children = g_list_prepend (parent_private->children, window);
373 switch (private->drawable.window_type)
375 case GDK_WINDOW_TOPLEVEL:
376 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
377 xparent = gdk_root_window;
379 case GDK_WINDOW_CHILD:
380 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
382 case GDK_WINDOW_DIALOG:
383 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
385 dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
387 xparent = gdk_root_window;
389 case GDK_WINDOW_TEMP:
390 dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
391 dwExStyle |= WS_EX_TOOLWINDOW;
393 case GDK_WINDOW_ROOT:
394 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
396 case GDK_DRAWABLE_PIXMAP:
397 g_error ("cannot make windows of type GDK_DRAWABLE_PIXMAP (use gdk_pixmap_new)");
401 klass = RegisterGdkClass (private->drawable.window_type);
403 if (private->drawable.window_type != GDK_WINDOW_CHILD)
405 if (x == CW_USEDEFAULT)
416 rect.right = rect.left + private->drawable.width;
417 rect.bottom = rect.top + private->drawable.height;
419 SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
421 if (x != CW_USEDEFAULT)
426 width = rect.right - rect.left;
427 height = rect.bottom - rect.top;
431 width = private->drawable.width;
432 height = private->drawable.height;
435 titlelen = strlen (title);
436 wctitle = g_new (wchar_t, titlelen + 1);
437 mbtitle = g_new (char, 3*titlelen + 1);
438 wlen = gdk_nmbstowchar_ts (wctitle, title, titlelen, titlelen);
440 WideCharToMultiByte (GetACP (), 0, wctitle, -1,
441 mbtitle, 3*titlelen, NULL, NULL);
443 GDK_DRAWABLE_WIN32DATA (window)->xid =
444 CreateWindowEx (dwExStyle,
445 MAKEINTRESOURCE(klass),
456 g_print ("gdk_window_new: %s %s %dx%d@+%d+%d %#x = %#x\n"
457 "...locale %#x codepage %d\n",
458 (private->drawable.window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
459 (private->drawable.window_type == GDK_WINDOW_CHILD ? "CHILD" :
460 (private->drawable.window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
461 (private->drawable.window_type == GDK_WINDOW_TEMP ? "TEMP" :
464 width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
466 GDK_DRAWABLE_XID (window),
467 GDK_WINDOW_WIN32DATA (window)->input_locale,
468 GDK_WINDOW_WIN32DATA (window)->charset_info.ciACP));
473 if (GDK_DRAWABLE_XID (window) == NULL)
475 WIN32_API_FAILED ("CreateWindowEx");
476 g_free (GDK_DRAWABLE_WIN32DATA (window));
481 gdk_drawable_ref (window);
482 gdk_xid_table_insert (&GDK_DRAWABLE_XID (window), window);
484 if (private->drawable.colormap)
485 gdk_colormap_ref (private->drawable.colormap);
487 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
488 (attributes->cursor) :
495 gdk_window_foreign_new (guint32 anid)
498 GdkWindowPrivate *private;
499 GdkWindowPrivate *parent_private;
504 window = gdk_win32_window_alloc ();
505 private = (GdkWindowPrivate *)window;
507 parent = GetParent ((HWND) anid);
508 private->parent = gdk_xid_table_lookup (parent);
510 parent_private = (GdkWindowPrivate *)private->parent;
513 parent_private->children = g_list_prepend (parent_private->children, window);
515 GDK_DRAWABLE_WIN32DATA (window)->xid = (HWND) anid;
516 GetClientRect ((HWND) anid, &rect);
518 point.y = rect.right;
519 ClientToScreen ((HWND) anid, &point);
520 if (parent != GetDesktopWindow ())
521 ScreenToClient (parent, &point);
522 private->x = point.x;
523 private->y = point.y;
524 private->drawable.width = rect.right - rect.left;
525 private->drawable.height = rect.bottom - rect.top;
526 private->drawable.window_type = GDK_WINDOW_FOREIGN;
527 private->drawable.destroyed = FALSE;
528 private->mapped = IsWindowVisible (GDK_DRAWABLE_XID (window));
530 private->drawable.colormap = NULL;
532 gdk_drawable_ref (window);
533 gdk_xid_table_insert (&GDK_DRAWABLE_XID (window), window);
539 _gdk_windowing_window_destroy (GdkWindow *window,
541 gboolean foreign_destroy)
543 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
545 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy %#x\n",
546 GDK_DRAWABLE_XID (window)));
548 if (private->extension_events != 0)
549 gdk_input_window_destroy (window);
551 if (private->drawable.window_type == GDK_WINDOW_FOREIGN)
553 if (!foreign_destroy && (private->parent != NULL))
555 /* It's somebody else's window, but in our heirarchy,
556 * so reparent it to the root window, and then call
557 * DestroyWindow() on it.
559 gdk_window_hide (window);
560 gdk_window_reparent (window, NULL, 0, 0);
562 /* Is this too drastic? Many (most?) applications
563 * quit if any window receives WM_QUIT I think.
564 * OTOH, I don't think foreign windows are much
565 * used, so the question is maybe academic.
567 PostMessage (GDK_DRAWABLE_XID (window), WM_QUIT, 0, 0);
570 else if (!recursing && !foreign_destroy)
571 DestroyWindow (GDK_DRAWABLE_XID (window));
574 /* This function is called when the window really gone.
577 gdk_window_destroy_notify (GdkWindow *window)
579 g_return_if_fail (window != NULL);
582 g_print ("gdk_window_destroy_notify: %#x %s\n",
583 GDK_DRAWABLE_XID (window),
584 (GDK_DRAWABLE_DESTROYED (window) ? "(destroyed)" : "")));
586 if (!GDK_DRAWABLE_DESTROYED (window))
588 if (GDK_DRAWABLE_TYPE(window) != GDK_WINDOW_FOREIGN)
589 g_warning ("window %#x unexpectedly destroyed",
590 GDK_DRAWABLE_XID (window));
592 _gdk_window_destroy (window, TRUE);
595 gdk_xid_table_remove (GDK_DRAWABLE_XID (window));
596 gdk_drawable_unref (window);
600 gdk_window_show (GdkWindow *window)
602 g_return_if_fail (window != NULL);
604 if (!GDK_DRAWABLE_DESTROYED (window))
606 GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n",
607 GDK_DRAWABLE_XID (window)));
609 ((GdkWindowPrivate *) window)->mapped = TRUE;
610 if (GDK_DRAWABLE_TYPE (window) == GDK_WINDOW_TEMP)
612 ShowWindow (GDK_DRAWABLE_XID (window), SW_SHOWNOACTIVATE);
613 SetWindowPos (GDK_DRAWABLE_XID (window), HWND_TOPMOST, 0, 0, 0, 0,
614 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
616 /* Don't put on toolbar */
617 ShowWindow (GDK_DRAWABLE_XID (window), SW_HIDE);
622 ShowWindow (GDK_DRAWABLE_XID (window), SW_SHOWNORMAL);
623 ShowWindow (GDK_DRAWABLE_XID (window), SW_RESTORE);
624 SetForegroundWindow (GDK_DRAWABLE_XID (window));
625 BringWindowToTop (GDK_DRAWABLE_XID (window));
627 ShowOwnedPopups (GDK_DRAWABLE_XID (window), TRUE);
634 gdk_window_hide (GdkWindow *window)
636 g_return_if_fail (window != NULL);
638 if (!GDK_DRAWABLE_DESTROYED (window))
640 GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n",
641 GDK_DRAWABLE_XID (window)));
643 ((GdkWindowPrivate *) window)->mapped = FALSE;
644 if (GDK_DRAWABLE_TYPE (window) == GDK_WINDOW_TOPLEVEL)
645 ShowOwnedPopups (GDK_DRAWABLE_XID (window), FALSE);
647 ShowWindow (GDK_DRAWABLE_XID (window), SW_HIDE);
649 ShowWindow (GDK_DRAWABLE_XID (window), SW_MINIMIZE);
651 CloseWindow (GDK_DRAWABLE_XID (window));
657 gdk_window_withdraw (GdkWindow *window)
659 g_return_if_fail (window != NULL);
661 if (!GDK_DRAWABLE_DESTROYED (window))
663 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n",
664 GDK_DRAWABLE_XID (window)));
666 gdk_window_hide (window); /* XXX */
671 gdk_window_move (GdkWindow *window,
675 GdkWindowPrivate *private;
677 g_return_if_fail (window != NULL);
679 if (!GDK_DRAWABLE_DESTROYED (window))
683 GDK_NOTE (MISC, g_print ("gdk_window_move: %#x +%d+%d\n",
684 GDK_DRAWABLE_XID (window), x, y));
686 private = (GdkWindowPrivate *) window;
687 GetClientRect (GDK_DRAWABLE_XID (window), &rect);
689 if (GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD)
697 ClientToScreen (GDK_DRAWABLE_XID (window), &ptTL);
702 ptBR.y = rect.bottom;
703 ClientToScreen (GDK_DRAWABLE_XID (window), &ptBR);
704 rect.right = x + ptBR.x - ptTL.x;
705 rect.bottom = y + ptBR.y - ptTL.y;
707 dwStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
708 dwExStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
709 SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
719 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
720 GDK_DRAWABLE_XID (window),
721 rect.right - rect.left, rect.bottom - rect.top,
723 if (!MoveWindow (GDK_DRAWABLE_XID (window),
724 x, y, rect.right - rect.left, rect.bottom - rect.top,
726 WIN32_API_FAILED ("MoveWindow");
731 gdk_window_resize (GdkWindow *window,
735 GdkWindowPrivate *private;
737 g_return_if_fail (window != NULL);
739 if ((gint16) width < 1)
741 if ((gint16) height < 1)
744 private = (GdkWindowPrivate*) window;
746 if (!private->drawable.destroyed &&
747 ((private->resize_count > 0) ||
748 (private->drawable.width != (guint16) width) ||
749 (private->drawable.height != (guint16) height)))
753 GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
754 GDK_DRAWABLE_XID (window), width, height));
756 if (private->drawable.window_type != GDK_WINDOW_CHILD)
765 ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
768 rect.right = pt.x + width;
769 rect.bottom = pt.y + height;
771 dwStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
772 dwExStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
773 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
774 WIN32_API_FAILED ("AdjustWindowRectEx");
778 width = rect.right - rect.left;
779 height = rect.bottom - rect.top;
785 private->drawable.width = width;
786 private->drawable.height = height;
789 private->resize_count += 1;
792 g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
793 GDK_DRAWABLE_XID (window), width, height, x, y));
794 if (!MoveWindow (GDK_DRAWABLE_XID (window),
797 WIN32_API_FAILED ("MoveWindow");
802 gdk_window_move_resize (GdkWindow *window,
808 GdkWindowPrivate *private;
810 g_return_if_fail (window != NULL);
812 if ((gint16) width < 1)
814 if ((gint16) height < 1)
817 if (!GDK_DRAWABLE_DESTROYED (window))
823 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
824 GDK_DRAWABLE_XID (window), width, height, x, y));
826 private = (GdkWindowPrivate*) window;
829 rect.right = x + width;
830 rect.bottom = y + height;
832 dwStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
833 dwExStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
834 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
835 WIN32_API_FAILED ("AdjustWindowRectEx");
837 if (private->drawable.window_type == GDK_WINDOW_CHILD)
841 private->drawable.width = width;
842 private->drawable.height = height;
844 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
845 GDK_DRAWABLE_XID (window),
846 rect.right - rect.left, rect.bottom - rect.top,
847 rect.left, rect.top));
848 if (!MoveWindow (GDK_DRAWABLE_XID (window),
850 rect.right - rect.left, rect.bottom - rect.top,
852 WIN32_API_FAILED ("MoveWindow");
854 if (private->guffaw_gravity)
856 GList *tmp_list = private->children;
859 GdkWindowPrivate *child_private = tmp_list->data;
861 child_private->x -= x - private->x;
862 child_private->y -= y - private->y;
864 tmp_list = tmp_list->next;
872 gdk_window_reparent (GdkWindow *window,
873 GdkWindow *new_parent,
877 GdkWindowPrivate *window_private;
878 GdkWindowPrivate *parent_private;
879 GdkWindowPrivate *old_parent_private;
881 g_return_if_fail (window != NULL);
884 new_parent = gdk_parent_root;
886 window_private = (GdkWindowPrivate*) window;
887 old_parent_private = (GdkWindowPrivate *) window_private->parent;
888 parent_private = (GdkWindowPrivate*) new_parent;
890 if (!GDK_DRAWABLE_DESTROYED (window)
891 && !GDK_DRAWABLE_DESTROYED (new_parent))
893 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
894 GDK_DRAWABLE_XID (window),
895 GDK_DRAWABLE_XID (new_parent)));
896 if (!SetParent (GDK_DRAWABLE_XID (window),
897 GDK_DRAWABLE_XID (new_parent)))
898 WIN32_API_FAILED ("SetParent");
900 if (!MoveWindow (GDK_DRAWABLE_XID (window),
902 window_private->drawable.width,
903 window_private->drawable.height,
905 WIN32_API_FAILED ("MoveWindow");
908 window_private->parent = new_parent;
910 if (old_parent_private)
911 old_parent_private->children =
912 g_list_remove (old_parent_private->children, window);
914 if ((old_parent_private &&
915 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
916 (!old_parent_private && parent_private->guffaw_gravity))
917 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
919 parent_private->children = g_list_prepend (parent_private->children, window);
923 _gdk_windowing_window_clear_area (GdkWindow *window,
929 g_return_if_fail (window != NULL);
930 g_return_if_fail (GDK_IS_WINDOW (window));
932 if (!GDK_DRAWABLE_DESTROYED (window))
937 width = ((GdkDrawablePrivate *) window)->width - x;
939 height = ((GdkDrawablePrivate *) window)->height - y;
940 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area: "
941 "%#x %dx%d@+%d+%d\n",
942 GDK_DRAWABLE_XID (window), width, height, x, y));
943 hdc = GetDC (GDK_DRAWABLE_XID (window));
944 IntersectClipRect (hdc, x, y, x + width + 1, y + height + 1);
945 SendMessage (GDK_DRAWABLE_XID (window), WM_ERASEBKGND, (WPARAM) hdc, 0);
946 ReleaseDC (GDK_DRAWABLE_XID (window), hdc);
951 _gdk_windowing_window_clear_area_e (GdkWindow *window,
957 g_return_if_fail (window != NULL);
958 g_return_if_fail (GDK_IS_WINDOW (window));
960 if (!GDK_DRAWABLE_DESTROYED (window))
964 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area_e: "
965 "%#x %dx%d@+%d+%d\n",
966 GDK_DRAWABLE_XID (window), width, height, x, y));
969 rect.right = x + width + 1;
971 rect.bottom = y + height + 1;
972 if (!InvalidateRect (GDK_DRAWABLE_XID (window), &rect, TRUE))
973 WIN32_GDI_FAILED ("InvalidateRect");
974 UpdateWindow (GDK_DRAWABLE_XID (window));
979 gdk_window_raise (GdkWindow *window)
981 g_return_if_fail (window != NULL);
982 g_return_if_fail (GDK_IS_WINDOW (window));
984 if (!GDK_DRAWABLE_DESTROYED (window))
986 GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n",
987 GDK_DRAWABLE_XID (window)));
989 if (!BringWindowToTop (GDK_DRAWABLE_XID (window)))
990 WIN32_API_FAILED ("BringWindowToTop");
995 gdk_window_lower (GdkWindow *window)
997 g_return_if_fail (window != NULL);
998 g_return_if_fail (GDK_IS_WINDOW (window));
1000 if (!GDK_DRAWABLE_DESTROYED (window))
1002 GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n",
1003 GDK_DRAWABLE_XID (window)));
1005 if (!SetWindowPos (GDK_DRAWABLE_XID (window), HWND_BOTTOM, 0, 0, 0, 0,
1006 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1007 WIN32_API_FAILED ("SetWindowPos");
1012 gdk_window_set_hints (GdkWindow *window,
1021 WINDOWPLACEMENT size_hints;
1027 g_return_if_fail (window != NULL);
1028 g_return_if_fail (GDK_IS_WINDOW (window));
1030 if (GDK_DRAWABLE_DESTROYED (window))
1033 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1034 GDK_DRAWABLE_XID (window),
1035 min_width, min_height, max_width, max_height,
1038 GDK_WINDOW_WIN32DATA (window)->hint_flags = flags;
1039 size_hints.length = sizeof (size_hints);
1043 if (flags & GDK_HINT_POS)
1044 if (!GetWindowPlacement (GDK_DRAWABLE_XID (window), &size_hints))
1045 WIN32_API_FAILED ("GetWindowPlacement");
1048 GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1049 " (%d,%d)--(%d,%d)\n",
1050 size_hints.rcNormalPosition.left,
1051 size_hints.rcNormalPosition.top,
1052 size_hints.rcNormalPosition.right,
1053 size_hints.rcNormalPosition.bottom));
1054 /* What are the corresponding window coordinates for client
1055 * area coordinates x, y
1059 rect.right = rect.left + 200; /* dummy */
1060 rect.bottom = rect.top + 200;
1061 dwStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
1062 dwExStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
1063 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1064 size_hints.flags = 0;
1065 size_hints.showCmd = SW_SHOWNA;
1067 /* Set the normal position hint to that location, with unchanged
1070 diff = size_hints.rcNormalPosition.left - rect.left;
1071 size_hints.rcNormalPosition.left = rect.left;
1072 size_hints.rcNormalPosition.right -= diff;
1073 diff = size_hints.rcNormalPosition.top - rect.top;
1074 size_hints.rcNormalPosition.top = rect.top;
1075 size_hints.rcNormalPosition.bottom -= diff;
1076 GDK_NOTE (MISC, g_print ("...setting: (%d,%d)--(%d,%d)\n",
1077 size_hints.rcNormalPosition.left,
1078 size_hints.rcNormalPosition.top,
1079 size_hints.rcNormalPosition.right,
1080 size_hints.rcNormalPosition.bottom));
1081 if (!SetWindowPlacement (GDK_DRAWABLE_XID (window), &size_hints))
1082 WIN32_API_FAILED ("SetWindowPlacement");
1083 GDK_WINDOW_WIN32DATA (window)->hint_x = rect.left;
1084 GDK_WINDOW_WIN32DATA (window)->hint_y = rect.top;
1087 if (flags & GDK_HINT_MIN_SIZE)
1091 rect.right = min_width;
1092 rect.bottom = min_height;
1093 dwStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
1094 dwExStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
1095 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1096 GDK_WINDOW_WIN32DATA (window)->hint_min_width =
1097 rect.right - rect.left;
1098 GDK_WINDOW_WIN32DATA (window)->hint_min_height =
1099 rect.bottom - rect.top;
1101 /* Also chek if he current size of the window is in bounds. */
1102 GetClientRect (GDK_DRAWABLE_XID (window), &rect);
1103 if (rect.right < min_width && rect.bottom < min_height)
1104 gdk_window_resize (window, min_width, min_height);
1105 else if (rect.right < min_width)
1106 gdk_window_resize (window, min_width, rect.bottom);
1107 else if (rect.bottom < min_height)
1108 gdk_window_resize (window, rect.right, min_height);
1111 if (flags & GDK_HINT_MAX_SIZE)
1115 rect.right = max_width;
1116 rect.bottom = max_height;
1117 dwStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
1118 dwExStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
1119 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1120 GDK_WINDOW_WIN32DATA (window)->hint_max_width =
1121 rect.right - rect.left;
1122 GDK_WINDOW_WIN32DATA (window)->hint_max_height =
1123 rect.bottom - rect.top;
1124 /* Again, check if the window is too large currently. */
1125 GetClientRect (GDK_DRAWABLE_XID (window), &rect);
1126 if (rect.right > max_width && rect.bottom > max_height)
1127 gdk_window_resize (window, max_width, max_height);
1128 else if (rect.right > max_width)
1129 gdk_window_resize (window, max_width, rect.bottom);
1130 else if (rect.bottom > max_height)
1131 gdk_window_resize (window, rect.right, max_height);
1137 gdk_window_set_geometry_hints (GdkWindow *window,
1138 GdkGeometry *geometry,
1139 GdkWindowHints geom_mask)
1141 WINDOWPLACEMENT size_hints;
1147 g_return_if_fail (window != NULL);
1148 g_return_if_fail (GDK_IS_WINDOW (window));
1150 if (GDK_DRAWABLE_DESTROYED (window))
1153 size_hints.length = sizeof (size_hints);
1155 GDK_WINDOW_WIN32DATA (window)->hint_flags = geom_mask;
1157 if (geom_mask & GDK_HINT_POS)
1160 if (geom_mask & GDK_HINT_MIN_SIZE)
1164 rect.right = geometry->min_width;
1165 rect.bottom = geometry->min_height;
1166 dwStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
1167 dwExStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
1168 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1169 GDK_WINDOW_WIN32DATA (window)->hint_min_width = rect.right - rect.left;
1170 GDK_WINDOW_WIN32DATA (window)->hint_min_height = rect.bottom - rect.top;
1172 /* Also check if he current size of the window is in bounds */
1173 GetClientRect (GDK_DRAWABLE_XID (window), &rect);
1174 if (rect.right < geometry->min_width
1175 && rect.bottom < geometry->min_height)
1176 gdk_window_resize (window, geometry->min_width, geometry->min_height);
1177 else if (rect.right < geometry->min_width)
1178 gdk_window_resize (window, geometry->min_width, rect.bottom);
1179 else if (rect.bottom < geometry->min_height)
1180 gdk_window_resize (window, rect.right, geometry->min_height);
1183 if (geom_mask & GDK_HINT_MAX_SIZE)
1187 rect.right = geometry->max_width;
1188 rect.bottom = geometry->max_height;
1189 dwStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
1190 dwExStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
1191 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1192 GDK_WINDOW_WIN32DATA (window)->hint_max_width = rect.right - rect.left;
1193 GDK_WINDOW_WIN32DATA (window)->hint_max_height = rect.bottom - rect.top;
1195 /* Again, check if the window is too large currently. */
1196 GetClientRect (GDK_DRAWABLE_XID (window), &rect);
1197 if (rect.right > geometry->max_width
1198 && rect.bottom > geometry->max_height)
1199 gdk_window_resize (window, geometry->max_width, geometry->max_height);
1200 else if (rect.right > geometry->max_width)
1201 gdk_window_resize (window, geometry->max_width, rect.bottom);
1202 else if (rect.bottom > geometry->max_height)
1203 gdk_window_resize (window, rect.right, geometry->max_height);
1206 /* I don't know what to do when called with zero base_width and height. */
1207 if (geom_mask & GDK_HINT_BASE_SIZE
1208 && geometry->base_width > 0
1209 && geometry->base_height > 0)
1210 if (!GetWindowPlacement (GDK_DRAWABLE_XID (window), &size_hints))
1211 WIN32_API_FAILED ("GetWindowPlacement");
1214 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1215 " rcNormalPosition: (%d,%d)--(%d,%d)\n",
1216 size_hints.rcNormalPosition.left,
1217 size_hints.rcNormalPosition.top,
1218 size_hints.rcNormalPosition.right,
1219 size_hints.rcNormalPosition.bottom));
1220 size_hints.rcNormalPosition.right =
1221 size_hints.rcNormalPosition.left + geometry->base_width;
1222 size_hints.rcNormalPosition.bottom =
1223 size_hints.rcNormalPosition.top + geometry->base_height;
1224 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
1225 size_hints.rcNormalPosition.left,
1226 size_hints.rcNormalPosition.top,
1227 size_hints.rcNormalPosition.right,
1228 size_hints.rcNormalPosition.bottom));
1229 if (!SetWindowPlacement (GDK_DRAWABLE_XID (window), &size_hints))
1230 WIN32_API_FAILED ("SetWindowPlacement");
1233 if (geom_mask & GDK_HINT_RESIZE_INC)
1238 if (geom_mask & GDK_HINT_ASPECT)
1245 gdk_window_set_title (GdkWindow *window,
1253 g_return_if_fail (window != NULL);
1254 g_return_if_fail (GDK_IS_WINDOW (window));
1255 g_return_if_fail (title != NULL);
1256 g_return_if_fail (strlen (title) > 0);
1258 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
1259 GDK_DRAWABLE_XID (window), title));
1260 if (!GDK_DRAWABLE_DESTROYED (window))
1262 /* As the title is in UTF-8 we must translate it
1263 * to the system codepage.
1265 titlelen = strlen (title);
1266 wcstr = g_new (wchar_t, titlelen + 1);
1267 mbstr = g_new (char, 3*titlelen + 1);
1268 wlen = gdk_nmbstowchar_ts (wcstr, title, titlelen, titlelen);
1270 WideCharToMultiByte (GetACP (), 0, wcstr, -1,
1271 mbstr, 3*titlelen, NULL, NULL);
1273 if (!SetWindowText (GDK_DRAWABLE_XID (window), mbstr))
1274 WIN32_API_FAILED ("SetWindowText");
1282 gdk_window_set_role (GdkWindow *window,
1285 g_return_if_fail (window != NULL);
1286 g_return_if_fail (GDK_IS_WINDOW (window));
1288 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1289 GDK_DRAWABLE_XID (window), (role ? role : "NULL")));
1294 gdk_window_set_transient_for (GdkWindow *window,
1297 g_return_if_fail (window != NULL);
1298 g_return_if_fail (GDK_IS_WINDOW (window));
1300 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1301 GDK_DRAWABLE_XID (window),
1302 GDK_DRAWABLE_XID (parent)));
1307 gdk_window_set_background (GdkWindow *window,
1310 g_return_if_fail (window != NULL);
1311 g_return_if_fail (GDK_IS_WINDOW (window));
1313 if (!GDK_DRAWABLE_DESTROYED (window))
1315 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1316 GDK_DRAWABLE_XID (window),
1317 gdk_win32_color_to_string (color)));
1319 if (GDK_WINDOW_WIN32DATA (window)->bg_type == GDK_WIN32_BG_PIXMAP)
1321 if (GDK_WINDOW_WIN32DATA (window)->bg_pixmap != NULL)
1323 gdk_drawable_unref (GDK_WINDOW_WIN32DATA (window)->bg_pixmap);
1324 GDK_WINDOW_WIN32DATA (window)->bg_pixmap = NULL;
1326 GDK_WINDOW_WIN32DATA (window)->bg_type = GDK_WIN32_BG_NORMAL;
1328 GDK_WINDOW_WIN32DATA (window)->bg_type = GDK_WIN32_BG_PIXEL;
1329 GDK_WINDOW_WIN32DATA (window)->bg_pixel = color->pixel;
1334 gdk_window_set_back_pixmap (GdkWindow *window,
1336 gint parent_relative)
1338 g_return_if_fail (window != NULL);
1339 g_return_if_fail (GDK_IS_WINDOW (window));
1341 if (!GDK_DRAWABLE_DESTROYED (window))
1343 if (GDK_WINDOW_WIN32DATA (window)->bg_type == GDK_WIN32_BG_PIXMAP)
1345 if (GDK_WINDOW_WIN32DATA (window)->bg_pixmap != NULL)
1347 gdk_drawable_unref (GDK_WINDOW_WIN32DATA (window)->bg_pixmap);
1348 GDK_WINDOW_WIN32DATA (window)->bg_pixmap = NULL;
1350 GDK_WINDOW_WIN32DATA (window)->bg_type = GDK_WIN32_BG_NORMAL;
1352 if (parent_relative)
1354 GDK_WINDOW_WIN32DATA (window)->bg_type =
1355 GDK_WIN32_BG_PARENT_RELATIVE;
1363 /* We must cache the pixmap in the GdkWindowWin32Data and
1364 * paint it each time we get WM_ERASEBKGND
1366 GDK_WINDOW_WIN32DATA (window)->bg_type = GDK_WIN32_BG_PIXMAP;
1367 GDK_WINDOW_WIN32DATA (window)->bg_pixmap = pixmap;
1368 gdk_drawable_ref (pixmap);
1374 gdk_window_set_cursor (GdkWindow *window,
1377 GdkCursorPrivate *cursor_private;
1381 g_return_if_fail (window != NULL);
1382 g_return_if_fail (GDK_IS_WINDOW (window));
1384 cursor_private = (GdkCursorPrivate*) cursor;
1386 if (!GDK_DRAWABLE_DESTROYED (window))
1391 xcursor = cursor_private->xcursor;
1393 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1394 GDK_DRAWABLE_XID (window), xcursor));
1395 if (GDK_WINDOW_WIN32DATA (window)->xcursor != NULL)
1397 GDK_NOTE (MISC, g_print ("...DestroyCursor (%#x)\n",
1398 GDK_WINDOW_WIN32DATA (window)->xcursor));
1400 DestroyCursor (GDK_WINDOW_WIN32DATA (window)->xcursor);
1401 GDK_WINDOW_WIN32DATA (window)->xcursor = NULL;
1403 if (xcursor != NULL)
1405 /* We must copy the cursor as it is OK to destroy the GdkCursor
1406 * while still in use for some window. See for instance
1407 * gimp_change_win_cursor() which calls
1408 * gdk_window_set_cursor (win, cursor), and immediately
1409 * afterwards gdk_cursor_destroy (cursor).
1411 GDK_WINDOW_WIN32DATA (window)->xcursor = CopyCursor (xcursor);
1412 GDK_NOTE (MISC, g_print ("...CopyCursor (%#x) = %#x\n",
1414 GDK_WINDOW_WIN32DATA (window)->xcursor));
1417 if (ChildWindowFromPoint (GDK_DRAWABLE_XID (window), pt) == GDK_DRAWABLE_XID (window))
1418 SetCursor (GDK_WINDOW_WIN32DATA (window)->xcursor);
1424 gdk_window_get_geometry (GdkWindow *window,
1431 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1434 window = gdk_parent_root;
1436 if (!GDK_DRAWABLE_DESTROYED (window))
1440 if (!GetClientRect (GDK_DRAWABLE_XID (window), &rect))
1441 WIN32_API_FAILED ("GetClientRect");
1448 *width = rect.right - rect.left;
1450 *height = rect.bottom - rect.top;
1452 *depth = gdk_drawable_get_visual (window)->depth;
1457 gdk_window_get_origin (GdkWindow *window,
1465 g_return_val_if_fail (window != NULL, 0);
1467 if (!GDK_DRAWABLE_DESTROYED (window))
1473 ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
1486 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
1487 GDK_DRAWABLE_XID (window), tx, ty));
1492 gdk_window_get_deskrelative_origin (GdkWindow *window,
1496 return gdk_window_get_origin (window, x, y);
1500 gdk_window_get_root_origin (GdkWindow *window,
1504 GdkWindowPrivate *rover;
1507 g_return_if_fail (window != NULL);
1508 g_return_if_fail (GDK_IS_WINDOW (window));
1510 rover = (GdkWindowPrivate*) window;
1515 if (GDK_DRAWABLE_DESTROYED (window))
1518 while (rover->parent && ((GdkWindowPrivate*) rover->parent)->parent)
1519 rover = (GdkWindowPrivate *) rover->parent;
1520 if (rover->drawable.destroyed)
1525 ClientToScreen (GDK_DRAWABLE_XID (rover), &pt);
1531 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%d+%d\n",
1532 GDK_DRAWABLE_XID (window),
1533 GDK_DRAWABLE_XID (rover), pt.x, pt.y));
1537 gdk_window_get_pointer (GdkWindow *window,
1540 GdkModifierType *mask)
1542 GdkWindow *return_val;
1543 POINT pointc, point;
1546 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1549 window = gdk_parent_root;
1552 GetCursorPos (&pointc);
1554 ScreenToClient (GDK_DRAWABLE_XID (window), &point);
1561 hwnd = WindowFromPoint (point);
1563 ScreenToClient (hwnd, &point);
1566 hwndc = ChildWindowFromPoint (hwnd, point);
1567 ClientToScreen (hwnd, &point);
1568 ScreenToClient (hwndc, &point);
1569 } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1571 return_val = gdk_window_lookup (hwnd);
1577 GetKeyboardState (kbd);
1579 if (kbd[VK_SHIFT] & 0x80)
1580 *mask |= GDK_SHIFT_MASK;
1581 if (kbd[VK_CAPITAL] & 0x80)
1582 *mask |= GDK_LOCK_MASK;
1583 if (kbd[VK_CONTROL] & 0x80)
1584 *mask |= GDK_CONTROL_MASK;
1585 if (kbd[VK_MENU] & 0x80)
1586 *mask |= GDK_MOD1_MASK;
1587 if (kbd[VK_LBUTTON] & 0x80)
1588 *mask |= GDK_BUTTON1_MASK;
1589 if (kbd[VK_MBUTTON] & 0x80)
1590 *mask |= GDK_BUTTON2_MASK;
1591 if (kbd[VK_RBUTTON] & 0x80)
1592 *mask |= GDK_BUTTON3_MASK;
1599 gdk_window_at_pointer (gint *win_x,
1603 POINT point, pointc;
1607 GetCursorPos (&pointc);
1609 hwnd = WindowFromPoint (point);
1613 window = gdk_parent_root;
1621 ScreenToClient (hwnd, &point);
1624 hwndc = ChildWindowFromPoint (hwnd, point);
1625 ClientToScreen (hwnd, &point);
1626 ScreenToClient (hwndc, &point);
1627 } while (hwndc != hwnd && (hwnd = hwndc, 1));
1629 window = gdk_window_lookup (hwnd);
1631 if (window && (win_x || win_y))
1633 GetClientRect (hwnd, &rect);
1635 *win_x = point.x - rect.left;
1637 *win_y = point.y - rect.top;
1640 GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%d+%d %#x%s\n",
1641 point.x, point.y, hwnd,
1642 (window == NULL ? " NULL" : "")));
1648 gdk_window_get_children (GdkWindow *window)
1650 GdkWindowPrivate *private;
1653 g_return_val_if_fail (window != NULL, NULL);
1654 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1656 if (GDK_DRAWABLE_DESTROYED (window))
1660 g_warning ("gdk_window_get_children not implemented");
1667 gdk_window_get_events (GdkWindow *window)
1669 g_return_val_if_fail (window != NULL, 0);
1670 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1672 if (GDK_DRAWABLE_DESTROYED (window))
1675 return GDK_WINDOW_WIN32DATA (window)->event_mask;
1679 gdk_window_set_events (GdkWindow *window,
1680 GdkEventMask event_mask)
1682 g_return_if_fail (window != NULL);
1683 g_return_if_fail (GDK_IS_WINDOW (window));
1685 if (GDK_DRAWABLE_DESTROYED (window))
1688 GDK_WINDOW_WIN32DATA (window)->event_mask = event_mask;
1692 gdk_window_add_colormap_windows (GdkWindow *window)
1694 g_warning ("gdk_window_add_colormap_windows not implemented");
1698 gdk_window_shape_combine_mask (GdkWindow *window,
1702 g_return_if_fail (window != NULL);
1703 g_return_if_fail (GDK_IS_WINDOW (window));
1707 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
1708 GDK_DRAWABLE_XID (window)));
1709 SetWindowRgn (GDK_DRAWABLE_XID (window), NULL, TRUE);
1718 /* Convert mask bitmap to region */
1719 hrgn = BitmapToRegion (GDK_DRAWABLE_XID (mask));
1721 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
1722 GDK_DRAWABLE_XID (window),
1723 GDK_DRAWABLE_XID (mask)));
1725 /* SetWindowRgn wants window (not client) coordinates */
1726 dwStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
1727 dwExStyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
1728 GetClientRect (GDK_DRAWABLE_XID (window), &rect);
1729 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1730 OffsetRgn (hrgn, -rect.left, -rect.top);
1732 OffsetRgn (hrgn, x, y);
1734 /* If this is a top-level window, add the title bar to the region */
1735 if (GDK_DRAWABLE_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1737 CombineRgn (hrgn, hrgn,
1738 CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
1742 SetWindowRgn (GDK_DRAWABLE_XID (window), hrgn, TRUE);
1747 gdk_window_set_override_redirect (GdkWindow *window,
1748 gboolean override_redirect)
1750 g_return_if_fail (window != NULL);
1751 g_return_if_fail (GDK_IS_WINDOW (window));
1753 g_warning ("gdk_window_set_override_redirect not implemented");
1757 gdk_window_set_icon (GdkWindow *window,
1758 GdkWindow *icon_window,
1762 g_return_if_fail (window != NULL);
1763 g_return_if_fail (GDK_IS_WINDOW (window));
1765 if (GDK_DRAWABLE_DESTROYED (window))
1768 /* Nothing to do, really. As we share window classes between windows
1769 * we can't have window-specific icons, sorry. Don't print any warning
1775 gdk_window_set_icon_name (GdkWindow *window,
1778 g_return_if_fail (window != NULL);
1779 g_return_if_fail (GDK_IS_WINDOW (window));
1781 if (GDK_DRAWABLE_DESTROYED (window))
1784 if (!SetWindowText (GDK_DRAWABLE_XID (window), name))
1785 WIN32_API_FAILED ("SetWindowText");
1789 gdk_window_set_group (GdkWindow *window,
1792 g_return_if_fail (window != NULL);
1793 g_return_if_fail (GDK_IS_WINDOW (window));
1794 g_return_if_fail (leader != NULL);
1795 g_return_if_fail (GDK_IS_WINDOW (leader));
1797 if (GDK_DRAWABLE_DESTROYED (window) || GDK_DRAWABLE_DESTROYED (leader))
1800 g_warning ("gdk_window_set_group not implemented");
1804 gdk_window_set_decorations (GdkWindow *window,
1805 GdkWMDecoration decorations)
1807 LONG style, exstyle;
1809 g_return_if_fail (window != NULL);
1810 g_return_if_fail (GDK_IS_WINDOW (window));
1812 style = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
1813 exstyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
1815 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
1816 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
1818 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
1820 if (decorations & GDK_DECOR_ALL)
1821 style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
1822 if (decorations & GDK_DECOR_BORDER)
1823 style |= (WS_BORDER);
1824 if (decorations & GDK_DECOR_RESIZEH)
1825 style |= (WS_THICKFRAME);
1826 if (decorations & GDK_DECOR_TITLE)
1827 style |= (WS_CAPTION);
1828 if (decorations & GDK_DECOR_MENU)
1829 style |= (WS_SYSMENU);
1830 if (decorations & GDK_DECOR_MINIMIZE)
1831 style |= (WS_MINIMIZEBOX);
1832 if (decorations & GDK_DECOR_MAXIMIZE)
1833 style |= (WS_MAXIMIZEBOX);
1835 SetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE, style);
1839 gdk_window_set_functions (GdkWindow *window,
1840 GdkWMFunction functions)
1842 LONG style, exstyle;
1844 g_return_if_fail (window != NULL);
1845 g_return_if_fail (GDK_IS_WINDOW (window));
1847 style = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE);
1848 exstyle = GetWindowLong (GDK_DRAWABLE_XID (window), GWL_EXSTYLE);
1850 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
1851 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
1854 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
1856 if (functions & GDK_FUNC_ALL)
1857 style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
1858 if (functions & GDK_FUNC_RESIZE)
1859 style |= (WS_THICKFRAME);
1860 if (functions & GDK_FUNC_MOVE)
1861 style |= (WS_THICKFRAME);
1862 if (functions & GDK_FUNC_MINIMIZE)
1863 style |= (WS_MINIMIZEBOX);
1864 if (functions & GDK_FUNC_MAXIMIZE)
1865 style |= (WS_MAXIMIZEBOX);
1867 SetWindowLong (GDK_DRAWABLE_XID (window), GWL_STYLE, style);
1871 * propagate the shapes from all child windows of a GDK window to the parent
1872 * window. Shamelessly ripped from Enlightenment's code
1878 QueryTree (HWND hwnd,
1888 child = GetWindow (hwnd, GW_CHILD);
1890 child = GetWindow (child, GW_HWNDNEXT);
1893 } while (child != NULL);
1897 *children = g_new (HWND, n);
1898 for (i = 0; i < n; i++)
1901 child = GetWindow (hwnd, GW_CHILD);
1903 child = GetWindow (child, GW_HWNDNEXT);
1904 *children[i] = child;
1910 gdk_propagate_shapes (HANDLE win,
1914 HRGN region, childRegion;
1919 SetRectEmpty (&emptyRect);
1920 region = CreateRectRgnIndirect (&emptyRect);
1922 GetWindowRgn (win, region);
1924 QueryTree (win, &list, &num);
1927 WINDOWPLACEMENT placement;
1929 placement.length = sizeof (WINDOWPLACEMENT);
1930 /* go through all child windows and combine regions */
1931 for (i = 0; i < num; i++)
1933 GetWindowPlacement (list[i], &placement);
1934 if (placement.showCmd == SW_SHOWNORMAL)
1936 childRegion = CreateRectRgnIndirect (&emptyRect);
1937 GetWindowRgn (list[i], childRegion);
1938 CombineRgn (region, region, childRegion, RGN_OR);
1939 DeleteObject (childRegion);
1942 SetWindowRgn (win, region, TRUE);
1945 DeleteObject (region);
1949 gdk_window_set_child_shapes (GdkWindow *window)
1951 g_return_if_fail (window != NULL);
1952 g_return_if_fail (GDK_IS_WINDOW (window));
1954 if (GDK_DRAWABLE_DESTROYED (window))
1957 gdk_propagate_shapes (GDK_DRAWABLE_XID (window), FALSE);
1961 gdk_window_merge_child_shapes (GdkWindow *window)
1963 g_return_if_fail (window != NULL);
1964 g_return_if_fail (GDK_IS_WINDOW (window));
1966 if (GDK_DRAWABLE_DESTROYED (window))
1969 gdk_propagate_shapes (GDK_DRAWABLE_XID (window), TRUE);
1972 /* Support for windows that can be guffaw-scrolled
1973 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
1977 gdk_window_gravity_works (void)
1979 enum { UNKNOWN, NO, YES };
1980 static gint gravity_works = UNKNOWN;
1982 if (gravity_works == UNKNOWN)
1989 attr.window_type = GDK_WINDOW_TEMP;
1990 attr.wclass = GDK_INPUT_OUTPUT;
1995 attr.event_mask = 0;
1997 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
1999 attr.window_type = GDK_WINDOW_CHILD;
2000 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2002 gdk_window_set_static_win_gravity (child, TRUE);
2004 gdk_window_resize (parent, 100, 110);
2005 gdk_window_move (parent, 0, -10);
2006 gdk_window_move_resize (parent, 0, 0, 100, 100);
2008 gdk_window_resize (parent, 100, 110);
2009 gdk_window_move (parent, 0, -10);
2010 gdk_window_move_resize (parent, 0, 0, 100, 100);
2012 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2014 gdk_window_destroy (parent);
2015 gdk_window_destroy (child);
2017 gravity_works = ((y == -20) ? YES : NO);
2020 return (gravity_works == YES);
2024 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2026 g_return_if_fail (window != NULL);
2028 GDK_NOTE (MISC, g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2032 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2034 g_return_if_fail (window != NULL);
2037 g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2040 /*************************************************************
2041 * gdk_window_set_static_gravities:
2042 * Set the bit gravity of the given window to static,
2043 * and flag it so all children get static subwindow
2046 * window: window for which to set static gravity
2047 * use_static: Whether to turn static gravity on or off.
2049 * Does the XServer support static gravity?
2050 *************************************************************/
2053 gdk_window_set_static_gravities (GdkWindow *window,
2054 gboolean use_static)
2056 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2059 g_return_val_if_fail (window != NULL, FALSE);
2060 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2062 if (!use_static == !private->guffaw_gravity)
2065 if (use_static && !gdk_window_gravity_works ())
2068 private->guffaw_gravity = use_static;
2070 if (!GDK_DRAWABLE_DESTROYED (window))
2072 gdk_window_set_static_bit_gravity (window, use_static);
2074 tmp_list = private->children;
2077 gdk_window_set_static_win_gravity (window, use_static);
2079 tmp_list = tmp_list->next;