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 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 /* width and height already initialised in _gdk_root_window_size_init() */
281 private->viewable = TRUE;
283 gdk_win32_handle_table_insert ((HANDLE *) &draw_impl->handle, _gdk_root);
285 GDK_NOTE (MISC, g_print ("_gdk_root=%p\n", GDK_WINDOW_HWND (_gdk_root)));
289 get_default_title (void)
292 title = g_get_application_name ();
294 title = g_get_prgname ();
300 * is a wrapper function for RegisterWindowClassEx.
301 * It creates at least one unique class for every
302 * GdkWindowType. If support for single window-specific icons
303 * is ever needed (e.g Dialog specific), every such window should
307 RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
309 static ATOM klassTOPLEVEL = 0;
310 static ATOM klassDIALOG = 0;
311 static ATOM klassCHILD = 0;
312 static ATOM klassTEMP = 0;
313 static ATOM klassTEMPSHADOW = 0;
314 static HICON hAppIcon = NULL;
315 static HICON hAppIconSm = NULL;
316 static WNDCLASSEXW wcl;
319 wcl.cbSize = sizeof (WNDCLASSEX);
320 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
321 * on WM_SIZE and WM_MOVE. Flicker, Performance!
323 wcl.lpfnWndProc = _gdk_win32_window_procedure;
326 wcl.hInstance = _gdk_app_hmodule;
330 /* initialize once! */
331 if (0 == hAppIcon && 0 == hAppIconSm)
333 gchar sLoc [MAX_PATH+1];
335 if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
337 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
339 if (0 == hAppIcon && 0 == hAppIconSm)
341 if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
343 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
348 if (0 == hAppIcon && 0 == hAppIconSm)
350 hAppIcon = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
351 GetSystemMetrics (SM_CXICON),
352 GetSystemMetrics (SM_CYICON), 0);
353 hAppIconSm = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
354 GetSystemMetrics (SM_CXSMICON),
355 GetSystemMetrics (SM_CYSMICON), 0);
360 hAppIcon = hAppIconSm;
361 else if (0 == hAppIconSm)
362 hAppIconSm = hAppIcon;
364 wcl.lpszMenuName = NULL;
366 /* initialize once per class */
368 * HB: Setting the background brush leads to flicker, because we
369 * don't get asked how to clear the background. This is not what
370 * we want, at least not for input_only windows ...
372 #define ONCE_PER_CLASS() \
373 wcl.hIcon = CopyIcon (hAppIcon); \
374 wcl.hIconSm = CopyIcon (hAppIconSm); \
375 wcl.hbrBackground = NULL; \
376 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
380 case GDK_WINDOW_TOPLEVEL:
381 if (0 == klassTOPLEVEL)
383 wcl.lpszClassName = L"gdkWindowToplevel";
386 klassTOPLEVEL = RegisterClassExW (&wcl);
388 klass = klassTOPLEVEL;
391 case GDK_WINDOW_CHILD:
394 wcl.lpszClassName = L"gdkWindowChild";
396 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
398 klassCHILD = RegisterClassExW (&wcl);
403 case GDK_WINDOW_DIALOG:
404 if (0 == klassDIALOG)
406 wcl.lpszClassName = L"gdkWindowDialog";
407 wcl.style |= CS_SAVEBITS;
409 klassDIALOG = RegisterClassExW (&wcl);
414 case GDK_WINDOW_TEMP:
415 if ((wtype_hint == GDK_WINDOW_TYPE_HINT_MENU) ||
416 (wtype_hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU) ||
417 (wtype_hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU) ||
418 (wtype_hint == GDK_WINDOW_TYPE_HINT_TOOLTIP))
420 if (klassTEMPSHADOW == 0)
422 wcl.lpszClassName = L"gdkWindowTempShadow";
423 wcl.style |= CS_SAVEBITS;
424 if (LOBYTE (g_win32_get_windows_version()) > 0x05 ||
425 LOWORD (g_win32_get_windows_version()) == 0x0105)
427 /* Windows XP (5.1) or above */
428 wcl.style |= 0x00020000; /* CS_DROPSHADOW */
431 klassTEMPSHADOW = RegisterClassExW (&wcl);
434 klass = klassTEMPSHADOW;
440 wcl.lpszClassName = L"gdkWindowTemp";
441 wcl.style |= CS_SAVEBITS;
443 klassTEMP = RegisterClassExW (&wcl);
451 g_assert_not_reached ();
457 WIN32_API_FAILED ("RegisterClassExW");
458 g_error ("That is a fatal error");
464 _gdk_window_impl_new (GdkWindow *window,
465 GdkWindow *real_parent,
468 GdkEventMask event_mask,
469 GdkWindowAttr *attributes,
470 gint attributes_mask)
475 DWORD dwStyle = 0, dwExStyle;
477 GdkWindow *orig_parent;
478 GdkWindowObject *private;
479 GdkWindowImplWin32 *impl;
480 GdkDrawableImplWin32 *draw_impl;
483 gint window_width, window_height;
484 gint offset_x = 0, offset_y = 0;
486 private = (GdkWindowObject *)window;
488 orig_parent = real_parent;
491 g_print ("_gdk_window_impl_new: %s\n",
492 (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
493 (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" :
494 (attributes->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
495 (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
498 hparent = GDK_WINDOW_HWND (real_parent);
500 impl = g_object_new (_gdk_window_impl_get_type (), NULL);
501 private->impl = (GdkDrawable *)impl;
502 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (impl);
503 draw_impl->wrapper = GDK_DRAWABLE (window);
505 // XXX: xattributes_mask = 0
508 if (attributes_mask & GDK_WA_VISUAL)
509 visual = attributes->visual;
511 visual = gdk_visual_get_system ();
515 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
516 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
518 impl->extension_events_selected = FALSE;
521 if (attributes->wclass == GDK_INPUT_OUTPUT)
525 private->input_only = FALSE;
526 private->depth = visual->depth;
528 if (attributes_mask & GDK_WA_COLORMAP)
530 draw_impl->colormap = attributes->colormap;
531 g_object_ref (attributes->colormap);
535 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
536 g_object_ref (draw_impl->colormap);
541 /* I very much doubt using WS_EX_TRANSPARENT actually
542 * corresponds to how X11 InputOnly windows work, but it appears
543 * to work well enough for the actual use cases in gtk.
545 dwExStyle = WS_EX_TRANSPARENT;
547 private->input_only = TRUE;
548 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
549 g_object_ref (draw_impl->colormap);
550 GDK_NOTE (MISC, g_print ("... GDK_INPUT_ONLY, system colormap\n"));
553 switch (private->window_type)
555 case GDK_WINDOW_TOPLEVEL:
556 case GDK_WINDOW_DIALOG:
557 if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT)
559 /* The common code warns for this case. */
560 hparent = GetDesktopWindow ();
562 /* Children of foreign windows aren't toplevel windows */
563 if (GDK_WINDOW_TYPE (orig_parent) == GDK_WINDOW_FOREIGN)
565 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN;
569 if (private->window_type == GDK_WINDOW_TOPLEVEL)
570 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
572 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
574 offset_x = _gdk_offset_x;
575 offset_y = _gdk_offset_y;
579 case GDK_WINDOW_CHILD:
580 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
583 case GDK_WINDOW_TEMP:
584 /* A temp window is not necessarily a top level window */
585 dwStyle = (_gdk_root == real_parent ? WS_POPUP : WS_CHILDWINDOW);
586 dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
587 dwExStyle |= WS_EX_TOOLWINDOW;
588 offset_x = _gdk_offset_x;
589 offset_y = _gdk_offset_y;
593 g_assert_not_reached ();
596 if (private->window_type != GDK_WINDOW_CHILD)
598 rect.left = rect.top = 0;
599 rect.right = private->width;
600 rect.bottom = private->height;
602 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
604 window_width = rect.right - rect.left;
605 window_height = rect.bottom - rect.top;
609 window_width = private->width;
610 window_height = private->height;
613 if (attributes_mask & GDK_WA_TITLE)
614 title = attributes->title;
616 title = get_default_title ();
617 if (!title || !*title)
620 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
622 if (attributes_mask & GDK_WA_TYPE_HINT)
623 impl->type_hint = attributes->type_hint;
625 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
627 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
628 dwExStyle |= WS_EX_TOOLWINDOW;
631 private->parent->children = g_list_prepend (private->parent->children, window);
633 klass = RegisterGdkClass (private->window_type, impl->type_hint);
635 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
637 hwndNew = CreateWindowExW (dwExStyle,
638 MAKEINTRESOURCEW (klass),
641 ((attributes_mask & GDK_WA_X) ?
642 private->x - offset_x : CW_USEDEFAULT),
643 private->y - offset_y,
644 window_width, window_height,
649 if (GDK_WINDOW_HWND (window) != hwndNew)
651 g_warning ("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.",
652 GDK_WINDOW_HWND (window),
655 /* HB: IHMO due to a race condition the handle was increased by
656 * one, which causes much trouble. Because I can't find the
657 * real bug, try to workaround it ...
658 * To reproduce: compile with MSVC 5, DEBUG=1
661 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
662 GDK_WINDOW_HWND (window) = hwndNew;
663 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
665 /* the old behaviour, but with warning */
666 draw_impl->handle = hwndNew;
671 g_object_ref (window);
672 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
674 GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
676 window_width, window_height,
677 ((attributes_mask & GDK_WA_X) ?
678 private->x - offset_x: CW_USEDEFAULT),
679 private->y - offset_y,
681 GDK_WINDOW_HWND (window)));
683 /* Add window handle to title */
684 GDK_NOTE (MISC_OR_EVENTS, gdk_window_set_title (window, title));
688 if (draw_impl->handle == NULL)
690 WIN32_API_FAILED ("CreateWindowExW");
691 g_object_unref (window);
695 // if (!from_set_skip_taskbar_hint && private->window_type == GDK_WINDOW_TEMP)
696 // gdk_window_set_skip_taskbar_hint (window, TRUE);
698 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
699 (attributes->cursor) :
704 gdk_window_foreign_new_for_display (GdkDisplay *display,
705 GdkNativeWindow anid)
708 GdkWindowObject *private;
709 GdkWindowImplWin32 *impl;
710 GdkDrawableImplWin32 *draw_impl;
716 g_return_val_if_fail (display == _gdk_display, NULL);
718 window = g_object_new (GDK_TYPE_WINDOW, NULL);
719 private = (GdkWindowObject *)window;
720 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
721 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
722 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
723 draw_impl->wrapper = GDK_DRAWABLE (window);
724 parent = GetParent ((HWND)anid);
726 private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
727 if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
728 private->parent = (GdkWindowObject *)_gdk_root;
730 private->parent->children = g_list_prepend (private->parent->children, window);
732 draw_impl->handle = (HWND) anid;
733 GetClientRect ((HWND) anid, &rect);
735 point.y = rect.right;
736 ClientToScreen ((HWND) anid, &point);
737 if (parent != GetDesktopWindow ())
738 ScreenToClient (parent, &point);
739 private->x = point.x;
740 private->y = point.y;
741 private->width = rect.right - rect.left;
742 private->height = rect.bottom - rect.top;
743 private->window_type = GDK_WINDOW_FOREIGN;
744 private->destroyed = FALSE;
745 private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
746 if (IsWindowVisible ((HWND) anid))
747 private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
749 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
750 if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST)
751 private->state |= GDK_WINDOW_STATE_ABOVE;
753 private->state &= (~GDK_WINDOW_STATE_ABOVE);
754 private->state &= (~GDK_WINDOW_STATE_BELOW);
755 private->viewable = TRUE;
757 private->depth = gdk_visual_get_system ()->depth;
759 g_object_ref (window);
760 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
762 GDK_NOTE (MISC, g_print ("gdk_window_foreign_new_for_display: %p: %s@%+d%+d\n",
764 _gdk_win32_drawable_description (window),
765 private->x, private->y));
771 gdk_window_lookup (GdkNativeWindow hwnd)
773 return (GdkWindow*) gdk_win32_handle_table_lookup (hwnd);
777 _gdk_win32_window_destroy (GdkWindow *window,
779 gboolean foreign_destroy)
781 GdkWindowObject *private = (GdkWindowObject *)window;
782 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
785 g_return_if_fail (GDK_IS_WINDOW (window));
787 GDK_NOTE (MISC, g_print ("_gdk_win32_window_destroy: %p\n",
788 GDK_WINDOW_HWND (window)));
790 if (private->extension_events != 0)
791 _gdk_input_window_destroy (window);
793 /* Remove ourself from the modal stack */
794 _gdk_remove_modal_window (window);
796 /* Remove all our transient children */
797 tmp = window_impl->transient_children;
800 GdkWindow *child = tmp->data;
801 GdkWindowImplWin32 *child_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (child)->impl);
803 child_impl->transient_owner = NULL;
804 tmp = g_slist_next (tmp);
806 g_slist_free (window_impl->transient_children);
807 window_impl->transient_children = NULL;
809 /* Remove ourself from our transient owner */
810 if (window_impl->transient_owner != NULL)
812 gdk_window_set_transient_for (window, NULL);
815 if (!recursing && !foreign_destroy)
817 _gdk_win32_drawable_finish (private->impl);
819 private->destroyed = TRUE;
820 DestroyWindow (GDK_WINDOW_HWND (window));
823 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
827 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
829 /* It's somebody else's window, but in our hierarchy, so reparent it
830 * to the desktop, and then try to destroy it.
832 gdk_window_hide (window);
833 gdk_window_reparent (window, NULL, 0, 0);
835 PostMessage (GDK_WINDOW_HWND (window), WM_CLOSE, 0, 0);
838 /* This function is called when the window really gone.
841 gdk_window_destroy_notify (GdkWindow *window)
843 g_return_if_fail (GDK_IS_WINDOW (window));
846 g_print ("gdk_window_destroy_notify: %p%s\n",
847 GDK_WINDOW_HWND (window),
848 (GDK_WINDOW_DESTROYED (window) ? " (destroyed)" : "")));
850 if (!GDK_WINDOW_DESTROYED (window))
852 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
853 g_warning ("window %p unexpectedly destroyed",
854 GDK_WINDOW_HWND (window));
856 _gdk_window_destroy (window, TRUE);
859 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
860 g_object_unref (window);
864 get_outer_rect (GdkWindow *window,
869 rect->left = rect->top = 0;
871 rect->bottom = height;
873 _gdk_win32_adjust_client_rect (window, rect);
877 adjust_for_gravity_hints (GdkWindow *window,
882 GdkWindowObject *obj;
883 GdkWindowImplWin32 *impl;
885 obj = GDK_WINDOW_OBJECT (window);
886 impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);
888 if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
890 gint orig_x = *x, orig_y = *y;
892 switch (impl->hints.win_gravity)
894 case GDK_GRAVITY_NORTH:
895 case GDK_GRAVITY_CENTER:
896 case GDK_GRAVITY_SOUTH:
897 *x -= (outer_rect->right - outer_rect->left) / 2;
898 *x += obj->width / 2;
901 case GDK_GRAVITY_SOUTH_EAST:
902 case GDK_GRAVITY_EAST:
903 case GDK_GRAVITY_NORTH_EAST:
904 *x -= outer_rect->right - outer_rect->left;
908 case GDK_GRAVITY_STATIC:
909 *x += outer_rect->left;
916 switch (impl->hints.win_gravity)
918 case GDK_GRAVITY_WEST:
919 case GDK_GRAVITY_CENTER:
920 case GDK_GRAVITY_EAST:
921 *y -= (outer_rect->bottom - outer_rect->top) / 2;
922 *y += obj->height / 2;
925 case GDK_GRAVITY_SOUTH_WEST:
926 case GDK_GRAVITY_SOUTH:
927 case GDK_GRAVITY_SOUTH_EAST:
928 *y -= outer_rect->bottom - outer_rect->top;
932 case GDK_GRAVITY_STATIC:
933 *y += outer_rect->top;
940 (orig_x != *x || orig_y != *y) ?
941 g_print ("adjust_for_gravity_hints: x: %d->%d, y: %d->%d\n",
942 orig_x, *x, orig_y, *y)
948 show_window_internal (GdkWindow *window,
952 GdkWindowObject *private;
953 HWND old_active_window;
954 gboolean focus_on_map = TRUE;
958 private = (GdkWindowObject *) window;
960 if (private->destroyed)
963 GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
964 GDK_WINDOW_HWND (window),
965 _gdk_win32_window_state_to_string (private->state),
966 (raise ? " raise" : ""),
967 (deiconify ? " deiconify" : "")));
969 /* If asked to show (not deiconify) an withdrawn and iconified
973 !GDK_WINDOW_IS_MAPPED (window) &&
974 (private->state & GDK_WINDOW_STATE_ICONIFIED))
976 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
980 /* If asked to just show an iconified window, do nothing. */
981 if (!deiconify && (private->state & GDK_WINDOW_STATE_ICONIFIED))
984 /* If asked to deiconify an already noniconified window, do
985 * nothing. (Especially, don't cause the window to rise and
986 * activate. There are different calls for that.)
988 if (deiconify && !(private->state & GDK_WINDOW_STATE_ICONIFIED))
991 /* If asked to show (but not raise) a window that is already
992 * visible, do nothing.
994 if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
999 if (!GDK_WINDOW_IS_MAPPED (window))
1001 gdk_synthesize_window_state (window,
1002 GDK_WINDOW_STATE_WITHDRAWN,
1004 focus_on_map = private->focus_on_map;
1007 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1009 if (private->state & GDK_WINDOW_STATE_BELOW)
1010 exstyle &= (~WS_EX_TOPMOST);
1012 if (private->state & GDK_WINDOW_STATE_ABOVE)
1013 exstyle |= WS_EX_TOPMOST;
1015 if (exstyle & WS_EX_TOPMOST)
1020 /* Use SetWindowPos to show transparent windows so automatic redraws
1021 * in other windows can be suppressed.
1023 if (exstyle & WS_EX_TRANSPARENT)
1025 UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
1028 flags |= SWP_NOZORDER;
1029 if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1030 flags |= SWP_NOACTIVATE;
1032 SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, flags);
1037 old_active_window = GetActiveWindow ();
1039 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1041 gdk_window_fullscreen (window);
1043 else if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1045 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
1047 else if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1049 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
1051 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1053 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
1057 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
1062 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1063 SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1065 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1066 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL ||
1067 GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
1069 if (focus_on_map && private->accept_focus)
1071 SetForegroundWindow (GDK_WINDOW_HWND (window));
1072 if (top == HWND_TOPMOST)
1073 SetWindowPos (GDK_WINDOW_HWND (window), top,
1075 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1079 SetWindowPos (GDK_WINDOW_HWND (window), top,
1081 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1086 BringWindowToTop (GDK_WINDOW_HWND (window));
1089 else if (old_active_window != GDK_WINDOW_HWND (window))
1091 SetActiveWindow (old_active_window);
1096 gdk_win32_window_show (GdkWindow *window,
1097 gboolean already_mapped)
1099 show_window_internal (window, FALSE, FALSE);
1103 gdk_win32_window_hide (GdkWindow *window)
1105 GdkWindowObject *private;
1107 private = (GdkWindowObject*) window;
1108 if (private->destroyed)
1111 GDK_NOTE (MISC, g_print ("gdk_win32_window_hide: %p: %s\n",
1112 GDK_WINDOW_HWND (window),
1113 _gdk_win32_window_state_to_string (private->state)));
1115 if (GDK_WINDOW_IS_MAPPED (window))
1116 gdk_synthesize_window_state (window,
1118 GDK_WINDOW_STATE_WITHDRAWN);
1120 _gdk_window_clear_update_area (window);
1122 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1123 ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
1125 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
1127 SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1129 SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
1133 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
1138 gdk_win32_window_withdraw (GdkWindow *window)
1140 GdkWindowObject *private;
1142 private = (GdkWindowObject*) window;
1143 if (private->destroyed)
1146 GDK_NOTE (MISC, g_print ("gdk_win32_window_withdraw: %p: %s\n",
1147 GDK_WINDOW_HWND (window),
1148 _gdk_win32_window_state_to_string (private->state)));
1150 gdk_window_hide (window); /* ??? */
1154 gdk_win32_window_move (GdkWindow *window,
1157 GdkWindowObject *private = (GdkWindowObject *)window;
1158 GdkWindowImplWin32 *impl;
1160 g_return_if_fail (GDK_IS_WINDOW (window));
1162 if (GDK_WINDOW_DESTROYED (window))
1165 GDK_NOTE (MISC, g_print ("gdk_win32_window_move: %p: %+d%+d\n",
1166 GDK_WINDOW_HWND (window), x, y));
1168 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1170 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1173 /* Don't check GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD.
1174 * Foreign windows (another app's windows) might be children of our
1175 * windows! Especially in the case of gtkplug/socket.
1177 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1179 _gdk_window_move_resize_child (window, x, y, private->width, private->height);
1185 get_outer_rect (window, private->width, private->height, &outer_rect);
1187 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1189 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0,"
1190 "NOACTIVATE|NOSIZE|NOZORDER)\n",
1191 GDK_WINDOW_HWND (window),
1192 x - _gdk_offset_x, y - _gdk_offset_y));
1194 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1195 x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
1196 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
1201 gdk_win32_window_resize (GdkWindow *window,
1202 gint width, gint height)
1204 GdkWindowObject *private = (GdkWindowObject*) window;
1205 GdkWindowImplWin32 *impl;
1207 g_return_if_fail (GDK_IS_WINDOW (window));
1209 if (GDK_WINDOW_DESTROYED (window))
1217 GDK_NOTE (MISC, g_print ("gdk_win32_window_resize: %p: %dx%d\n",
1218 GDK_WINDOW_HWND (window), width, height));
1220 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1222 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1225 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1227 _gdk_window_move_resize_child (window, private->x, private->y, width, height);
1233 get_outer_rect (window, width, height, &outer_rect);
1235 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,0,0,%ld,%ld,"
1236 "NOACTIVATE|NOMOVE|NOZORDER)\n",
1237 GDK_WINDOW_HWND (window),
1238 outer_rect.right - outer_rect.left,
1239 outer_rect.bottom - outer_rect.top));
1241 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1243 outer_rect.right - outer_rect.left,
1244 outer_rect.bottom - outer_rect.top,
1245 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
1246 private->resize_count += 1;
1251 gdk_win32_window_move_resize_internal (GdkWindow *window,
1257 GdkWindowObject *private;
1258 GdkWindowImplWin32 *impl;
1260 g_return_if_fail (GDK_IS_WINDOW (window));
1262 if (GDK_WINDOW_DESTROYED (window))
1270 private = GDK_WINDOW_OBJECT (window);
1271 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1273 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1276 GDK_NOTE (MISC, g_print ("gdk_win32_window_move_resize: %p: %dx%d@%+d%+d\n",
1277 GDK_WINDOW_HWND (window),
1278 width, height, x, y));
1280 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1282 _gdk_window_move_resize_child (window, x, y, width, height);
1288 get_outer_rect (window, width, height, &outer_rect);
1290 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1292 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld,"
1293 "NOACTIVATE|NOZORDER)\n",
1294 GDK_WINDOW_HWND (window),
1295 x - _gdk_offset_x, y - _gdk_offset_y,
1296 outer_rect.right - outer_rect.left,
1297 outer_rect.bottom - outer_rect.top));
1299 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1300 x - _gdk_offset_x, y - _gdk_offset_y,
1301 outer_rect.right - outer_rect.left,
1302 outer_rect.bottom - outer_rect.top,
1303 SWP_NOACTIVATE | SWP_NOZORDER));
1308 gdk_win32_window_move_resize (GdkWindow *window,
1315 if (with_move && (width < 0 && height < 0))
1317 gdk_win32_window_move (window, x, y);
1323 gdk_win32_window_move_resize_internal (window, x, y, width, height);
1327 gdk_win32_window_resize (window, width, height);
1333 gdk_win32_window_reparent (GdkWindow *window,
1334 GdkWindow *new_parent,
1338 GdkWindowObject *window_private;
1339 GdkWindowObject *parent_private;
1340 GdkWindowObject *old_parent_private;
1341 GdkWindowImplWin32 *impl;
1342 gboolean was_toplevel;
1346 new_parent = _gdk_root;
1348 window_private = (GdkWindowObject*) window;
1349 old_parent_private = (GdkWindowObject *) window_private->parent;
1350 parent_private = (GdkWindowObject*) new_parent;
1351 impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
1353 GDK_NOTE (MISC, g_print ("gdk_win32_window_reparent: %p: %p\n",
1354 GDK_WINDOW_HWND (window),
1355 GDK_WINDOW_HWND (new_parent)));
1357 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1359 was_toplevel = GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) == GetDesktopWindow ();
1360 if (was_toplevel && new_parent != _gdk_root)
1362 /* Reparenting from top-level (child of desktop). Clear out
1365 style &= ~(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
1367 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1369 else if (new_parent == _gdk_root)
1371 /* Reparenting to top-level. Add decorations. */
1372 style &= ~(WS_CHILD);
1373 style |= WS_OVERLAPPEDWINDOW;
1374 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1377 API_CALL (SetParent, (GDK_WINDOW_HWND (window),
1378 GDK_WINDOW_HWND (new_parent)));
1380 API_CALL (MoveWindow, (GDK_WINDOW_HWND (window),
1381 x, y, window_private->width, window_private->height, TRUE));
1383 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1386 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1387 new_parent = _gdk_root;
1389 window_private->parent = (GdkWindowObject *)new_parent;
1391 /* Switch the window type as appropriate */
1393 switch (GDK_WINDOW_TYPE (new_parent))
1395 case GDK_WINDOW_ROOT:
1396 if (impl->toplevel_window_type != -1)
1397 GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
1398 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1399 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1402 case GDK_WINDOW_TOPLEVEL:
1403 case GDK_WINDOW_CHILD:
1404 case GDK_WINDOW_DIALOG:
1405 case GDK_WINDOW_TEMP:
1406 if (WINDOW_IS_TOPLEVEL (window))
1408 /* Save the original window type so we can restore it if the
1409 * window is reparented back to be a toplevel.
1411 impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
1412 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1416 if (old_parent_private)
1417 old_parent_private->children =
1418 g_list_remove (old_parent_private->children, window);
1420 parent_private->children = g_list_prepend (parent_private->children, window);
1426 gdk_win32_window_raise (GdkWindow *window)
1428 if (!GDK_WINDOW_DESTROYED (window))
1430 GDK_NOTE (MISC, g_print ("gdk_win32_window_raise: %p\n",
1431 GDK_WINDOW_HWND (window)));
1433 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1434 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1436 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1437 else if (((GdkWindowObject *)window)->accept_focus)
1438 API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
1440 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
1442 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1447 gdk_win32_window_lower (GdkWindow *window)
1449 if (!GDK_WINDOW_DESTROYED (window))
1451 GDK_NOTE (MISC, g_print ("gdk_win32_window_lower: %p\n"
1452 "... SetWindowPos(%p,HWND_BOTTOM,0,0,0,0,"
1453 "NOACTIVATE|NOMOVE|NOSIZE)\n",
1454 GDK_WINDOW_HWND (window),
1455 GDK_WINDOW_HWND (window)));
1457 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1459 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1464 gdk_window_set_urgency_hint (GdkWindow *window,
1467 FLASHWINFO flashwinfo;
1468 typedef BOOL (*PFN_FlashWindowEx) (FLASHWINFO*);
1469 PFN_FlashWindowEx flashWindowEx = NULL;
1471 g_return_if_fail (GDK_IS_WINDOW (window));
1472 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1474 if (GDK_WINDOW_DESTROYED (window))
1477 flashWindowEx = (PFN_FlashWindowEx) GetProcAddress (GetModuleHandle ("user32.dll"), "FlashWindowEx");
1481 flashwinfo.cbSize = sizeof (flashwinfo);
1482 flashwinfo.hwnd = GDK_WINDOW_HWND (window);
1484 flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
1486 flashwinfo.dwFlags = FLASHW_STOP;
1487 flashwinfo.uCount = 0;
1488 flashwinfo.dwTimeout = 0;
1490 flashWindowEx (&flashwinfo);
1494 FlashWindow (GDK_WINDOW_HWND (window), urgent);
1499 get_effective_window_decorations (GdkWindow *window,
1500 GdkWMDecoration *decoration)
1502 GdkWindowImplWin32 *impl;
1504 impl = (GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl;
1506 if (gdk_window_get_decorations (window, decoration))
1509 if (((GdkWindowObject *) window)->window_type != GDK_WINDOW_TOPLEVEL &&
1510 ((GdkWindowObject *) window)->window_type != GDK_WINDOW_DIALOG)
1515 if ((impl->hint_flags & GDK_HINT_MIN_SIZE) &&
1516 (impl->hint_flags & GDK_HINT_MAX_SIZE) &&
1517 impl->hints.min_width == impl->hints.max_width &&
1518 impl->hints.min_height == impl->hints.max_height)
1520 *decoration = GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MAXIMIZE;
1522 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1523 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1524 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1526 *decoration |= GDK_DECOR_MINIMIZE;
1528 else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
1530 *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE;
1535 else if (impl->hint_flags & GDK_HINT_MAX_SIZE)
1537 *decoration = GDK_DECOR_ALL | GDK_DECOR_MAXIMIZE;
1538 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1539 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1540 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1542 *decoration |= GDK_DECOR_MINIMIZE;
1549 switch (impl->type_hint)
1551 case GDK_WINDOW_TYPE_HINT_DIALOG:
1552 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1555 case GDK_WINDOW_TYPE_HINT_MENU:
1556 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1559 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1560 case GDK_WINDOW_TYPE_HINT_UTILITY:
1561 gdk_window_set_skip_taskbar_hint (window, TRUE);
1562 gdk_window_set_skip_pager_hint (window, TRUE);
1563 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1566 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1567 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MENU |
1568 GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1571 case GDK_WINDOW_TYPE_HINT_DOCK:
1574 case GDK_WINDOW_TYPE_HINT_DESKTOP:
1579 case GDK_WINDOW_TYPE_HINT_NORMAL:
1580 *decoration = GDK_DECOR_ALL;
1589 gdk_window_set_geometry_hints (GdkWindow *window,
1590 const GdkGeometry *geometry,
1591 GdkWindowHints geom_mask)
1593 GdkWindowImplWin32 *impl;
1595 g_return_if_fail (GDK_IS_WINDOW (window));
1597 if (GDK_WINDOW_DESTROYED (window))
1600 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints: %p\n",
1601 GDK_WINDOW_HWND (window)));
1603 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1605 impl->hint_flags = geom_mask;
1606 impl->hints = *geometry;
1608 if (geom_mask & GDK_HINT_POS)
1609 ; /* even the X11 mplementation doesn't care */
1611 if (geom_mask & GDK_HINT_MIN_SIZE)
1613 GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n",
1614 geometry->min_width, geometry->min_height));
1617 if (geom_mask & GDK_HINT_MAX_SIZE)
1619 GDK_NOTE (MISC, g_print ("... MAX_SIZE: %dx%d\n",
1620 geometry->max_width, geometry->max_height));
1623 if (geom_mask & GDK_HINT_BASE_SIZE)
1625 GDK_NOTE (MISC, g_print ("... BASE_SIZE: %dx%d\n",
1626 geometry->base_width, geometry->base_height));
1629 if (geom_mask & GDK_HINT_RESIZE_INC)
1631 GDK_NOTE (MISC, g_print ("... RESIZE_INC: (%d,%d)\n",
1632 geometry->width_inc, geometry->height_inc));
1635 if (geom_mask & GDK_HINT_ASPECT)
1637 GDK_NOTE (MISC, g_print ("... ASPECT: %g--%g\n",
1638 geometry->min_aspect, geometry->max_aspect));
1641 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1643 GDK_NOTE (MISC, g_print ("... GRAVITY: %d\n", geometry->win_gravity));
1646 update_style_bits (window);
1650 gdk_window_set_title (GdkWindow *window,
1655 g_return_if_fail (GDK_IS_WINDOW (window));
1656 g_return_if_fail (title != NULL);
1658 if (GDK_WINDOW_DESTROYED (window))
1661 /* Empty window titles not allowed, so set it to just a period. */
1665 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
1666 GDK_WINDOW_HWND (window), title));
1668 GDK_NOTE (MISC_OR_EVENTS, title = g_strdup_printf ("%p %s", GDK_WINDOW_HWND (window), title));
1670 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
1671 API_CALL (SetWindowTextW, (GDK_WINDOW_HWND (window), wtitle));
1674 GDK_NOTE (MISC_OR_EVENTS, g_free ((char *) title));
1678 gdk_window_set_role (GdkWindow *window,
1681 g_return_if_fail (GDK_IS_WINDOW (window));
1683 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %p: %s\n",
1684 GDK_WINDOW_HWND (window),
1685 (role ? role : "NULL")));
1690 gdk_window_set_transient_for (GdkWindow *window,
1693 HWND window_id, parent_id;
1694 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1695 GdkWindowImplWin32 *parent_impl = NULL;
1698 g_return_if_fail (GDK_IS_WINDOW (window));
1700 window_id = GDK_WINDOW_HWND (window);
1701 parent_id = parent != NULL ? GDK_WINDOW_HWND (parent) : NULL;
1703 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n", window_id, parent_id));
1705 if (GDK_WINDOW_DESTROYED (window) || (parent && GDK_WINDOW_DESTROYED (parent)))
1707 if (GDK_WINDOW_DESTROYED (window))
1708 GDK_NOTE (MISC, g_print ("... destroyed!\n"));
1710 GDK_NOTE (MISC, g_print ("... owner destroyed!\n"));
1715 if (((GdkWindowObject *) window)->window_type == GDK_WINDOW_CHILD)
1717 GDK_NOTE (MISC, g_print ("... a child window!\n"));
1723 GdkWindowImplWin32 *trans_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window_impl->transient_owner)->impl);
1724 if (trans_impl->transient_children != NULL)
1726 item = g_slist_find (trans_impl->transient_children, window);
1728 trans_impl->transient_children = g_slist_delete_link (trans_impl->transient_children, item);
1729 trans_impl->num_transients--;
1731 if (!trans_impl->num_transients)
1733 trans_impl->transient_children = NULL;
1736 g_object_unref (G_OBJECT (window_impl->transient_owner));
1737 g_object_unref (G_OBJECT (window));
1739 window_impl->transient_owner = NULL;
1743 parent_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (parent)->impl);
1745 parent_impl->transient_children = g_slist_append (parent_impl->transient_children, window);
1746 g_object_ref (G_OBJECT (window));
1747 parent_impl->num_transients++;
1748 window_impl->transient_owner = parent;
1749 g_object_ref (G_OBJECT (parent));
1752 /* This changes the *owner* of the window, despite the misleading
1753 * name. (Owner and parent are unrelated concepts.) At least that's
1754 * what people who seem to know what they talk about say on
1755 * USENET. Search on Google.
1758 if (SetWindowLongPtr (window_id, GWLP_HWNDPARENT, (LONG_PTR) parent_id) == 0 &&
1759 GetLastError () != 0)
1760 WIN32_API_FAILED ("SetWindowLongPtr");
1764 _gdk_push_modal_window (GdkWindow *window)
1766 modal_window_stack = g_slist_prepend (modal_window_stack,
1771 _gdk_remove_modal_window (GdkWindow *window)
1775 g_return_if_fail (window != NULL);
1777 /* It's possible to be NULL here if someone sets the modal hint of the window
1778 * to FALSE before a modal window stack has ever been created. */
1779 if (modal_window_stack == NULL)
1782 /* Find the requested window in the stack and remove it. Yeah, I realize this
1783 * means we're not a 'real stack', strictly speaking. Sue me. :) */
1784 tmp = g_slist_find (modal_window_stack, window);
1787 modal_window_stack = g_slist_delete_link (modal_window_stack, tmp);
1792 _gdk_modal_current (void)
1794 if (modal_window_stack != NULL)
1796 GSList *tmp = modal_window_stack;
1798 while (tmp != NULL && !GDK_WINDOW_IS_MAPPED (tmp->data))
1800 tmp = g_slist_next (tmp);
1803 return tmp != NULL ? tmp->data : NULL;
1812 gdk_win32_window_set_background (GdkWindow *window,
1813 const GdkColor *color)
1815 GdkWindowObject *private = (GdkWindowObject *)window;
1817 GDK_NOTE (MISC, g_print ("gdk_win32_window_set_background: %p: %s\n",
1818 GDK_WINDOW_HWND (window),
1819 _gdk_win32_color_to_string (color)));
1821 private->bg_color = *color;
1825 gdk_win32_window_set_back_pixmap (GdkWindow *window,
1828 /* TODO_CSW? but win32 has no XSetWindowBackgroundPixmap */
1832 gdk_win32_window_set_cursor (GdkWindow *window,
1835 GdkWindowImplWin32 *impl;
1836 GdkCursorPrivate *cursor_private;
1837 GdkWindowObject *parent_window;
1839 HCURSOR hprevcursor;
1841 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1842 cursor_private = (GdkCursorPrivate*) cursor;
1844 if (GDK_WINDOW_DESTROYED (window))
1850 hcursor = cursor_private->hcursor;
1852 GDK_NOTE (MISC, g_print ("gdk_win32_window_set_cursor: %p: %p\n",
1853 GDK_WINDOW_HWND (window),
1856 /* First get the old cursor, if any (we wait to free the old one
1857 * since it may be the current cursor set in the Win32 API right
1860 hprevcursor = impl->hcursor;
1862 if (hcursor == NULL)
1863 impl->hcursor = NULL;
1866 /* We must copy the cursor as it is OK to destroy the GdkCursor
1867 * while still in use for some window. See for instance
1868 * gimp_change_win_cursor() which calls gdk_window_set_cursor
1869 * (win, cursor), and immediately afterwards gdk_cursor_destroy
1872 if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
1873 WIN32_API_FAILED ("CopyCursor");
1874 GDK_NOTE (MISC, g_print ("... CopyCursor (%p) = %p\n",
1875 hcursor, impl->hcursor));
1878 if (impl->hcursor != NULL)
1880 /* If the pointer is over our window, set new cursor */
1881 GdkWindow *curr_window = gdk_window_get_pointer (window, NULL, NULL, NULL);
1882 if (curr_window == window ||
1883 (curr_window && window == gdk_window_get_toplevel (curr_window)))
1884 SetCursor (impl->hcursor);
1887 /* Climb up the tree and find whether our window is the
1888 * first ancestor that has cursor defined, and if so, set
1891 GdkWindowObject *curr_window_obj = GDK_WINDOW_OBJECT (curr_window);
1892 while (curr_window_obj &&
1893 !GDK_WINDOW_IMPL_WIN32 (curr_window_obj->impl)->hcursor)
1895 curr_window_obj = curr_window_obj->parent;
1896 if (curr_window_obj == GDK_WINDOW_OBJECT (window))
1898 SetCursor (impl->hcursor);
1905 /* Destroy the previous cursor: Need to make sure it's no longer in
1906 * use before we destroy it, in case we're not over our window but
1907 * the cursor is still set to our old one.
1909 if (hprevcursor != NULL)
1911 if (GetCursor () == hprevcursor)
1913 /* Look for a suitable cursor to use instead */
1915 parent_window = GDK_WINDOW_OBJECT (window)->parent;
1916 while (hcursor == NULL)
1920 impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl);
1921 hcursor = impl->hcursor;
1922 parent_window = parent_window->parent;
1926 hcursor = LoadCursor (NULL, IDC_ARROW);
1929 SetCursor (hcursor);
1932 GDK_NOTE (MISC, g_print ("... DestroyCursor (%p)\n", hprevcursor));
1934 API_CALL (DestroyCursor, (hprevcursor));
1939 gdk_win32_window_get_geometry (GdkWindow *window,
1949 if (!GDK_WINDOW_DESTROYED (window))
1953 API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
1955 if (window != _gdk_root)
1958 GdkWindow *parent = gdk_window_get_parent (window);
1962 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1963 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1969 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1970 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1974 if (parent == _gdk_root)
1976 rect.left += _gdk_offset_x;
1977 rect.top += _gdk_offset_y;
1978 rect.right += _gdk_offset_x;
1979 rect.bottom += _gdk_offset_y;
1988 *width = rect.right - rect.left;
1990 *height = rect.bottom - rect.top;
1992 *depth = gdk_drawable_get_visual (window)->depth;
1994 GDK_NOTE (MISC, g_print ("gdk_win32_window_get_geometry: %p: %ldx%ldx%d@%+ld%+ld\n",
1995 GDK_WINDOW_HWND (window),
1996 rect.right - rect.left, rect.bottom - rect.top,
1997 gdk_drawable_get_visual (window)->depth,
1998 rect.left, rect.top));
2003 gdk_win32_window_get_root_coords (GdkWindow *window,
2015 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2020 *root_x = tx + _gdk_offset_x;
2022 *root_y = ty + _gdk_offset_y;
2024 GDK_NOTE (MISC, g_print ("gdk_win32_window_get_root_coords: %p: %+d%+d %+d%+d\n",
2025 GDK_WINDOW_HWND (window),
2027 tx + _gdk_offset_x, ty + _gdk_offset_y));
2032 gdk_win32_window_get_deskrelative_origin (GdkWindow *window,
2036 return gdk_win32_window_get_root_coords (window, 0, 0, x, y);
2040 gdk_win32_window_restack_under (GdkWindow *window,
2041 GList *native_siblings)
2047 gdk_win32_window_restack_toplevel (GdkWindow *window,
2055 gdk_window_get_root_origin (GdkWindow *window,
2061 g_return_if_fail (GDK_IS_WINDOW (window));
2063 gdk_window_get_frame_extents (window, &rect);
2071 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %p: %+d%+d\n",
2072 GDK_WINDOW_HWND (window), rect.x, rect.y));
2076 gdk_window_get_frame_extents (GdkWindow *window,
2079 GdkWindowObject *private;
2083 g_return_if_fail (GDK_IS_WINDOW (window));
2084 g_return_if_fail (rect != NULL);
2086 private = GDK_WINDOW_OBJECT (window);
2093 if (GDK_WINDOW_DESTROYED (window))
2096 /* FIXME: window is documented to be a toplevel GdkWindow, so is it really
2097 * necessary to walk its parent chain?
2099 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
2100 private = (GdkWindowObject*) private->parent;
2102 hwnd = GDK_WINDOW_HWND (window);
2103 API_CALL (GetWindowRect, (hwnd, &r));
2105 rect->x = r.left + _gdk_offset_x;
2106 rect->y = r.top + _gdk_offset_y;
2107 rect->width = r.right - r.left;
2108 rect->height = r.bottom - r.top;
2110 GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@%+ld%+ld\n",
2111 GDK_WINDOW_HWND (window),
2112 r.right - r.left, r.bottom - r.top,
2117 static GdkModifierType
2118 get_current_mask (void)
2120 GdkModifierType mask;
2123 GetKeyboardState (kbd);
2125 if (kbd[VK_SHIFT] & 0x80)
2126 mask |= GDK_SHIFT_MASK;
2127 if (kbd[VK_CAPITAL] & 0x80)
2128 mask |= GDK_LOCK_MASK;
2129 if (kbd[VK_CONTROL] & 0x80)
2130 mask |= GDK_CONTROL_MASK;
2131 if (kbd[VK_MENU] & 0x80)
2132 mask |= GDK_MOD1_MASK;
2133 if (kbd[VK_LBUTTON] & 0x80)
2134 mask |= GDK_BUTTON1_MASK;
2135 if (kbd[VK_MBUTTON] & 0x80)
2136 mask |= GDK_BUTTON2_MASK;
2137 if (kbd[VK_RBUTTON] & 0x80)
2138 mask |= GDK_BUTTON3_MASK;
2144 gdk_window_win32_get_pointer (GdkWindow *window,
2147 GdkModifierType *mask)
2149 gboolean return_val;
2153 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
2157 hwnd = GDK_WINDOW_HWND (window);
2158 GetCursorPos (&point);
2159 ScreenToClient (hwnd, &point);
2164 if (window == _gdk_root)
2166 *x += _gdk_offset_x;
2167 *y += _gdk_offset_y;
2170 hwndc = ChildWindowFromPoint (hwnd, point);
2171 if (hwndc != NULL && hwndc != hwnd &&
2172 !gdk_win32_handle_table_lookup ((GdkNativeWindow) hwndc))
2173 return_val = FALSE; /* Direct child unknown to gdk */
2175 *mask = get_current_mask ();
2181 _gdk_windowing_get_pointer (GdkDisplay *display,
2185 GdkModifierType *mask)
2189 g_return_if_fail (display == _gdk_display);
2191 *screen = _gdk_screen;
2192 GetCursorPos (&point);
2193 *x = point.x + _gdk_offset_x;
2194 *y = point.y + _gdk_offset_y;
2196 *mask = get_current_mask ();
2200 gdk_display_warp_pointer (GdkDisplay *display,
2205 g_return_if_fail (display == _gdk_display);
2206 g_return_if_fail (screen == _gdk_screen);
2208 SetCursorPos (x - _gdk_offset_x, y - _gdk_offset_y);
2212 _gdk_windowing_window_at_pointer (GdkDisplay *display,
2215 GdkModifierType *mask,
2216 gboolean get_toplevel)
2219 POINT point, pointc;
2223 GetCursorPos (&pointc);
2225 hwnd = WindowFromPoint (point);
2230 *win_x = pointc.x + _gdk_offset_x;
2231 *win_y = pointc.y + _gdk_offset_y;
2235 ScreenToClient (hwnd, &point);
2239 (window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd)) != NULL &&
2240 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
2243 hwndc = ChildWindowFromPoint (hwnd, point);
2244 ClientToScreen (hwnd, &point);
2245 ScreenToClient (hwndc, &point);
2246 } while (hwndc != hwnd && (hwnd = hwndc, 1));
2248 window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
2250 if (window && (win_x || win_y))
2252 GetClientRect (hwnd, &rect);
2253 *win_x = point.x - rect.left;
2254 *win_y = point.y - rect.top;
2257 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_at_pointer: %+d%+d %p%s\n",
2260 (window == NULL ? " NULL" : "")));
2266 gdk_win32_window_get_events (GdkWindow *window)
2268 if (GDK_WINDOW_DESTROYED (window))
2271 return GDK_WINDOW_OBJECT (window)->event_mask;
2275 gdk_win32_window_set_events (GdkWindow *window,
2276 GdkEventMask event_mask)
2278 /* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
2279 * set it here, too. Not that I know or remember why it is
2280 * necessary, will have to test some day.
2282 GDK_WINDOW_OBJECT (window)->event_mask = GDK_STRUCTURE_MASK | event_mask;
2286 do_shape_combine_region (GdkWindow *window,
2292 GetClientRect (GDK_WINDOW_HWND (window), &rect);
2293 _gdk_win32_adjust_client_rect (window, &rect);
2295 OffsetRgn (hrgn, -rect.left, -rect.top);
2296 OffsetRgn (hrgn, x, y);
2298 /* If this is a top-level window, add the title bar to the region */
2299 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
2301 HRGN tmp = CreateRectRgn (0, 0, rect.right - rect.left, -rect.top);
2302 CombineRgn (hrgn, hrgn, tmp, RGN_OR);
2306 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
2310 gdk_window_set_override_redirect (GdkWindow *window,
2311 gboolean override_redirect)
2313 g_return_if_fail (GDK_IS_WINDOW (window));
2315 g_warning ("gdk_window_set_override_redirect not implemented");
2319 gdk_window_set_accept_focus (GdkWindow *window,
2320 gboolean accept_focus)
2322 GdkWindowObject *private;
2324 g_return_if_fail (GDK_IS_WINDOW (window));
2326 private = (GdkWindowObject *)window;
2328 accept_focus = accept_focus != FALSE;
2330 if (private->accept_focus != accept_focus)
2331 private->accept_focus = accept_focus;
2335 gdk_window_set_focus_on_map (GdkWindow *window,
2336 gboolean focus_on_map)
2338 GdkWindowObject *private;
2340 g_return_if_fail (GDK_IS_WINDOW (window));
2342 private = (GdkWindowObject *)window;
2344 focus_on_map = focus_on_map != FALSE;
2346 if (private->focus_on_map != focus_on_map)
2347 private->focus_on_map = focus_on_map;
2351 gdk_window_set_icon_list (GdkWindow *window,
2354 GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
2355 gint big_diff, small_diff;
2356 gint big_w, big_h, small_w, small_h;
2359 HICON small_hicon, big_hicon;
2360 GdkWindowImplWin32 *impl;
2361 gint i, big_i, small_i;
2363 g_return_if_fail (GDK_IS_WINDOW (window));
2365 if (GDK_WINDOW_DESTROYED (window))
2368 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
2370 /* ideal sizes for small and large icons */
2371 big_w = GetSystemMetrics (SM_CXICON);
2372 big_h = GetSystemMetrics (SM_CYICON);
2373 small_w = GetSystemMetrics (SM_CXSMICON);
2374 small_h = GetSystemMetrics (SM_CYSMICON);
2376 /* find closest sized icons in the list */
2378 small_pixbuf = NULL;
2384 pixbuf = (GdkPixbuf*) pixbufs->data;
2385 w = gdk_pixbuf_get_width (pixbuf);
2386 h = gdk_pixbuf_get_height (pixbuf);
2388 dw = ABS (w - big_w);
2389 dh = ABS (h - big_h);
2390 diff = dw*dw + dh*dh;
2391 if (big_pixbuf == NULL || diff < big_diff)
2393 big_pixbuf = pixbuf;
2398 dw = ABS (w - small_w);
2399 dh = ABS (h - small_h);
2400 diff = dw*dw + dh*dh;
2401 if (small_pixbuf == NULL || diff < small_diff)
2403 small_pixbuf = pixbuf;
2408 pixbufs = g_list_next (pixbufs);
2412 /* Create the icons */
2413 big_hicon = _gdk_win32_pixbuf_to_hicon (big_pixbuf);
2414 small_hicon = _gdk_win32_pixbuf_to_hicon (small_pixbuf);
2417 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
2419 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_SMALL,
2420 (LPARAM)small_hicon);
2422 /* Store the icons, destroying any previous icons */
2423 if (impl->hicon_big)
2424 GDI_CALL (DestroyIcon, (impl->hicon_big));
2425 impl->hicon_big = big_hicon;
2426 if (impl->hicon_small)
2427 GDI_CALL (DestroyIcon, (impl->hicon_small));
2428 impl->hicon_small = small_hicon;
2432 gdk_window_set_icon (GdkWindow *window,
2433 GdkWindow *icon_window,
2437 g_return_if_fail (GDK_IS_WINDOW (window));
2439 /* do nothing, use gdk_window_set_icon_list instead */
2443 gdk_window_set_icon_name (GdkWindow *window,
2446 /* In case I manage to confuse this again (or somebody else does):
2447 * Please note that "icon name" here really *does* mean the name or
2448 * title of an window minimized as an icon on the desktop, or in the
2449 * taskbar. It has nothing to do with the freedesktop.org icon
2453 g_return_if_fail (GDK_IS_WINDOW (window));
2455 if (GDK_WINDOW_DESTROYED (window))
2459 /* This is not the correct thing to do. We should keep both the
2460 * "normal" window title, and the icon name. When the window is
2461 * minimized, call SetWindowText() with the icon name, and when the
2462 * window is restored, with the normal window title. Also, the name
2463 * is in UTF-8, so we should do the normal conversion to either wide
2464 * chars or system codepage, and use either the W or A version of
2465 * SetWindowText(), depending on Windows version.
2467 API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
2472 gdk_window_get_group (GdkWindow *window)
2474 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2475 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
2477 if (GDK_WINDOW_DESTROYED (window))
2480 g_warning ("gdk_window_get_group not yet implemented");
2486 gdk_window_set_group (GdkWindow *window,
2489 g_return_if_fail (GDK_IS_WINDOW (window));
2490 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2491 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
2493 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2496 g_warning ("gdk_window_set_group not implemented");
2500 update_single_bit (LONG *style,
2505 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2506 * gdk_bit indicates whether style_bit is off; if all is FALSE, gdk
2507 * bit indicate whether style_bit is on
2509 if ((!all && gdk_bit) || (all && !gdk_bit))
2510 *style |= style_bit;
2512 *style &= ~style_bit;
2516 update_style_bits (GdkWindow *window)
2518 GdkWindowObject *private = (GdkWindowObject *)window;
2519 GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)private->impl;
2520 GdkWMDecoration decorations;
2521 LONG old_style, new_style, old_exstyle, new_exstyle;
2523 RECT rect, before, after;
2525 old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2526 old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
2528 GetClientRect (GDK_WINDOW_HWND (window), &before);
2530 AdjustWindowRectEx (&before, old_style, FALSE, old_exstyle);
2532 new_style = old_style;
2533 new_exstyle = old_exstyle;
2535 if (private->window_type == GDK_WINDOW_TEMP ||
2536 impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
2537 new_exstyle |= WS_EX_TOOLWINDOW;
2539 new_exstyle &= ~WS_EX_TOOLWINDOW;
2541 if (get_effective_window_decorations (window, &decorations))
2543 all = (decorations & GDK_DECOR_ALL);
2544 update_single_bit (&new_style, all, decorations & GDK_DECOR_BORDER, WS_BORDER);
2545 update_single_bit (&new_style, all, decorations & GDK_DECOR_RESIZEH, WS_THICKFRAME);
2546 update_single_bit (&new_style, all, decorations & GDK_DECOR_TITLE, WS_CAPTION);
2547 update_single_bit (&new_style, all, decorations & GDK_DECOR_MENU, WS_SYSMENU);
2548 update_single_bit (&new_style, all, decorations & GDK_DECOR_MINIMIZE, WS_MINIMIZEBOX);
2549 update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
2552 if (old_style == new_style && old_exstyle == new_exstyle )
2554 GDK_NOTE (MISC, g_print ("update_style_bits: %p: no change\n",
2555 GDK_WINDOW_HWND (window)));
2559 if (old_style != new_style)
2561 GDK_NOTE (MISC, g_print ("update_style_bits: %p: STYLE: %s => %s\n",
2562 GDK_WINDOW_HWND (window),
2563 _gdk_win32_window_style_to_string (old_style),
2564 _gdk_win32_window_style_to_string (new_style)));
2566 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, new_style);
2569 if (old_exstyle != new_exstyle)
2571 GDK_NOTE (MISC, g_print ("update_style_bits: %p: EXSTYLE: %s => %s\n",
2572 GDK_WINDOW_HWND (window),
2573 _gdk_win32_window_exstyle_to_string (old_exstyle),
2574 _gdk_win32_window_exstyle_to_string (new_exstyle)));
2576 SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, new_exstyle);
2579 AdjustWindowRectEx (&after, new_style, FALSE, new_exstyle);
2581 GetWindowRect (GDK_WINDOW_HWND (window), &rect);
2582 rect.left += after.left - before.left;
2583 rect.top += after.top - before.top;
2584 rect.right += after.right - before.right;
2585 rect.bottom += after.bottom - before.bottom;
2587 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
2588 rect.left, rect.top,
2589 rect.right - rect.left, rect.bottom - rect.top,
2590 SWP_FRAMECHANGED | SWP_NOACTIVATE |
2591 SWP_NOREPOSITION | SWP_NOZORDER);
2596 update_single_system_menu_entry (HMENU hmenu,
2601 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2602 * gdk_bit indicates whether menu entry is disabled; if all is
2603 * FALSE, gdk bit indicate whether menu entry is enabled
2605 if ((!all && gdk_bit) || (all && !gdk_bit))
2606 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_ENABLED);
2608 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_GRAYED);
2612 update_system_menu (GdkWindow *window)
2614 GdkWMFunction functions;
2617 if (_gdk_window_get_functions (window, &functions))
2619 HMENU hmenu = GetSystemMenu (GDK_WINDOW_HWND (window), FALSE);
2621 all = (functions & GDK_FUNC_ALL);
2622 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_RESIZE, SC_SIZE);
2623 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MOVE, SC_MOVE);
2624 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MINIMIZE, SC_MINIMIZE);
2625 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MAXIMIZE, SC_MAXIMIZE);
2626 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_CLOSE, SC_CLOSE);
2631 get_decorations_quark ()
2633 static GQuark quark = 0;
2636 quark = g_quark_from_static_string ("gdk-window-decorations");
2642 gdk_window_set_decorations (GdkWindow *window,
2643 GdkWMDecoration decorations)
2645 GdkWMDecoration* decorations_copy;
2647 g_return_if_fail (GDK_IS_WINDOW (window));
2649 GDK_NOTE (MISC, g_print ("gdk_window_set_decorations: %p: %s %s%s%s%s%s%s\n",
2650 GDK_WINDOW_HWND (window),
2651 (decorations & GDK_DECOR_ALL ? "clearing" : "setting"),
2652 (decorations & GDK_DECOR_BORDER ? "BORDER " : ""),
2653 (decorations & GDK_DECOR_RESIZEH ? "RESIZEH " : ""),
2654 (decorations & GDK_DECOR_TITLE ? "TITLE " : ""),
2655 (decorations & GDK_DECOR_MENU ? "MENU " : ""),
2656 (decorations & GDK_DECOR_MINIMIZE ? "MINIMIZE " : ""),
2657 (decorations & GDK_DECOR_MAXIMIZE ? "MAXIMIZE " : "")));
2659 decorations_copy = g_malloc (sizeof (GdkWMDecoration));
2660 *decorations_copy = decorations;
2661 g_object_set_qdata_full (G_OBJECT (window), get_decorations_quark (), decorations_copy, g_free);
2663 update_style_bits (window);
2667 gdk_window_get_decorations (GdkWindow *window,
2668 GdkWMDecoration *decorations)
2670 GdkWMDecoration* decorations_set;
2672 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2674 decorations_set = g_object_get_qdata (G_OBJECT (window), get_decorations_quark ());
2675 if (decorations_set)
2676 *decorations = *decorations_set;
2678 return (decorations_set != NULL);
2682 get_functions_quark ()
2684 static GQuark quark = 0;
2687 quark = g_quark_from_static_string ("gdk-window-functions");
2693 gdk_window_set_functions (GdkWindow *window,
2694 GdkWMFunction functions)
2696 GdkWMFunction* functions_copy;
2698 g_return_if_fail (GDK_IS_WINDOW (window));
2700 GDK_NOTE (MISC, g_print ("gdk_window_set_functions: %p: %s %s%s%s%s%s\n",
2701 GDK_WINDOW_HWND (window),
2702 (functions & GDK_FUNC_ALL ? "clearing" : "setting"),
2703 (functions & GDK_FUNC_RESIZE ? "RESIZE " : ""),
2704 (functions & GDK_FUNC_MOVE ? "MOVE " : ""),
2705 (functions & GDK_FUNC_MINIMIZE ? "MINIMIZE " : ""),
2706 (functions & GDK_FUNC_MAXIMIZE ? "MAXIMIZE " : ""),
2707 (functions & GDK_FUNC_CLOSE ? "CLOSE " : "")));
2709 functions_copy = g_malloc (sizeof (GdkWMFunction));
2710 *functions_copy = functions;
2711 g_object_set_qdata_full (G_OBJECT (window), get_functions_quark (), functions_copy, g_free);
2713 update_system_menu (window);
2717 _gdk_window_get_functions (GdkWindow *window,
2718 GdkWMFunction *functions)
2720 GdkWMDecoration* functions_set;
2722 functions_set = g_object_get_qdata (G_OBJECT (window), get_functions_quark ());
2724 *functions = *functions_set;
2726 return (functions_set != NULL);
2730 gdk_win32_window_set_static_gravities (GdkWindow *window,
2731 gboolean use_static)
2733 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2739 gdk_window_begin_resize_drag (GdkWindow *window,
2748 g_return_if_fail (GDK_IS_WINDOW (window));
2750 if (GDK_WINDOW_DESTROYED (window))
2753 /* Tell Windows to start interactively resizing the window by pretending that
2754 * the left pointer button was clicked in the suitable edge or corner. This
2755 * will only work if the button is down when this function is called, and
2756 * will only work with button 1 (left), since Windows only allows window
2757 * dragging using the left mouse button.
2762 /* Must break the automatic grab that occured when the button was
2763 * pressed, otherwise it won't work.
2765 gdk_display_pointer_ungrab (_gdk_display, 0);
2769 case GDK_WINDOW_EDGE_NORTH_WEST:
2770 winedge = HTTOPLEFT;
2773 case GDK_WINDOW_EDGE_NORTH:
2777 case GDK_WINDOW_EDGE_NORTH_EAST:
2778 winedge = HTTOPRIGHT;
2781 case GDK_WINDOW_EDGE_WEST:
2785 case GDK_WINDOW_EDGE_EAST:
2789 case GDK_WINDOW_EDGE_SOUTH_WEST:
2790 winedge = HTBOTTOMLEFT;
2793 case GDK_WINDOW_EDGE_SOUTH:
2797 case GDK_WINDOW_EDGE_SOUTH_EAST:
2799 winedge = HTBOTTOMRIGHT;
2803 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, winedge,
2804 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
2808 gdk_window_begin_move_drag (GdkWindow *window,
2814 g_return_if_fail (GDK_IS_WINDOW (window));
2816 if (GDK_WINDOW_DESTROYED (window))
2819 /* Tell Windows to start interactively moving the window by pretending that
2820 * the left pointer button was clicked in the titlebar. This will only work
2821 * if the button is down when this function is called, and will only work
2822 * with button 1 (left), since Windows only allows window dragging using the
2823 * left mouse button.
2828 /* Must break the automatic grab that occured when the button was pressed,
2829 * otherwise it won't work.
2831 gdk_display_pointer_ungrab (_gdk_display, 0);
2833 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, HTCAPTION,
2834 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
2839 * Setting window states
2842 gdk_window_iconify (GdkWindow *window)
2844 HWND old_active_window;
2846 g_return_if_fail (GDK_IS_WINDOW (window));
2848 if (GDK_WINDOW_DESTROYED (window))
2851 GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
2852 GDK_WINDOW_HWND (window),
2853 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2855 if (GDK_WINDOW_IS_MAPPED (window))
2857 old_active_window = GetActiveWindow ();
2858 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
2859 if (old_active_window != GDK_WINDOW_HWND (window))
2860 SetActiveWindow (old_active_window);
2864 gdk_synthesize_window_state (window,
2866 GDK_WINDOW_STATE_ICONIFIED);
2871 gdk_window_deiconify (GdkWindow *window)
2873 g_return_if_fail (GDK_IS_WINDOW (window));
2875 if (GDK_WINDOW_DESTROYED (window))
2878 GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
2879 GDK_WINDOW_HWND (window),
2880 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2882 if (GDK_WINDOW_IS_MAPPED (window))
2884 show_window_internal (window, FALSE, TRUE);
2888 gdk_synthesize_window_state (window,
2889 GDK_WINDOW_STATE_ICONIFIED,
2895 gdk_window_stick (GdkWindow *window)
2897 g_return_if_fail (GDK_IS_WINDOW (window));
2899 if (GDK_WINDOW_DESTROYED (window))
2902 /* FIXME: Do something? */
2906 gdk_window_unstick (GdkWindow *window)
2908 g_return_if_fail (GDK_IS_WINDOW (window));
2910 if (GDK_WINDOW_DESTROYED (window))
2913 /* FIXME: Do something? */
2917 gdk_window_maximize (GdkWindow *window)
2919 g_return_if_fail (GDK_IS_WINDOW (window));
2921 if (GDK_WINDOW_DESTROYED (window))
2924 GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
2925 GDK_WINDOW_HWND (window),
2926 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2928 if (GDK_WINDOW_IS_MAPPED (window))
2929 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
2931 gdk_synthesize_window_state (window,
2933 GDK_WINDOW_STATE_MAXIMIZED);
2937 gdk_window_unmaximize (GdkWindow *window)
2939 g_return_if_fail (GDK_IS_WINDOW (window));
2941 if (GDK_WINDOW_DESTROYED (window))
2944 GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
2945 GDK_WINDOW_HWND (window),
2946 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2948 if (GDK_WINDOW_IS_MAPPED (window))
2949 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
2951 gdk_synthesize_window_state (window,
2952 GDK_WINDOW_STATE_MAXIMIZED,
2956 typedef struct _FullscreenInfo FullscreenInfo;
2958 struct _FullscreenInfo
2966 gdk_window_fullscreen (GdkWindow *window)
2968 gint x, y, width, height;
2970 GdkWindowObject *private = (GdkWindowObject *) window;
2974 g_return_if_fail (GDK_IS_WINDOW (window));
2976 fi = g_new (FullscreenInfo, 1);
2978 if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
2982 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
2984 monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
2985 mi.cbSize = sizeof (mi);
2986 if (monitor && GetMonitorInfo (monitor, &mi))
2988 x = mi.rcMonitor.left;
2989 y = mi.rcMonitor.top;
2990 width = mi.rcMonitor.right - x;
2991 height = mi.rcMonitor.bottom - y;
2996 width = GetSystemMetrics (SM_CXSCREEN);
2997 height = GetSystemMetrics (SM_CYSCREEN);
3000 /* remember for restoring */
3001 fi->hint_flags = impl->hint_flags;
3002 impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
3003 g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
3004 fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
3006 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3007 (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
3009 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
3010 x, y, width, height,
3011 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
3013 gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
3018 gdk_window_unfullscreen (GdkWindow *window)
3021 GdkWindowObject *private = (GdkWindowObject *) window;
3023 g_return_if_fail (GDK_IS_WINDOW (window));
3025 fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
3028 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
3030 impl->hint_flags = fi->hint_flags;
3031 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
3032 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
3033 fi->r.left, fi->r.top,
3034 fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
3035 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
3037 g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
3040 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
3045 gdk_window_set_keep_above (GdkWindow *window,
3048 g_return_if_fail (GDK_IS_WINDOW (window));
3050 if (GDK_WINDOW_DESTROYED (window))
3053 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_above: %p: %s\n",
3054 GDK_WINDOW_HWND (window),
3055 setting ? "YES" : "NO"));
3057 if (GDK_WINDOW_IS_MAPPED (window))
3059 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3060 setting ? HWND_TOPMOST : HWND_NOTOPMOST,
3062 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
3065 gdk_synthesize_window_state (window,
3066 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
3067 setting ? GDK_WINDOW_STATE_ABOVE : 0);
3071 gdk_window_set_keep_below (GdkWindow *window,
3074 g_return_if_fail (GDK_IS_WINDOW (window));
3076 if (GDK_WINDOW_DESTROYED (window))
3079 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_below: %p: %s\n",
3080 GDK_WINDOW_HWND (window),
3081 setting ? "YES" : "NO"));
3083 if (GDK_WINDOW_IS_MAPPED (window))
3085 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3086 setting ? HWND_BOTTOM : HWND_NOTOPMOST,
3088 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
3091 gdk_synthesize_window_state (window,
3092 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
3093 setting ? GDK_WINDOW_STATE_BELOW : 0);
3097 gdk_window_focus (GdkWindow *window,
3100 g_return_if_fail (GDK_IS_WINDOW (window));
3102 if (GDK_WINDOW_DESTROYED (window))
3105 GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
3106 GDK_WINDOW_HWND (window),
3107 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3109 if (((GdkWindowObject *) window)->state & GDK_WINDOW_STATE_MAXIMIZED)
3110 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
3112 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
3113 SetFocus (GDK_WINDOW_HWND (window));
3117 gdk_window_set_modal_hint (GdkWindow *window,
3120 GdkWindowObject *private;
3122 g_return_if_fail (GDK_IS_WINDOW (window));
3124 if (GDK_WINDOW_DESTROYED (window))
3127 GDK_NOTE (MISC, g_print ("gdk_window_set_modal_hint: %p: %s\n",
3128 GDK_WINDOW_HWND (window),
3129 modal ? "YES" : "NO"));
3131 private = (GdkWindowObject*) window;
3133 if (modal == private->modal_hint)
3136 private->modal_hint = modal;
3139 /* Not sure about this one.. -- Cody */
3140 if (GDK_WINDOW_IS_MAPPED (window))
3141 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3142 modal ? HWND_TOPMOST : HWND_NOTOPMOST,
3144 SWP_NOMOVE | SWP_NOSIZE));
3149 _gdk_push_modal_window (window);
3150 gdk_window_raise (window);
3154 _gdk_remove_modal_window (window);
3161 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
3162 gboolean skips_taskbar)
3164 static GdkWindow *owner = NULL;
3167 g_return_if_fail (GDK_IS_WINDOW (window));
3169 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s, doing nothing\n",
3170 GDK_WINDOW_HWND (window),
3171 skips_taskbar ? "YES" : "NO"));
3173 // ### TODO: Need to figure out what to do here.
3181 wa.window_type = GDK_WINDOW_TEMP;
3182 wa.wclass = GDK_INPUT_OUTPUT;
3183 wa.width = wa.height = 1;
3185 owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
3189 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner));
3191 #if 0 /* Should we also turn off the minimize and maximize buttons? */
3192 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3193 GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
3195 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
3197 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
3198 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
3203 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, 0);
3208 gdk_window_set_skip_pager_hint (GdkWindow *window,
3209 gboolean skips_pager)
3211 g_return_if_fail (GDK_IS_WINDOW (window));
3213 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_pager_hint: %p: %s, doing nothing\n",
3214 GDK_WINDOW_HWND (window),
3215 skips_pager ? "YES" : "NO"));
3219 gdk_window_set_type_hint (GdkWindow *window,
3220 GdkWindowTypeHint hint)
3222 g_return_if_fail (GDK_IS_WINDOW (window));
3224 if (GDK_WINDOW_DESTROYED (window))
3229 static GEnumClass *class = NULL;
3231 class = g_type_class_ref (GDK_TYPE_WINDOW_TYPE_HINT);
3232 g_print ("gdk_window_set_type_hint: %p: %s\n",
3233 GDK_WINDOW_HWND (window),
3234 g_enum_get_value (class, hint)->value_name);
3237 ((GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl)->type_hint = hint;
3239 update_style_bits (window);
3243 gdk_window_get_type_hint (GdkWindow *window)
3245 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
3247 if (GDK_WINDOW_DESTROYED (window))
3248 return GDK_WINDOW_TYPE_HINT_NORMAL;
3250 return GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->type_hint;
3254 gdk_win32_window_shape_combine_region (GdkWindow *window,
3255 const GdkRegion *shape_region,
3259 if (GDK_WINDOW_DESTROYED (window))
3264 GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: none\n",
3265 GDK_WINDOW_HWND (window)));
3266 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
3272 hrgn = _gdk_win32_gdkregion_to_hrgn (shape_region, 0, 0);
3274 GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: %p\n",
3275 GDK_WINDOW_HWND (window),
3278 do_shape_combine_region (window, hrgn, offset_x, offset_y);
3283 gdk_window_lookup_for_display (GdkDisplay *display,
3284 GdkNativeWindow anid)
3286 g_return_val_if_fail (display == _gdk_display, NULL);
3288 return gdk_window_lookup (anid);
3292 gdk_window_enable_synchronized_configure (GdkWindow *window)
3294 g_return_if_fail (GDK_IS_WINDOW (window));
3298 gdk_window_configure_finished (GdkWindow *window)
3300 g_return_if_fail (GDK_IS_WINDOW (window));
3304 _gdk_windowing_window_beep (GdkWindow *window)
3306 gdk_display_beep (_gdk_display);
3310 gdk_window_set_opacity (GdkWindow *window,
3314 typedef BOOL (*PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
3315 PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
3317 g_return_if_fail (GDK_IS_WINDOW (window));
3318 g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
3320 if (GDK_WINDOW_DESTROYED (window))
3325 else if (opacity > 1)
3328 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
3330 if (!(exstyle & WS_EX_LAYERED))
3331 API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window),
3333 exstyle | WS_EX_LAYERED));
3335 setLayeredWindowAttributes =
3336 (PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
3338 if (setLayeredWindowAttributes)
3340 API_CALL (setLayeredWindowAttributes, (GDK_WINDOW_HWND (window),
3348 _gdk_windowing_get_shape_for_mask (GdkBitmap *mask)
3351 HRGN hrgn = _gdk_win32_bitmap_to_hrgn (mask);
3353 region = _gdk_win32_hrgn_to_region (hrgn);
3354 DeleteObject (hrgn);
3360 _gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
3365 _gdk_windowing_window_get_shape (GdkWindow *window)
3367 HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
3368 int type = GetWindowRgn (GDK_WINDOW_HWND (window), hrgn);
3370 if (type == SIMPLEREGION || type == COMPLEXREGION)
3372 GdkRegion *region = _gdk_win32_hrgn_to_region (hrgn);
3374 DeleteObject (hrgn);
3382 _gdk_windowing_window_get_input_shape (GdkWindow *window)
3384 /* CHECK: are these really supposed to be the same? */
3385 return _gdk_windowing_window_get_shape (window);
3389 _gdk_win32_window_queue_antiexpose (GdkWindow *window,
3392 HRGN hrgn = _gdk_win32_gdkregion_to_hrgn (area, 0, 0);
3394 GDK_NOTE (EVENTS, g_print ("_gdk_windowing_window_queue_antiexpose: ValidateRgn %p %s\n",
3395 GDK_WINDOW_HWND (window),
3396 _gdk_win32_gdkregion_to_string (area)));
3398 ValidateRgn (GDK_WINDOW_HWND (window), hrgn);
3400 DeleteObject (hrgn);
3406 * queue_translation is meant to only move any outstanding invalid area
3407 * in the given area by dx,dy. A typical example of when its needed is an
3408 * app with two toplevels where one (A) overlaps the other (B). If the
3409 * app first moves A so that B is invalidated and then scrolls B before
3410 * handling the expose. The scroll operation will copy the invalid area
3411 * to a new position, but when the invalid area is then exposed it only
3412 * redraws the old areas not the place where the invalid data was copied
3416 _gdk_win32_window_queue_translation (GdkWindow *window,
3422 HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
3423 int ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE);
3425 WIN32_API_FAILED ("GetUpdateRgn");
3426 else if (ret != NULLREGION)
3428 /* Get current updateregion, move any part of it that intersects area by dx,dy */
3429 HRGN update = _gdk_win32_gdkregion_to_hrgn (area, 0, 0);
3430 ret = CombineRgn (update, hrgn, update, RGN_AND);
3432 WIN32_API_FAILED ("CombineRgn");
3433 else if (ret != NULLREGION)
3435 OffsetRgn (update, dx, dy);
3436 API_CALL (InvalidateRgn, (GDK_WINDOW_HWND (window), update, TRUE));
3438 DeleteObject (update);
3440 DeleteObject (hrgn);
3444 gdk_win32_input_shape_combine_region (GdkWindow *window,
3445 const GdkRegion *shape_region,
3449 if (GDK_WINDOW_DESTROYED (window))
3451 /* CHECK: are these really supposed to be the same? */
3452 gdk_win32_window_shape_combine_region (window, shape_region, offset_x, offset_y);
3456 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
3459 _gdk_window_process_updates_recurse (window, region);
3463 _gdk_windowing_before_process_all_updates (void)
3468 _gdk_windowing_after_process_all_updates (void)
3473 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
3475 iface->show = gdk_win32_window_show;
3476 iface->hide = gdk_win32_window_hide;
3477 iface->withdraw = gdk_win32_window_withdraw;
3478 iface->set_events = gdk_win32_window_set_events;
3479 iface->get_events = gdk_win32_window_get_events;
3480 iface->raise = gdk_win32_window_raise;
3481 iface->lower = gdk_win32_window_lower;
3482 iface->restack_under = gdk_win32_window_restack_under;
3483 iface->restack_toplevel = gdk_win32_window_restack_toplevel;
3484 iface->move_resize = gdk_win32_window_move_resize;
3485 iface->set_background = gdk_win32_window_set_background;
3486 iface->set_back_pixmap = gdk_win32_window_set_back_pixmap;
3487 iface->reparent = gdk_win32_window_reparent;
3488 iface->set_cursor = gdk_win32_window_set_cursor;
3489 iface->get_geometry = gdk_win32_window_get_geometry;
3490 iface->get_pointer = gdk_window_win32_get_pointer;
3491 iface->get_root_coords = gdk_win32_window_get_root_coords;
3492 iface->shape_combine_region = gdk_win32_window_shape_combine_region;
3493 iface->input_shape_combine_region = gdk_win32_input_shape_combine_region;
3494 iface->get_deskrelative_origin = gdk_win32_window_get_deskrelative_origin;
3495 iface->set_static_gravities = gdk_win32_window_set_static_gravities;
3496 iface->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
3497 iface->queue_translation = _gdk_win32_window_queue_translation;
3498 iface->destroy = _gdk_win32_window_destroy;
3499 iface->input_window_destroy = _gdk_input_window_destroy;
3500 iface->input_window_crossing = _gdk_input_crossing_event;