1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * Copyright (C) 1998-2004 Tor Lillqvist
4 * Copyright (C) 2001-2009 Hans Breuer
5 * Copyright (C) 2007-2009 Cody Russell
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
25 * file for a list of people on the GTK+ Team. See the ChangeLog
26 * files for a list of changes. These files are distributed with
27 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
34 #include "gdkwindowimpl.h"
35 #include "gdkprivate-win32.h"
36 #include "gdkinput-win32.h"
37 #include "gdkenumtypes.h"
39 static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable);
40 static void gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
42 static void gdk_window_impl_win32_init (GdkWindowImplWin32 *window);
43 static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass);
44 static void gdk_window_impl_win32_finalize (GObject *object);
46 static gpointer parent_class = NULL;
47 static GSList *modal_window_stack = NULL;
49 static void update_style_bits (GdkWindow *window);
50 static gboolean _gdk_window_get_functions (GdkWindow *window,
51 GdkWMFunction *functions);
53 #define WINDOW_IS_TOPLEVEL(window) \
54 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
55 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
56 GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
58 static void gdk_window_impl_iface_init (GdkWindowImplIface *iface);
61 GDK_WINDOW_SCREEN (GObject *win)
67 _gdk_window_impl_win32_get_type (void)
69 static GType object_type = 0;
73 static const GTypeInfo object_info =
75 sizeof (GdkWindowImplWin32Class),
77 (GBaseFinalizeFunc) NULL,
78 (GClassInitFunc) gdk_window_impl_win32_class_init,
79 NULL, /* class_finalize */
80 NULL, /* class_data */
81 sizeof (GdkWindowImplWin32),
83 (GInstanceInitFunc) gdk_window_impl_win32_init,
86 const GInterfaceInfo window_impl_info =
88 (GInterfaceInitFunc) gdk_window_impl_iface_init,
93 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_WIN32,
96 g_type_add_interface_static (object_type,
105 _gdk_window_impl_get_type (void)
107 return _gdk_window_impl_win32_get_type ();
111 gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
113 impl->toplevel_window_type = -1;
114 impl->hcursor = NULL;
115 impl->hicon_big = NULL;
116 impl->hicon_small = NULL;
117 impl->hint_flags = 0;
118 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
119 impl->extension_events_selected = FALSE;
120 impl->transient_owner = NULL;
121 impl->transient_children = NULL;
122 impl->num_transients = 0;
123 impl->changing_state = FALSE;
127 gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
129 GObjectClass *object_class = G_OBJECT_CLASS (klass);
130 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
132 parent_class = g_type_class_peek_parent (klass);
134 object_class->finalize = gdk_window_impl_win32_finalize;
136 drawable_class->set_colormap = gdk_window_impl_win32_set_colormap;
137 drawable_class->get_colormap = gdk_window_impl_win32_get_colormap;
141 gdk_window_impl_win32_finalize (GObject *object)
143 GdkWindowObject *wrapper;
144 GdkDrawableImplWin32 *draw_impl;
145 GdkWindowImplWin32 *window_impl;
147 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (object));
149 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (object);
150 window_impl = GDK_WINDOW_IMPL_WIN32 (object);
152 wrapper = (GdkWindowObject*) draw_impl->wrapper;
154 if (!GDK_WINDOW_DESTROYED (wrapper))
156 gdk_win32_handle_table_remove (draw_impl->handle);
159 if (window_impl->hcursor != NULL)
161 if (GetCursor () == window_impl->hcursor)
164 GDI_CALL (DestroyCursor, (window_impl->hcursor));
165 window_impl->hcursor = NULL;
168 if (window_impl->hicon_big != NULL)
170 GDI_CALL (DestroyIcon, (window_impl->hicon_big));
171 window_impl->hicon_big = NULL;
174 if (window_impl->hicon_small != NULL)
176 GDI_CALL (DestroyIcon, (window_impl->hicon_small));
177 window_impl->hicon_small = NULL;
180 G_OBJECT_CLASS (parent_class)->finalize (object);
184 _gdk_win32_adjust_client_rect (GdkWindow *window,
189 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
190 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
191 API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));
195 gdk_window_impl_win32_get_colormap (GdkDrawable *drawable)
197 GdkDrawableImplWin32 *drawable_impl;
199 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable), NULL);
201 drawable_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
203 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
204 drawable_impl->colormap == NULL)
206 drawable_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
207 g_object_ref (drawable_impl->colormap);
210 return drawable_impl->colormap;
214 gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
217 GdkWindowImplWin32 *impl;
218 GdkDrawableImplWin32 *draw_impl;
220 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
222 impl = GDK_WINDOW_IMPL_WIN32 (drawable);
223 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
226 GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
231 g_print ("gdk_window_impl_win32_set_colormap: XXX\n");
236 _gdk_root_window_size_init (void)
238 GdkWindowObject *window_object;
242 window_object = GDK_WINDOW_OBJECT (_gdk_root);
243 rect = _gdk_monitors[0].rect;
244 for (i = 1; i < _gdk_num_monitors; i++)
245 gdk_rectangle_union (&rect, &_gdk_monitors[i].rect, &rect);
247 window_object->width = rect.width;
248 window_object->height = rect.height;
252 _gdk_windowing_window_init (GdkScreen *screen)
254 GdkWindowObject *private;
255 GdkDrawableImplWin32 *draw_impl;
257 g_assert (_gdk_root == NULL);
259 _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
260 private = (GdkWindowObject *)_gdk_root;
261 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
262 private->impl_window = private;
264 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
266 draw_impl->handle = GetDesktopWindow ();
267 draw_impl->wrapper = GDK_DRAWABLE (private);
268 draw_impl->colormap = gdk_screen_get_default_colormap (_gdk_screen);
269 g_object_ref (draw_impl->colormap);
271 private->window_type = GDK_WINDOW_ROOT;
272 private->depth = gdk_visual_get_system ()->depth;
274 _gdk_root_window_size_init ();
280 private->width = GetSystemMetrics (SM_CXSCREEN);
281 private->height = GetSystemMetrics (SM_CYSCREEN);
282 private->viewable = TRUE;
284 gdk_win32_handle_table_insert ((HANDLE *) &draw_impl->handle, _gdk_root);
286 GDK_NOTE (MISC, g_print ("_gdk_root=%p\n", GDK_WINDOW_HWND (_gdk_root)));
290 get_default_title (void)
293 title = g_get_application_name ();
295 title = g_get_prgname ();
301 * is a wrapper function for RegisterWindowClassEx.
302 * It creates at least one unique class for every
303 * GdkWindowType. If support for single window-specific icons
304 * is ever needed (e.g Dialog specific), every such window should
308 RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
310 static ATOM klassTOPLEVEL = 0;
311 static ATOM klassDIALOG = 0;
312 static ATOM klassCHILD = 0;
313 static ATOM klassTEMP = 0;
314 static ATOM klassTEMPSHADOW = 0;
315 static HICON hAppIcon = NULL;
316 static HICON hAppIconSm = NULL;
317 static WNDCLASSEXW wcl;
320 wcl.cbSize = sizeof (WNDCLASSEX);
321 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
322 * on WM_SIZE and WM_MOVE. Flicker, Performance!
324 wcl.lpfnWndProc = _gdk_win32_window_procedure;
327 wcl.hInstance = _gdk_app_hmodule;
331 /* initialize once! */
332 if (0 == hAppIcon && 0 == hAppIconSm)
334 gchar sLoc [MAX_PATH+1];
336 if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
338 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
340 if (0 == hAppIcon && 0 == hAppIconSm)
342 if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
344 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
349 if (0 == hAppIcon && 0 == hAppIconSm)
351 hAppIcon = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
352 GetSystemMetrics (SM_CXICON),
353 GetSystemMetrics (SM_CYICON), 0);
354 hAppIconSm = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
355 GetSystemMetrics (SM_CXSMICON),
356 GetSystemMetrics (SM_CYSMICON), 0);
361 hAppIcon = hAppIconSm;
362 else if (0 == hAppIconSm)
363 hAppIconSm = hAppIcon;
365 wcl.lpszMenuName = NULL;
367 /* initialize once per class */
369 * HB: Setting the background brush leads to flicker, because we
370 * don't get asked how to clear the background. This is not what
371 * we want, at least not for input_only windows ...
373 #define ONCE_PER_CLASS() \
374 wcl.hIcon = CopyIcon (hAppIcon); \
375 wcl.hIconSm = CopyIcon (hAppIconSm); \
376 wcl.hbrBackground = NULL; \
377 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
381 case GDK_WINDOW_TOPLEVEL:
382 if (0 == klassTOPLEVEL)
384 wcl.lpszClassName = L"gdkWindowToplevel";
387 klassTOPLEVEL = RegisterClassExW (&wcl);
389 klass = klassTOPLEVEL;
392 case GDK_WINDOW_CHILD:
395 wcl.lpszClassName = L"gdkWindowChild";
397 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
399 klassCHILD = RegisterClassExW (&wcl);
404 case GDK_WINDOW_DIALOG:
405 if (0 == klassDIALOG)
407 wcl.lpszClassName = L"gdkWindowDialog";
408 wcl.style |= CS_SAVEBITS;
410 klassDIALOG = RegisterClassExW (&wcl);
415 case GDK_WINDOW_TEMP:
416 if ((wtype_hint == GDK_WINDOW_TYPE_HINT_MENU) ||
417 (wtype_hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU) ||
418 (wtype_hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU) ||
419 (wtype_hint == GDK_WINDOW_TYPE_HINT_TOOLTIP))
421 if (klassTEMPSHADOW == 0)
423 wcl.lpszClassName = L"gdkWindowTempShadow";
424 wcl.style |= CS_SAVEBITS;
425 if (LOBYTE (g_win32_get_windows_version()) > 0x05 ||
426 LOWORD (g_win32_get_windows_version()) == 0x0105)
428 /* Windows XP (5.1) or above */
429 wcl.style |= 0x00020000; /* CS_DROPSHADOW */
432 klassTEMPSHADOW = RegisterClassExW (&wcl);
435 klass = klassTEMPSHADOW;
441 wcl.lpszClassName = L"gdkWindowTemp";
442 wcl.style |= CS_SAVEBITS;
444 klassTEMP = RegisterClassExW (&wcl);
452 g_assert_not_reached ();
458 WIN32_API_FAILED ("RegisterClassExW");
459 g_error ("That is a fatal error");
465 _gdk_window_impl_new (GdkWindow *window,
466 GdkWindow *real_parent,
469 GdkEventMask event_mask,
470 GdkWindowAttr *attributes,
471 gint attributes_mask)
476 DWORD dwStyle = 0, dwExStyle;
478 GdkWindow *orig_parent;
479 GdkWindowObject *private;
480 GdkWindowImplWin32 *impl;
481 GdkDrawableImplWin32 *draw_impl;
484 gint window_width, window_height;
485 gint offset_x = 0, offset_y = 0;
487 private = (GdkWindowObject *)window;
489 orig_parent = real_parent;
492 g_print ("_gdk_window_impl_new: %s\n",
493 (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
494 (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" :
495 (attributes->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
496 (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
499 hparent = GDK_WINDOW_HWND (real_parent);
501 impl = g_object_new (_gdk_window_impl_get_type (), NULL);
502 private->impl = (GdkDrawable *)impl;
503 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (impl);
504 draw_impl->wrapper = GDK_DRAWABLE (window);
506 // XXX: xattributes_mask = 0
509 if (attributes_mask & GDK_WA_VISUAL)
510 visual = attributes->visual;
512 visual = gdk_visual_get_system ();
516 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
517 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
519 impl->extension_events_selected = FALSE;
522 if (attributes->wclass == GDK_INPUT_OUTPUT)
526 private->input_only = FALSE;
527 private->depth = visual->depth;
529 if (attributes_mask & GDK_WA_COLORMAP)
531 draw_impl->colormap = attributes->colormap;
532 g_object_ref (attributes->colormap);
536 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
537 g_object_ref (draw_impl->colormap);
542 /* I very much doubt using WS_EX_TRANSPARENT actually
543 * corresponds to how X11 InputOnly windows work, but it appears
544 * to work well enough for the actual use cases in gtk.
546 dwExStyle = WS_EX_TRANSPARENT;
548 private->input_only = TRUE;
549 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
550 g_object_ref (draw_impl->colormap);
551 GDK_NOTE (MISC, g_print ("... GDK_INPUT_ONLY, system colormap"));
554 switch (private->window_type)
556 case GDK_WINDOW_TOPLEVEL:
557 case GDK_WINDOW_DIALOG:
558 if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT)
560 /* The common code warns for this case. */
561 hparent = GetDesktopWindow ();
563 /* Children of foreign windows aren't toplevel windows */
564 if (GDK_WINDOW_TYPE (orig_parent) == GDK_WINDOW_FOREIGN)
566 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN;
570 if (private->window_type == GDK_WINDOW_TOPLEVEL)
571 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
573 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
575 offset_x = _gdk_offset_x;
576 offset_y = _gdk_offset_y;
580 case GDK_WINDOW_CHILD:
581 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
584 case GDK_WINDOW_TEMP:
585 /* A temp window is not necessarily a top level window */
586 dwStyle = (_gdk_root == real_parent ? WS_POPUP : WS_CHILDWINDOW);
587 dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
588 dwExStyle |= WS_EX_TOOLWINDOW;
589 offset_x = _gdk_offset_x;
590 offset_y = _gdk_offset_y;
594 g_assert_not_reached ();
597 if (private->window_type != GDK_WINDOW_CHILD)
599 rect.left = rect.top = 0;
600 rect.right = private->width;
601 rect.bottom = private->height;
603 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
605 window_width = rect.right - rect.left;
606 window_height = rect.bottom - rect.top;
610 window_width = private->width;
611 window_height = private->height;
614 if (attributes_mask & GDK_WA_TITLE)
615 title = attributes->title;
617 title = get_default_title ();
618 if (!title || !*title)
621 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
623 if (attributes_mask & GDK_WA_TYPE_HINT)
624 impl->type_hint = attributes->type_hint;
626 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
628 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
629 dwExStyle |= WS_EX_TOOLWINDOW;
632 private->parent->children = g_list_prepend (private->parent->children, window);
634 klass = RegisterGdkClass (private->window_type, impl->type_hint);
636 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
638 hwndNew = CreateWindowExW (dwExStyle,
639 MAKEINTRESOURCEW (klass),
642 ((attributes_mask & GDK_WA_X) ?
643 private->x - offset_x : CW_USEDEFAULT),
644 private->y - offset_y,
645 window_width, window_height,
650 if (GDK_WINDOW_HWND (window) != hwndNew)
652 g_warning ("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.",
653 GDK_WINDOW_HWND (window),
656 /* HB: IHMO due to a race condition the handle was increased by
657 * one, which causes much trouble. Because I can't find the
658 * real bug, try to workaround it ...
659 * To reproduce: compile with MSVC 5, DEBUG=1
662 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
663 GDK_WINDOW_HWND (window) = hwndNew;
664 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
666 /* the old behaviour, but with warning */
667 draw_impl->handle = hwndNew;
672 g_object_ref (window);
673 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
675 GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
677 window_width, window_height,
678 ((attributes_mask & GDK_WA_X) ?
679 private->x - offset_x: CW_USEDEFAULT),
680 private->y - offset_y,
682 GDK_WINDOW_HWND (window)));
684 /* Add window handle to title */
685 GDK_NOTE (MISC_OR_EVENTS, gdk_window_set_title (window, title));
689 if (draw_impl->handle == NULL)
691 WIN32_API_FAILED ("CreateWindowExW");
692 g_object_unref (window);
696 // if (!from_set_skip_taskbar_hint && private->window_type == GDK_WINDOW_TEMP)
697 // gdk_window_set_skip_taskbar_hint (window, TRUE);
699 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
700 (attributes->cursor) :
705 gdk_window_foreign_new_for_display (GdkDisplay *display,
706 GdkNativeWindow anid)
709 GdkWindowObject *private;
710 GdkWindowImplWin32 *impl;
711 GdkDrawableImplWin32 *draw_impl;
717 g_return_val_if_fail (display == _gdk_display, NULL);
719 window = g_object_new (GDK_TYPE_WINDOW, NULL);
720 private = (GdkWindowObject *)window;
721 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
722 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
723 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
724 draw_impl->wrapper = GDK_DRAWABLE (window);
725 parent = GetParent ((HWND)anid);
727 private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
728 if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
729 private->parent = (GdkWindowObject *)_gdk_root;
731 private->parent->children = g_list_prepend (private->parent->children, window);
733 draw_impl->handle = (HWND) anid;
734 GetClientRect ((HWND) anid, &rect);
736 point.y = rect.right;
737 ClientToScreen ((HWND) anid, &point);
738 if (parent != GetDesktopWindow ())
739 ScreenToClient (parent, &point);
740 private->x = point.x;
741 private->y = point.y;
742 private->width = rect.right - rect.left;
743 private->height = rect.bottom - rect.top;
744 private->window_type = GDK_WINDOW_FOREIGN;
745 private->destroyed = FALSE;
746 private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
747 if (IsWindowVisible ((HWND) anid))
748 private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
750 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
751 if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST)
752 private->state |= GDK_WINDOW_STATE_ABOVE;
754 private->state &= (~GDK_WINDOW_STATE_ABOVE);
755 private->state &= (~GDK_WINDOW_STATE_BELOW);
756 private->viewable = TRUE;
758 private->depth = gdk_visual_get_system ()->depth;
760 g_object_ref (window);
761 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
763 GDK_NOTE (MISC, g_print ("gdk_window_foreign_new_for_display: %p: %s@%+d%+d\n",
765 _gdk_win32_drawable_description (window),
766 private->x, private->y));
772 gdk_window_lookup (GdkNativeWindow hwnd)
774 return (GdkWindow*) gdk_win32_handle_table_lookup (hwnd);
778 _gdk_win32_window_destroy (GdkWindow *window,
780 gboolean foreign_destroy)
782 GdkWindowObject *private = (GdkWindowObject *)window;
783 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
786 g_return_if_fail (GDK_IS_WINDOW (window));
788 GDK_NOTE (MISC, g_print ("_gdk_win32_window_destroy: %p\n",
789 GDK_WINDOW_HWND (window)));
791 if (private->extension_events != 0)
792 _gdk_input_window_destroy (window);
794 /* Remove ourself from the modal stack */
795 _gdk_remove_modal_window (window);
797 /* Remove all our transient children */
798 tmp = window_impl->transient_children;
801 GdkWindow *child = tmp->data;
802 GdkWindowImplWin32 *child_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (child)->impl);
804 child_impl->transient_owner = NULL;
805 tmp = g_slist_next (tmp);
807 g_slist_free (window_impl->transient_children);
808 window_impl->transient_children = NULL;
810 /* Remove ourself from our transient owner */
811 if (window_impl->transient_owner != NULL)
813 gdk_window_set_transient_for (window, NULL);
816 if (!recursing && !foreign_destroy)
818 _gdk_win32_drawable_finish (private->impl);
820 private->destroyed = TRUE;
821 DestroyWindow (GDK_WINDOW_HWND (window));
824 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
828 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
830 /* It's somebody else's window, but in our hierarchy, so reparent it
831 * to the desktop, and then try to destroy it.
833 gdk_window_hide (window);
834 gdk_window_reparent (window, NULL, 0, 0);
836 PostMessage (GDK_WINDOW_HWND (window), WM_CLOSE, 0, 0);
839 /* This function is called when the window really gone.
842 gdk_window_destroy_notify (GdkWindow *window)
844 g_return_if_fail (GDK_IS_WINDOW (window));
847 g_print ("gdk_window_destroy_notify: %p%s\n",
848 GDK_WINDOW_HWND (window),
849 (GDK_WINDOW_DESTROYED (window) ? " (destroyed)" : "")));
851 if (!GDK_WINDOW_DESTROYED (window))
853 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
854 g_warning ("window %p unexpectedly destroyed",
855 GDK_WINDOW_HWND (window));
857 _gdk_window_destroy (window, TRUE);
860 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
861 g_object_unref (window);
865 get_outer_rect (GdkWindow *window,
870 rect->left = rect->top = 0;
872 rect->bottom = height;
874 _gdk_win32_adjust_client_rect (window, rect);
878 adjust_for_gravity_hints (GdkWindow *window,
883 GdkWindowObject *obj;
884 GdkWindowImplWin32 *impl;
886 obj = GDK_WINDOW_OBJECT (window);
887 impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);
889 if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
891 gint orig_x = *x, orig_y = *y;
893 switch (impl->hints.win_gravity)
895 case GDK_GRAVITY_NORTH:
896 case GDK_GRAVITY_CENTER:
897 case GDK_GRAVITY_SOUTH:
898 *x -= (outer_rect->right - outer_rect->left) / 2;
899 *x += obj->width / 2;
902 case GDK_GRAVITY_SOUTH_EAST:
903 case GDK_GRAVITY_EAST:
904 case GDK_GRAVITY_NORTH_EAST:
905 *x -= outer_rect->right - outer_rect->left;
909 case GDK_GRAVITY_STATIC:
910 *x += outer_rect->left;
917 switch (impl->hints.win_gravity)
919 case GDK_GRAVITY_WEST:
920 case GDK_GRAVITY_CENTER:
921 case GDK_GRAVITY_EAST:
922 *y -= (outer_rect->bottom - outer_rect->top) / 2;
923 *y += obj->height / 2;
926 case GDK_GRAVITY_SOUTH_WEST:
927 case GDK_GRAVITY_SOUTH:
928 case GDK_GRAVITY_SOUTH_EAST:
929 *y -= outer_rect->bottom - outer_rect->top;
933 case GDK_GRAVITY_STATIC:
934 *y += outer_rect->top;
941 (orig_x != *x || orig_y != *y) ?
942 g_print ("adjust_for_gravity_hints: x: %d->%d, y: %d->%d\n",
943 orig_x, *x, orig_y, *y)
949 show_window_internal (GdkWindow *window,
953 GdkWindowObject *private;
954 HWND old_active_window;
955 gboolean focus_on_map = TRUE;
959 private = (GdkWindowObject *) window;
961 if (private->destroyed)
964 GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
965 GDK_WINDOW_HWND (window),
966 _gdk_win32_window_state_to_string (private->state),
967 (raise ? " raise" : ""),
968 (deiconify ? " deiconify" : "")));
970 /* If asked to show (not deiconify) an withdrawn and iconified
974 !GDK_WINDOW_IS_MAPPED (window) &&
975 (private->state & GDK_WINDOW_STATE_ICONIFIED))
977 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
981 /* If asked to just show an iconified window, do nothing. */
982 if (!deiconify && (private->state & GDK_WINDOW_STATE_ICONIFIED))
985 /* If asked to deiconify an already noniconified window, do
986 * nothing. (Especially, don't cause the window to rise and
987 * activate. There are different calls for that.)
989 if (deiconify && !(private->state & GDK_WINDOW_STATE_ICONIFIED))
992 /* If asked to show (but not raise) a window that is already
993 * visible, do nothing.
995 if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
1000 if (!GDK_WINDOW_IS_MAPPED (window))
1002 gdk_synthesize_window_state (window,
1003 GDK_WINDOW_STATE_WITHDRAWN,
1005 focus_on_map = private->focus_on_map;
1008 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1010 if (private->state & GDK_WINDOW_STATE_BELOW)
1011 exstyle &= (~WS_EX_TOPMOST);
1013 if (private->state & GDK_WINDOW_STATE_ABOVE)
1014 exstyle |= WS_EX_TOPMOST;
1016 if (exstyle & WS_EX_TOPMOST)
1021 /* Use SetWindowPos to show transparent windows so automatic redraws
1022 * in other windows can be suppressed.
1024 if (exstyle & WS_EX_TRANSPARENT)
1026 UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
1029 flags |= SWP_NOZORDER;
1030 if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1031 flags |= SWP_NOACTIVATE;
1033 SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, flags);
1038 old_active_window = GetActiveWindow ();
1040 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1042 gdk_window_fullscreen (window);
1044 else if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1046 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
1048 else if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1050 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
1052 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1054 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
1058 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
1063 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1064 SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1066 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1067 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL ||
1068 GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
1070 if (focus_on_map && private->accept_focus)
1072 SetForegroundWindow (GDK_WINDOW_HWND (window));
1073 if (top == HWND_TOPMOST)
1074 SetWindowPos (GDK_WINDOW_HWND (window), top,
1076 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1080 SetWindowPos (GDK_WINDOW_HWND (window), top,
1082 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1087 BringWindowToTop (GDK_WINDOW_HWND (window));
1090 else if (old_active_window != GDK_WINDOW_HWND (window))
1092 SetActiveWindow (old_active_window);
1097 gdk_win32_window_show (GdkWindow *window,
1098 gboolean already_mapped)
1100 show_window_internal (window, FALSE, FALSE);
1104 gdk_win32_window_hide (GdkWindow *window)
1106 GdkWindowObject *private;
1108 private = (GdkWindowObject*) window;
1109 if (private->destroyed)
1112 GDK_NOTE (MISC, g_print ("gdk_win32_window_hide: %p: %s\n",
1113 GDK_WINDOW_HWND (window),
1114 _gdk_win32_window_state_to_string (private->state)));
1116 if (GDK_WINDOW_IS_MAPPED (window))
1117 gdk_synthesize_window_state (window,
1119 GDK_WINDOW_STATE_WITHDRAWN);
1121 _gdk_window_clear_update_area (window);
1123 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1124 ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
1126 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
1128 SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1130 SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
1134 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
1139 gdk_win32_window_withdraw (GdkWindow *window)
1141 GdkWindowObject *private;
1143 private = (GdkWindowObject*) window;
1144 if (private->destroyed)
1147 GDK_NOTE (MISC, g_print ("gdk_win32_window_withdraw: %p: %s\n",
1148 GDK_WINDOW_HWND (window),
1149 _gdk_win32_window_state_to_string (private->state)));
1151 gdk_window_hide (window); /* ??? */
1155 gdk_win32_window_move (GdkWindow *window,
1158 GdkWindowObject *private = (GdkWindowObject *)window;
1159 GdkWindowImplWin32 *impl;
1161 g_return_if_fail (GDK_IS_WINDOW (window));
1163 if (GDK_WINDOW_DESTROYED (window))
1166 GDK_NOTE (MISC, g_print ("gdk_win32_window_move: %p: %+d%+d\n",
1167 GDK_WINDOW_HWND (window), x, y));
1169 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1171 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1174 /* Don't check GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD.
1175 * Foreign windows (another app's windows) might be children of our
1176 * windows! Especially in the case of gtkplug/socket.
1178 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1180 _gdk_window_move_resize_child (window, x, y, private->width, private->height);
1186 get_outer_rect (window, private->width, private->height, &outer_rect);
1188 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1190 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0,"
1191 "NOACTIVATE|NOSIZE|NOZORDER)\n",
1192 GDK_WINDOW_HWND (window),
1193 x - _gdk_offset_x, y - _gdk_offset_y));
1195 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1196 x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
1197 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
1202 gdk_win32_window_resize (GdkWindow *window,
1203 gint width, gint height)
1205 GdkWindowObject *private = (GdkWindowObject*) window;
1206 GdkWindowImplWin32 *impl;
1208 g_return_if_fail (GDK_IS_WINDOW (window));
1210 if (GDK_WINDOW_DESTROYED (window))
1218 GDK_NOTE (MISC, g_print ("gdk_win32_window_resize: %p: %dx%d\n",
1219 GDK_WINDOW_HWND (window), width, height));
1221 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1223 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1226 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1228 _gdk_window_move_resize_child (window, private->x, private->y, width, height);
1234 get_outer_rect (window, width, height, &outer_rect);
1236 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,0,0,%ld,%ld,"
1237 "NOACTIVATE|NOMOVE|NOZORDER)\n",
1238 GDK_WINDOW_HWND (window),
1239 outer_rect.right - outer_rect.left,
1240 outer_rect.bottom - outer_rect.top));
1242 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1244 outer_rect.right - outer_rect.left,
1245 outer_rect.bottom - outer_rect.top,
1246 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
1247 private->resize_count += 1;
1252 gdk_win32_window_move_resize_internal (GdkWindow *window,
1258 GdkWindowObject *private;
1259 GdkWindowImplWin32 *impl;
1261 g_return_if_fail (GDK_IS_WINDOW (window));
1263 if (GDK_WINDOW_DESTROYED (window))
1271 private = GDK_WINDOW_OBJECT (window);
1272 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1274 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1277 GDK_NOTE (MISC, g_print ("gdk_win32_window_move_resize: %p: %dx%d@%+d%+d\n",
1278 GDK_WINDOW_HWND (window),
1279 width, height, x, y));
1281 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1283 _gdk_window_move_resize_child (window, x, y, width, height);
1289 get_outer_rect (window, width, height, &outer_rect);
1291 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1293 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld,"
1294 "NOACTIVATE|NOZORDER)\n",
1295 GDK_WINDOW_HWND (window),
1296 x - _gdk_offset_x, y - _gdk_offset_y,
1297 outer_rect.right - outer_rect.left,
1298 outer_rect.bottom - outer_rect.top));
1300 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1301 x - _gdk_offset_x, y - _gdk_offset_y,
1302 outer_rect.right - outer_rect.left,
1303 outer_rect.bottom - outer_rect.top,
1304 SWP_NOACTIVATE | SWP_NOZORDER));
1309 gdk_win32_window_move_resize (GdkWindow *window,
1316 if (with_move && (width < 0 && height < 0))
1318 gdk_win32_window_move (window, x, y);
1324 gdk_win32_window_move_resize_internal (window, x, y, width, height);
1328 gdk_win32_window_resize (window, width, height);
1334 gdk_win32_window_reparent (GdkWindow *window,
1335 GdkWindow *new_parent,
1339 GdkWindowObject *window_private;
1340 GdkWindowObject *parent_private;
1341 GdkWindowObject *old_parent_private;
1342 GdkWindowImplWin32 *impl;
1343 gboolean was_toplevel;
1347 new_parent = _gdk_root;
1349 window_private = (GdkWindowObject*) window;
1350 old_parent_private = (GdkWindowObject *) window_private->parent;
1351 parent_private = (GdkWindowObject*) new_parent;
1352 impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
1354 GDK_NOTE (MISC, g_print ("gdk_win32_window_reparent: %p: %p\n",
1355 GDK_WINDOW_HWND (window),
1356 GDK_WINDOW_HWND (new_parent)));
1358 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1360 was_toplevel = GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) == GetDesktopWindow ();
1361 if (was_toplevel && new_parent != _gdk_root)
1363 /* Reparenting from top-level (child of desktop). Clear out
1366 style &= ~(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
1368 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1370 else if (new_parent == _gdk_root)
1372 /* Reparenting to top-level. Add decorations. */
1373 style &= ~(WS_CHILD);
1374 style |= WS_OVERLAPPEDWINDOW;
1375 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1378 API_CALL (SetParent, (GDK_WINDOW_HWND (window),
1379 GDK_WINDOW_HWND (new_parent)));
1381 API_CALL (MoveWindow, (GDK_WINDOW_HWND (window),
1382 x, y, window_private->width, window_private->height, TRUE));
1384 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1387 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1388 new_parent = _gdk_root;
1390 window_private->parent = (GdkWindowObject *)new_parent;
1392 /* Switch the window type as appropriate */
1394 switch (GDK_WINDOW_TYPE (new_parent))
1396 case GDK_WINDOW_ROOT:
1397 if (impl->toplevel_window_type != -1)
1398 GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
1399 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1400 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1403 case GDK_WINDOW_TOPLEVEL:
1404 case GDK_WINDOW_CHILD:
1405 case GDK_WINDOW_DIALOG:
1406 case GDK_WINDOW_TEMP:
1407 if (WINDOW_IS_TOPLEVEL (window))
1409 /* Save the original window type so we can restore it if the
1410 * window is reparented back to be a toplevel.
1412 impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
1413 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1417 if (old_parent_private)
1418 old_parent_private->children =
1419 g_list_remove (old_parent_private->children, window);
1421 parent_private->children = g_list_prepend (parent_private->children, window);
1427 gdk_win32_window_raise (GdkWindow *window)
1429 if (!GDK_WINDOW_DESTROYED (window))
1431 GDK_NOTE (MISC, g_print ("gdk_win32_window_raise: %p\n",
1432 GDK_WINDOW_HWND (window)));
1434 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1435 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1437 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1438 else if (((GdkWindowObject *)window)->accept_focus)
1439 API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
1441 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
1443 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1448 gdk_win32_window_lower (GdkWindow *window)
1450 if (!GDK_WINDOW_DESTROYED (window))
1452 GDK_NOTE (MISC, g_print ("gdk_win32_window_lower: %p\n"
1453 "... SetWindowPos(%p,HWND_BOTTOM,0,0,0,0,"
1454 "NOACTIVATE|NOMOVE|NOSIZE)\n",
1455 GDK_WINDOW_HWND (window),
1456 GDK_WINDOW_HWND (window)));
1458 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1460 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1465 gdk_window_set_hints (GdkWindow *window,
1474 /* Note that this function is obsolete */
1476 GdkWindowImplWin32 *impl;
1478 g_return_if_fail (GDK_IS_WINDOW (window));
1480 if (GDK_WINDOW_DESTROYED (window))
1483 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1485 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %p: %dx%d..%dx%d @%+d%+d\n",
1486 GDK_WINDOW_HWND (window),
1487 min_width, min_height, max_width, max_height,
1495 geom.min_width = min_width;
1496 geom.min_height = min_height;
1497 geom.max_width = max_width;
1498 geom.max_height = max_height;
1500 if (flags & GDK_HINT_MIN_SIZE)
1501 geom_mask |= GDK_HINT_MIN_SIZE;
1503 if (flags & GDK_HINT_MAX_SIZE)
1504 geom_mask |= GDK_HINT_MAX_SIZE;
1506 gdk_window_set_geometry_hints (window, &geom, geom_mask);
1511 gdk_window_set_urgency_hint (GdkWindow *window,
1514 FLASHWINFO flashwinfo;
1515 typedef BOOL (*PFN_FlashWindowEx) (FLASHWINFO*);
1516 PFN_FlashWindowEx flashWindowEx = NULL;
1518 g_return_if_fail (GDK_IS_WINDOW (window));
1519 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1521 if (GDK_WINDOW_DESTROYED (window))
1524 flashWindowEx = (PFN_FlashWindowEx) GetProcAddress (GetModuleHandle ("user32.dll"), "FlashWindowEx");
1528 flashwinfo.cbSize = sizeof (flashwinfo);
1529 flashwinfo.hwnd = GDK_WINDOW_HWND (window);
1531 flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
1533 flashwinfo.dwFlags = FLASHW_STOP;
1534 flashwinfo.uCount = 0;
1535 flashwinfo.dwTimeout = 0;
1537 flashWindowEx (&flashwinfo);
1541 FlashWindow (GDK_WINDOW_HWND (window), urgent);
1546 get_effective_window_decorations (GdkWindow *window,
1547 GdkWMDecoration *decoration)
1549 GdkWindowImplWin32 *impl;
1551 impl = (GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl;
1553 if (gdk_window_get_decorations (window, decoration))
1556 if (((GdkWindowObject *) window)->window_type != GDK_WINDOW_TOPLEVEL &&
1557 ((GdkWindowObject *) window)->window_type != GDK_WINDOW_DIALOG)
1562 if ((impl->hint_flags & GDK_HINT_MIN_SIZE) &&
1563 (impl->hint_flags & GDK_HINT_MAX_SIZE) &&
1564 impl->hints.min_width == impl->hints.max_width &&
1565 impl->hints.min_height == impl->hints.max_height)
1567 *decoration = GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MAXIMIZE;
1569 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1570 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1571 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1573 *decoration |= GDK_DECOR_MINIMIZE;
1575 else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
1577 *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE;
1582 else if (impl->hint_flags & GDK_HINT_MAX_SIZE)
1584 *decoration = GDK_DECOR_ALL | GDK_DECOR_MAXIMIZE;
1585 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1586 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1587 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1589 *decoration |= GDK_DECOR_MINIMIZE;
1596 switch (impl->type_hint)
1598 case GDK_WINDOW_TYPE_HINT_DIALOG:
1599 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1602 case GDK_WINDOW_TYPE_HINT_MENU:
1603 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1606 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1607 case GDK_WINDOW_TYPE_HINT_UTILITY:
1608 gdk_window_set_skip_taskbar_hint (window, TRUE);
1609 gdk_window_set_skip_pager_hint (window, TRUE);
1610 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1613 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1614 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MENU |
1615 GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1618 case GDK_WINDOW_TYPE_HINT_DOCK:
1621 case GDK_WINDOW_TYPE_HINT_DESKTOP:
1626 case GDK_WINDOW_TYPE_HINT_NORMAL:
1627 *decoration = GDK_DECOR_ALL;
1636 gdk_window_set_geometry_hints (GdkWindow *window,
1637 const GdkGeometry *geometry,
1638 GdkWindowHints geom_mask)
1640 GdkWindowImplWin32 *impl;
1642 g_return_if_fail (GDK_IS_WINDOW (window));
1644 if (GDK_WINDOW_DESTROYED (window))
1647 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints: %p\n",
1648 GDK_WINDOW_HWND (window)));
1650 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1652 impl->hint_flags = geom_mask;
1653 impl->hints = *geometry;
1655 if (geom_mask & GDK_HINT_POS)
1656 ; /* even the X11 mplementation doesn't care */
1658 if (geom_mask & GDK_HINT_MIN_SIZE)
1660 GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n",
1661 geometry->min_width, geometry->min_height));
1664 if (geom_mask & GDK_HINT_MAX_SIZE)
1666 GDK_NOTE (MISC, g_print ("... MAX_SIZE: %dx%d\n",
1667 geometry->max_width, geometry->max_height));
1670 if (geom_mask & GDK_HINT_BASE_SIZE)
1672 GDK_NOTE (MISC, g_print ("... BASE_SIZE: %dx%d\n",
1673 geometry->base_width, geometry->base_height));
1676 if (geom_mask & GDK_HINT_RESIZE_INC)
1678 GDK_NOTE (MISC, g_print ("... RESIZE_INC: (%d,%d)\n",
1679 geometry->width_inc, geometry->height_inc));
1682 if (geom_mask & GDK_HINT_ASPECT)
1684 GDK_NOTE (MISC, g_print ("... ASPECT: %g--%g\n",
1685 geometry->min_aspect, geometry->max_aspect));
1688 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1690 GDK_NOTE (MISC, g_print ("... GRAVITY: %d\n", geometry->win_gravity));
1693 update_style_bits (window);
1697 gdk_window_set_title (GdkWindow *window,
1702 g_return_if_fail (GDK_IS_WINDOW (window));
1703 g_return_if_fail (title != NULL);
1705 if (GDK_WINDOW_DESTROYED (window))
1708 /* Empty window titles not allowed, so set it to just a period. */
1712 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
1713 GDK_WINDOW_HWND (window), title));
1715 GDK_NOTE (MISC_OR_EVENTS, title = g_strdup_printf ("%p %s", GDK_WINDOW_HWND (window), title));
1717 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
1718 API_CALL (SetWindowTextW, (GDK_WINDOW_HWND (window), wtitle));
1721 GDK_NOTE (MISC_OR_EVENTS, g_free ((char *) title));
1725 gdk_window_set_role (GdkWindow *window,
1728 g_return_if_fail (GDK_IS_WINDOW (window));
1730 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %p: %s\n",
1731 GDK_WINDOW_HWND (window),
1732 (role ? role : "NULL")));
1737 gdk_window_set_transient_for (GdkWindow *window,
1740 HWND window_id, parent_id;
1741 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1742 GdkWindowImplWin32 *parent_impl = NULL;
1745 g_return_if_fail (GDK_IS_WINDOW (window));
1747 window_id = GDK_WINDOW_HWND (window);
1748 parent_id = parent != NULL ? GDK_WINDOW_HWND (parent) : NULL;
1750 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n", window_id, parent_id));
1752 if (GDK_WINDOW_DESTROYED (window) || (parent && GDK_WINDOW_DESTROYED (parent)))
1754 if (GDK_WINDOW_DESTROYED (window))
1755 GDK_NOTE (MISC, g_print ("... destroyed!\n"));
1757 GDK_NOTE (MISC, g_print ("... owner destroyed!\n"));
1762 if (((GdkWindowObject *) window)->window_type == GDK_WINDOW_CHILD)
1764 GDK_NOTE (MISC, g_print ("... a child window!\n"));
1770 GdkWindowImplWin32 *trans_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window_impl->transient_owner)->impl);
1771 if (trans_impl->transient_children != NULL)
1773 item = g_slist_find (trans_impl->transient_children, window);
1775 trans_impl->transient_children = g_slist_delete_link (trans_impl->transient_children, item);
1776 trans_impl->num_transients--;
1778 if (!trans_impl->num_transients)
1780 trans_impl->transient_children = NULL;
1783 g_object_unref (G_OBJECT (window_impl->transient_owner));
1784 g_object_unref (G_OBJECT (window));
1786 window_impl->transient_owner = NULL;
1790 parent_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (parent)->impl);
1792 parent_impl->transient_children = g_slist_append (parent_impl->transient_children, window);
1793 g_object_ref (G_OBJECT (window));
1794 parent_impl->num_transients++;
1795 window_impl->transient_owner = parent;
1796 g_object_ref (G_OBJECT (parent));
1799 /* This changes the *owner* of the window, despite the misleading
1800 * name. (Owner and parent are unrelated concepts.) At least that's
1801 * what people who seem to know what they talk about say on
1802 * USENET. Search on Google.
1805 if (SetWindowLongPtr (window_id, GWLP_HWNDPARENT, (LONG_PTR) parent_id) == 0 &&
1806 GetLastError () != 0)
1807 WIN32_API_FAILED ("SetWindowLongPtr");
1811 _gdk_push_modal_window (GdkWindow *window)
1813 modal_window_stack = g_slist_prepend (modal_window_stack,
1818 _gdk_remove_modal_window (GdkWindow *window)
1822 g_return_if_fail (window != NULL);
1824 /* It's possible to be NULL here if someone sets the modal hint of the window
1825 * to FALSE before a modal window stack has ever been created. */
1826 if (modal_window_stack == NULL)
1829 /* Find the requested window in the stack and remove it. Yeah, I realize this
1830 * means we're not a 'real stack', strictly speaking. Sue me. :) */
1831 tmp = g_slist_find (modal_window_stack, window);
1834 modal_window_stack = g_slist_delete_link (modal_window_stack, tmp);
1839 _gdk_modal_current ()
1841 if (modal_window_stack != NULL)
1843 GSList *tmp = modal_window_stack;
1845 while (tmp != NULL && !GDK_WINDOW_IS_MAPPED (tmp->data))
1847 tmp = g_slist_next (tmp);
1850 return tmp != NULL ? tmp->data : NULL;
1859 gdk_win32_window_set_background (GdkWindow *window,
1860 const GdkColor *color)
1862 GdkWindowObject *private = (GdkWindowObject *)window;
1864 GDK_NOTE (MISC, g_print ("gdk_win32_window_set_background: %p: %s\n",
1865 GDK_WINDOW_HWND (window),
1866 _gdk_win32_color_to_string (color)));
1868 private->bg_color = *color;
1872 gdk_win32_window_set_back_pixmap (GdkWindow *window,
1875 /* TODO_CSW? but win32 has no XSetWindowBackgroundPixmap */
1879 gdk_win32_window_set_cursor (GdkWindow *window,
1882 GdkWindowImplWin32 *impl;
1883 GdkCursorPrivate *cursor_private;
1884 GdkWindowObject *parent_window;
1886 HCURSOR hprevcursor;
1888 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1889 cursor_private = (GdkCursorPrivate*) cursor;
1891 if (GDK_WINDOW_DESTROYED (window))
1897 hcursor = cursor_private->hcursor;
1899 GDK_NOTE (MISC, g_print ("gdk_win32_window_set_cursor: %p: %p\n",
1900 GDK_WINDOW_HWND (window),
1903 /* First get the old cursor, if any (we wait to free the old one
1904 * since it may be the current cursor set in the Win32 API right
1907 hprevcursor = impl->hcursor;
1909 if (hcursor == NULL)
1910 impl->hcursor = NULL;
1913 /* We must copy the cursor as it is OK to destroy the GdkCursor
1914 * while still in use for some window. See for instance
1915 * gimp_change_win_cursor() which calls gdk_window_set_cursor
1916 * (win, cursor), and immediately afterwards gdk_cursor_destroy
1919 if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
1920 WIN32_API_FAILED ("CopyCursor");
1921 GDK_NOTE (MISC, g_print ("... CopyCursor (%p) = %p\n",
1922 hcursor, impl->hcursor));
1925 if (impl->hcursor != NULL)
1927 /* If the pointer is over our window, set new cursor */
1928 GdkWindow *curr_window = gdk_window_get_pointer (window, NULL, NULL, NULL);
1929 if (curr_window == window ||
1930 (curr_window && window == gdk_window_get_toplevel (curr_window)))
1931 SetCursor (impl->hcursor);
1934 /* Climb up the tree and find whether our window is the
1935 * first ancestor that has cursor defined, and if so, set
1938 GdkWindowObject *curr_window_obj = GDK_WINDOW_OBJECT (curr_window);
1939 while (curr_window_obj &&
1940 !GDK_WINDOW_IMPL_WIN32 (curr_window_obj->impl)->hcursor)
1942 curr_window_obj = curr_window_obj->parent;
1943 if (curr_window_obj == GDK_WINDOW_OBJECT (window))
1945 SetCursor (impl->hcursor);
1952 /* Destroy the previous cursor: Need to make sure it's no longer in
1953 * use before we destroy it, in case we're not over our window but
1954 * the cursor is still set to our old one.
1956 if (hprevcursor != NULL)
1958 if (GetCursor () == hprevcursor)
1960 /* Look for a suitable cursor to use instead */
1962 parent_window = GDK_WINDOW_OBJECT (window)->parent;
1963 while (hcursor == NULL)
1967 impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl);
1968 hcursor = impl->hcursor;
1969 parent_window = parent_window->parent;
1973 hcursor = LoadCursor (NULL, IDC_ARROW);
1976 SetCursor (hcursor);
1979 GDK_NOTE (MISC, g_print ("... DestroyCursor (%p)\n", hprevcursor));
1981 API_CALL (DestroyCursor, (hprevcursor));
1986 gdk_win32_window_get_geometry (GdkWindow *window,
1996 if (!GDK_WINDOW_DESTROYED (window))
2000 API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
2002 if (window != _gdk_root)
2005 GdkWindow *parent = gdk_window_get_parent (window);
2009 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2010 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
2016 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2017 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
2021 if (parent == _gdk_root)
2023 rect.left += _gdk_offset_x;
2024 rect.top += _gdk_offset_y;
2025 rect.right += _gdk_offset_x;
2026 rect.bottom += _gdk_offset_y;
2035 *width = rect.right - rect.left;
2037 *height = rect.bottom - rect.top;
2039 *depth = gdk_drawable_get_visual (window)->depth;
2041 GDK_NOTE (MISC, g_print ("gdk_win32_window_get_geometry: %p: %ldx%ldx%d@%+ld%+ld\n",
2042 GDK_WINDOW_HWND (window),
2043 rect.right - rect.left, rect.bottom - rect.top,
2044 gdk_drawable_get_visual (window)->depth,
2045 rect.left, rect.top));
2050 gdk_win32_window_get_root_coords (GdkWindow *window,
2062 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2067 *root_x = tx + _gdk_offset_x;
2069 *root_y = ty + _gdk_offset_y;
2071 GDK_NOTE (MISC, g_print ("gdk_win32_window_get_root_coords: %p: %+d%+d %+d%+d\n",
2072 GDK_WINDOW_HWND (window),
2074 tx + _gdk_offset_x, ty + _gdk_offset_y));
2079 gdk_win32_window_get_deskrelative_origin (GdkWindow *window,
2083 return gdk_win32_window_get_root_coords (window, 0, 0, x, y);
2087 gdk_win32_window_restack_under (GdkWindow *window,
2088 GList *native_siblings)
2094 gdk_win32_window_restack_toplevel (GdkWindow *window,
2102 gdk_window_get_root_origin (GdkWindow *window,
2108 g_return_if_fail (GDK_IS_WINDOW (window));
2110 gdk_window_get_frame_extents (window, &rect);
2118 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %p: %+d%+d\n",
2119 GDK_WINDOW_HWND (window), rect.x, rect.y));
2123 gdk_window_get_frame_extents (GdkWindow *window,
2126 GdkWindowObject *private;
2130 g_return_if_fail (GDK_IS_WINDOW (window));
2131 g_return_if_fail (rect != NULL);
2133 private = GDK_WINDOW_OBJECT (window);
2140 if (GDK_WINDOW_DESTROYED (window))
2143 /* FIXME: window is documented to be a toplevel GdkWindow, so is it really
2144 * necessary to walk its parent chain?
2146 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
2147 private = (GdkWindowObject*) private->parent;
2149 hwnd = GDK_WINDOW_HWND (window);
2150 API_CALL (GetWindowRect, (hwnd, &r));
2152 rect->x = r.left + _gdk_offset_x;
2153 rect->y = r.top + _gdk_offset_y;
2154 rect->width = r.right - r.left;
2155 rect->height = r.bottom - r.top;
2157 GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@%+ld%+ld\n",
2158 GDK_WINDOW_HWND (window),
2159 r.right - r.left, r.bottom - r.top,
2164 static GdkModifierType
2165 get_current_mask (void)
2167 GdkModifierType mask;
2170 GetKeyboardState (kbd);
2172 if (kbd[VK_SHIFT] & 0x80)
2173 mask |= GDK_SHIFT_MASK;
2174 if (kbd[VK_CAPITAL] & 0x80)
2175 mask |= GDK_LOCK_MASK;
2176 if (kbd[VK_CONTROL] & 0x80)
2177 mask |= GDK_CONTROL_MASK;
2178 if (kbd[VK_MENU] & 0x80)
2179 mask |= GDK_MOD1_MASK;
2180 if (kbd[VK_LBUTTON] & 0x80)
2181 mask |= GDK_BUTTON1_MASK;
2182 if (kbd[VK_MBUTTON] & 0x80)
2183 mask |= GDK_BUTTON2_MASK;
2184 if (kbd[VK_RBUTTON] & 0x80)
2185 mask |= GDK_BUTTON3_MASK;
2191 gdk_window_win32_get_pointer (GdkWindow *window,
2194 GdkModifierType *mask)
2196 gboolean return_val;
2200 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
2204 hwnd = GDK_WINDOW_HWND (window);
2205 GetCursorPos (&point);
2206 ScreenToClient (hwnd, &point);
2211 if (window == _gdk_root)
2213 *x += _gdk_offset_x;
2214 *y += _gdk_offset_y;
2217 hwndc = ChildWindowFromPoint (hwnd, point);
2218 if (hwndc != NULL && hwndc != hwnd &&
2219 !gdk_win32_handle_table_lookup ((GdkNativeWindow) hwndc))
2220 return_val = FALSE; /* Direct child unknown to gdk */
2222 *mask = get_current_mask ();
2228 _gdk_windowing_get_pointer (GdkDisplay *display,
2232 GdkModifierType *mask)
2236 g_return_if_fail (display == _gdk_display);
2238 *screen = _gdk_screen;
2239 GetCursorPos (&point);
2240 *x = point.x + _gdk_offset_x;
2241 *y = point.y + _gdk_offset_y;
2243 *mask = get_current_mask ();
2247 gdk_display_warp_pointer (GdkDisplay *display,
2252 g_return_if_fail (display == _gdk_display);
2253 g_return_if_fail (screen == _gdk_screen);
2255 SetCursorPos (x - _gdk_offset_x, y - _gdk_offset_y);
2259 _gdk_windowing_window_at_pointer (GdkDisplay *display,
2262 GdkModifierType *mask,
2263 gboolean get_toplevel)
2266 POINT point, pointc;
2270 GetCursorPos (&pointc);
2272 hwnd = WindowFromPoint (point);
2277 *win_x = pointc.x + _gdk_offset_x;
2278 *win_y = pointc.y + _gdk_offset_y;
2282 ScreenToClient (hwnd, &point);
2286 (window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd)) != NULL &&
2287 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
2290 hwndc = ChildWindowFromPoint (hwnd, point);
2291 ClientToScreen (hwnd, &point);
2292 ScreenToClient (hwndc, &point);
2293 } while (hwndc != hwnd && (hwnd = hwndc, 1));
2295 window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
2297 if (window && (win_x || win_y))
2299 GetClientRect (hwnd, &rect);
2300 *win_x = point.x - rect.left;
2301 *win_y = point.y - rect.top;
2304 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_at_pointer: %+d%+d %p%s\n",
2307 (window == NULL ? " NULL" : "")));
2313 gdk_win32_window_get_events (GdkWindow *window)
2315 if (GDK_WINDOW_DESTROYED (window))
2318 return GDK_WINDOW_OBJECT (window)->event_mask;
2322 gdk_win32_window_set_events (GdkWindow *window,
2323 GdkEventMask event_mask)
2325 /* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
2326 * set it here, too. Not that I know or remember why it is
2327 * necessary, will have to test some day.
2329 GDK_WINDOW_OBJECT (window)->event_mask = GDK_STRUCTURE_MASK | event_mask;
2333 do_shape_combine_region (GdkWindow *window,
2339 GetClientRect (GDK_WINDOW_HWND (window), &rect);
2340 _gdk_win32_adjust_client_rect (window, &rect);
2342 OffsetRgn (hrgn, -rect.left, -rect.top);
2343 OffsetRgn (hrgn, x, y);
2345 /* If this is a top-level window, add the title bar to the region */
2346 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
2348 HRGN tmp = CreateRectRgn (0, 0, rect.right - rect.left, -rect.top);
2349 CombineRgn (hrgn, hrgn, tmp, RGN_OR);
2353 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
2357 gdk_window_set_override_redirect (GdkWindow *window,
2358 gboolean override_redirect)
2360 g_return_if_fail (GDK_IS_WINDOW (window));
2362 g_warning ("gdk_window_set_override_redirect not implemented");
2366 gdk_window_set_accept_focus (GdkWindow *window,
2367 gboolean accept_focus)
2369 GdkWindowObject *private;
2371 g_return_if_fail (GDK_IS_WINDOW (window));
2373 private = (GdkWindowObject *)window;
2375 accept_focus = accept_focus != FALSE;
2377 if (private->accept_focus != accept_focus)
2378 private->accept_focus = accept_focus;
2382 gdk_window_set_focus_on_map (GdkWindow *window,
2383 gboolean focus_on_map)
2385 GdkWindowObject *private;
2387 g_return_if_fail (GDK_IS_WINDOW (window));
2389 private = (GdkWindowObject *)window;
2391 focus_on_map = focus_on_map != FALSE;
2393 if (private->focus_on_map != focus_on_map)
2394 private->focus_on_map = focus_on_map;
2398 gdk_window_set_icon_list (GdkWindow *window,
2401 GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
2402 gint big_diff, small_diff;
2403 gint big_w, big_h, small_w, small_h;
2406 HICON small_hicon, big_hicon;
2407 GdkWindowImplWin32 *impl;
2408 gint i, big_i, small_i;
2410 g_return_if_fail (GDK_IS_WINDOW (window));
2412 if (GDK_WINDOW_DESTROYED (window))
2415 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
2417 /* ideal sizes for small and large icons */
2418 big_w = GetSystemMetrics (SM_CXICON);
2419 big_h = GetSystemMetrics (SM_CYICON);
2420 small_w = GetSystemMetrics (SM_CXSMICON);
2421 small_h = GetSystemMetrics (SM_CYSMICON);
2423 /* find closest sized icons in the list */
2425 small_pixbuf = NULL;
2431 pixbuf = (GdkPixbuf*) pixbufs->data;
2432 w = gdk_pixbuf_get_width (pixbuf);
2433 h = gdk_pixbuf_get_height (pixbuf);
2435 dw = ABS (w - big_w);
2436 dh = ABS (h - big_h);
2437 diff = dw*dw + dh*dh;
2438 if (big_pixbuf == NULL || diff < big_diff)
2440 big_pixbuf = pixbuf;
2445 dw = ABS (w - small_w);
2446 dh = ABS (h - small_h);
2447 diff = dw*dw + dh*dh;
2448 if (small_pixbuf == NULL || diff < small_diff)
2450 small_pixbuf = pixbuf;
2455 pixbufs = g_list_next (pixbufs);
2459 /* Create the icons */
2460 big_hicon = _gdk_win32_pixbuf_to_hicon (big_pixbuf);
2461 small_hicon = _gdk_win32_pixbuf_to_hicon (small_pixbuf);
2464 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
2466 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_SMALL,
2467 (LPARAM)small_hicon);
2469 /* Store the icons, destroying any previous icons */
2470 if (impl->hicon_big)
2471 GDI_CALL (DestroyIcon, (impl->hicon_big));
2472 impl->hicon_big = big_hicon;
2473 if (impl->hicon_small)
2474 GDI_CALL (DestroyIcon, (impl->hicon_small));
2475 impl->hicon_small = small_hicon;
2479 gdk_window_set_icon (GdkWindow *window,
2480 GdkWindow *icon_window,
2484 g_return_if_fail (GDK_IS_WINDOW (window));
2486 /* do nothing, use gdk_window_set_icon_list instead */
2490 gdk_window_set_icon_name (GdkWindow *window,
2493 /* In case I manage to confuse this again (or somebody else does):
2494 * Please note that "icon name" here really *does* mean the name or
2495 * title of an window minimized as an icon on the desktop, or in the
2496 * taskbar. It has nothing to do with the freedesktop.org icon
2500 g_return_if_fail (GDK_IS_WINDOW (window));
2502 if (GDK_WINDOW_DESTROYED (window))
2506 /* This is not the correct thing to do. We should keep both the
2507 * "normal" window title, and the icon name. When the window is
2508 * minimized, call SetWindowText() with the icon name, and when the
2509 * window is restored, with the normal window title. Also, the name
2510 * is in UTF-8, so we should do the normal conversion to either wide
2511 * chars or system codepage, and use either the W or A version of
2512 * SetWindowText(), depending on Windows version.
2514 API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
2519 gdk_window_get_group (GdkWindow *window)
2521 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2522 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
2524 if (GDK_WINDOW_DESTROYED (window))
2527 g_warning ("gdk_window_get_group not yet implemented");
2533 gdk_window_set_group (GdkWindow *window,
2536 g_return_if_fail (GDK_IS_WINDOW (window));
2537 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2538 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
2540 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2543 g_warning ("gdk_window_set_group not implemented");
2547 update_single_bit (LONG *style,
2552 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2553 * gdk_bit indicates whether style_bit is off; if all is FALSE, gdk
2554 * bit indicate whether style_bit is on
2556 if ((!all && gdk_bit) || (all && !gdk_bit))
2557 *style |= style_bit;
2559 *style &= ~style_bit;
2563 update_style_bits (GdkWindow *window)
2565 GdkWindowObject *private = (GdkWindowObject *)window;
2566 GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)private->impl;
2567 GdkWMDecoration decorations;
2568 LONG old_style, new_style, old_exstyle, new_exstyle;
2570 RECT rect, before, after;
2572 old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2573 old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
2575 GetClientRect (GDK_WINDOW_HWND (window), &before);
2577 AdjustWindowRectEx (&before, old_style, FALSE, old_exstyle);
2579 new_style = old_style;
2580 new_exstyle = old_exstyle;
2582 if (private->window_type == GDK_WINDOW_TEMP ||
2583 impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
2584 new_exstyle |= WS_EX_TOOLWINDOW;
2586 new_exstyle &= ~WS_EX_TOOLWINDOW;
2588 if (get_effective_window_decorations (window, &decorations))
2590 all = (decorations & GDK_DECOR_ALL);
2591 update_single_bit (&new_style, all, decorations & GDK_DECOR_BORDER, WS_BORDER);
2592 update_single_bit (&new_style, all, decorations & GDK_DECOR_RESIZEH, WS_THICKFRAME);
2593 update_single_bit (&new_style, all, decorations & GDK_DECOR_TITLE, WS_CAPTION);
2594 update_single_bit (&new_style, all, decorations & GDK_DECOR_MENU, WS_SYSMENU);
2595 update_single_bit (&new_style, all, decorations & GDK_DECOR_MINIMIZE, WS_MINIMIZEBOX);
2596 update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
2599 if (old_style == new_style && old_exstyle == new_exstyle )
2601 GDK_NOTE (MISC, g_print ("update_style_bits: %p: no change\n",
2602 GDK_WINDOW_HWND (window)));
2606 if (old_style != new_style)
2608 GDK_NOTE (MISC, g_print ("update_style_bits: %p: STYLE: %s => %s\n",
2609 GDK_WINDOW_HWND (window),
2610 _gdk_win32_window_style_to_string (old_style),
2611 _gdk_win32_window_style_to_string (new_style)));
2613 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, new_style);
2616 if (old_exstyle != new_exstyle)
2618 GDK_NOTE (MISC, g_print ("update_style_bits: %p: EXSTYLE: %s => %s\n",
2619 GDK_WINDOW_HWND (window),
2620 _gdk_win32_window_exstyle_to_string (old_exstyle),
2621 _gdk_win32_window_exstyle_to_string (new_exstyle)));
2623 SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, new_exstyle);
2626 AdjustWindowRectEx (&after, new_style, FALSE, new_exstyle);
2628 GetWindowRect (GDK_WINDOW_HWND (window), &rect);
2629 rect.left += after.left - before.left;
2630 rect.top += after.top - before.top;
2631 rect.right += after.right - before.right;
2632 rect.bottom += after.bottom - before.bottom;
2634 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
2635 rect.left, rect.top,
2636 rect.right - rect.left, rect.bottom - rect.top,
2637 SWP_FRAMECHANGED | SWP_NOACTIVATE |
2638 SWP_NOREPOSITION | SWP_NOZORDER);
2643 update_single_system_menu_entry (HMENU hmenu,
2648 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2649 * gdk_bit indicates whether menu entry is disabled; if all is
2650 * FALSE, gdk bit indicate whether menu entry is enabled
2652 if ((!all && gdk_bit) || (all && !gdk_bit))
2653 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_ENABLED);
2655 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_GRAYED);
2659 update_system_menu (GdkWindow *window)
2661 GdkWMFunction functions;
2664 if (_gdk_window_get_functions (window, &functions))
2666 HMENU hmenu = GetSystemMenu (GDK_WINDOW_HWND (window), FALSE);
2668 all = (functions & GDK_FUNC_ALL);
2669 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_RESIZE, SC_SIZE);
2670 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MOVE, SC_MOVE);
2671 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MINIMIZE, SC_MINIMIZE);
2672 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MAXIMIZE, SC_MAXIMIZE);
2673 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_CLOSE, SC_CLOSE);
2678 get_decorations_quark ()
2680 static GQuark quark = 0;
2683 quark = g_quark_from_static_string ("gdk-window-decorations");
2689 gdk_window_set_decorations (GdkWindow *window,
2690 GdkWMDecoration decorations)
2692 GdkWMDecoration* decorations_copy;
2694 g_return_if_fail (GDK_IS_WINDOW (window));
2696 GDK_NOTE (MISC, g_print ("gdk_window_set_decorations: %p: %s %s%s%s%s%s%s\n",
2697 GDK_WINDOW_HWND (window),
2698 (decorations & GDK_DECOR_ALL ? "clearing" : "setting"),
2699 (decorations & GDK_DECOR_BORDER ? "BORDER " : ""),
2700 (decorations & GDK_DECOR_RESIZEH ? "RESIZEH " : ""),
2701 (decorations & GDK_DECOR_TITLE ? "TITLE " : ""),
2702 (decorations & GDK_DECOR_MENU ? "MENU " : ""),
2703 (decorations & GDK_DECOR_MINIMIZE ? "MINIMIZE " : ""),
2704 (decorations & GDK_DECOR_MAXIMIZE ? "MAXIMIZE " : "")));
2706 decorations_copy = g_malloc (sizeof (GdkWMDecoration));
2707 *decorations_copy = decorations;
2708 g_object_set_qdata_full (G_OBJECT (window), get_decorations_quark (), decorations_copy, g_free);
2710 update_style_bits (window);
2714 gdk_window_get_decorations (GdkWindow *window,
2715 GdkWMDecoration *decorations)
2717 GdkWMDecoration* decorations_set;
2719 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2721 decorations_set = g_object_get_qdata (G_OBJECT (window), get_decorations_quark ());
2722 if (decorations_set)
2723 *decorations = *decorations_set;
2725 return (decorations_set != NULL);
2729 get_functions_quark ()
2731 static GQuark quark = 0;
2734 quark = g_quark_from_static_string ("gdk-window-functions");
2740 gdk_window_set_functions (GdkWindow *window,
2741 GdkWMFunction functions)
2743 GdkWMFunction* functions_copy;
2745 g_return_if_fail (GDK_IS_WINDOW (window));
2747 GDK_NOTE (MISC, g_print ("gdk_window_set_functions: %p: %s %s%s%s%s%s\n",
2748 GDK_WINDOW_HWND (window),
2749 (functions & GDK_FUNC_ALL ? "clearing" : "setting"),
2750 (functions & GDK_FUNC_RESIZE ? "RESIZE " : ""),
2751 (functions & GDK_FUNC_MOVE ? "MOVE " : ""),
2752 (functions & GDK_FUNC_MINIMIZE ? "MINIMIZE " : ""),
2753 (functions & GDK_FUNC_MAXIMIZE ? "MAXIMIZE " : ""),
2754 (functions & GDK_FUNC_CLOSE ? "CLOSE " : "")));
2756 functions_copy = g_malloc (sizeof (GdkWMFunction));
2757 *functions_copy = functions;
2758 g_object_set_qdata_full (G_OBJECT (window), get_functions_quark (), functions_copy, g_free);
2760 update_system_menu (window);
2764 _gdk_window_get_functions (GdkWindow *window,
2765 GdkWMFunction *functions)
2767 GdkWMDecoration* functions_set;
2769 functions_set = g_object_get_qdata (G_OBJECT (window), get_functions_quark ());
2771 *functions = *functions_set;
2773 return (functions_set != NULL);
2777 QueryTree (HWND hwnd,
2787 child = GetWindow (hwnd, GW_CHILD);
2789 child = GetWindow (child, GW_HWNDNEXT);
2792 } while (child != NULL);
2796 *children = g_new (HWND, n);
2797 for (i = 0; i < n; i++)
2800 child = GetWindow (hwnd, GW_CHILD);
2802 child = GetWindow (child, GW_HWNDNEXT);
2803 *children[i] = child;
2809 gdk_win32_window_set_static_gravities (GdkWindow *window,
2810 gboolean use_static)
2812 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2818 gdk_window_begin_resize_drag (GdkWindow *window,
2827 g_return_if_fail (GDK_IS_WINDOW (window));
2829 if (GDK_WINDOW_DESTROYED (window))
2832 /* Tell Windows to start interactively resizing the window by pretending that
2833 * the left pointer button was clicked in the suitable edge or corner. This
2834 * will only work if the button is down when this function is called, and
2835 * will only work with button 1 (left), since Windows only allows window
2836 * dragging using the left mouse button.
2841 /* Must break the automatic grab that occured when the button was
2842 * pressed, otherwise it won't work.
2844 gdk_display_pointer_ungrab (_gdk_display, 0);
2848 case GDK_WINDOW_EDGE_NORTH_WEST:
2849 winedge = HTTOPLEFT;
2852 case GDK_WINDOW_EDGE_NORTH:
2856 case GDK_WINDOW_EDGE_NORTH_EAST:
2857 winedge = HTTOPRIGHT;
2860 case GDK_WINDOW_EDGE_WEST:
2864 case GDK_WINDOW_EDGE_EAST:
2868 case GDK_WINDOW_EDGE_SOUTH_WEST:
2869 winedge = HTBOTTOMLEFT;
2872 case GDK_WINDOW_EDGE_SOUTH:
2876 case GDK_WINDOW_EDGE_SOUTH_EAST:
2878 winedge = HTBOTTOMRIGHT;
2882 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, winedge,
2883 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
2887 gdk_window_begin_move_drag (GdkWindow *window,
2893 g_return_if_fail (GDK_IS_WINDOW (window));
2895 if (GDK_WINDOW_DESTROYED (window))
2898 /* Tell Windows to start interactively moving the window by pretending that
2899 * the left pointer button was clicked in the titlebar. This will only work
2900 * if the button is down when this function is called, and will only work
2901 * with button 1 (left), since Windows only allows window dragging using the
2902 * left mouse button.
2907 /* Must break the automatic grab that occured when the button was pressed,
2908 * otherwise it won't work.
2910 gdk_display_pointer_ungrab (_gdk_display, 0);
2912 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, HTCAPTION,
2913 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
2918 * Setting window states
2921 gdk_window_iconify (GdkWindow *window)
2923 HWND old_active_window;
2925 g_return_if_fail (GDK_IS_WINDOW (window));
2927 if (GDK_WINDOW_DESTROYED (window))
2930 GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
2931 GDK_WINDOW_HWND (window),
2932 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2934 if (GDK_WINDOW_IS_MAPPED (window))
2936 old_active_window = GetActiveWindow ();
2937 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
2938 if (old_active_window != GDK_WINDOW_HWND (window))
2939 SetActiveWindow (old_active_window);
2943 gdk_synthesize_window_state (window,
2945 GDK_WINDOW_STATE_ICONIFIED);
2950 gdk_window_deiconify (GdkWindow *window)
2952 g_return_if_fail (GDK_IS_WINDOW (window));
2954 if (GDK_WINDOW_DESTROYED (window))
2957 GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
2958 GDK_WINDOW_HWND (window),
2959 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2961 if (GDK_WINDOW_IS_MAPPED (window))
2963 show_window_internal (window, FALSE, TRUE);
2967 gdk_synthesize_window_state (window,
2968 GDK_WINDOW_STATE_ICONIFIED,
2974 gdk_window_stick (GdkWindow *window)
2976 g_return_if_fail (GDK_IS_WINDOW (window));
2978 if (GDK_WINDOW_DESTROYED (window))
2981 /* FIXME: Do something? */
2985 gdk_window_unstick (GdkWindow *window)
2987 g_return_if_fail (GDK_IS_WINDOW (window));
2989 if (GDK_WINDOW_DESTROYED (window))
2992 /* FIXME: Do something? */
2996 gdk_window_maximize (GdkWindow *window)
2998 g_return_if_fail (GDK_IS_WINDOW (window));
3000 if (GDK_WINDOW_DESTROYED (window))
3003 GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
3004 GDK_WINDOW_HWND (window),
3005 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3007 if (GDK_WINDOW_IS_MAPPED (window))
3008 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
3010 gdk_synthesize_window_state (window,
3012 GDK_WINDOW_STATE_MAXIMIZED);
3016 gdk_window_unmaximize (GdkWindow *window)
3018 g_return_if_fail (GDK_IS_WINDOW (window));
3020 if (GDK_WINDOW_DESTROYED (window))
3023 GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
3024 GDK_WINDOW_HWND (window),
3025 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3027 if (GDK_WINDOW_IS_MAPPED (window))
3028 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
3030 gdk_synthesize_window_state (window,
3031 GDK_WINDOW_STATE_MAXIMIZED,
3035 typedef struct _FullscreenInfo FullscreenInfo;
3037 struct _FullscreenInfo
3045 gdk_window_fullscreen (GdkWindow *window)
3047 gint x, y, width, height;
3049 GdkWindowObject *private = (GdkWindowObject *) window;
3053 g_return_if_fail (GDK_IS_WINDOW (window));
3055 fi = g_new (FullscreenInfo, 1);
3057 if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
3061 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
3063 monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
3064 mi.cbSize = sizeof (mi);
3065 if (monitor && GetMonitorInfo (monitor, &mi))
3067 x = mi.rcMonitor.left;
3068 y = mi.rcMonitor.top;
3069 width = mi.rcMonitor.right - x;
3070 height = mi.rcMonitor.bottom - y;
3075 width = GetSystemMetrics (SM_CXSCREEN);
3076 height = GetSystemMetrics (SM_CYSCREEN);
3079 /* remember for restoring */
3080 fi->hint_flags = impl->hint_flags;
3081 impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
3082 g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
3083 fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
3085 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3086 (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
3088 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
3089 x, y, width, height,
3090 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
3092 gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
3097 gdk_window_unfullscreen (GdkWindow *window)
3100 GdkWindowObject *private = (GdkWindowObject *) window;
3102 g_return_if_fail (GDK_IS_WINDOW (window));
3104 fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
3107 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
3109 impl->hint_flags = fi->hint_flags;
3110 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
3111 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
3112 fi->r.left, fi->r.top,
3113 fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
3114 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
3116 g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
3119 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
3124 gdk_window_set_keep_above (GdkWindow *window,
3127 g_return_if_fail (GDK_IS_WINDOW (window));
3129 if (GDK_WINDOW_DESTROYED (window))
3132 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_above: %p: %s\n",
3133 GDK_WINDOW_HWND (window),
3134 setting ? "YES" : "NO"));
3136 if (GDK_WINDOW_IS_MAPPED (window))
3138 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3139 setting ? HWND_TOPMOST : HWND_NOTOPMOST,
3141 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
3144 gdk_synthesize_window_state (window,
3145 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
3146 setting ? GDK_WINDOW_STATE_ABOVE : 0);
3150 gdk_window_set_keep_below (GdkWindow *window,
3153 g_return_if_fail (GDK_IS_WINDOW (window));
3155 if (GDK_WINDOW_DESTROYED (window))
3158 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_below: %p: %s\n",
3159 GDK_WINDOW_HWND (window),
3160 setting ? "YES" : "NO"));
3162 if (GDK_WINDOW_IS_MAPPED (window))
3164 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3165 setting ? HWND_BOTTOM : HWND_NOTOPMOST,
3167 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
3170 gdk_synthesize_window_state (window,
3171 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
3172 setting ? GDK_WINDOW_STATE_BELOW : 0);
3176 gdk_window_focus (GdkWindow *window,
3179 g_return_if_fail (GDK_IS_WINDOW (window));
3181 if (GDK_WINDOW_DESTROYED (window))
3184 GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
3185 GDK_WINDOW_HWND (window),
3186 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3188 if (((GdkWindowObject *) window)->state & GDK_WINDOW_STATE_MAXIMIZED)
3189 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
3191 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
3192 SetFocus (GDK_WINDOW_HWND (window));
3196 gdk_window_set_modal_hint (GdkWindow *window,
3199 GdkWindowObject *private;
3201 g_return_if_fail (GDK_IS_WINDOW (window));
3203 if (GDK_WINDOW_DESTROYED (window))
3206 GDK_NOTE (MISC, g_print ("gdk_window_set_modal_hint: %p: %s\n",
3207 GDK_WINDOW_HWND (window),
3208 modal ? "YES" : "NO"));
3210 private = (GdkWindowObject*) window;
3212 if (modal == private->modal_hint)
3215 private->modal_hint = modal;
3218 /* Not sure about this one.. -- Cody */
3219 if (GDK_WINDOW_IS_MAPPED (window))
3220 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3221 modal ? HWND_TOPMOST : HWND_NOTOPMOST,
3223 SWP_NOMOVE | SWP_NOSIZE));
3228 _gdk_push_modal_window (window);
3229 gdk_window_raise (window);
3233 _gdk_remove_modal_window (window);
3240 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
3241 gboolean skips_taskbar)
3243 static GdkWindow *owner = NULL;
3246 g_return_if_fail (GDK_IS_WINDOW (window));
3248 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s, doing nothing\n",
3249 GDK_WINDOW_HWND (window),
3250 skips_taskbar ? "YES" : "NO"));
3252 // ### TODO: Need to figure out what to do here.
3260 wa.window_type = GDK_WINDOW_TEMP;
3261 wa.wclass = GDK_INPUT_OUTPUT;
3262 wa.width = wa.height = 1;
3264 owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
3268 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner));
3270 #if 0 /* Should we also turn off the minimize and maximize buttons? */
3271 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3272 GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
3274 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
3276 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
3277 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
3282 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, 0);
3287 gdk_window_set_skip_pager_hint (GdkWindow *window,
3288 gboolean skips_pager)
3290 g_return_if_fail (GDK_IS_WINDOW (window));
3292 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_pager_hint: %p: %s, doing nothing\n",
3293 GDK_WINDOW_HWND (window),
3294 skips_pager ? "YES" : "NO"));
3298 gdk_window_set_type_hint (GdkWindow *window,
3299 GdkWindowTypeHint hint)
3301 g_return_if_fail (GDK_IS_WINDOW (window));
3303 if (GDK_WINDOW_DESTROYED (window))
3308 static GEnumClass *class = NULL;
3310 class = g_type_class_ref (GDK_TYPE_WINDOW_TYPE_HINT);
3311 g_print ("gdk_window_set_type_hint: %p: %s\n",
3312 GDK_WINDOW_HWND (window),
3313 g_enum_get_value (class, hint)->value_name);
3316 ((GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl)->type_hint = hint;
3318 update_style_bits (window);
3322 gdk_window_get_type_hint (GdkWindow *window)
3324 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
3326 if (GDK_WINDOW_DESTROYED (window))
3327 return GDK_WINDOW_TYPE_HINT_NORMAL;
3329 return GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->type_hint;
3333 gdk_win32_window_shape_combine_region (GdkWindow *window,
3334 const GdkRegion *shape_region,
3338 if (GDK_WINDOW_DESTROYED (window))
3343 GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: none\n",
3344 GDK_WINDOW_HWND (window)));
3345 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
3351 hrgn = _gdk_win32_gdkregion_to_hrgn (shape_region, 0, 0);
3353 GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: %p\n",
3354 GDK_WINDOW_HWND (window),
3357 do_shape_combine_region (window, hrgn, offset_x, offset_y);
3362 gdk_window_lookup_for_display (GdkDisplay *display,
3363 GdkNativeWindow anid)
3365 g_return_val_if_fail (display == _gdk_display, NULL);
3367 return gdk_window_lookup (anid);
3371 gdk_window_enable_synchronized_configure (GdkWindow *window)
3373 g_return_if_fail (GDK_IS_WINDOW (window));
3377 gdk_window_configure_finished (GdkWindow *window)
3379 g_return_if_fail (GDK_IS_WINDOW (window));
3383 _gdk_windowing_window_beep (GdkWindow *window)
3385 gdk_display_beep (_gdk_display);
3389 gdk_window_set_opacity (GdkWindow *window,
3393 typedef BOOL (*PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
3394 PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
3396 g_return_if_fail (GDK_IS_WINDOW (window));
3397 g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
3399 if (GDK_WINDOW_DESTROYED (window))
3404 else if (opacity > 1)
3407 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
3409 if (!(exstyle & WS_EX_LAYERED))
3410 API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window),
3412 exstyle | WS_EX_LAYERED));
3414 setLayeredWindowAttributes =
3415 (PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
3417 if (setLayeredWindowAttributes)
3419 API_CALL (setLayeredWindowAttributes, (GDK_WINDOW_HWND (window),
3427 _gdk_windowing_get_shape_for_mask (GdkBitmap *mask)
3430 HRGN hrgn = _gdk_win32_bitmap_to_hrgn (mask);
3432 region = _gdk_win32_hrgn_to_region (hrgn);
3433 DeleteObject (hrgn);
3439 _gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
3444 _gdk_windowing_window_get_shape (GdkWindow *window)
3446 HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
3447 int type = GetWindowRgn (GDK_WINDOW_HWND (window), hrgn);
3449 if (type == SIMPLEREGION || type == COMPLEXREGION)
3451 GdkRegion *region = _gdk_win32_hrgn_to_region (hrgn);
3453 DeleteObject (hrgn);
3461 _gdk_windowing_window_get_input_shape (GdkWindow *window)
3463 /* CHECK: are these really supposed to be the same? */
3464 return _gdk_windowing_window_get_shape (window);
3468 _gdk_win32_window_queue_antiexpose (GdkWindow *window,
3471 HRGN hrgn = _gdk_win32_gdkregion_to_hrgn (area, 0, 0);
3473 GDK_NOTE (EVENTS, g_print ("_gdk_windowing_window_queue_antiexpose: ValidateRgn %p %s\n",
3474 GDK_WINDOW_HWND (window),
3475 _gdk_win32_gdkregion_to_string (area)));
3477 ValidateRgn (GDK_WINDOW_HWND (window), hrgn);
3479 DeleteObject (hrgn);
3485 * queue_translation is meant to only move any outstanding invalid area
3486 * in the given area by dx,dy. A typical example of when its needed is an
3487 * app with two toplevels where one (A) overlaps the other (B). If the
3488 * app first moves A so that B is invalidated and then scrolls B before
3489 * handling the expose. The scroll operation will copy the invalid area
3490 * to a new position, but when the invalid area is then exposed it only
3491 * redraws the old areas not the place where the invalid data was copied
3495 _gdk_win32_window_queue_translation (GdkWindow *window,
3501 HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
3502 int ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE);
3504 WIN32_API_FAILED ("GetUpdateRgn");
3505 else if (ret != NULLREGION)
3507 /* Get current updateregion, move any part of it that intersects area by dx,dy */
3508 HRGN update = _gdk_win32_gdkregion_to_hrgn (area, 0, 0);
3509 ret = CombineRgn (update, hrgn, update, RGN_AND);
3511 WIN32_API_FAILED ("CombineRgn");
3512 else if (ret != NULLREGION)
3514 OffsetRgn (update, dx, dy);
3515 API_CALL (InvalidateRgn, (GDK_WINDOW_HWND (window), update, TRUE));
3517 DeleteObject (update);
3519 DeleteObject (hrgn);
3523 gdk_win32_input_shape_combine_region (GdkWindow *window,
3524 const GdkRegion *shape_region,
3528 if (GDK_WINDOW_DESTROYED (window))
3530 /* CHECK: are these really supposed to be the same? */
3531 gdk_win32_window_shape_combine_region (window, shape_region, offset_x, offset_y);
3535 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
3538 _gdk_window_process_updates_recurse (window, region);
3542 _gdk_windowing_before_process_all_updates (void)
3547 _gdk_windowing_after_process_all_updates (void)
3552 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
3554 iface->show = gdk_win32_window_show;
3555 iface->hide = gdk_win32_window_hide;
3556 iface->withdraw = gdk_win32_window_withdraw;
3557 iface->set_events = gdk_win32_window_set_events;
3558 iface->get_events = gdk_win32_window_get_events;
3559 iface->raise = gdk_win32_window_raise;
3560 iface->lower = gdk_win32_window_lower;
3561 iface->restack_under = gdk_win32_window_restack_under;
3562 iface->restack_toplevel = gdk_win32_window_restack_toplevel;
3563 iface->move_resize = gdk_win32_window_move_resize;
3564 iface->set_background = gdk_win32_window_set_background;
3565 iface->set_back_pixmap = gdk_win32_window_set_back_pixmap;
3566 iface->reparent = gdk_win32_window_reparent;
3567 iface->set_cursor = gdk_win32_window_set_cursor;
3568 iface->get_geometry = gdk_win32_window_get_geometry;
3569 iface->get_pointer = gdk_window_win32_get_pointer;
3570 iface->get_root_coords = gdk_win32_window_get_root_coords;
3571 iface->shape_combine_region = gdk_win32_window_shape_combine_region;
3572 iface->input_shape_combine_region = gdk_win32_input_shape_combine_region;
3573 iface->get_deskrelative_origin = gdk_win32_window_get_deskrelative_origin;
3574 iface->set_static_gravities = gdk_win32_window_set_static_gravities;
3575 iface->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
3576 iface->queue_translation = _gdk_win32_window_queue_translation;
3577 iface->destroy = _gdk_win32_window_destroy;
3578 iface->input_window_destroy = _gdk_input_window_destroy;
3579 iface->input_window_crossing = _gdk_input_crossing_event;