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-2004 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;
239 //GdkWindowImplWin32 *impl;
243 window_object = GDK_WINDOW_OBJECT (_gdk_root);
244 //impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) _gdk_root)->impl);
245 rect = _gdk_monitors[0].rect;
246 for (i = 1; i < _gdk_num_monitors; i++)
247 gdk_rectangle_union (&rect, &_gdk_monitors[i].rect, &rect);
249 window_object->width = rect.width;
250 window_object->height = rect.height;
251 //impl->width = rect.width;
252 //impl->height = rect.height;
256 _gdk_windowing_window_init (GdkScreen *screen)
258 GdkWindowObject *private;
259 GdkDrawableImplWin32 *draw_impl;
261 g_assert (_gdk_root == NULL);
263 _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
264 private = (GdkWindowObject *)_gdk_root;
265 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
266 private->impl_window = private;
268 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
270 draw_impl->handle = GetDesktopWindow ();
271 draw_impl->wrapper = GDK_DRAWABLE (private);
272 draw_impl->colormap = gdk_screen_get_default_colormap (_gdk_screen);
273 g_object_ref (draw_impl->colormap);
275 private->window_type = GDK_WINDOW_ROOT;
276 private->depth = gdk_visual_get_system ()->depth;
278 _gdk_root_window_size_init ();
284 private->width = GetSystemMetrics (SM_CXSCREEN);
285 private->height = GetSystemMetrics (SM_CYSCREEN);
287 gdk_win32_handle_table_insert ((HANDLE *) &draw_impl->handle, _gdk_root);
289 GDK_NOTE (MISC, g_print ("_gdk_root=%p\n", GDK_WINDOW_HWND (_gdk_root)));
293 get_default_title (void)
296 title = g_get_application_name ();
298 title = g_get_prgname ();
304 * is a wrapper function for RegisterWindowClassEx.
305 * It creates at least one unique class for every
306 * GdkWindowType. If support for single window-specific icons
307 * is ever needed (e.g Dialog specific), every such window should
311 RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
313 static ATOM klassTOPLEVEL = 0;
314 static ATOM klassDIALOG = 0;
315 static ATOM klassCHILD = 0;
316 static ATOM klassTEMP = 0;
317 static ATOM klassTEMPSHADOW = 0;
318 static HICON hAppIcon = NULL;
319 static HICON hAppIconSm = NULL;
320 static WNDCLASSEXW wcl;
323 wcl.cbSize = sizeof (WNDCLASSEX);
324 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
325 * on WM_SIZE and WM_MOVE. Flicker, Performance!
327 wcl.lpfnWndProc = _gdk_win32_window_procedure;
330 wcl.hInstance = _gdk_app_hmodule;
334 /* initialize once! */
335 if (0 == hAppIcon && 0 == hAppIconSm)
337 gchar sLoc [MAX_PATH+1];
339 if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
341 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
343 if (0 == hAppIcon && 0 == hAppIconSm)
345 if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
347 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
352 if (0 == hAppIcon && 0 == hAppIconSm)
354 hAppIcon = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
355 GetSystemMetrics (SM_CXICON),
356 GetSystemMetrics (SM_CYICON), 0);
357 hAppIconSm = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
358 GetSystemMetrics (SM_CXSMICON),
359 GetSystemMetrics (SM_CYSMICON), 0);
364 hAppIcon = hAppIconSm;
365 else if (0 == hAppIconSm)
366 hAppIconSm = hAppIcon;
368 wcl.lpszMenuName = NULL;
370 /* initialize once per class */
372 * HB: Setting the background brush leads to flicker, because we
373 * don't get asked how to clear the background. This is not what
374 * we want, at least not for input_only windows ...
376 #define ONCE_PER_CLASS() \
377 wcl.hIcon = CopyIcon (hAppIcon); \
378 wcl.hIconSm = CopyIcon (hAppIconSm); \
379 wcl.hbrBackground = NULL; \
380 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
384 case GDK_WINDOW_TOPLEVEL:
385 if (0 == klassTOPLEVEL)
387 wcl.lpszClassName = L"gdkWindowToplevel";
390 klassTOPLEVEL = RegisterClassExW (&wcl);
392 klass = klassTOPLEVEL;
395 case GDK_WINDOW_CHILD:
398 wcl.lpszClassName = L"gdkWindowChild";
400 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
402 klassCHILD = RegisterClassExW (&wcl);
407 case GDK_WINDOW_DIALOG:
408 if (0 == klassDIALOG)
410 wcl.lpszClassName = L"gdkWindowDialog";
411 wcl.style |= CS_SAVEBITS;
413 klassDIALOG = RegisterClassExW (&wcl);
418 case GDK_WINDOW_TEMP:
419 if ((wtype_hint == GDK_WINDOW_TYPE_HINT_MENU) ||
420 (wtype_hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU) ||
421 (wtype_hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU) ||
422 (wtype_hint == GDK_WINDOW_TYPE_HINT_TOOLTIP))
424 if (klassTEMPSHADOW == 0)
426 wcl.lpszClassName = L"gdkWindowTempShadow";
427 wcl.style |= CS_SAVEBITS;
428 if (LOBYTE (g_win32_get_windows_version()) > 0x05 ||
429 LOWORD (g_win32_get_windows_version()) == 0x0105)
431 /* Windows XP (5.1) or above */
432 wcl.style |= 0x00020000; /* CS_DROPSHADOW */
435 klassTEMPSHADOW = RegisterClassExW (&wcl);
438 klass = klassTEMPSHADOW;
444 wcl.lpszClassName = L"gdkWindowTemp";
445 wcl.style |= CS_SAVEBITS;
447 klassTEMP = RegisterClassExW (&wcl);
455 g_assert_not_reached ();
461 WIN32_API_FAILED ("RegisterClassExW");
462 g_error ("That is a fatal error");
468 _gdk_window_impl_new (GdkWindow *window,
469 GdkWindow *real_parent,
472 GdkEventMask event_mask,
473 GdkWindowAttr *attributes,
474 gint attributes_mask)
479 DWORD dwStyle = 0, dwExStyle;
481 GdkWindow *orig_parent;
482 GdkWindowObject *private;
483 GdkWindowImplWin32 *impl;
484 GdkDrawableImplWin32 *draw_impl;
487 gint window_width, window_height;
488 gint offset_x = 0, offset_y = 0;
490 private = (GdkWindowObject *)window;
492 orig_parent = real_parent;
495 g_print ("gdk_window_new_internal: %s\n",
496 (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
497 (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" :
498 (attributes->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
499 (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
502 hparent = GDK_WINDOW_HWND (real_parent);
504 impl = g_object_new (_gdk_window_impl_get_type (), NULL);
505 private->impl = (GdkDrawable *)impl;
506 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (impl);
507 draw_impl->wrapper = GDK_DRAWABLE (window);
509 // XXX: xattributes_mask = 0
512 if (attributes_mask & GDK_WA_VISUAL)
513 visual = attributes->visual;
515 visual = gdk_visual_get_system ();
519 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
520 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
522 impl->extension_events_selected = FALSE;
525 if (attributes->wclass == GDK_INPUT_OUTPUT)
529 private->input_only = FALSE;
530 private->depth = visual->depth;
532 if (attributes_mask & GDK_WA_COLORMAP)
534 draw_impl->colormap = attributes->colormap;
535 g_object_ref (attributes->colormap);
539 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
540 g_object_ref (draw_impl->colormap);
545 /* I very much doubt using WS_EX_TRANSPARENT actually
546 * corresponds to how X11 InputOnly windows work, but it appears
547 * to work well enough for the actual use cases in gtk.
549 dwExStyle = WS_EX_TRANSPARENT;
551 private->input_only = TRUE;
552 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
553 g_object_ref (draw_impl->colormap);
554 GDK_NOTE (MISC, g_print ("... GDK_INPUT_ONLY, system colormap"));
557 switch (private->window_type)
559 case GDK_WINDOW_TOPLEVEL:
560 case GDK_WINDOW_DIALOG:
561 if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT)
563 /* The common code warns for this case. */
564 hparent = GetDesktopWindow ();
566 /* Children of foreign windows aren't toplevel windows */
567 if (GDK_WINDOW_TYPE (orig_parent) == GDK_WINDOW_FOREIGN)
569 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN;
573 if (private->window_type == GDK_WINDOW_TOPLEVEL)
574 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
576 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
578 offset_x = _gdk_offset_x;
579 offset_y = _gdk_offset_y;
583 case GDK_WINDOW_CHILD:
584 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
587 case GDK_WINDOW_TEMP:
588 /* A temp window is not necessarily a top level window */
589 dwStyle = (_gdk_root == real_parent ? WS_POPUP : WS_CHILDWINDOW);
590 dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
591 dwExStyle |= WS_EX_TOOLWINDOW;
592 offset_x = _gdk_offset_x;
593 offset_y = _gdk_offset_y;
597 g_assert_not_reached ();
600 //_gdk_window_init_position (GDK_WINDOW (private));
602 if (private->window_type != GDK_WINDOW_CHILD)
604 rect.left = rect.top = 0;
605 rect.right = private->width;
606 rect.bottom = private->height;
608 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
610 window_width = rect.right - rect.left;
611 window_height = rect.bottom - rect.top;
615 window_width = private->width;
616 window_height = private->height;
619 if (attributes_mask & GDK_WA_TITLE)
620 title = attributes->title;
622 title = get_default_title ();
623 if (!title || !*title)
626 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
628 if (attributes_mask & GDK_WA_TYPE_HINT)
629 impl->type_hint = attributes->type_hint;
631 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
633 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
634 dwExStyle |= WS_EX_TOOLWINDOW;
637 private->parent->children = g_list_prepend (private->parent->children, window);
639 klass = RegisterGdkClass (private->window_type, impl->type_hint);
641 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
643 hwndNew = CreateWindowExW (dwExStyle,
644 MAKEINTRESOURCEW (klass),
647 ((attributes_mask & GDK_WA_X) ?
648 private->x - offset_x : CW_USEDEFAULT),
649 private->y - offset_y,
650 window_width, window_height,
655 if (GDK_WINDOW_HWND (window) != hwndNew)
657 g_warning ("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.",
658 GDK_WINDOW_HWND (window),
661 /* HB: IHMO due to a race condition the handle was increased by
662 * one, which causes much trouble. Because I can't find the
663 * real bug, try to workaround it ...
664 * To reproduce: compile with MSVC 5, DEBUG=1
667 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
668 GDK_WINDOW_HWND (window) = hwndNew;
669 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
671 /* the old behaviour, but with warning */
672 draw_impl->handle = hwndNew;
677 g_object_ref (window);
678 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
680 GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
682 window_width, window_height,
683 ((attributes_mask & GDK_WA_X) ?
684 private->x - offset_x: CW_USEDEFAULT),
685 private->y - offset_y,
687 GDK_WINDOW_HWND (window)));
689 /* Add window handle to title */
690 GDK_NOTE (MISC_OR_EVENTS, gdk_window_set_title (window, title));
694 if (draw_impl->handle == NULL)
696 WIN32_API_FAILED ("CreateWindowExW");
697 g_object_unref (window);
701 // if (!from_set_skip_taskbar_hint && private->window_type == GDK_WINDOW_TEMP)
702 // gdk_window_set_skip_taskbar_hint (window, TRUE);
704 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
705 (attributes->cursor) :
710 gdk_window_foreign_new_for_display (GdkDisplay *display,
711 GdkNativeWindow anid)
714 GdkWindowObject *private;
715 GdkWindowImplWin32 *impl;
716 GdkDrawableImplWin32 *draw_impl;
722 g_return_val_if_fail (display == _gdk_display, NULL);
724 window = g_object_new (GDK_TYPE_WINDOW, NULL);
725 private = (GdkWindowObject *)window;
726 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
727 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
728 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
729 draw_impl->wrapper = GDK_DRAWABLE (window);
730 parent = GetParent ((HWND)anid);
732 private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
733 if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
734 private->parent = (GdkWindowObject *)_gdk_root;
736 private->parent->children = g_list_prepend (private->parent->children, window);
738 draw_impl->handle = (HWND) anid;
739 GetClientRect ((HWND) anid, &rect);
741 point.y = rect.right;
742 ClientToScreen ((HWND) anid, &point);
743 if (parent != GetDesktopWindow ())
744 ScreenToClient (parent, &point);
745 private->x = point.x;
746 private->y = point.y;
747 private->width = rect.right - rect.left;
748 private->height = rect.bottom - rect.top;
749 private->window_type = GDK_WINDOW_FOREIGN;
750 private->destroyed = FALSE;
751 private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
752 if (IsWindowVisible ((HWND) anid))
753 private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
755 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
756 if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST)
757 private->state |= GDK_WINDOW_STATE_ABOVE;
759 private->state &= (~GDK_WINDOW_STATE_ABOVE);
760 private->state &= (~GDK_WINDOW_STATE_BELOW);
762 private->depth = gdk_visual_get_system ()->depth;
764 //_gdk_window_init_position (GDK_WINDOW (private));
766 g_object_ref (window);
767 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
769 GDK_NOTE (MISC, g_print ("gdk_window_foreign_new_for_display: %p: %s@%+d%+d\n",
771 _gdk_win32_drawable_description (window),
772 private->x, private->y));
778 gdk_window_lookup (GdkNativeWindow hwnd)
780 return (GdkWindow*) gdk_win32_handle_table_lookup (hwnd);
784 _gdk_windowing_window_destroy (GdkWindow *window,
786 gboolean foreign_destroy)
788 GdkWindowObject *private = (GdkWindowObject *)window;
789 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
792 g_return_if_fail (GDK_IS_WINDOW (window));
794 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy: %p\n",
795 GDK_WINDOW_HWND (window)));
797 if (private->extension_events != 0)
798 _gdk_input_window_destroy (window);
800 /* Remove ourself from the modal stack */
801 _gdk_remove_modal_window (window);
803 /* Remove all our transient children */
804 tmp = window_impl->transient_children;
807 GdkWindow *child = tmp->data;
808 GdkWindowImplWin32 *child_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (child)->impl);
810 child_impl->transient_owner = NULL;
811 tmp = g_slist_next (tmp);
813 g_slist_free (window_impl->transient_children);
814 window_impl->transient_children = NULL;
816 /* Remove ourself from our transient owner */
817 if (window_impl->transient_owner != NULL)
819 gdk_window_set_transient_for (window, NULL);
822 if (!recursing && !foreign_destroy)
824 _gdk_win32_drawable_finish (private->impl);
826 private->destroyed = TRUE;
827 DestroyWindow (GDK_WINDOW_HWND (window));
830 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
834 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
836 /* It's somebody else's window, but in our hierarchy, so reparent it
837 * to the desktop, and then try to destroy it.
839 gdk_window_hide (window);
840 gdk_window_reparent (window, NULL, 0, 0);
842 PostMessage (GDK_WINDOW_HWND (window), WM_CLOSE, 0, 0);
845 /* This function is called when the window really gone.
848 gdk_window_destroy_notify (GdkWindow *window)
850 g_return_if_fail (GDK_IS_WINDOW (window));
853 g_print ("gdk_window_destroy_notify: %p%s\n",
854 GDK_WINDOW_HWND (window),
855 (GDK_WINDOW_DESTROYED (window) ? " (destroyed)" : "")));
857 if (!GDK_WINDOW_DESTROYED (window))
859 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
860 g_warning ("window %p unexpectedly destroyed",
861 GDK_WINDOW_HWND (window));
863 _gdk_window_destroy (window, TRUE);
866 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
867 g_object_unref (window);
871 get_outer_rect (GdkWindow *window,
876 rect->left = rect->top = 0;
878 rect->bottom = height;
880 _gdk_win32_adjust_client_rect (window, rect);
884 adjust_for_gravity_hints (GdkWindow *window,
889 GdkWindowObject *obj;
890 GdkWindowImplWin32 *impl;
892 obj = GDK_WINDOW_OBJECT (window);
893 impl = GDK_WINDOW_IMPL_WIN32 (obj->impl);
895 if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
897 gint orig_x = *x, orig_y = *y;
899 switch (impl->hints.win_gravity)
901 case GDK_GRAVITY_NORTH:
902 case GDK_GRAVITY_CENTER:
903 case GDK_GRAVITY_SOUTH:
904 *x -= (outer_rect->right - outer_rect->left) / 2;
905 *x += obj->width / 2;
908 case GDK_GRAVITY_SOUTH_EAST:
909 case GDK_GRAVITY_EAST:
910 case GDK_GRAVITY_NORTH_EAST:
911 *x -= outer_rect->right - outer_rect->left;
915 case GDK_GRAVITY_STATIC:
916 *x += outer_rect->left;
923 switch (impl->hints.win_gravity)
925 case GDK_GRAVITY_WEST:
926 case GDK_GRAVITY_CENTER:
927 case GDK_GRAVITY_EAST:
928 *y -= (outer_rect->bottom - outer_rect->top) / 2;
929 *y += obj->height / 2;
932 case GDK_GRAVITY_SOUTH_WEST:
933 case GDK_GRAVITY_SOUTH:
934 case GDK_GRAVITY_SOUTH_EAST:
935 *y -= outer_rect->bottom - outer_rect->top;
939 case GDK_GRAVITY_STATIC:
940 *y += outer_rect->top;
947 (orig_x != *x || orig_y != *y) ?
948 g_print ("adjust_for_gravity_hints: x: %d->%d, y: %d->%d\n",
949 orig_x, *x, orig_y, *y)
955 show_window_internal (GdkWindow *window,
959 GdkWindowObject *private;
960 HWND old_active_window;
961 gboolean focus_on_map = TRUE;
965 private = (GdkWindowObject *) window;
967 if (private->destroyed)
970 GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
971 GDK_WINDOW_HWND (window),
972 _gdk_win32_window_state_to_string (private->state),
973 (raise ? " raise" : ""),
974 (deiconify ? " deiconify" : "")));
976 /* If asked to show (not deiconify) an withdrawn and iconified
980 !GDK_WINDOW_IS_MAPPED (window) &&
981 (private->state & GDK_WINDOW_STATE_ICONIFIED))
983 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
987 /* If asked to just show an iconified window, do nothing. */
988 if (!deiconify && (private->state & GDK_WINDOW_STATE_ICONIFIED))
991 /* If asked to deiconify an already noniconified window, do
992 * nothing. (Especially, don't cause the window to rise and
993 * activate. There are different calls for that.)
995 if (deiconify && !(private->state & GDK_WINDOW_STATE_ICONIFIED))
998 /* If asked to show (but not raise) a window that is already
999 * visible, do nothing.
1001 if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
1006 if (!GDK_WINDOW_IS_MAPPED (window))
1008 gdk_synthesize_window_state (window,
1009 GDK_WINDOW_STATE_WITHDRAWN,
1011 focus_on_map = private->focus_on_map;
1014 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1016 if (private->state & GDK_WINDOW_STATE_BELOW)
1017 exstyle &= (~WS_EX_TOPMOST);
1019 if (private->state & GDK_WINDOW_STATE_ABOVE)
1020 exstyle |= WS_EX_TOPMOST;
1022 if (exstyle & WS_EX_TOPMOST)
1027 /* Use SetWindowPos to show transparent windows so automatic redraws
1028 * in other windows can be suppressed.
1030 if (exstyle & WS_EX_TRANSPARENT)
1032 UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
1035 flags |= SWP_NOZORDER;
1036 if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1037 flags |= SWP_NOACTIVATE;
1039 SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, flags);
1044 old_active_window = GetActiveWindow ();
1046 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1048 gdk_window_fullscreen (window);
1050 else if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1052 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
1054 else if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1056 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
1058 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
1060 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
1064 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
1069 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1070 SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1072 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1073 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL ||
1074 GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
1076 if (focus_on_map && private->accept_focus)
1078 SetForegroundWindow (GDK_WINDOW_HWND (window));
1079 if (top == HWND_TOPMOST)
1080 SetWindowPos (GDK_WINDOW_HWND (window), top,
1082 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1086 SetWindowPos (GDK_WINDOW_HWND (window), top,
1088 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1093 BringWindowToTop (GDK_WINDOW_HWND (window));
1096 else if (old_active_window != GDK_WINDOW_HWND (window))
1098 SetActiveWindow (old_active_window);
1103 gdk_win32_window_show (GdkWindow *window,
1104 gboolean already_mapped)
1106 show_window_internal (window, FALSE, FALSE);
1110 gdk_win32_window_hide (GdkWindow *window)
1112 GdkWindowObject *private;
1114 private = (GdkWindowObject*) window;
1115 if (private->destroyed)
1118 GDK_NOTE (MISC, g_print ("gdk_window_hide: %p: %s\n",
1119 GDK_WINDOW_HWND (window),
1120 _gdk_win32_window_state_to_string (private->state)));
1122 if (GDK_WINDOW_IS_MAPPED (window))
1123 gdk_synthesize_window_state (window,
1125 GDK_WINDOW_STATE_WITHDRAWN);
1127 _gdk_window_clear_update_area (window);
1129 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1130 ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
1132 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
1134 SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1136 SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
1140 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
1145 gdk_win32_window_withdraw (GdkWindow *window)
1147 GdkWindowObject *private;
1149 private = (GdkWindowObject*) window;
1150 if (private->destroyed)
1153 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %p: %s\n",
1154 GDK_WINDOW_HWND (window),
1155 _gdk_win32_window_state_to_string (private->state)));
1157 gdk_window_hide (window); /* ??? */
1161 gdk_win32_window_move (GdkWindow *window,
1164 GdkWindowObject *private = (GdkWindowObject *)window;
1165 GdkWindowImplWin32 *impl;
1167 g_return_if_fail (GDK_IS_WINDOW (window));
1169 if (GDK_WINDOW_DESTROYED (window))
1172 GDK_NOTE (MISC, g_print ("gdk_window_move: %p: %+d%+d\n",
1173 GDK_WINDOW_HWND (window), x, y));
1175 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1177 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1180 /* Don't check GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD.
1181 * Foreign windows (another app's windows) might be children of our
1182 * windows! Especially in the case of gtkplug/socket.
1184 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1186 _gdk_window_move_resize_child (window, x, y, private->width, private->height);
1192 get_outer_rect (window, private->width, private->height, &outer_rect);
1194 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1196 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0,"
1197 "NOACTIVATE|NOSIZE|NOZORDER)\n",
1198 GDK_WINDOW_HWND (window),
1199 x - _gdk_offset_x, y - _gdk_offset_y));
1201 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1202 x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
1203 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
1208 gdk_win32_window_resize (GdkWindow *window,
1209 gint width, gint height)
1211 GdkWindowObject *private = (GdkWindowObject*) window;
1212 GdkWindowImplWin32 *impl;
1214 g_return_if_fail (GDK_IS_WINDOW (window));
1216 if (GDK_WINDOW_DESTROYED (window))
1224 GDK_NOTE (MISC, g_print ("gdk_window_resize: %p: %dx%d\n",
1225 GDK_WINDOW_HWND (window), width, height));
1227 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1229 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1232 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1234 _gdk_window_move_resize_child (window, private->x, private->y, width, height);
1240 get_outer_rect (window, width, height, &outer_rect);
1242 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,0,0,%ld,%ld,"
1243 "NOACTIVATE|NOMOVE|NOZORDER)\n",
1244 GDK_WINDOW_HWND (window),
1245 outer_rect.right - outer_rect.left,
1246 outer_rect.bottom - outer_rect.top));
1248 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1250 outer_rect.right - outer_rect.left,
1251 outer_rect.bottom - outer_rect.top,
1252 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
1253 private->resize_count += 1;
1258 gdk_win32_window_move_resize_internal (GdkWindow *window,
1264 GdkWindowObject *private;
1265 GdkWindowImplWin32 *impl;
1267 g_return_if_fail (GDK_IS_WINDOW (window));
1269 if (GDK_WINDOW_DESTROYED (window))
1277 private = GDK_WINDOW_OBJECT (window);
1278 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1280 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1283 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %p: %dx%d@%+d%+d\n",
1284 GDK_WINDOW_HWND (window),
1285 width, height, x, y));
1287 if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
1289 _gdk_window_move_resize_child (window, x, y, width, height);
1295 get_outer_rect (window, width, height, &outer_rect);
1297 adjust_for_gravity_hints (window, &outer_rect, &x, &y);
1299 GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld,"
1300 "NOACTIVATE|NOZORDER)\n",
1301 GDK_WINDOW_HWND (window),
1302 x - _gdk_offset_x, y - _gdk_offset_y,
1303 outer_rect.right - outer_rect.left,
1304 outer_rect.bottom - outer_rect.top));
1306 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1307 x - _gdk_offset_x, y - _gdk_offset_y,
1308 outer_rect.right - outer_rect.left,
1309 outer_rect.bottom - outer_rect.top,
1310 SWP_NOACTIVATE | SWP_NOZORDER));
1315 gdk_win32_window_move_resize (GdkWindow *window,
1322 if (with_move && (width < 0 && height < 0))
1324 gdk_win32_window_move (window, x, y);
1330 gdk_win32_window_move_resize_internal (window, x, y, width, height);
1334 gdk_win32_window_resize (window, width, height);
1340 gdk_win32_window_reparent (GdkWindow *window,
1341 GdkWindow *new_parent,
1345 GdkWindowObject *window_private;
1346 GdkWindowObject *parent_private;
1347 GdkWindowObject *old_parent_private;
1348 GdkWindowImplWin32 *impl;
1349 gboolean was_toplevel;
1353 new_parent = _gdk_root;
1355 window_private = (GdkWindowObject*) window;
1356 old_parent_private = (GdkWindowObject *) window_private->parent;
1357 parent_private = (GdkWindowObject*) new_parent;
1358 impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
1360 GDK_NOTE (MISC, g_print ("_gdk_window_reparent: %p: %p\n",
1361 GDK_WINDOW_HWND (window),
1362 GDK_WINDOW_HWND (new_parent)));
1364 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1366 was_toplevel = GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) == GetDesktopWindow ();
1367 if (was_toplevel && new_parent != _gdk_root)
1369 /* Reparenting from top-level (child of desktop). Clear out
1372 style &= ~(WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
1374 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1376 else if (new_parent == _gdk_root)
1378 /* Reparenting to top-level. Add decorations. */
1379 style &= ~(WS_CHILD);
1380 style |= WS_OVERLAPPEDWINDOW;
1381 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
1384 API_CALL (SetParent, (GDK_WINDOW_HWND (window),
1385 GDK_WINDOW_HWND (new_parent)));
1387 API_CALL (MoveWindow, (GDK_WINDOW_HWND (window),
1388 x, y, window_private->width, window_private->height, TRUE));
1390 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1393 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1394 new_parent = _gdk_root;
1396 window_private->parent = (GdkWindowObject *)new_parent;
1398 /* Switch the window type as appropriate */
1400 switch (GDK_WINDOW_TYPE (new_parent))
1402 case GDK_WINDOW_ROOT:
1403 if (impl->toplevel_window_type != -1)
1404 GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
1405 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1406 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1409 case GDK_WINDOW_TOPLEVEL:
1410 case GDK_WINDOW_CHILD:
1411 case GDK_WINDOW_DIALOG:
1412 case GDK_WINDOW_TEMP:
1413 if (WINDOW_IS_TOPLEVEL (window))
1415 /* Save the original window type so we can restore it if the
1416 * window is reparented back to be a toplevel.
1418 impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
1419 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1423 if (old_parent_private)
1424 old_parent_private->children =
1425 g_list_remove (old_parent_private->children, window);
1427 parent_private->children = g_list_prepend (parent_private->children, window);
1428 //_gdk_window_init_position (GDK_WINDOW (window_private));
1434 gdk_win32_window_raise (GdkWindow *window)
1436 if (!GDK_WINDOW_DESTROYED (window))
1438 GDK_NOTE (MISC, g_print ("gdk_window_raise: %p\n",
1439 GDK_WINDOW_HWND (window)));
1441 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
1442 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOPMOST,
1444 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1445 else if (((GdkWindowObject *)window)->accept_focus)
1446 API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
1448 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
1450 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1455 gdk_win32_window_lower (GdkWindow *window)
1457 if (!GDK_WINDOW_DESTROYED (window))
1459 GDK_NOTE (MISC, g_print ("gdk_window_lower: %p\n"
1460 "... SetWindowPos(%p,HWND_BOTTOM,0,0,0,0,"
1461 "NOACTIVATE|NOMOVE|NOSIZE)\n",
1462 GDK_WINDOW_HWND (window),
1463 GDK_WINDOW_HWND (window)));
1465 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_BOTTOM,
1467 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1472 gdk_window_set_hints (GdkWindow *window,
1481 /* Note that this function is obsolete */
1483 GdkWindowImplWin32 *impl;
1485 g_return_if_fail (GDK_IS_WINDOW (window));
1487 if (GDK_WINDOW_DESTROYED (window))
1490 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1492 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %p: %dx%d..%dx%d @%+d%+d\n",
1493 GDK_WINDOW_HWND (window),
1494 min_width, min_height, max_width, max_height,
1502 geom.min_width = min_width;
1503 geom.min_height = min_height;
1504 geom.max_width = max_width;
1505 geom.max_height = max_height;
1507 if (flags & GDK_HINT_MIN_SIZE)
1508 geom_mask |= GDK_HINT_MIN_SIZE;
1510 if (flags & GDK_HINT_MAX_SIZE)
1511 geom_mask |= GDK_HINT_MAX_SIZE;
1513 gdk_window_set_geometry_hints (window, &geom, geom_mask);
1518 gdk_window_set_urgency_hint (GdkWindow *window,
1521 FLASHWINFO flashwinfo;
1522 typedef BOOL (*PFN_FlashWindowEx) (FLASHWINFO*);
1523 PFN_FlashWindowEx flashWindowEx = NULL;
1525 g_return_if_fail (GDK_IS_WINDOW (window));
1526 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1528 if (GDK_WINDOW_DESTROYED (window))
1531 flashWindowEx = (PFN_FlashWindowEx) GetProcAddress (GetModuleHandle ("user32.dll"), "FlashWindowEx");
1535 flashwinfo.cbSize = sizeof (flashwinfo);
1536 flashwinfo.hwnd = GDK_WINDOW_HWND (window);
1538 flashwinfo.dwFlags = FLASHW_ALL | FLASHW_TIMER;
1540 flashwinfo.dwFlags = FLASHW_STOP;
1541 flashwinfo.uCount = 0;
1542 flashwinfo.dwTimeout = 0;
1544 flashWindowEx (&flashwinfo);
1548 FlashWindow (GDK_WINDOW_HWND (window), urgent);
1553 get_effective_window_decorations (GdkWindow *window,
1554 GdkWMDecoration *decoration)
1556 GdkWindowImplWin32 *impl;
1558 impl = (GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl;
1560 if (gdk_window_get_decorations (window, decoration))
1563 if (((GdkWindowObject *) window)->window_type != GDK_WINDOW_TOPLEVEL &&
1564 ((GdkWindowObject *) window)->window_type != GDK_WINDOW_DIALOG)
1569 if ((impl->hint_flags & GDK_HINT_MIN_SIZE) &&
1570 (impl->hint_flags & GDK_HINT_MAX_SIZE) &&
1571 impl->hints.min_width == impl->hints.max_width &&
1572 impl->hints.min_height == impl->hints.max_height)
1574 *decoration = GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MAXIMIZE;
1576 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1577 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1578 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1580 *decoration |= GDK_DECOR_MINIMIZE;
1582 else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
1584 *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE;
1589 else if (impl->hint_flags & GDK_HINT_MAX_SIZE)
1591 *decoration = GDK_DECOR_ALL | GDK_DECOR_MAXIMIZE;
1592 if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
1593 impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
1594 impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
1596 *decoration |= GDK_DECOR_MINIMIZE;
1603 switch (impl->type_hint)
1605 case GDK_WINDOW_TYPE_HINT_DIALOG:
1606 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1609 case GDK_WINDOW_TYPE_HINT_MENU:
1610 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1613 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1614 case GDK_WINDOW_TYPE_HINT_UTILITY:
1615 gdk_window_set_skip_taskbar_hint (window, TRUE);
1616 gdk_window_set_skip_pager_hint (window, TRUE);
1617 *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1620 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1621 *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MENU |
1622 GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
1625 case GDK_WINDOW_TYPE_HINT_DOCK:
1628 case GDK_WINDOW_TYPE_HINT_DESKTOP:
1633 case GDK_WINDOW_TYPE_HINT_NORMAL:
1634 *decoration = GDK_DECOR_ALL;
1643 gdk_window_set_geometry_hints (GdkWindow *window,
1644 const GdkGeometry *geometry,
1645 GdkWindowHints geom_mask)
1647 GdkWindowImplWin32 *impl;
1649 g_return_if_fail (GDK_IS_WINDOW (window));
1651 if (GDK_WINDOW_DESTROYED (window))
1654 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints: %p\n",
1655 GDK_WINDOW_HWND (window)));
1657 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1659 impl->hint_flags = geom_mask;
1660 impl->hints = *geometry;
1662 if (geom_mask & GDK_HINT_POS)
1663 ; /* even the X11 mplementation doesn't care */
1665 if (geom_mask & GDK_HINT_MIN_SIZE)
1667 GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n",
1668 geometry->min_width, geometry->min_height));
1671 if (geom_mask & GDK_HINT_MAX_SIZE)
1673 GDK_NOTE (MISC, g_print ("... MAX_SIZE: %dx%d\n",
1674 geometry->max_width, geometry->max_height));
1677 if (geom_mask & GDK_HINT_BASE_SIZE)
1679 GDK_NOTE (MISC, g_print ("... BASE_SIZE: %dx%d\n",
1680 geometry->base_width, geometry->base_height));
1683 if (geom_mask & GDK_HINT_RESIZE_INC)
1685 GDK_NOTE (MISC, g_print ("... RESIZE_INC: (%d,%d)\n",
1686 geometry->width_inc, geometry->height_inc));
1689 if (geom_mask & GDK_HINT_ASPECT)
1691 GDK_NOTE (MISC, g_print ("... ASPECT: %g--%g\n",
1692 geometry->min_aspect, geometry->max_aspect));
1695 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1697 GDK_NOTE (MISC, g_print ("... GRAVITY: %d\n", geometry->win_gravity));
1700 update_style_bits (window);
1704 gdk_window_set_title (GdkWindow *window,
1709 g_return_if_fail (GDK_IS_WINDOW (window));
1710 g_return_if_fail (title != NULL);
1712 if (GDK_WINDOW_DESTROYED (window))
1715 /* Empty window titles not allowed, so set it to just a period. */
1719 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
1720 GDK_WINDOW_HWND (window), title));
1722 GDK_NOTE (MISC_OR_EVENTS, title = g_strdup_printf ("%p %s", GDK_WINDOW_HWND (window), title));
1724 wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
1725 API_CALL (SetWindowTextW, (GDK_WINDOW_HWND (window), wtitle));
1728 GDK_NOTE (MISC_OR_EVENTS, g_free ((char *) title));
1732 gdk_window_set_role (GdkWindow *window,
1735 g_return_if_fail (GDK_IS_WINDOW (window));
1737 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %p: %s\n",
1738 GDK_WINDOW_HWND (window),
1739 (role ? role : "NULL")));
1744 gdk_window_set_transient_for (GdkWindow *window,
1747 HWND window_id, parent_id;
1748 GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1749 GdkWindowImplWin32 *parent_impl = NULL;
1752 g_return_if_fail (GDK_IS_WINDOW (window));
1754 window_id = GDK_WINDOW_HWND (window);
1755 parent_id = parent != NULL ? GDK_WINDOW_HWND (parent) : NULL;
1757 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n", window_id, parent_id));
1759 if (GDK_WINDOW_DESTROYED (window) || (parent && GDK_WINDOW_DESTROYED (parent)))
1761 if (GDK_WINDOW_DESTROYED (window))
1762 GDK_NOTE (MISC, g_print ("... destroyed!\n"));
1764 GDK_NOTE (MISC, g_print ("... owner destroyed!\n"));
1769 if (((GdkWindowObject *) window)->window_type == GDK_WINDOW_CHILD)
1771 GDK_NOTE (MISC, g_print ("... a child window!\n"));
1777 GdkWindowImplWin32 *trans_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window_impl->transient_owner)->impl);
1778 if (trans_impl->transient_children != NULL)
1780 item = g_slist_find (trans_impl->transient_children, window);
1782 trans_impl->transient_children = g_slist_delete_link (trans_impl->transient_children, item);
1783 trans_impl->num_transients--;
1785 if (!trans_impl->num_transients)
1787 trans_impl->transient_children = NULL;
1790 g_object_unref (G_OBJECT (window_impl->transient_owner));
1791 g_object_unref (G_OBJECT (window));
1793 window_impl->transient_owner = NULL;
1797 parent_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (parent)->impl);
1799 parent_impl->transient_children = g_slist_append (parent_impl->transient_children, window);
1800 g_object_ref (G_OBJECT (window));
1801 parent_impl->num_transients++;
1802 window_impl->transient_owner = parent;
1803 g_object_ref (G_OBJECT (parent));
1806 /* This changes the *owner* of the window, despite the misleading
1807 * name. (Owner and parent are unrelated concepts.) At least that's
1808 * what people who seem to know what they talk about say on
1809 * USENET. Search on Google.
1812 if (SetWindowLongPtr (window_id, GWLP_HWNDPARENT, (LONG_PTR) parent_id) == 0 &&
1813 GetLastError () != 0)
1814 WIN32_API_FAILED ("SetWindowLongPtr");
1818 _gdk_push_modal_window (GdkWindow *window)
1820 modal_window_stack = g_slist_prepend (modal_window_stack,
1825 _gdk_remove_modal_window (GdkWindow *window)
1829 g_return_if_fail (window != NULL);
1831 /* It's possible to be NULL here if someone sets the modal hint of the window
1832 * to FALSE before a modal window stack has ever been created. */
1833 if (modal_window_stack == NULL)
1836 /* Find the requested window in the stack and remove it. Yeah, I realize this
1837 * means we're not a 'real stack', strictly speaking. Sue me. :) */
1838 tmp = g_slist_find (modal_window_stack, window);
1841 modal_window_stack = g_slist_delete_link (modal_window_stack, tmp);
1846 _gdk_modal_current ()
1848 if (modal_window_stack != NULL)
1850 GSList *tmp = modal_window_stack;
1852 while (tmp != NULL && !GDK_WINDOW_IS_MAPPED (tmp->data))
1854 tmp = g_slist_next (tmp);
1857 return tmp != NULL ? tmp->data : NULL;
1866 gdk_win32_window_set_background (GdkWindow *window,
1867 const GdkColor *color)
1870 GdkWindowObject *private = (GdkWindowObject *)window;
1872 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %p: %s\n",
1873 GDK_WINDOW_HWND (window),
1874 _gdk_win32_color_to_string (color)));
1876 private->bg_color = *color;
1878 if (private->bg_pixmap &&
1879 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1880 private->bg_pixmap != GDK_NO_BG)
1882 g_object_unref (private->bg_pixmap);
1883 private->bg_pixmap = NULL;
1889 gdk_win32_window_set_back_pixmap (GdkWindow *window,
1892 GdkWindowObject *private = (GdkWindowObject *)window;
1894 if (private->bg_pixmap &&
1895 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1896 private->bg_pixmap != GDK_NO_BG)
1897 g_object_unref (private->bg_pixmap);
1899 if (pixmap == GDK_PARENT_RELATIVE_BG || pixmap == GDK_NO_BG)
1901 private->bg_pixmap = pixmap;
1906 gdk_win32_window_set_cursor (GdkWindow *window,
1909 GdkWindowImplWin32 *impl;
1910 GdkCursorPrivate *cursor_private;
1911 GdkWindowObject *parent_window;
1913 HCURSOR hprevcursor;
1915 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1916 cursor_private = (GdkCursorPrivate*) cursor;
1918 if (GDK_WINDOW_DESTROYED (window))
1924 hcursor = cursor_private->hcursor;
1926 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %p: %p\n",
1927 GDK_WINDOW_HWND (window),
1930 /* First get the old cursor, if any (we wait to free the old one
1931 * since it may be the current cursor set in the Win32 API right
1934 hprevcursor = impl->hcursor;
1936 if (hcursor == NULL)
1937 impl->hcursor = NULL;
1940 /* We must copy the cursor as it is OK to destroy the GdkCursor
1941 * while still in use for some window. See for instance
1942 * gimp_change_win_cursor() which calls gdk_window_set_cursor
1943 * (win, cursor), and immediately afterwards gdk_cursor_destroy
1946 if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
1947 WIN32_API_FAILED ("CopyCursor");
1948 GDK_NOTE (MISC, g_print ("... CopyCursor (%p) = %p\n",
1949 hcursor, impl->hcursor));
1952 if (impl->hcursor != NULL)
1954 /* If the pointer is over our window, set new cursor */
1955 GdkWindow *curr_window = gdk_window_get_pointer (window, NULL, NULL, NULL);
1956 if (curr_window == window)
1957 SetCursor (impl->hcursor);
1960 /* Climb up the tree and find whether our window is the
1961 * first ancestor that has cursor defined, and if so, set
1964 GdkWindowObject *curr_window_obj = GDK_WINDOW_OBJECT (curr_window);
1965 while (curr_window_obj &&
1966 !GDK_WINDOW_IMPL_WIN32 (curr_window_obj->impl)->hcursor)
1968 curr_window_obj = curr_window_obj->parent;
1969 if (curr_window_obj == GDK_WINDOW_OBJECT (window))
1971 SetCursor (impl->hcursor);
1978 /* Destroy the previous cursor: Need to make sure it's no longer in
1979 * use before we destroy it, in case we're not over our window but
1980 * the cursor is still set to our old one.
1982 if (hprevcursor != NULL)
1984 if (GetCursor () == hprevcursor)
1986 /* Look for a suitable cursor to use instead */
1988 parent_window = GDK_WINDOW_OBJECT (window)->parent;
1989 while (hcursor == NULL)
1993 impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl);
1994 hcursor = impl->hcursor;
1995 parent_window = parent_window->parent;
1999 hcursor = LoadCursor (NULL, IDC_ARROW);
2002 SetCursor (hcursor);
2005 GDK_NOTE (MISC, g_print ("... DestroyCursor (%p)\n", hprevcursor));
2007 API_CALL (DestroyCursor, (hprevcursor));
2012 gdk_win32_window_get_geometry (GdkWindow *window,
2022 if (!GDK_WINDOW_DESTROYED (window))
2026 API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
2028 if (window != _gdk_root)
2031 GdkWindow *parent = gdk_window_get_parent (window);
2035 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2036 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
2042 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2043 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
2047 if (parent == _gdk_root)
2049 rect.left += _gdk_offset_x;
2050 rect.top += _gdk_offset_y;
2051 rect.right += _gdk_offset_x;
2052 rect.bottom += _gdk_offset_y;
2061 *width = rect.right - rect.left;
2063 *height = rect.bottom - rect.top;
2065 *depth = gdk_drawable_get_visual (window)->depth;
2067 GDK_NOTE (MISC, g_print ("gdk_window_get_geometry: %p: %ldx%ldx%d@%+ld%+ld\n",
2068 GDK_WINDOW_HWND (window),
2069 rect.right - rect.left, rect.bottom - rect.top,
2070 gdk_drawable_get_visual (window)->depth,
2071 rect.left, rect.top));
2076 gdk_win32_window_get_root_coords (GdkWindow *window,
2088 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
2093 *root_x = tx + _gdk_offset_x;
2095 *root_y = ty + _gdk_offset_y;
2097 GDK_NOTE (MISC, g_print ("gdk_window_get_root_coords: %p: %+d%+d %+d%+d\n",
2098 GDK_WINDOW_HWND (window),
2105 gdk_win32_window_get_deskrelative_origin (GdkWindow *window,
2109 return gdk_win32_window_get_root_coords (window, 0, 0, x, y);
2113 gdk_win32_window_restack_under (GdkWindow *window,
2114 GList *native_siblings)
2120 gdk_window_get_root_origin (GdkWindow *window,
2126 g_return_if_fail (GDK_IS_WINDOW (window));
2128 gdk_window_get_frame_extents (window, &rect);
2136 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %p: %+d%+d\n",
2137 GDK_WINDOW_HWND (window), rect.x, rect.y));
2141 gdk_window_get_frame_extents (GdkWindow *window,
2144 GdkWindowObject *private;
2148 g_return_if_fail (GDK_IS_WINDOW (window));
2149 g_return_if_fail (rect != NULL);
2151 private = GDK_WINDOW_OBJECT (window);
2158 if (GDK_WINDOW_DESTROYED (window))
2161 /* FIXME: window is documented to be a toplevel GdkWindow, so is it really
2162 * necessary to walk its parent chain?
2164 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
2165 private = (GdkWindowObject*) private->parent;
2167 hwnd = GDK_WINDOW_HWND (window);
2168 API_CALL (GetWindowRect, (hwnd, &r));
2170 rect->x = r.left + _gdk_offset_x;
2171 rect->y = r.top + _gdk_offset_y;
2172 rect->width = r.right - r.left;
2173 rect->height = r.bottom - r.top;
2175 GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@%+ld%+ld\n",
2176 GDK_WINDOW_HWND (window),
2177 r.right - r.left, r.bottom - r.top,
2182 static GdkModifierType
2183 get_current_mask (void)
2185 GdkModifierType mask;
2188 GetKeyboardState (kbd);
2190 if (kbd[VK_SHIFT] & 0x80)
2191 mask |= GDK_SHIFT_MASK;
2192 if (kbd[VK_CAPITAL] & 0x80)
2193 mask |= GDK_LOCK_MASK;
2194 if (kbd[VK_CONTROL] & 0x80)
2195 mask |= GDK_CONTROL_MASK;
2196 if (kbd[VK_MENU] & 0x80)
2197 mask |= GDK_MOD1_MASK;
2198 if (kbd[VK_LBUTTON] & 0x80)
2199 mask |= GDK_BUTTON1_MASK;
2200 if (kbd[VK_MBUTTON] & 0x80)
2201 mask |= GDK_BUTTON2_MASK;
2202 if (kbd[VK_RBUTTON] & 0x80)
2203 mask |= GDK_BUTTON3_MASK;
2209 gdk_window_win32_get_pointer (GdkWindow *window,
2212 GdkModifierType *mask)
2214 gboolean return_val;
2218 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
2222 hwnd = GDK_WINDOW_HWND (window);
2223 GetCursorPos (&point);
2224 ScreenToClient (hwnd, &point);
2229 if (window == _gdk_root)
2231 *x += _gdk_offset_x;
2232 *y += _gdk_offset_y;
2235 hwndc = ChildWindowFromPoint (hwnd, point);
2236 if (hwndc != NULL && hwndc != hwnd &&
2237 !gdk_win32_handle_table_lookup ((GdkNativeWindow) hwndc))
2238 return_val = FALSE; /* Direct child unknown to gdk */
2240 *mask = get_current_mask ();
2246 _gdk_windowing_get_pointer (GdkDisplay *display,
2250 GdkModifierType *mask)
2254 g_return_if_fail (display == _gdk_display);
2256 *screen = _gdk_screen;
2257 GetCursorPos (&point);
2258 *x = point.x + _gdk_offset_x;
2259 *y = point.y + _gdk_offset_y;
2261 *mask = get_current_mask ();
2265 gdk_display_warp_pointer (GdkDisplay *display,
2270 g_return_if_fail (display == _gdk_display);
2271 g_return_if_fail (screen == _gdk_screen);
2273 SetCursorPos (x - _gdk_offset_x, y - _gdk_offset_y);
2277 _gdk_windowing_window_at_pointer (GdkDisplay *display,
2280 GdkModifierType *mask)
2283 POINT point, pointc;
2287 GetCursorPos (&pointc);
2289 hwnd = WindowFromPoint (point);
2294 *win_x = pointc.x + _gdk_offset_x;
2295 *win_y = pointc.y + _gdk_offset_y;
2299 ScreenToClient (hwnd, &point);
2302 hwndc = ChildWindowFromPoint (hwnd, point);
2303 ClientToScreen (hwnd, &point);
2304 ScreenToClient (hwndc, &point);
2305 } while (hwndc != hwnd && (hwnd = hwndc, 1));
2307 window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
2309 if (window && (win_x || win_y))
2311 GetClientRect (hwnd, &rect);
2312 *win_x = point.x - rect.left;
2313 *win_y = point.y - rect.top;
2316 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_at_pointer: %+d%+d %p%s\n",
2319 (window == NULL ? " NULL" : "")));
2325 gdk_win32_window_get_events (GdkWindow *window)
2327 if (GDK_WINDOW_DESTROYED (window))
2330 return GDK_WINDOW_OBJECT (window)->event_mask;
2334 gdk_win32_window_set_events (GdkWindow *window,
2335 GdkEventMask event_mask)
2337 /* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
2338 * set it here, too. Not that I know or remember why it is
2339 * necessary, will have to test some day.
2341 GDK_WINDOW_OBJECT (window)->event_mask = GDK_STRUCTURE_MASK | event_mask;
2345 do_shape_combine_region (GdkWindow *window,
2351 GetClientRect (GDK_WINDOW_HWND (window), &rect);
2352 _gdk_win32_adjust_client_rect (window, &rect);
2354 OffsetRgn (hrgn, -rect.left, -rect.top);
2355 OffsetRgn (hrgn, x, y);
2357 /* If this is a top-level window, add the title bar to the region */
2358 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
2360 HRGN tmp = CreateRectRgn (0, 0, rect.right - rect.left, -rect.top);
2361 CombineRgn (hrgn, hrgn, tmp, RGN_OR);
2365 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
2369 gdk_win32_window_shape_combine_mask (GdkWindow *window,
2373 GdkWindowObject *private = (GdkWindowObject *)window;
2377 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: none\n",
2378 GDK_WINDOW_HWND (window)));
2379 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
2381 private->shaped = FALSE;
2387 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: %p\n",
2388 GDK_WINDOW_HWND (window),
2389 GDK_WINDOW_HWND (mask)));
2391 /* Convert mask bitmap to region */
2392 hrgn = _gdk_win32_bitmap_to_hrgn (mask);
2394 do_shape_combine_region (window, hrgn, x, y);
2396 private->shaped = TRUE;
2401 gdk_window_set_override_redirect (GdkWindow *window,
2402 gboolean override_redirect)
2404 g_return_if_fail (GDK_IS_WINDOW (window));
2406 g_warning ("gdk_window_set_override_redirect not implemented");
2410 gdk_window_set_accept_focus (GdkWindow *window,
2411 gboolean accept_focus)
2413 GdkWindowObject *private;
2415 g_return_if_fail (GDK_IS_WINDOW (window));
2417 private = (GdkWindowObject *)window;
2419 accept_focus = accept_focus != FALSE;
2421 if (private->accept_focus != accept_focus)
2422 private->accept_focus = accept_focus;
2426 gdk_window_set_focus_on_map (GdkWindow *window,
2427 gboolean focus_on_map)
2429 GdkWindowObject *private;
2431 g_return_if_fail (GDK_IS_WINDOW (window));
2433 private = (GdkWindowObject *)window;
2435 focus_on_map = focus_on_map != FALSE;
2437 if (private->focus_on_map != focus_on_map)
2438 private->focus_on_map = focus_on_map;
2442 gdk_window_set_icon_list (GdkWindow *window,
2445 GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
2446 gint big_diff, small_diff;
2447 gint big_w, big_h, small_w, small_h;
2450 HICON small_hicon, big_hicon;
2451 GdkWindowImplWin32 *impl;
2452 gint i, big_i, small_i;
2454 g_return_if_fail (GDK_IS_WINDOW (window));
2456 if (GDK_WINDOW_DESTROYED (window))
2459 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
2461 /* ideal sizes for small and large icons */
2462 big_w = GetSystemMetrics (SM_CXICON);
2463 big_h = GetSystemMetrics (SM_CYICON);
2464 small_w = GetSystemMetrics (SM_CXSMICON);
2465 small_h = GetSystemMetrics (SM_CYSMICON);
2467 /* find closest sized icons in the list */
2469 small_pixbuf = NULL;
2475 pixbuf = (GdkPixbuf*) pixbufs->data;
2476 w = gdk_pixbuf_get_width (pixbuf);
2477 h = gdk_pixbuf_get_height (pixbuf);
2479 dw = ABS (w - big_w);
2480 dh = ABS (h - big_h);
2481 diff = dw*dw + dh*dh;
2482 if (big_pixbuf == NULL || diff < big_diff)
2484 big_pixbuf = pixbuf;
2489 dw = ABS (w - small_w);
2490 dh = ABS (h - small_h);
2491 diff = dw*dw + dh*dh;
2492 if (small_pixbuf == NULL || diff < small_diff)
2494 small_pixbuf = pixbuf;
2499 pixbufs = g_list_next (pixbufs);
2503 /* Create the icons */
2504 big_hicon = _gdk_win32_pixbuf_to_hicon (big_pixbuf);
2505 small_hicon = _gdk_win32_pixbuf_to_hicon (small_pixbuf);
2508 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
2510 SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_SMALL,
2511 (LPARAM)small_hicon);
2513 /* Store the icons, destroying any previous icons */
2514 if (impl->hicon_big)
2515 GDI_CALL (DestroyIcon, (impl->hicon_big));
2516 impl->hicon_big = big_hicon;
2517 if (impl->hicon_small)
2518 GDI_CALL (DestroyIcon, (impl->hicon_small));
2519 impl->hicon_small = small_hicon;
2523 gdk_window_set_icon (GdkWindow *window,
2524 GdkWindow *icon_window,
2528 g_return_if_fail (GDK_IS_WINDOW (window));
2530 /* do nothing, use gdk_window_set_icon_list instead */
2534 gdk_window_set_icon_name (GdkWindow *window,
2537 /* In case I manage to confuse this again (or somebody else does):
2538 * Please note that "icon name" here really *does* mean the name or
2539 * title of an window minimized as an icon on the desktop, or in the
2540 * taskbar. It has nothing to do with the freedesktop.org icon
2544 g_return_if_fail (GDK_IS_WINDOW (window));
2546 if (GDK_WINDOW_DESTROYED (window))
2550 /* This is not the correct thing to do. We should keep both the
2551 * "normal" window title, and the icon name. When the window is
2552 * minimized, call SetWindowText() with the icon name, and when the
2553 * window is restored, with the normal window title. Also, the name
2554 * is in UTF-8, so we should do the normal conversion to either wide
2555 * chars or system codepage, and use either the W or A version of
2556 * SetWindowText(), depending on Windows version.
2558 API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
2563 gdk_window_get_group (GdkWindow *window)
2565 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2566 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
2568 if (GDK_WINDOW_DESTROYED (window))
2571 g_warning ("gdk_window_get_group not yet implemented");
2577 gdk_window_set_group (GdkWindow *window,
2580 g_return_if_fail (GDK_IS_WINDOW (window));
2581 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2582 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
2584 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2587 g_warning ("gdk_window_set_group not implemented");
2591 update_single_bit (LONG *style,
2596 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2597 * gdk_bit indicates whether style_bit is off; if all is FALSE, gdk
2598 * bit indicate whether style_bit is on
2600 if ((!all && gdk_bit) || (all && !gdk_bit))
2601 *style |= style_bit;
2603 *style &= ~style_bit;
2607 update_style_bits (GdkWindow *window)
2609 GdkWindowObject *private = (GdkWindowObject *)window;
2610 GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)private->impl;
2611 GdkWMDecoration decorations;
2612 LONG old_style, new_style, old_exstyle, new_exstyle;
2614 RECT rect, before, after;
2616 old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2617 old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
2619 GetClientRect (GDK_WINDOW_HWND (window), &before);
2621 AdjustWindowRectEx (&before, old_style, FALSE, old_exstyle);
2623 new_style = old_style;
2624 new_exstyle = old_exstyle;
2626 if (private->window_type == GDK_WINDOW_TEMP ||
2627 impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
2628 new_exstyle |= WS_EX_TOOLWINDOW;
2630 new_exstyle &= ~WS_EX_TOOLWINDOW;
2632 if (get_effective_window_decorations (window, &decorations))
2634 all = (decorations & GDK_DECOR_ALL);
2635 update_single_bit (&new_style, all, decorations & GDK_DECOR_BORDER, WS_BORDER);
2636 update_single_bit (&new_style, all, decorations & GDK_DECOR_RESIZEH, WS_THICKFRAME);
2637 update_single_bit (&new_style, all, decorations & GDK_DECOR_TITLE, WS_CAPTION);
2638 update_single_bit (&new_style, all, decorations & GDK_DECOR_MENU, WS_SYSMENU);
2639 update_single_bit (&new_style, all, decorations & GDK_DECOR_MINIMIZE, WS_MINIMIZEBOX);
2640 update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
2643 if (old_style == new_style && old_exstyle == new_exstyle )
2645 GDK_NOTE (MISC, g_print ("update_style_bits: %p: no change\n",
2646 GDK_WINDOW_HWND (window)));
2650 if (old_style != new_style)
2652 GDK_NOTE (MISC, g_print ("update_style_bits: %p: STYLE: %s => %s\n",
2653 GDK_WINDOW_HWND (window),
2654 _gdk_win32_window_style_to_string (old_style),
2655 _gdk_win32_window_style_to_string (new_style)));
2657 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, new_style);
2660 if (old_exstyle != new_exstyle)
2662 GDK_NOTE (MISC, g_print ("update_style_bits: %p: EXSTYLE: %s => %s\n",
2663 GDK_WINDOW_HWND (window),
2664 _gdk_win32_window_exstyle_to_string (old_exstyle),
2665 _gdk_win32_window_exstyle_to_string (new_exstyle)));
2667 SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, new_exstyle);
2670 AdjustWindowRectEx (&after, new_style, FALSE, new_exstyle);
2672 GetWindowRect (GDK_WINDOW_HWND (window), &rect);
2673 rect.left += after.left - before.left;
2674 rect.top += after.top - before.top;
2675 rect.right += after.right - before.right;
2676 rect.bottom += after.bottom - before.bottom;
2678 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
2679 rect.left, rect.top,
2680 rect.right - rect.left, rect.bottom - rect.top,
2681 SWP_FRAMECHANGED | SWP_NOACTIVATE |
2682 SWP_NOREPOSITION | SWP_NOZORDER);
2687 update_single_system_menu_entry (HMENU hmenu,
2692 /* all controls the interpretation of gdk_bit -- if all is TRUE,
2693 * gdk_bit indicates whether menu entry is disabled; if all is
2694 * FALSE, gdk bit indicate whether menu entry is enabled
2696 if ((!all && gdk_bit) || (all && !gdk_bit))
2697 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_ENABLED);
2699 EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_GRAYED);
2703 update_system_menu (GdkWindow *window)
2705 GdkWMFunction functions;
2708 if (_gdk_window_get_functions (window, &functions))
2710 HMENU hmenu = GetSystemMenu (GDK_WINDOW_HWND (window), FALSE);
2712 all = (functions & GDK_FUNC_ALL);
2713 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_RESIZE, SC_SIZE);
2714 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MOVE, SC_MOVE);
2715 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MINIMIZE, SC_MINIMIZE);
2716 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MAXIMIZE, SC_MAXIMIZE);
2717 update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_CLOSE, SC_CLOSE);
2722 get_decorations_quark ()
2724 static GQuark quark = 0;
2727 quark = g_quark_from_static_string ("gdk-window-decorations");
2733 gdk_window_set_decorations (GdkWindow *window,
2734 GdkWMDecoration decorations)
2736 GdkWMDecoration* decorations_copy;
2738 g_return_if_fail (GDK_IS_WINDOW (window));
2740 GDK_NOTE (MISC, g_print ("gdk_window_set_decorations: %p: %s %s%s%s%s%s%s\n",
2741 GDK_WINDOW_HWND (window),
2742 (decorations & GDK_DECOR_ALL ? "clearing" : "setting"),
2743 (decorations & GDK_DECOR_BORDER ? "BORDER " : ""),
2744 (decorations & GDK_DECOR_RESIZEH ? "RESIZEH " : ""),
2745 (decorations & GDK_DECOR_TITLE ? "TITLE " : ""),
2746 (decorations & GDK_DECOR_MENU ? "MENU " : ""),
2747 (decorations & GDK_DECOR_MINIMIZE ? "MINIMIZE " : ""),
2748 (decorations & GDK_DECOR_MAXIMIZE ? "MAXIMIZE " : "")));
2750 decorations_copy = g_malloc (sizeof (GdkWMDecoration));
2751 *decorations_copy = decorations;
2752 g_object_set_qdata_full (G_OBJECT (window), get_decorations_quark (), decorations_copy, g_free);
2754 update_style_bits (window);
2758 gdk_window_get_decorations (GdkWindow *window,
2759 GdkWMDecoration *decorations)
2761 GdkWMDecoration* decorations_set;
2763 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2765 decorations_set = g_object_get_qdata (G_OBJECT (window), get_decorations_quark ());
2766 if (decorations_set)
2767 *decorations = *decorations_set;
2769 return (decorations_set != NULL);
2773 get_functions_quark ()
2775 static GQuark quark = 0;
2778 quark = g_quark_from_static_string ("gdk-window-functions");
2784 gdk_window_set_functions (GdkWindow *window,
2785 GdkWMFunction functions)
2787 GdkWMFunction* functions_copy;
2789 g_return_if_fail (GDK_IS_WINDOW (window));
2791 GDK_NOTE (MISC, g_print ("gdk_window_set_functions: %p: %s %s%s%s%s%s\n",
2792 GDK_WINDOW_HWND (window),
2793 (functions & GDK_FUNC_ALL ? "clearing" : "setting"),
2794 (functions & GDK_FUNC_RESIZE ? "RESIZE " : ""),
2795 (functions & GDK_FUNC_MOVE ? "MOVE " : ""),
2796 (functions & GDK_FUNC_MINIMIZE ? "MINIMIZE " : ""),
2797 (functions & GDK_FUNC_MAXIMIZE ? "MAXIMIZE " : ""),
2798 (functions & GDK_FUNC_CLOSE ? "CLOSE " : "")));
2800 functions_copy = g_malloc (sizeof (GdkWMFunction));
2801 *functions_copy = functions;
2802 g_object_set_qdata_full (G_OBJECT (window), get_functions_quark (), functions_copy, g_free);
2804 update_system_menu (window);
2808 _gdk_window_get_functions (GdkWindow *window,
2809 GdkWMFunction *functions)
2811 GdkWMDecoration* functions_set;
2813 functions_set = g_object_get_qdata (G_OBJECT (window), get_functions_quark ());
2815 *functions = *functions_set;
2817 return (functions_set != NULL);
2821 QueryTree (HWND hwnd,
2831 child = GetWindow (hwnd, GW_CHILD);
2833 child = GetWindow (child, GW_HWNDNEXT);
2836 } while (child != NULL);
2840 *children = g_new (HWND, n);
2841 for (i = 0; i < n; i++)
2844 child = GetWindow (hwnd, GW_CHILD);
2846 child = GetWindow (child, GW_HWNDNEXT);
2847 *children[i] = child;
2853 gdk_propagate_shapes (HANDLE win,
2857 HRGN region, childRegion;
2861 SetRectEmpty (&emptyRect);
2862 region = CreateRectRgnIndirect (&emptyRect);
2864 GetWindowRgn (win, region);
2866 QueryTree (win, &list, &num);
2869 WINDOWPLACEMENT placement;
2871 placement.length = sizeof (WINDOWPLACEMENT);
2872 /* go through all child windows and combine regions */
2873 for (i = 0; i < num; i++)
2875 GetWindowPlacement (list[i], &placement);
2876 if (placement.showCmd == SW_SHOWNORMAL)
2878 childRegion = CreateRectRgnIndirect (&emptyRect);
2879 GetWindowRgn (list[i], childRegion);
2880 CombineRgn (region, region, childRegion, RGN_OR);
2881 DeleteObject (childRegion);
2884 SetWindowRgn (win, region, TRUE);
2888 DeleteObject (region);
2892 gdk_win32_window_set_child_shapes (GdkWindow *window)
2894 if (GDK_WINDOW_DESTROYED (window))
2897 gdk_propagate_shapes (GDK_WINDOW_HWND (window), FALSE);
2901 gdk_win32_window_merge_child_shapes (GdkWindow *window)
2903 if (GDK_WINDOW_DESTROYED (window))
2906 gdk_propagate_shapes (GDK_WINDOW_HWND (window), TRUE);
2911 gdk_window_set_child_input_shapes (GdkWindow *window)
2913 g_return_if_fail (GDK_IS_WINDOW (window));
2915 /* Not yet implemented. See comment in
2916 * gdk_window_input_shape_combine_mask().
2923 gdk_window_merge_child_input_shapes (GdkWindow *window)
2925 g_return_if_fail (GDK_IS_WINDOW (window));
2927 /* Not yet implemented. See comment in
2928 * gdk_window_input_shape_combine_mask().
2934 gdk_win32_window_set_static_gravities (GdkWindow *window,
2935 gboolean use_static)
2937 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2943 gdk_window_begin_resize_drag (GdkWindow *window,
2952 g_return_if_fail (GDK_IS_WINDOW (window));
2954 if (GDK_WINDOW_DESTROYED (window))
2957 /* Tell Windows to start interactively resizing the window by pretending that
2958 * the left pointer button was clicked in the suitable edge or corner. This
2959 * will only work if the button is down when this function is called, and
2960 * will only work with button 1 (left), since Windows only allows window
2961 * dragging using the left mouse button.
2966 /* Must break the automatic grab that occured when the button was
2967 * pressed, otherwise it won't work.
2969 gdk_display_pointer_ungrab (_gdk_display, 0);
2973 case GDK_WINDOW_EDGE_NORTH_WEST:
2974 winedge = HTTOPLEFT;
2977 case GDK_WINDOW_EDGE_NORTH:
2981 case GDK_WINDOW_EDGE_NORTH_EAST:
2982 winedge = HTTOPRIGHT;
2985 case GDK_WINDOW_EDGE_WEST:
2989 case GDK_WINDOW_EDGE_EAST:
2993 case GDK_WINDOW_EDGE_SOUTH_WEST:
2994 winedge = HTBOTTOMLEFT;
2997 case GDK_WINDOW_EDGE_SOUTH:
3001 case GDK_WINDOW_EDGE_SOUTH_EAST:
3003 winedge = HTBOTTOMRIGHT;
3007 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, winedge,
3008 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
3012 gdk_window_begin_move_drag (GdkWindow *window,
3018 g_return_if_fail (GDK_IS_WINDOW (window));
3020 if (GDK_WINDOW_DESTROYED (window))
3023 /* Tell Windows to start interactively moving the window by pretending that
3024 * the left pointer button was clicked in the titlebar. This will only work
3025 * if the button is down when this function is called, and will only work
3026 * with button 1 (left), since Windows only allows window dragging using the
3027 * left mouse button.
3032 /* Must break the automatic grab that occured when the button was pressed,
3033 * otherwise it won't work.
3035 gdk_display_pointer_ungrab (_gdk_display, 0);
3037 DefWindowProcW (GDK_WINDOW_HWND (window), WM_NCLBUTTONDOWN, HTCAPTION,
3038 MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
3043 * Setting window states
3046 gdk_window_iconify (GdkWindow *window)
3048 HWND old_active_window;
3050 g_return_if_fail (GDK_IS_WINDOW (window));
3052 if (GDK_WINDOW_DESTROYED (window))
3055 GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
3056 GDK_WINDOW_HWND (window),
3057 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3059 if (GDK_WINDOW_IS_MAPPED (window))
3061 old_active_window = GetActiveWindow ();
3062 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
3063 if (old_active_window != GDK_WINDOW_HWND (window))
3064 SetActiveWindow (old_active_window);
3068 gdk_synthesize_window_state (window,
3070 GDK_WINDOW_STATE_ICONIFIED);
3075 gdk_window_deiconify (GdkWindow *window)
3077 g_return_if_fail (GDK_IS_WINDOW (window));
3079 if (GDK_WINDOW_DESTROYED (window))
3082 GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
3083 GDK_WINDOW_HWND (window),
3084 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3086 if (GDK_WINDOW_IS_MAPPED (window))
3088 show_window_internal (window, FALSE, TRUE);
3092 gdk_synthesize_window_state (window,
3093 GDK_WINDOW_STATE_ICONIFIED,
3099 gdk_window_stick (GdkWindow *window)
3101 g_return_if_fail (GDK_IS_WINDOW (window));
3103 if (GDK_WINDOW_DESTROYED (window))
3106 /* FIXME: Do something? */
3110 gdk_window_unstick (GdkWindow *window)
3112 g_return_if_fail (GDK_IS_WINDOW (window));
3114 if (GDK_WINDOW_DESTROYED (window))
3117 /* FIXME: Do something? */
3121 gdk_window_maximize (GdkWindow *window)
3123 g_return_if_fail (GDK_IS_WINDOW (window));
3125 if (GDK_WINDOW_DESTROYED (window))
3128 GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
3129 GDK_WINDOW_HWND (window),
3130 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3132 if (GDK_WINDOW_IS_MAPPED (window))
3133 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
3135 gdk_synthesize_window_state (window,
3137 GDK_WINDOW_STATE_MAXIMIZED);
3141 gdk_window_unmaximize (GdkWindow *window)
3143 g_return_if_fail (GDK_IS_WINDOW (window));
3145 if (GDK_WINDOW_DESTROYED (window))
3148 GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
3149 GDK_WINDOW_HWND (window),
3150 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3152 if (GDK_WINDOW_IS_MAPPED (window))
3153 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
3155 gdk_synthesize_window_state (window,
3156 GDK_WINDOW_STATE_MAXIMIZED,
3160 typedef struct _FullscreenInfo FullscreenInfo;
3162 struct _FullscreenInfo
3170 gdk_window_fullscreen (GdkWindow *window)
3172 gint x, y, width, height;
3174 GdkWindowObject *private = (GdkWindowObject *) window;
3178 g_return_if_fail (GDK_IS_WINDOW (window));
3180 fi = g_new (FullscreenInfo, 1);
3182 if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
3186 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
3188 monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
3189 mi.cbSize = sizeof (mi);
3190 if (monitor && GetMonitorInfo (monitor, &mi))
3192 x = mi.rcMonitor.left;
3193 y = mi.rcMonitor.top;
3194 width = mi.rcMonitor.right - x;
3195 height = mi.rcMonitor.bottom - y;
3200 width = GetSystemMetrics (SM_CXSCREEN);
3201 height = GetSystemMetrics (SM_CYSCREEN);
3204 /* remember for restoring */
3205 fi->hint_flags = impl->hint_flags;
3206 impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
3207 g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
3208 fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
3210 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3211 (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
3213 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
3214 x, y, width, height,
3215 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
3217 gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
3222 gdk_window_unfullscreen (GdkWindow *window)
3225 GdkWindowObject *private = (GdkWindowObject *) window;
3227 g_return_if_fail (GDK_IS_WINDOW (window));
3229 fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
3232 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
3234 impl->hint_flags = fi->hint_flags;
3235 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
3236 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
3237 fi->r.left, fi->r.top,
3238 fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
3239 SWP_NOCOPYBITS | SWP_SHOWWINDOW));
3241 g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
3244 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
3249 gdk_window_set_keep_above (GdkWindow *window,
3252 g_return_if_fail (GDK_IS_WINDOW (window));
3254 if (GDK_WINDOW_DESTROYED (window))
3257 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_above: %p: %s\n",
3258 GDK_WINDOW_HWND (window),
3259 setting ? "YES" : "NO"));
3261 if (GDK_WINDOW_IS_MAPPED (window))
3263 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3264 setting ? HWND_TOPMOST : HWND_NOTOPMOST,
3266 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
3269 gdk_synthesize_window_state (window,
3270 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
3271 setting ? GDK_WINDOW_STATE_ABOVE : 0);
3275 gdk_window_set_keep_below (GdkWindow *window,
3278 g_return_if_fail (GDK_IS_WINDOW (window));
3280 if (GDK_WINDOW_DESTROYED (window))
3283 GDK_NOTE (MISC, g_print ("gdk_window_set_keep_below: %p: %s\n",
3284 GDK_WINDOW_HWND (window),
3285 setting ? "YES" : "NO"));
3287 if (GDK_WINDOW_IS_MAPPED (window))
3289 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3290 setting ? HWND_BOTTOM : HWND_NOTOPMOST,
3292 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE));
3295 gdk_synthesize_window_state (window,
3296 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
3297 setting ? GDK_WINDOW_STATE_BELOW : 0);
3301 gdk_window_focus (GdkWindow *window,
3304 g_return_if_fail (GDK_IS_WINDOW (window));
3306 if (GDK_WINDOW_DESTROYED (window))
3309 GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
3310 GDK_WINDOW_HWND (window),
3311 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
3313 if (((GdkWindowObject *) window)->state & GDK_WINDOW_STATE_MAXIMIZED)
3314 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
3316 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
3317 SetFocus (GDK_WINDOW_HWND (window));
3321 gdk_window_set_modal_hint (GdkWindow *window,
3324 GdkWindowObject *private;
3326 g_return_if_fail (GDK_IS_WINDOW (window));
3328 if (GDK_WINDOW_DESTROYED (window))
3331 GDK_NOTE (MISC, g_print ("gdk_window_set_modal_hint: %p: %s\n",
3332 GDK_WINDOW_HWND (window),
3333 modal ? "YES" : "NO"));
3335 private = (GdkWindowObject*) window;
3337 if (modal == private->modal_hint)
3340 private->modal_hint = modal;
3343 /* Not sure about this one.. -- Cody */
3344 if (GDK_WINDOW_IS_MAPPED (window))
3345 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
3346 modal ? HWND_TOPMOST : HWND_NOTOPMOST,
3348 SWP_NOMOVE | SWP_NOSIZE));
3353 _gdk_push_modal_window (window);
3354 gdk_window_raise (window);
3358 _gdk_remove_modal_window (window);
3365 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
3366 gboolean skips_taskbar)
3368 static GdkWindow *owner = NULL;
3371 g_return_if_fail (GDK_IS_WINDOW (window));
3373 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s, doing nothing\n",
3374 GDK_WINDOW_HWND (window),
3375 skips_taskbar ? "YES" : "NO"));
3377 // ### TODO: Need to figure out what to do here.
3385 wa.window_type = GDK_WINDOW_TEMP;
3386 wa.wclass = GDK_INPUT_OUTPUT;
3387 wa.width = wa.height = 1;
3389 owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
3393 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner));
3395 #if 0 /* Should we also turn off the minimize and maximize buttons? */
3396 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
3397 GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
3398 SetWindowPos (GDK_WINDOW_HWND (window), NULL,
3400 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
3401 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
3406 SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, 0);
3411 gdk_window_set_skip_pager_hint (GdkWindow *window,
3412 gboolean skips_pager)
3414 g_return_if_fail (GDK_IS_WINDOW (window));
3416 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_pager_hint: %p: %s, doing nothing\n",
3417 GDK_WINDOW_HWND (window),
3418 skips_pager ? "YES" : "NO"));
3422 gdk_window_set_type_hint (GdkWindow *window,
3423 GdkWindowTypeHint hint)
3425 g_return_if_fail (GDK_IS_WINDOW (window));
3427 if (GDK_WINDOW_DESTROYED (window))
3432 static GEnumClass *class = NULL;
3434 class = g_type_class_ref (GDK_TYPE_WINDOW_TYPE_HINT);
3435 g_print ("gdk_window_set_type_hint: %p: %s\n",
3436 GDK_WINDOW_HWND (window),
3437 g_enum_get_value (class, hint)->value_name);
3440 ((GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl)->type_hint = hint;
3442 update_style_bits (window);
3446 gdk_window_get_type_hint (GdkWindow *window)
3448 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
3450 if (GDK_WINDOW_DESTROYED (window))
3451 return GDK_WINDOW_TYPE_HINT_NORMAL;
3453 return GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->type_hint;
3457 gdk_win32_window_shape_combine_region (GdkWindow *window,
3458 const GdkRegion *shape_region,
3462 GdkWindowObject *private = (GdkWindowObject *)window;
3464 if (GDK_WINDOW_DESTROYED (window))
3469 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_region: %p: none\n",
3470 GDK_WINDOW_HWND (window)));
3471 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
3473 private->shaped = FALSE;
3479 hrgn = _gdk_win32_gdkregion_to_hrgn (shape_region, 0, 0);
3481 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_region: %p: %p\n",
3482 GDK_WINDOW_HWND (window),
3485 do_shape_combine_region (window, hrgn, offset_x, offset_y);
3487 private->shaped = TRUE;
3492 gdk_window_lookup_for_display (GdkDisplay *display,
3493 GdkNativeWindow anid)
3495 g_return_val_if_fail (display == _gdk_display, NULL);
3497 return gdk_window_lookup (anid);
3501 gdk_window_enable_synchronized_configure (GdkWindow *window)
3503 g_return_if_fail (GDK_IS_WINDOW (window));
3507 gdk_window_configure_finished (GdkWindow *window)
3509 g_return_if_fail (GDK_IS_WINDOW (window));
3513 _gdk_windowing_window_beep (GdkWindow *window)
3515 gdk_display_beep (_gdk_display);
3519 gdk_window_set_opacity (GdkWindow *window,
3523 typedef BOOL (*PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
3524 PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
3526 g_return_if_fail (GDK_IS_WINDOW (window));
3527 g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
3529 if (GDK_WINDOW_DESTROYED (window))
3534 else if (opacity > 1)
3537 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
3539 if (!(exstyle & WS_EX_LAYERED))
3540 API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window),
3542 exstyle | WS_EX_LAYERED));
3544 setLayeredWindowAttributes =
3545 (PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
3547 if (setLayeredWindowAttributes)
3549 API_CALL (setLayeredWindowAttributes, (GDK_WINDOW_HWND (window),
3557 _gdk_windowing_get_shape_for_mask (GdkBitmap *mask)
3564 _gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
3569 _gdk_windowing_window_get_shape (GdkWindow *window)
3575 _gdk_windowing_window_get_input_shape (GdkWindow *window)
3581 _gdk_win32_window_destroy (GdkWindow *window,
3583 gboolean foreign_destroy)
3588 _gdk_win32_window_queue_antiexpose (GdkWindow *window,
3591 HRGN hrgn = _gdk_win32_gdkregion_to_hrgn (area, 0, 0);
3593 GDK_NOTE (EVENTS, g_print ("_gdk_windowing_window_queue_antiexpose: ValidateRgn %p %s\n",
3594 GDK_WINDOW_HWND (window),
3595 _gdk_win32_gdkregion_to_string (area)));
3597 ValidateRgn (GDK_WINDOW_HWND (window), hrgn);
3599 DeleteObject (hrgn);
3605 _gdk_win32_window_queue_translation (GdkWindow *window,
3610 /* TODO: Get current updateregion, move any part of it that intersects area by dx,dy */
3611 g_print ("queue_translation\n");
3615 gdk_win32_input_shape_combine_region (GdkWindow *window,
3616 const GdkRegion *shape_region,
3623 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
3626 _gdk_window_process_updates_recurse (window, region);
3630 _gdk_windowing_before_process_all_updates (void)
3635 _gdk_windowing_after_process_all_updates (void)
3640 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
3642 iface->show = gdk_win32_window_show;
3643 iface->hide = gdk_win32_window_hide;
3644 iface->withdraw = gdk_win32_window_withdraw;
3645 iface->set_events = gdk_win32_window_set_events;
3646 iface->get_events = gdk_win32_window_get_events;
3647 iface->raise = gdk_win32_window_raise;
3648 iface->lower = gdk_win32_window_lower;
3649 iface->restack_under = gdk_win32_window_restack_under;
3650 iface->move_resize = gdk_win32_window_move_resize;
3651 iface->set_background = gdk_win32_window_set_background;
3652 iface->set_back_pixmap = gdk_win32_window_set_back_pixmap;
3653 iface->reparent = gdk_win32_window_reparent;
3654 iface->set_cursor = gdk_win32_window_set_cursor;
3655 iface->get_geometry = gdk_win32_window_get_geometry;
3656 iface->get_pointer = gdk_window_win32_get_pointer;
3657 iface->get_root_coords = gdk_win32_window_get_root_coords;
3658 iface->shape_combine_region = gdk_win32_window_shape_combine_region;
3659 iface->input_shape_combine_region = gdk_win32_input_shape_combine_region;
3660 iface->get_deskrelative_origin = gdk_win32_window_get_deskrelative_origin;
3661 iface->set_static_gravities = gdk_win32_window_set_static_gravities;
3662 iface->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
3663 iface->queue_translation = _gdk_win32_window_queue_translation;
3664 iface->destroy = _gdk_win32_window_destroy;