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_new_internal: %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_windowing_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_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_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_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_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_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_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_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_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_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 GdkWindowObject *private = (GdkWindowObject *)window;
1877 /* TODO_CSW? but win32 has no XSetWindowBackgroundPixmap */
1881 gdk_win32_window_set_cursor (GdkWindow *window,
1884 GdkWindowImplWin32 *impl;
1885 GdkCursorPrivate *cursor_private;
1886 GdkWindowObject *parent_window;
1888 HCURSOR hprevcursor;
1890 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1891 cursor_private = (GdkCursorPrivate*) cursor;
1893 if (GDK_WINDOW_DESTROYED (window))
1899 hcursor = cursor_private->hcursor;
1901 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %p: %p\n",
1902 GDK_WINDOW_HWND (window),
1905 /* First get the old cursor, if any (we wait to free the old one
1906 * since it may be the current cursor set in the Win32 API right
1909 hprevcursor = impl->hcursor;
1911 if (hcursor == NULL)
1912 impl->hcursor = NULL;
1915 /* We must copy the cursor as it is OK to destroy the GdkCursor
1916 * while still in use for some window. See for instance
1917 * gimp_change_win_cursor() which calls gdk_window_set_cursor
1918 * (win, cursor), and immediately afterwards gdk_cursor_destroy
1921 if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
1922 WIN32_API_FAILED ("CopyCursor");
1923 GDK_NOTE (MISC, g_print ("... CopyCursor (%p) = %p\n",
1924 hcursor, impl->hcursor));
1927 if (impl->hcursor != NULL)
1929 /* If the pointer is over our window, set new cursor */
1930 GdkWindow *curr_window = gdk_window_get_pointer (window, NULL, NULL, NULL);
1931 if (curr_window == window ||
1932 (curr_window && window == gdk_window_get_toplevel (curr_window)))
1933 SetCursor (impl->hcursor);
1936 /* Climb up the tree and find whether our window is the
1937 * first ancestor that has cursor defined, and if so, set
1940 GdkWindowObject *curr_window_obj = GDK_WINDOW_OBJECT (curr_window);
1941 while (curr_window_obj &&
1942 !GDK_WINDOW_IMPL_WIN32 (curr_window_obj->impl)->hcursor)
1944 curr_window_obj = curr_window_obj->parent;
1945 if (curr_window_obj == GDK_WINDOW_OBJECT (window))
1947 SetCursor (impl->hcursor);
1954 /* Destroy the previous cursor: Need to make sure it's no longer in
1955 * use before we destroy it, in case we're not over our window but
1956 * the cursor is still set to our old one.
1958 if (hprevcursor != NULL)
1960 if (GetCursor () == hprevcursor)
1962 /* Look for a suitable cursor to use instead */
1964 parent_window = GDK_WINDOW_OBJECT (window)->parent;
1965 while (hcursor == NULL)
1969 impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl);
1970 hcursor = impl->hcursor;
1971 parent_window = parent_window->parent;
1975 hcursor = LoadCursor (NULL, IDC_ARROW);
1978 SetCursor (hcursor);
1981 GDK_NOTE (MISC, g_print ("... DestroyCursor (%p)\n", hprevcursor));
1983 API_CALL (DestroyCursor, (hprevcursor));
1988 gdk_win32_window_get_geometry (GdkWindow *window,
1998 if (!GDK_WINDOW_DESTROYED (window))
2002 API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
2004 if (window != _gdk_root)
2007 GdkWindow *parent = gdk_window_get_parent (window);
2011 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2012 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
2018 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2019 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
2023 if (parent == _gdk_root)
2025 rect.left += _gdk_offset_x;
2026 rect.top += _gdk_offset_y;
2027 rect.right += _gdk_offset_x;
2028 rect.bottom += _gdk_offset_y;
2037 *width = rect.right - rect.left;
2039 *height = rect.bottom - rect.top;
2041 *depth = gdk_drawable_get_visual (window)->depth;
2043 GDK_NOTE (MISC, g_print ("gdk_window_get_geometry: %p: %ldx%ldx%d@%+ld%+ld\n",
2044 GDK_WINDOW_HWND (window),
2045 rect.right - rect.left, rect.bottom - rect.top,
2046 gdk_drawable_get_visual (window)->depth,
2047 rect.left, rect.top));
2052 gdk_win32_window_get_root_coords (GdkWindow *window,
2064 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2069 *root_x = tx + _gdk_offset_x;
2071 *root_y = ty + _gdk_offset_y;
2073 GDK_NOTE (MISC, g_print ("gdk_window_get_root_coords: %p: %+d%+d %+d%+d\n",
2074 GDK_WINDOW_HWND (window),
2081 gdk_win32_window_get_deskrelative_origin (GdkWindow *window,
2085 return gdk_win32_window_get_root_coords (window, 0, 0, x, y);
2089 gdk_win32_window_restack_under (GdkWindow *window,
2090 GList *native_siblings)
2096 gdk_win32_window_restack_toplevel (GdkWindow *window,
2104 gdk_window_get_root_origin (GdkWindow *window,
2110 g_return_if_fail (GDK_IS_WINDOW (window));
2112 gdk_window_get_frame_extents (window, &rect);
2120 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %p: %+d%+d\n",
2121 GDK_WINDOW_HWND (window), rect.x, rect.y));
2125 gdk_window_get_frame_extents (GdkWindow *window,
2128 GdkWindowObject *private;
2132 g_return_if_fail (GDK_IS_WINDOW (window));
2133 g_return_if_fail (rect != NULL);
2135 private = GDK_WINDOW_OBJECT (window);
2142 if (GDK_WINDOW_DESTROYED (window))
2145 /* FIXME: window is documented to be a toplevel GdkWindow, so is it really
2146 * necessary to walk its parent chain?
2148 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
2149 private = (GdkWindowObject*) private->parent;
2151 hwnd = GDK_WINDOW_HWND (window);
2152 API_CALL (GetWindowRect, (hwnd, &r));
2154 rect->x = r.left + _gdk_offset_x;
2155 rect->y = r.top + _gdk_offset_y;
2156 rect->width = r.right - r.left;
2157 rect->height = r.bottom - r.top;
2159 GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@%+ld%+ld\n",
2160 GDK_WINDOW_HWND (window),
2161 r.right - r.left, r.bottom - r.top,
2166 static GdkModifierType
2167 get_current_mask (void)
2169 GdkModifierType mask;
2172 GetKeyboardState (kbd);
2174 if (kbd[VK_SHIFT] & 0x80)
2175 mask |= GDK_SHIFT_MASK;
2176 if (kbd[VK_CAPITAL] & 0x80)
2177 mask |= GDK_LOCK_MASK;
2178 if (kbd[VK_CONTROL] & 0x80)
2179 mask |= GDK_CONTROL_MASK;
2180 if (kbd[VK_MENU] & 0x80)
2181 mask |= GDK_MOD1_MASK;
2182 if (kbd[VK_LBUTTON] & 0x80)
2183 mask |= GDK_BUTTON1_MASK;
2184 if (kbd[VK_MBUTTON] & 0x80)
2185 mask |= GDK_BUTTON2_MASK;
2186 if (kbd[VK_RBUTTON] & 0x80)
2187 mask |= GDK_BUTTON3_MASK;
2193 gdk_window_win32_get_pointer (GdkWindow *window,
2196 GdkModifierType *mask)
2198 gboolean return_val;
2202 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
2206 hwnd = GDK_WINDOW_HWND (window);
2207 GetCursorPos (&point);
2208 ScreenToClient (hwnd, &point);
2213 if (window == _gdk_root)
2215 *x += _gdk_offset_x;
2216 *y += _gdk_offset_y;
2219 hwndc = ChildWindowFromPoint (hwnd, point);
2220 if (hwndc != NULL && hwndc != hwnd &&
2221 !gdk_win32_handle_table_lookup ((GdkNativeWindow) hwndc))
2222 return_val = FALSE; /* Direct child unknown to gdk */
2224 *mask = get_current_mask ();
2230 _gdk_windowing_get_pointer (GdkDisplay *display,
2234 GdkModifierType *mask)
2238 g_return_if_fail (display == _gdk_display);
2240 *screen = _gdk_screen;
2241 GetCursorPos (&point);
2242 *x = point.x + _gdk_offset_x;
2243 *y = point.y + _gdk_offset_y;
2245 *mask = get_current_mask ();
2249 gdk_display_warp_pointer (GdkDisplay *display,
2254 g_return_if_fail (display == _gdk_display);
2255 g_return_if_fail (screen == _gdk_screen);
2257 SetCursorPos (x - _gdk_offset_x, y - _gdk_offset_y);
2261 _gdk_windowing_window_at_pointer (GdkDisplay *display,
2264 GdkModifierType *mask,
2265 gboolean get_toplevel)
2268 POINT point, pointc;
2272 GetCursorPos (&pointc);
2274 hwnd = WindowFromPoint (point);
2279 *win_x = pointc.x + _gdk_offset_x;
2280 *win_y = pointc.y + _gdk_offset_y;
2284 ScreenToClient (hwnd, &point);
2288 (window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd)) != NULL &&
2289 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
2292 hwndc = ChildWindowFromPoint (hwnd, point);
2293 ClientToScreen (hwnd, &point);
2294 ScreenToClient (hwndc, &point);
2295 } while (hwndc != hwnd && (hwnd = hwndc, 1));
2297 window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
2299 if (window && (win_x || win_y))
2301 GetClientRect (hwnd, &rect);
2302 *win_x = point.x - rect.left;
2303 *win_y = point.y - rect.top;
2306 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_at_pointer: %+d%+d %p%s\n",
2309 (window == NULL ? " NULL" : "")));
2315 gdk_win32_window_get_events (GdkWindow *window)
2317 if (GDK_WINDOW_DESTROYED (window))
2320 return GDK_WINDOW_OBJECT (window)->event_mask;
2324 gdk_win32_window_set_events (GdkWindow *window,
2325 GdkEventMask event_mask)
2327 /* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
2328 * set it here, too. Not that I know or remember why it is
2329 * necessary, will have to test some day.
2331 GDK_WINDOW_OBJECT (window)->event_mask = GDK_STRUCTURE_MASK | event_mask;
2335 do_shape_combine_region (GdkWindow *window,
2341 GetClientRect (GDK_WINDOW_HWND (window), &rect);
2342 _gdk_win32_adjust_client_rect (window, &rect);
2344 OffsetRgn (hrgn, -rect.left, -rect.top);
2345 OffsetRgn (hrgn, x, y);
2347 /* If this is a top-level window, add the title bar to the region */
2348 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
2350 HRGN tmp = CreateRectRgn (0, 0, rect.right - rect.left, -rect.top);
2351 CombineRgn (hrgn, hrgn, tmp, RGN_OR);
2355 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
2359 gdk_win32_window_shape_combine_mask (GdkWindow *window,
2363 GdkWindowObject *private = (GdkWindowObject *)window;
2367 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: none\n",
2368 GDK_WINDOW_HWND (window)));
2369 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
2375 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: %p\n",
2376 GDK_WINDOW_HWND (window),
2377 GDK_WINDOW_HWND (mask)));
2379 /* Convert mask bitmap to region */
2380 hrgn = _gdk_win32_bitmap_to_hrgn (mask);
2382 do_shape_combine_region (window, hrgn, x, y);
2387 gdk_window_set_override_redirect (GdkWindow *window,
2388 gboolean override_redirect)
2390 g_return_if_fail (GDK_IS_WINDOW (window));
2392 g_warning ("gdk_window_set_override_redirect not implemented");
2396 gdk_window_set_accept_focus (GdkWindow *window,
2397 gboolean accept_focus)
2399 GdkWindowObject *private;
2401 g_return_if_fail (GDK_IS_WINDOW (window));
2403 private = (GdkWindowObject *)window;
2405 accept_focus = accept_focus != FALSE;
2407 if (private->accept_focus != accept_focus)
2408 private->accept_focus = accept_focus;
2412 gdk_window_set_focus_on_map (GdkWindow *window,
2413 gboolean focus_on_map)
2415 GdkWindowObject *private;
2417 g_return_if_fail (GDK_IS_WINDOW (window));
2419 private = (GdkWindowObject *)window;
2421 focus_on_map = focus_on_map != FALSE;
2423 if (private->focus_on_map != focus_on_map)
2424 private->focus_on_map = focus_on_map;
2428 gdk_window_set_icon_list (GdkWindow *window,
2431 GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
2432 gint big_diff, small_diff;
2433 gint big_w, big_h, small_w, small_h;
2436 HICON small_hicon, big_hicon;
2437 GdkWindowImplWin32 *impl;
2438 gint i, big_i, small_i;
2440 g_return_if_fail (GDK_IS_WINDOW (window));
2442 if (GDK_WINDOW_DESTROYED (window))
2445 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
2447 /* ideal sizes for small and large icons */
2448 big_w = GetSystemMetrics (SM_CXICON);
2449 big_h = GetSystemMetrics (SM_CYICON);
2450 small_w = GetSystemMetrics (SM_CXSMICON);
2451 small_h = GetSystemMetrics (SM_CYSMICON);
2453 /* find closest sized icons in the list */
2455 small_pixbuf = NULL;
2461 pixbuf = (GdkPixbuf*) pixbufs->data;
2462 w = gdk_pixbuf_get_width (pixbuf);
2463 h = gdk_pixbuf_get_height (pixbuf);
2465 dw = ABS (w - big_w);
2466 dh = ABS (h - big_h);
2467 diff = dw*dw + dh*dh;
2468 if (big_pixbuf == NULL || diff < big_diff)
2470 big_pixbuf = pixbuf;
2475 dw = ABS (w - small_w);
2476 dh = ABS (h - small_h);
2477 diff = dw*dw + dh*dh;
2478 if (small_pixbuf == NULL || diff < small_diff)
2480 small_pixbuf = pixbuf;
2485 pixbufs = g_list_next (pixbufs);
2489 /* Create the icons */
2490 big_hicon = _gdk_win32_pixbuf_to_hicon (big_pixbuf);
2491 small_hicon = _gdk_win32_pixbuf_to_hicon (small_pixbuf);
2494 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
2496 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_SMALL,
2497 (LPARAM)small_hicon);
2499 /* Store the icons, destroying any previous icons */
2500 if (impl->hicon_big)
2501 GDI_CALL (DestroyIcon, (impl->hicon_big));
2502 impl->hicon_big = big_hicon;
2503 if (impl->hicon_small)
2504 GDI_CALL (DestroyIcon, (impl->hicon_small));
2505 impl->hicon_small = small_hicon;
2509 gdk_window_set_icon (GdkWindow *window,
2510 GdkWindow *icon_window,
2514 g_return_if_fail (GDK_IS_WINDOW (window));
2516 /* do nothing, use gdk_window_set_icon_list instead */
2520 gdk_window_set_icon_name (GdkWindow *window,
2523 /* In case I manage to confuse this again (or somebody else does):
2524 * Please note that "icon name" here really *does* mean the name or
2525 * title of an window minimized as an icon on the desktop, or in the
2526 * taskbar. It has nothing to do with the freedesktop.org icon
2530 g_return_if_fail (GDK_IS_WINDOW (window));
2532 if (GDK_WINDOW_DESTROYED (window))
2536 /* This is not the correct thing to do. We should keep both the
2537 * "normal" window title, and the icon name. When the window is
2538 * minimized, call SetWindowText() with the icon name, and when the
2539 * window is restored, with the normal window title. Also, the name
2540 * is in UTF-8, so we should do the normal conversion to either wide
2541 * chars or system codepage, and use either the W or A version of
2542 * SetWindowText(), depending on Windows version.
2544 API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
2549 gdk_window_get_group (GdkWindow *window)
2551 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2552 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
2554 if (GDK_WINDOW_DESTROYED (window))
2557 g_warning ("gdk_window_get_group not yet implemented");
2563 gdk_window_set_group (GdkWindow *window,
2566 g_return_if_fail (GDK_IS_WINDOW (window));
2567 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2568 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
2570 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2573 g_warning ("gdk_window_set_group not implemented");
2577 update_single_bit (LONG *style,
2582 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2583 * gdk_bit indicates whether style_bit is off; if all is FALSE, gdk
2584 * bit indicate whether style_bit is on
2586 if ((!all && gdk_bit) || (all && !gdk_bit))
2587 *style |= style_bit;
2589 *style &= ~style_bit;
2593 update_style_bits (GdkWindow *window)
2595 GdkWindowObject *private = (GdkWindowObject *)window;
2596 GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)private->impl;
2597 GdkWMDecoration decorations;
2598 LONG old_style, new_style, old_exstyle, new_exstyle;
2600 RECT rect, before, after;
2602 old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2603 old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
2605 GetClientRect (GDK_WINDOW_HWND (window), &before);
2607 AdjustWindowRectEx (&before, old_style, FALSE, old_exstyle);
2609 new_style = old_style;
2610 new_exstyle = old_exstyle;
2612 if (private->window_type == GDK_WINDOW_TEMP ||
2613 impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
2614 new_exstyle |= WS_EX_TOOLWINDOW;
2616 new_exstyle &= ~WS_EX_TOOLWINDOW;
2618 if (get_effective_window_decorations (window, &decorations))
2620 all = (decorations & GDK_DECOR_ALL);
2621 update_single_bit (&new_style, all, decorations & GDK_DECOR_BORDER, WS_BORDER);
2622 update_single_bit (&new_style, all, decorations & GDK_DECOR_RESIZEH, WS_THICKFRAME);
2623 update_single_bit (&new_style, all, decorations & GDK_DECOR_TITLE, WS_CAPTION);
2624 update_single_bit (&new_style, all, decorations & GDK_DECOR_MENU, WS_SYSMENU);
2625 update_single_bit (&new_style, all, decorations & GDK_DECOR_MINIMIZE, WS_MINIMIZEBOX);
2626 update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
2629 if (old_style == new_style && old_exstyle == new_exstyle )
2631 GDK_NOTE (MISC, g_print ("update_style_bits: %p: no change\n",
2632 GDK_WINDOW_HWND (window)));
2636 if (old_style != new_style)
2638 GDK_NOTE (MISC, g_print ("update_style_bits: %p: STYLE: %s => %s\n",
2639 GDK_WINDOW_HWND (window),
2640 _gdk_win32_window_style_to_string (old_style),
2641 _gdk_win32_window_style_to_string (new_style)));
2643 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, new_style);
2646 if (old_exstyle != new_exstyle)
2648 GDK_NOTE (MISC, g_print ("update_style_bits: %p: EXSTYLE: %s => %s\n",
2649 GDK_WINDOW_HWND (window),
2650 _gdk_win32_window_exstyle_to_string (old_exstyle),
2651 _gdk_win32_window_exstyle_to_string (new_exstyle)));
2653 SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, new_exstyle);
2656 AdjustWindowRectEx (&after, new_style, FALSE, new_exstyle);
2658 GetWindowRect (GDK_WINDOW_HWND (window), &rect);
2659 rect.left += after.left - before.left;
2660 rect.top += after.top - before.top;
2661 rect.right += after.right - before.right;
2662 rect.bottom += after.bottom - before.bottom;
2664 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
2665 rect.left, rect.top,
2666 rect.right - rect.left, rect.bottom - rect.top,
2667 SWP_FRAMECHANGED | SWP_NOACTIVATE |
2668 SWP_NOREPOSITION | SWP_NOZORDER);
2673 update_single_system_menu_entry (HMENU hmenu,
2678 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2679 * gdk_bit indicates whether menu entry is disabled; if all is
2680 * FALSE, gdk bit indicate whether menu entry is enabled
2682 if ((!all && gdk_bit) || (all && !gdk_bit))
2683 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_ENABLED);
2685 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_GRAYED);
2689 update_system_menu (GdkWindow *window)
2691 GdkWMFunction functions;
2694 if (_gdk_window_get_functions (window, &functions))
2696 HMENU hmenu = GetSystemMenu (GDK_WINDOW_HWND (window), FALSE);
2698 all = (functions & GDK_FUNC_ALL);
2699 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_RESIZE, SC_SIZE);
2700 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MOVE, SC_MOVE);
2701 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MINIMIZE, SC_MINIMIZE);
2702 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MAXIMIZE, SC_MAXIMIZE);
2703 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_CLOSE, SC_CLOSE);
2708 get_decorations_quark ()
2710 static GQuark quark = 0;
2713 quark = g_quark_from_static_string ("gdk-window-decorations");
2719 gdk_window_set_decorations (GdkWindow *window,
2720 GdkWMDecoration decorations)
2722 GdkWMDecoration* decorations_copy;
2724 g_return_if_fail (GDK_IS_WINDOW (window));
2726 GDK_NOTE (MISC, g_print ("gdk_window_set_decorations: %p: %s %s%s%s%s%s%s\n",
2727 GDK_WINDOW_HWND (window),
2728 (decorations & GDK_DECOR_ALL ? "clearing" : "setting"),
2729 (decorations & GDK_DECOR_BORDER ? "BORDER " : ""),
2730 (decorations & GDK_DECOR_RESIZEH ? "RESIZEH " : ""),
2731 (decorations & GDK_DECOR_TITLE ? "TITLE " : ""),
2732 (decorations & GDK_DECOR_MENU ? "MENU " : ""),
2733 (decorations & GDK_DECOR_MINIMIZE ? "MINIMIZE " : ""),
2734 (decorations & GDK_DECOR_MAXIMIZE ? "MAXIMIZE " : "")));
2736 decorations_copy = g_malloc (sizeof (GdkWMDecoration));
2737 *decorations_copy = decorations;
2738 g_object_set_qdata_full (G_OBJECT (window), get_decorations_quark (), decorations_copy, g_free);
2740 update_style_bits (window);
2744 gdk_window_get_decorations (GdkWindow *window,
2745 GdkWMDecoration *decorations)
2747 GdkWMDecoration* decorations_set;
2749 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2751 decorations_set = g_object_get_qdata (G_OBJECT (window), get_decorations_quark ());
2752 if (decorations_set)
2753 *decorations = *decorations_set;
2755 return (decorations_set != NULL);
2759 get_functions_quark ()
2761 static GQuark quark = 0;
2764 quark = g_quark_from_static_string ("gdk-window-functions");
2770 gdk_window_set_functions (GdkWindow *window,
2771 GdkWMFunction functions)
2773 GdkWMFunction* functions_copy;
2775 g_return_if_fail (GDK_IS_WINDOW (window));
2777 GDK_NOTE (MISC, g_print ("gdk_window_set_functions: %p: %s %s%s%s%s%s\n",
2778 GDK_WINDOW_HWND (window),
2779 (functions & GDK_FUNC_ALL ? "clearing" : "setting"),
2780 (functions & GDK_FUNC_RESIZE ? "RESIZE " : ""),
2781 (functions & GDK_FUNC_MOVE ? "MOVE " : ""),
2782 (functions & GDK_FUNC_MINIMIZE ? "MINIMIZE " : ""),
2783 (functions & GDK_FUNC_MAXIMIZE ? "MAXIMIZE " : ""),
2784 (functions & GDK_FUNC_CLOSE ? "CLOSE " : "")));
2786 functions_copy = g_malloc (sizeof (GdkWMFunction));
2787 *functions_copy = functions;
2788 g_object_set_qdata_full (G_OBJECT (window), get_functions_quark (), functions_copy, g_free);
2790 update_system_menu (window);
2794 _gdk_window_get_functions (GdkWindow *window,
2795 GdkWMFunction *functions)
2797 GdkWMDecoration* functions_set;
2799 functions_set = g_object_get_qdata (G_OBJECT (window), get_functions_quark ());
2801 *functions = *functions_set;
2803 return (functions_set != NULL);
2807 QueryTree (HWND hwnd,
2817 child = GetWindow (hwnd, GW_CHILD);
2819 child = GetWindow (child, GW_HWNDNEXT);
2822 } while (child != NULL);
2826 *children = g_new (HWND, n);
2827 for (i = 0; i < n; i++)
2830 child = GetWindow (hwnd, GW_CHILD);
2832 child = GetWindow (child, GW_HWNDNEXT);
2833 *children[i] = child;
2839 gdk_propagate_shapes (HANDLE win,
2843 HRGN region, childRegion;
2847 SetRectEmpty (&emptyRect);
2848 region = CreateRectRgnIndirect (&emptyRect);
2850 GetWindowRgn (win, region);
2852 QueryTree (win, &list, &num);
2855 WINDOWPLACEMENT placement;
2857 placement.length = sizeof (WINDOWPLACEMENT);
2858 /* go through all child windows and combine regions */
2859 for (i = 0; i < num; i++)
2861 GetWindowPlacement (list[i], &placement);
2862 if (placement.showCmd == SW_SHOWNORMAL)
2864 childRegion = CreateRectRgnIndirect (&emptyRect);
2865 GetWindowRgn (list[i], childRegion);
2866 CombineRgn (region, region, childRegion, RGN_OR);
2867 DeleteObject (childRegion);
2870 SetWindowRgn (win, region, TRUE);
2874 DeleteObject (region);
2878 gdk_win32_window_set_child_shapes (GdkWindow *window)
2880 if (GDK_WINDOW_DESTROYED (window))
2883 gdk_propagate_shapes (GDK_WINDOW_HWND (window), FALSE);
2887 gdk_win32_window_merge_child_shapes (GdkWindow *window)
2889 if (GDK_WINDOW_DESTROYED (window))
2892 gdk_propagate_shapes (GDK_WINDOW_HWND (window), TRUE);
2896 gdk_win32_window_set_static_gravities (GdkWindow *window,
2897 gboolean use_static)
2899 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2905 gdk_window_begin_resize_drag (GdkWindow *window,
2914 g_return_if_fail (GDK_IS_WINDOW (window));
2916 if (GDK_WINDOW_DESTROYED (window))
2919 /* Tell Windows to start interactively resizing the window by pretending that
2920 * the left pointer button was clicked in the suitable edge or corner. This
2921 * will only work if the button is down when this function is called, and
2922 * will only work with button 1 (left), since Windows only allows window
2923 * dragging using the left mouse button.
2928 /* Must break the automatic grab that occured when the button was
2929 * pressed, otherwise it won't work.
2931 gdk_display_pointer_ungrab (_gdk_display, 0);
2935 case GDK_WINDOW_EDGE_NORTH_WEST:
2936 winedge = HTTOPLEFT;
2939 case GDK_WINDOW_EDGE_NORTH:
2943 case GDK_WINDOW_EDGE_NORTH_EAST:
2944 winedge = HTTOPRIGHT;
2947 case GDK_WINDOW_EDGE_WEST:
2951 case GDK_WINDOW_EDGE_EAST:
2955 case GDK_WINDOW_EDGE_SOUTH_WEST:
2956 winedge = HTBOTTOMLEFT;
2959 case GDK_WINDOW_EDGE_SOUTH:
2963 case GDK_WINDOW_EDGE_SOUTH_EAST:
2965 winedge = HTBOTTOMRIGHT;
2969 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, winedge,
2970 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
2974 gdk_window_begin_move_drag (GdkWindow *window,
2980 g_return_if_fail (GDK_IS_WINDOW (window));
2982 if (GDK_WINDOW_DESTROYED (window))
2985 /* Tell Windows to start interactively moving the window by pretending that
2986 * the left pointer button was clicked in the titlebar. This will only work
2987 * if the button is down when this function is called, and will only work
2988 * with button 1 (left), since Windows only allows window dragging using the
2989 * left mouse button.
2994 /* Must break the automatic grab that occured when the button was pressed,
2995 * otherwise it won't work.
2997 gdk_display_pointer_ungrab (_gdk_display, 0);
2999 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, HTCAPTION,
3000 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
3005 * Setting window states
3008 gdk_window_iconify (GdkWindow *window)
3010 HWND old_active_window;
3012 g_return_if_fail (GDK_IS_WINDOW (window));
3014 if (GDK_WINDOW_DESTROYED (window))
3017 GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
3018 GDK_WINDOW_HWND (window),
3019 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3021 if (GDK_WINDOW_IS_MAPPED (window))
3023 old_active_window = GetActiveWindow ();
3024 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
3025 if (old_active_window != GDK_WINDOW_HWND (window))
3026 SetActiveWindow (old_active_window);
3030 gdk_synthesize_window_state (window,
3032 GDK_WINDOW_STATE_ICONIFIED);
3037 gdk_window_deiconify (GdkWindow *window)
3039 g_return_if_fail (GDK_IS_WINDOW (window));
3041 if (GDK_WINDOW_DESTROYED (window))
3044 GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
3045 GDK_WINDOW_HWND (window),
3046 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3048 if (GDK_WINDOW_IS_MAPPED (window))
3050 show_window_internal (window, FALSE, TRUE);
3054 gdk_synthesize_window_state (window,
3055 GDK_WINDOW_STATE_ICONIFIED,
3061 gdk_window_stick (GdkWindow *window)
3063 g_return_if_fail (GDK_IS_WINDOW (window));
3065 if (GDK_WINDOW_DESTROYED (window))
3068 /* FIXME: Do something? */
3072 gdk_window_unstick (GdkWindow *window)
3074 g_return_if_fail (GDK_IS_WINDOW (window));
3076 if (GDK_WINDOW_DESTROYED (window))
3079 /* FIXME: Do something? */
3083 gdk_window_maximize (GdkWindow *window)
3085 g_return_if_fail (GDK_IS_WINDOW (window));
3087 if (GDK_WINDOW_DESTROYED (window))
3090 GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
3091 GDK_WINDOW_HWND (window),
3092 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3094 if (GDK_WINDOW_IS_MAPPED (window))
3095 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
3097 gdk_synthesize_window_state (window,
3099 GDK_WINDOW_STATE_MAXIMIZED);
3103 gdk_window_unmaximize (GdkWindow *window)
3105 g_return_if_fail (GDK_IS_WINDOW (window));
3107 if (GDK_WINDOW_DESTROYED (window))
3110 GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
3111 GDK_WINDOW_HWND (window),
3112 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3114 if (GDK_WINDOW_IS_MAPPED (window))
3115 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
3117 gdk_synthesize_window_state (window,
3118 GDK_WINDOW_STATE_MAXIMIZED,
3122 typedef struct _FullscreenInfo FullscreenInfo;
3124 struct _FullscreenInfo
3132 gdk_window_fullscreen (GdkWindow *window)
3134 gint x, y, width, height;
3136 GdkWindowObject *private = (GdkWindowObject *) window;
3140 g_return_if_fail (GDK_IS_WINDOW (window));
3142 fi = g_new (FullscreenInfo, 1);
3144 if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
3148 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
3150 monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
3151 mi.cbSize = sizeof (mi);
3152 if (monitor && GetMonitorInfo (monitor, &mi))
3154 x = mi.rcMonitor.left;
3155 y = mi.rcMonitor.top;
3156 width = mi.rcMonitor.right - x;
3157 height = mi.rcMonitor.bottom - y;
3162 width = GetSystemMetrics (SM_CXSCREEN);
3163 height = GetSystemMetrics (SM_CYSCREEN);
3166 /* remember for restoring */
3167 fi->hint_flags = impl->hint_flags;
3168 impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
3169 g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
3170 fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
3172 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3173 (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
3175 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
3176 x, y, width, height,
3177 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
3179 gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
3184 gdk_window_unfullscreen (GdkWindow *window)
3187 GdkWindowObject *private = (GdkWindowObject *) window;
3189 g_return_if_fail (GDK_IS_WINDOW (window));
3191 fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
3194 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
3196 impl->hint_flags = fi->hint_flags;
3197 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
3198 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
3199 fi->r.left, fi->r.top,
3200 fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
3201 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
3203 g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
3206 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
3211 gdk_window_set_keep_above (GdkWindow *window,
3214 g_return_if_fail (GDK_IS_WINDOW (window));
3216 if (GDK_WINDOW_DESTROYED (window))
3219 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_above: %p: %s\n",
3220 GDK_WINDOW_HWND (window),
3221 setting ? "YES" : "NO"));
3223 if (GDK_WINDOW_IS_MAPPED (window))
3225 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3226 setting ? HWND_TOPMOST : HWND_NOTOPMOST,
3228 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
3231 gdk_synthesize_window_state (window,
3232 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
3233 setting ? GDK_WINDOW_STATE_ABOVE : 0);
3237 gdk_window_set_keep_below (GdkWindow *window,
3240 g_return_if_fail (GDK_IS_WINDOW (window));
3242 if (GDK_WINDOW_DESTROYED (window))
3245 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_below: %p: %s\n",
3246 GDK_WINDOW_HWND (window),
3247 setting ? "YES" : "NO"));
3249 if (GDK_WINDOW_IS_MAPPED (window))
3251 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3252 setting ? HWND_BOTTOM : HWND_NOTOPMOST,
3254 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
3257 gdk_synthesize_window_state (window,
3258 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
3259 setting ? GDK_WINDOW_STATE_BELOW : 0);
3263 gdk_window_focus (GdkWindow *window,
3266 g_return_if_fail (GDK_IS_WINDOW (window));
3268 if (GDK_WINDOW_DESTROYED (window))
3271 GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
3272 GDK_WINDOW_HWND (window),
3273 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3275 if (((GdkWindowObject *) window)->state & GDK_WINDOW_STATE_MAXIMIZED)
3276 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
3278 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
3279 SetFocus (GDK_WINDOW_HWND (window));
3283 gdk_window_set_modal_hint (GdkWindow *window,
3286 GdkWindowObject *private;
3288 g_return_if_fail (GDK_IS_WINDOW (window));
3290 if (GDK_WINDOW_DESTROYED (window))
3293 GDK_NOTE (MISC, g_print ("gdk_window_set_modal_hint: %p: %s\n",
3294 GDK_WINDOW_HWND (window),
3295 modal ? "YES" : "NO"));
3297 private = (GdkWindowObject*) window;
3299 if (modal == private->modal_hint)
3302 private->modal_hint = modal;
3305 /* Not sure about this one.. -- Cody */
3306 if (GDK_WINDOW_IS_MAPPED (window))
3307 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3308 modal ? HWND_TOPMOST : HWND_NOTOPMOST,
3310 SWP_NOMOVE | SWP_NOSIZE));
3315 _gdk_push_modal_window (window);
3316 gdk_window_raise (window);
3320 _gdk_remove_modal_window (window);
3327 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
3328 gboolean skips_taskbar)
3330 static GdkWindow *owner = NULL;
3333 g_return_if_fail (GDK_IS_WINDOW (window));
3335 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s, doing nothing\n",
3336 GDK_WINDOW_HWND (window),
3337 skips_taskbar ? "YES" : "NO"));
3339 // ### TODO: Need to figure out what to do here.
3347 wa.window_type = GDK_WINDOW_TEMP;
3348 wa.wclass = GDK_INPUT_OUTPUT;
3349 wa.width = wa.height = 1;
3351 owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
3355 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner));
3357 #if 0 /* Should we also turn off the minimize and maximize buttons? */
3358 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3359 GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
3361 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
3363 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
3364 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
3369 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, 0);
3374 gdk_window_set_skip_pager_hint (GdkWindow *window,
3375 gboolean skips_pager)
3377 g_return_if_fail (GDK_IS_WINDOW (window));
3379 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_pager_hint: %p: %s, doing nothing\n",
3380 GDK_WINDOW_HWND (window),
3381 skips_pager ? "YES" : "NO"));
3385 gdk_window_set_type_hint (GdkWindow *window,
3386 GdkWindowTypeHint hint)
3388 g_return_if_fail (GDK_IS_WINDOW (window));
3390 if (GDK_WINDOW_DESTROYED (window))
3395 static GEnumClass *class = NULL;
3397 class = g_type_class_ref (GDK_TYPE_WINDOW_TYPE_HINT);
3398 g_print ("gdk_window_set_type_hint: %p: %s\n",
3399 GDK_WINDOW_HWND (window),
3400 g_enum_get_value (class, hint)->value_name);
3403 ((GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl)->type_hint = hint;
3405 update_style_bits (window);
3409 gdk_window_get_type_hint (GdkWindow *window)
3411 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
3413 if (GDK_WINDOW_DESTROYED (window))
3414 return GDK_WINDOW_TYPE_HINT_NORMAL;
3416 return GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->type_hint;
3420 gdk_win32_window_shape_combine_region (GdkWindow *window,
3421 const GdkRegion *shape_region,
3425 GdkWindowObject *private = (GdkWindowObject *)window;
3427 if (GDK_WINDOW_DESTROYED (window))
3432 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_region: %p: none\n",
3433 GDK_WINDOW_HWND (window)));
3434 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
3440 hrgn = _gdk_win32_gdkregion_to_hrgn (shape_region, 0, 0);
3442 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_region: %p: %p\n",
3443 GDK_WINDOW_HWND (window),
3446 do_shape_combine_region (window, hrgn, offset_x, offset_y);
3451 gdk_window_lookup_for_display (GdkDisplay *display,
3452 GdkNativeWindow anid)
3454 g_return_val_if_fail (display == _gdk_display, NULL);
3456 return gdk_window_lookup (anid);
3460 gdk_window_enable_synchronized_configure (GdkWindow *window)
3462 g_return_if_fail (GDK_IS_WINDOW (window));
3466 gdk_window_configure_finished (GdkWindow *window)
3468 g_return_if_fail (GDK_IS_WINDOW (window));
3472 _gdk_windowing_window_beep (GdkWindow *window)
3474 gdk_display_beep (_gdk_display);
3478 gdk_window_set_opacity (GdkWindow *window,
3482 typedef BOOL (*PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
3483 PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
3485 g_return_if_fail (GDK_IS_WINDOW (window));
3486 g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
3488 if (GDK_WINDOW_DESTROYED (window))
3493 else if (opacity > 1)
3496 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
3498 if (!(exstyle & WS_EX_LAYERED))
3499 API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window),
3501 exstyle | WS_EX_LAYERED));
3503 setLayeredWindowAttributes =
3504 (PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
3506 if (setLayeredWindowAttributes)
3508 API_CALL (setLayeredWindowAttributes, (GDK_WINDOW_HWND (window),
3516 _gdk_windowing_get_shape_for_mask (GdkBitmap *mask)
3519 HRGN hrgn = _gdk_win32_bitmap_to_hrgn (mask);
3521 region = _gdk_win32_hrgn_to_region (hrgn);
3522 DeleteObject (hrgn);
3528 _gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
3533 _gdk_windowing_window_get_shape (GdkWindow *window)
3535 HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
3536 int type = GetWindowRgn (GDK_WINDOW_HWND (window), hrgn);
3538 if (type == SIMPLEREGION || type == COMPLEXREGION)
3540 GdkRegion *region = _gdk_win32_hrgn_to_region (hrgn);
3542 DeleteObject (hrgn);
3550 _gdk_windowing_window_get_input_shape (GdkWindow *window)
3552 /* CHECK: are these really supposed to be the same? */
3553 return _gdk_windowing_window_get_shape (window);
3557 _gdk_win32_window_queue_antiexpose (GdkWindow *window,
3560 HRGN hrgn = _gdk_win32_gdkregion_to_hrgn (area, 0, 0);
3562 GDK_NOTE (EVENTS, g_print ("_gdk_windowing_window_queue_antiexpose: ValidateRgn %p %s\n",
3563 GDK_WINDOW_HWND (window),
3564 _gdk_win32_gdkregion_to_string (area)));
3566 ValidateRgn (GDK_WINDOW_HWND (window), hrgn);
3568 DeleteObject (hrgn);
3574 * queue_translation is meant to only move any outstanding invalid area
3575 * in the given area by dx,dy. A typical example of when its needed is an
3576 * app with two toplevels where one (A) overlaps the other (B). If the
3577 * app first moves A so that B is invalidated and then scrolls B before
3578 * handling the expose. The scroll operation will copy the invalid area
3579 * to a new position, but when the invalid area is then exposed it only
3580 * redraws the old areas not the place where the invalid data was copied
3584 _gdk_win32_window_queue_translation (GdkWindow *window,
3590 HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
3591 int ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE);
3593 WIN32_API_FAILED ("GetUpdateRgn");
3594 else if (ret != NULLREGION)
3596 /* Get current updateregion, move any part of it that intersects area by dx,dy */
3597 HRGN update = _gdk_win32_gdkregion_to_hrgn (area, 0, 0);
3598 ret = CombineRgn (update, hrgn, update, RGN_AND);
3600 WIN32_API_FAILED ("CombineRgn");
3601 else if (ret != NULLREGION)
3603 OffsetRgn (update, dx, dy);
3604 API_CALL (InvalidateRgn, (GDK_WINDOW_HWND (window), update, TRUE));
3606 DeleteObject (update);
3608 DeleteObject (hrgn);
3612 gdk_win32_input_shape_combine_region (GdkWindow *window,
3613 const GdkRegion *shape_region,
3617 if (GDK_WINDOW_DESTROYED (window))
3619 /* CHECK: are these really supposed to be the same? */
3620 gdk_win32_window_shape_combine_region (window, shape_region, offset_x, offset_y);
3624 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
3627 _gdk_window_process_updates_recurse (window, region);
3631 _gdk_windowing_before_process_all_updates (void)
3636 _gdk_windowing_after_process_all_updates (void)
3641 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
3643 iface->show = gdk_win32_window_show;
3644 iface->hide = gdk_win32_window_hide;
3645 iface->withdraw = gdk_win32_window_withdraw;
3646 iface->set_events = gdk_win32_window_set_events;
3647 iface->get_events = gdk_win32_window_get_events;
3648 iface->raise = gdk_win32_window_raise;
3649 iface->lower = gdk_win32_window_lower;
3650 iface->restack_under = gdk_win32_window_restack_under;
3651 iface->restack_toplevel = gdk_win32_window_restack_toplevel;
3652 iface->move_resize = gdk_win32_window_move_resize;
3653 iface->set_background = gdk_win32_window_set_background;
3654 iface->set_back_pixmap = gdk_win32_window_set_back_pixmap;
3655 iface->reparent = gdk_win32_window_reparent;
3656 iface->set_cursor = gdk_win32_window_set_cursor;
3657 iface->get_geometry = gdk_win32_window_get_geometry;
3658 iface->get_pointer = gdk_window_win32_get_pointer;
3659 iface->get_root_coords = gdk_win32_window_get_root_coords;
3660 iface->shape_combine_region = gdk_win32_window_shape_combine_region;
3661 iface->input_shape_combine_region = gdk_win32_input_shape_combine_region;
3662 iface->get_deskrelative_origin = gdk_win32_window_get_deskrelative_origin;
3663 iface->set_static_gravities = gdk_win32_window_set_static_gravities;
3664 iface->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
3665 iface->queue_translation = _gdk_win32_window_queue_translation;
3666 iface->destroy = _gdk_win32_window_destroy;
3667 iface->input_window_destroy = _gdk_input_window_destroy;
3668 iface->input_window_crossing = _gdk_input_crossing_event;