1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * Copyright (C) 1998-2002 Tor Lillqvist
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include "gdk.h" /* gdk_rectangle_intersect */
31 #include "gdkevents.h"
32 #include "gdkpixmap.h"
33 #include "gdkwindow.h"
34 #include "gdkdisplay.h"
35 #include "gdkprivate-win32.h"
36 #include "gdkinput-win32.h"
38 #include <gdk-pixbuf/gdk-pixbuf.h>
39 #include <stdio.h> /* sprintf */
41 static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable);
42 static void gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
44 static void gdk_window_impl_win32_get_size (GdkDrawable *drawable,
47 static GdkRegion* gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable);
48 static void gdk_window_impl_win32_init (GdkWindowImplWin32 *window);
49 static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass);
50 static void gdk_window_impl_win32_finalize (GObject *object);
52 static gpointer parent_class = NULL;
55 _gdk_window_impl_win32_get_type (void)
57 static GType object_type = 0;
61 static const GTypeInfo object_info =
63 sizeof (GdkWindowImplWin32Class),
65 (GBaseFinalizeFunc) NULL,
66 (GClassInitFunc) gdk_window_impl_win32_class_init,
67 NULL, /* class_finalize */
68 NULL, /* class_data */
69 sizeof (GdkWindowImplWin32),
71 (GInstanceInitFunc) gdk_window_impl_win32_init,
74 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_WIN32,
83 _gdk_window_impl_get_type (void)
85 return _gdk_window_impl_win32_get_type ();
89 gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
97 impl->extension_events_selected = FALSE;
101 gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
103 GObjectClass *object_class = G_OBJECT_CLASS (klass);
104 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
106 parent_class = g_type_class_peek_parent (klass);
108 object_class->finalize = gdk_window_impl_win32_finalize;
110 drawable_class->set_colormap = gdk_window_impl_win32_set_colormap;
111 drawable_class->get_colormap = gdk_window_impl_win32_get_colormap;
112 drawable_class->get_size = gdk_window_impl_win32_get_size;
114 /* Visible and clip regions are the same */
115 drawable_class->get_clip_region = gdk_window_impl_win32_get_visible_region;
116 drawable_class->get_visible_region = gdk_window_impl_win32_get_visible_region;
120 gdk_window_impl_win32_finalize (GObject *object)
122 GdkWindowObject *wrapper;
123 GdkDrawableImplWin32 *draw_impl;
124 GdkWindowImplWin32 *window_impl;
126 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (object));
128 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (object);
129 window_impl = GDK_WINDOW_IMPL_WIN32 (object);
131 wrapper = (GdkWindowObject*) draw_impl->wrapper;
133 if (!GDK_WINDOW_DESTROYED (wrapper))
135 gdk_win32_handle_table_remove (draw_impl->handle);
138 if (window_impl->hcursor != NULL)
140 if (GetCursor () == window_impl->hcursor)
142 GDI_CALL (DestroyCursor, (window_impl->hcursor));
143 window_impl->hcursor = NULL;
145 if (window_impl->hicon != NULL)
147 GDI_CALL (DestroyIcon, (window_impl->hicon));
148 window_impl->hicon = NULL;
151 G_OBJECT_CLASS (parent_class)->finalize (object);
155 _gdk_win32_adjust_client_rect (GdkWindow *window,
160 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
161 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
162 API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));
166 _gdk_win32_get_adjusted_client_rect (GdkWindow *window,
169 GetClientRect (GDK_WINDOW_HWND (window), rect);
170 _gdk_win32_adjust_client_rect (window, rect);
174 gdk_window_impl_win32_get_colormap (GdkDrawable *drawable)
176 GdkDrawableImplWin32 *drawable_impl;
178 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable), NULL);
180 drawable_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
182 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
183 drawable_impl->colormap == NULL)
185 drawable_impl->colormap = gdk_colormap_get_system ();
186 g_object_ref (drawable_impl->colormap);
189 return drawable_impl->colormap;
193 gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
196 GdkWindowImplWin32 *impl;
197 GdkDrawableImplWin32 *draw_impl;
199 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
201 impl = GDK_WINDOW_IMPL_WIN32 (drawable);
202 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
205 GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
210 g_print("gdk_window_impl_win32_set_colormap: XXX\n");
215 gdk_window_impl_win32_get_size (GdkDrawable *drawable,
219 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
222 *width = GDK_WINDOW_IMPL_WIN32 (drawable)->width;
224 *height = GDK_WINDOW_IMPL_WIN32 (drawable)->height;
228 gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable)
230 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (drawable);
231 GdkRectangle result_rect;
235 result_rect.width = impl->width;
236 result_rect.height = impl->height;
238 gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
240 return gdk_region_rectangle (&result_rect);
244 _gdk_windowing_window_init (void)
246 GdkWindowObject *private;
247 GdkWindowImplWin32 *impl;
248 GdkDrawableImplWin32 *draw_impl;
252 g_assert (_gdk_parent_root == NULL);
254 _gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
255 private = (GdkWindowObject *)_gdk_parent_root;
256 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
257 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
259 draw_impl->handle = _gdk_root_window;
260 draw_impl->wrapper = GDK_DRAWABLE (private);
261 draw_impl->colormap = gdk_colormap_get_system ();
262 g_object_ref (draw_impl->colormap);
264 private->window_type = GDK_WINDOW_ROOT;
265 private->depth = gdk_visual_get_system ()->depth;
267 rect = _gdk_monitors[0];
268 for (i = 1; i < _gdk_num_monitors; i++)
269 gdk_rectangle_union (&rect, _gdk_monitors+i, &rect);
271 impl->width = rect.width;
272 impl->height = rect.height;
274 _gdk_window_init_position (GDK_WINDOW (private));
276 gdk_win32_handle_table_insert (&_gdk_root_window, _gdk_parent_root);
278 GDK_NOTE (MISC, g_print ("_gdk_parent_root=%p\n", GDK_WINDOW_HWND (_gdk_parent_root)));
282 get_default_title (void)
285 title = g_get_application_name ();
287 title = g_get_prgname ();
293 * is a wrapper function for RegisterWindowClassEx.
294 * It creates at least one unique class for every
295 * GdkWindowType. If support for single window-specific icons
296 * is ever needed (e.g Dialog specific), every such window should
300 RegisterGdkClass (GdkWindowType wtype)
302 static ATOM klassTOPLEVEL = 0;
303 static ATOM klassDIALOG = 0;
304 static ATOM klassCHILD = 0;
305 static ATOM klassTEMP = 0;
306 static HICON hAppIcon = NULL;
307 static WNDCLASSEX wcl;
310 wcl.cbSize = sizeof (WNDCLASSEX);
311 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
312 * on WM_SIZE and WM_MOVE. Flicker, Performance!
314 wcl.lpfnWndProc = _gdk_win32_window_procedure;
317 wcl.hInstance = _gdk_app_hmodule;
319 /* initialize once! */
322 gchar sLoc [MAX_PATH+1];
324 if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
326 hAppIcon = ExtractIcon (_gdk_app_hmodule, sLoc, 0);
329 if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
330 hAppIcon = ExtractIcon (_gdk_dll_hinstance, sLoc, 0);
334 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
337 wcl.lpszMenuName = NULL;
340 /* initialize once per class */
342 * HB: Setting the background brush leads to flicker, because we
343 * don't get asked how to clear the background. This is not what
344 * we want, at least not for input_only windows ...
346 #define ONCE_PER_CLASS() \
347 wcl.hIcon = CopyIcon (hAppIcon); \
348 wcl.hIconSm = CopyIcon (hAppIcon); \
349 wcl.hbrBackground = NULL; \
350 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
354 case GDK_WINDOW_TOPLEVEL:
355 if (0 == klassTOPLEVEL)
357 wcl.lpszClassName = "gdkWindowToplevel";
360 klassTOPLEVEL = RegisterClassEx (&wcl);
362 klass = klassTOPLEVEL;
365 case GDK_WINDOW_CHILD:
368 wcl.lpszClassName = "gdkWindowChild";
370 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
372 klassCHILD = RegisterClassEx (&wcl);
377 case GDK_WINDOW_DIALOG:
378 if (0 == klassDIALOG)
380 wcl.lpszClassName = "gdkWindowDialog";
381 wcl.style |= CS_SAVEBITS;
383 klassDIALOG = RegisterClassEx (&wcl);
388 case GDK_WINDOW_TEMP:
391 wcl.lpszClassName = "gdkWindowTemp";
392 wcl.style |= CS_SAVEBITS;
394 klassTEMP = RegisterClassEx (&wcl);
400 g_assert_not_reached ();
406 WIN32_API_FAILED ("RegisterClassEx");
407 g_error ("That is a fatal error");
413 gdk_window_new (GdkWindow *parent,
414 GdkWindowAttr *attributes,
415 gint attributes_mask)
419 DWORD dwStyle = 0, dwExStyle;
422 GdkWindowObject *private;
423 GdkWindowImplWin32 *impl;
424 GdkDrawableImplWin32 *draw_impl;
429 gint window_width, window_height;
430 gint offset_x = 0, offset_y = 0;
432 g_return_val_if_fail (attributes != NULL, NULL);
436 screen = gdk_screen_get_default ();
437 parent = gdk_screen_get_root_window (screen);
440 screen = gdk_drawable_get_screen (parent);
442 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
445 g_print ("gdk_window_new: %s\n",
446 (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
447 (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" :
448 (attributes->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
449 (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
452 if (GDK_WINDOW_DESTROYED (parent))
455 hparent = GDK_WINDOW_HWND (parent);
457 window = g_object_new (GDK_TYPE_WINDOW, NULL);
458 private = (GdkWindowObject *)window;
459 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
460 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
461 draw_impl->wrapper = GDK_DRAWABLE (window);
463 /* Windows with a foreign parent are treated as if they are children
464 * of the root window, except for actual creation.
466 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
467 parent = _gdk_parent_root;
469 private->parent = (GdkWindowObject *)parent;
471 if (attributes_mask & GDK_WA_X)
472 private->x = attributes->x;
476 if (attributes_mask & GDK_WA_Y)
477 private->y = attributes->y;
478 else if (attributes_mask & GDK_WA_X)
479 private->y = 100; /* ??? We must put it somewhere... */
483 if (attributes_mask & GDK_WA_VISUAL)
484 visual = attributes->visual;
486 visual = gdk_visual_get_system ();
488 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
489 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
490 impl->extension_events_selected = FALSE;
491 private->window_type = attributes->window_type;
493 if (attributes->wclass == GDK_INPUT_OUTPUT)
497 private->input_only = FALSE;
498 private->depth = visual->depth;
500 if (attributes_mask & GDK_WA_COLORMAP)
502 draw_impl->colormap = attributes->colormap;
503 g_object_ref (attributes->colormap);
507 draw_impl->colormap = gdk_screen_get_system_colormap (screen);
508 g_object_ref (draw_impl->colormap);
513 dwExStyle = WS_EX_TRANSPARENT;
515 private->input_only = TRUE;
516 draw_impl->colormap = gdk_colormap_get_system ();
517 g_object_ref (draw_impl->colormap);
518 GDK_NOTE (MISC, g_print ("...GDK_INPUT_ONLY, system colormap"));
521 switch (private->window_type)
523 case GDK_WINDOW_TOPLEVEL:
524 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
525 hparent = _gdk_root_window;
526 offset_x = _gdk_offset_x;
527 offset_y = _gdk_offset_y;
530 case GDK_WINDOW_CHILD:
531 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
534 case GDK_WINDOW_DIALOG:
535 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
537 dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
539 hparent = _gdk_root_window;
540 offset_x = _gdk_offset_x;
541 offset_y = _gdk_offset_y;
544 case GDK_WINDOW_TEMP:
545 dwStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
546 /* a temp window is not necessarily a top level window */
547 dwStyle |= (_gdk_parent_root == parent ? WS_POPUP : WS_CHILDWINDOW);
548 dwExStyle |= WS_EX_TOOLWINDOW;
549 offset_x = _gdk_offset_x;
550 offset_y = _gdk_offset_y;
553 case GDK_WINDOW_ROOT:
554 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
558 g_assert_not_reached ();
561 _gdk_window_init_position (GDK_WINDOW (private));
563 if (private->window_type != GDK_WINDOW_CHILD)
565 rect.left = rect.top = 0;
566 rect.right = impl->position_info.width;
567 rect.bottom = impl->position_info.height;
569 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
571 window_width = rect.right - rect.left;
572 window_height = rect.bottom - rect.top;
576 window_width = impl->position_info.width;
577 window_height = impl->position_info.height;
580 if (impl->position_info.big)
581 private->guffaw_gravity = TRUE;
583 if (attributes_mask & GDK_WA_TITLE)
584 title = attributes->title;
586 title = get_default_title ();
587 if (!title || !*title)
588 title = "GDK client window";
590 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
592 if (private->parent && private->parent->guffaw_gravity)
598 private->parent->children = g_list_prepend (private->parent->children, window);
600 klass = RegisterGdkClass (private->window_type);
602 mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
604 #ifdef WITHOUT_WM_CREATE
606 CreateWindowEx (dwExStyle,
607 MAKEINTRESOURCE(klass),
610 ((attributes_mask & GDK_WA_X) ?
611 impl->position_info.x - offset_x : CW_USEDEFAULT),
612 impl->position_info.y - offset_y,
613 window_width, window_height,
621 CreateWindowEx (dwExStyle,
622 MAKEINTRESOURCE(klass),
625 ((attributes_mask & GDK_WA_X) ?
626 impl->position_info.x - offset_x: CW_USEDEFAULT),
627 impl->position_info.y - offset_y,
628 window_width, window_height,
633 if (GDK_WINDOW_HWND (window) != hwndNew)
635 g_warning("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.",
636 GDK_WINDOW_HWND (window),
639 /* HB: IHMO due to a race condition the handle was increased by
640 * one, which causes much trouble. Because I can't find the
641 * real bug, try to workaround it ...
642 * To reproduce: compile with MSVC 5, DEBUG=1
645 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
646 GDK_WINDOW_HWND (window) = hwndNew;
647 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
649 /* the old behaviour, but with warning */
650 draw_impl->handle = hwndNew;
655 g_object_ref (window);
656 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
659 GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@+%d+%d %p = %p\n",
661 window_width, window_height,
662 ((attributes_mask & GDK_WA_X) ?
663 impl->position_info.x - offset_x: CW_USEDEFAULT),
664 impl->position_info.y - offset_y,
666 GDK_WINDOW_HWND (window)));
670 if (draw_impl->handle == NULL)
672 WIN32_API_FAILED ("CreateWindowEx");
673 g_object_unref (window);
677 #ifdef WITHOUT_WM_CREATE
678 g_object_ref (window);
679 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
682 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
683 (attributes->cursor) :
690 gdk_window_foreign_new_for_display (GdkDisplay *display,
691 GdkNativeWindow anid)
694 GdkWindowObject *private;
695 GdkWindowImplWin32 *impl;
696 GdkDrawableImplWin32 *draw_impl;
702 g_return_val_if_fail (display == gdk_display_get_default (), NULL);
704 window = g_object_new (GDK_TYPE_WINDOW, NULL);
705 private = (GdkWindowObject *)window;
706 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
707 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
708 draw_impl->wrapper = GDK_DRAWABLE (window);
709 parent = GetParent ((HWND)anid);
711 private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
712 if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
713 private->parent = (GdkWindowObject *)_gdk_parent_root;
715 private->parent->children = g_list_prepend (private->parent->children, window);
717 draw_impl->handle = (HWND) anid;
718 GetClientRect ((HWND) anid, &rect);
720 point.y = rect.right;
721 ClientToScreen ((HWND) anid, &point);
722 if (parent != _gdk_root_window)
723 ScreenToClient (parent, &point);
724 private->x = point.x;
725 private->y = point.y;
726 impl->width = rect.right - rect.left;
727 impl->height = rect.bottom - rect.top;
728 private->window_type = GDK_WINDOW_FOREIGN;
729 private->destroyed = FALSE;
730 private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
731 if (IsWindowVisible ((HWND) anid))
732 private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
734 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
735 if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST)
736 private->state |= GDK_WINDOW_STATE_ABOVE;
738 private->state &= (~GDK_WINDOW_STATE_ABOVE);
739 private->state &= (~GDK_WINDOW_STATE_BELOW);
741 private->depth = gdk_visual_get_system ()->depth;
743 _gdk_window_init_position (GDK_WINDOW (private));
745 g_object_ref (window);
746 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
752 gdk_window_lookup (GdkNativeWindow hwnd)
754 return (GdkWindow*) gdk_win32_handle_table_lookup (hwnd);
758 _gdk_windowing_window_destroy (GdkWindow *window,
760 gboolean foreign_destroy)
762 GdkWindowObject *private = (GdkWindowObject *)window;
764 g_return_if_fail (GDK_IS_WINDOW (window));
766 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy: %p\n",
767 GDK_WINDOW_HWND (window)));
769 if (private->extension_events != 0)
770 _gdk_input_window_destroy (window);
772 if (private->window_type == GDK_WINDOW_FOREIGN)
774 if (!foreign_destroy && (private->parent != NULL))
776 /* It's somebody else's window, but in our hierarchy,
777 * so reparent it to the root window, and then call
778 * DestroyWindow() on it.
780 gdk_window_hide (window);
781 gdk_window_reparent (window, NULL, 0, 0);
783 /* Is this too drastic? Many (most?) applications
784 * quit if any window receives WM_QUIT I think.
785 * OTOH, I don't think foreign windows are much
786 * used, so the question is maybe academic.
788 PostMessage (GDK_WINDOW_HWND (window), WM_QUIT, 0, 0);
791 else if (!recursing && !foreign_destroy)
793 private->destroyed = TRUE;
794 DestroyWindow (GDK_WINDOW_HWND (window));
798 /* This function is called when the window really gone.
801 gdk_window_destroy_notify (GdkWindow *window)
803 g_return_if_fail (window != NULL);
804 g_return_if_fail (GDK_IS_WINDOW (window));
807 g_print ("gdk_window_destroy_notify: %p%s\n",
808 GDK_WINDOW_HWND (window),
809 (GDK_WINDOW_DESTROYED (window) ? " (destroyed)" : "")));
811 if (!GDK_WINDOW_DESTROYED (window))
813 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
814 g_warning ("window %p unexpectedly destroyed",
815 GDK_WINDOW_HWND (window));
817 _gdk_window_destroy (window, TRUE);
820 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
821 g_object_unref (window);
825 get_outer_rect (GdkWindow *window,
832 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
833 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
835 rect->left = rect->top = 0;
837 rect->bottom = height;
839 API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));
843 adjust_for_gravity_hints (GdkWindowImplWin32 *impl,
848 if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
850 gint orig_x = *x, orig_y = *y;
852 switch (impl->hints.win_gravity)
854 case GDK_GRAVITY_NORTH:
855 case GDK_GRAVITY_CENTER:
856 case GDK_GRAVITY_SOUTH:
857 *x -= (outer_rect->right - outer_rect->left) / 2;
858 *x += impl->width / 2;
861 case GDK_GRAVITY_SOUTH_EAST:
862 case GDK_GRAVITY_EAST:
863 case GDK_GRAVITY_NORTH_EAST:
864 *x -= outer_rect->right - outer_rect->left;
868 case GDK_GRAVITY_STATIC:
869 *x += outer_rect->left;
876 switch (impl->hints.win_gravity)
878 case GDK_GRAVITY_WEST:
879 case GDK_GRAVITY_CENTER:
880 case GDK_GRAVITY_EAST:
881 *y -= (outer_rect->bottom - outer_rect->top) / 2;
882 *y += impl->height / 2;
885 case GDK_GRAVITY_SOUTH_WEST:
886 case GDK_GRAVITY_SOUTH:
887 case GDK_GRAVITY_SOUTH_EAST:
888 *y -= outer_rect->bottom - outer_rect->top;
892 case GDK_GRAVITY_STATIC:
893 *y += outer_rect->top;
900 (orig_x != *x || orig_y != *y) ?
901 g_print ("adjust_for_gravity_hints: x: %d->%d, y: %d->%d\n",
902 orig_x, *x, orig_y, *y)
908 show_window_internal (GdkWindow *window,
912 GdkWindowObject *private;
913 HWND old_active_window;
915 private = (GdkWindowObject *) window;
917 if (private->destroyed)
920 GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
921 GDK_WINDOW_HWND (window),
922 _gdk_win32_window_state_to_string (private->state),
923 (raise ? " raise" : ""),
924 (deiconify ? " deiconify" : "")));
926 /* If asked to show (not deiconify) an withdrawn and iconified
930 !GDK_WINDOW_IS_MAPPED (window) &&
931 (private->state & GDK_WINDOW_STATE_ICONIFIED))
933 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
937 /* If asked to just show an iconified window, do nothing. */
938 if (!deiconify && (private->state & GDK_WINDOW_STATE_ICONIFIED))
941 /* If asked to deiconify an already noniconified window, do
942 * nothing. (Especially, don't cause the window to rise and
943 * activate. There are different calls for that.)
945 if (deiconify && !(private->state & GDK_WINDOW_STATE_ICONIFIED))
948 /* If asked to show (but not raise) a window that is already
949 * visible, do nothing.
951 if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
956 if (!GDK_WINDOW_IS_MAPPED (window))
957 gdk_synthesize_window_state (window,
958 GDK_WINDOW_STATE_WITHDRAWN,
961 old_active_window = GetActiveWindow ();
963 if (private->state & (GDK_WINDOW_STATE_BELOW | GDK_WINDOW_STATE_ABOVE))
965 DWORD exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
967 if (private->state & GDK_WINDOW_STATE_BELOW)
968 exstyle &= (~WS_EX_TOPMOST);
969 if (private->state & GDK_WINDOW_STATE_ABOVE)
970 exstyle |= WS_EX_TOPMOST;
972 if (!SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, exstyle))
973 WIN32_API_FAILED ("SetWindowLong");
976 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
977 gdk_window_fullscreen (window);
978 else if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
979 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
980 else if (private->state & GDK_WINDOW_STATE_ICONIFIED)
981 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
982 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
983 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
985 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
988 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
989 SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST, 0, 0, 0, 0,
990 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
992 BringWindowToTop (GDK_WINDOW_HWND (window));
993 else if (old_active_window != GDK_WINDOW_HWND (window))
994 SetActiveWindow (old_active_window);
998 gdk_window_show_unraised (GdkWindow *window)
1000 g_return_if_fail (GDK_IS_WINDOW (window));
1002 show_window_internal (window, FALSE, FALSE);
1006 gdk_window_show (GdkWindow *window)
1008 g_return_if_fail (GDK_IS_WINDOW (window));
1010 show_window_internal (window, TRUE, FALSE);
1014 gdk_window_hide (GdkWindow *window)
1016 GdkWindowObject *private;
1018 g_return_if_fail (window != NULL);
1020 private = (GdkWindowObject*) window;
1021 if (private->destroyed)
1024 GDK_NOTE (MISC, g_print ("gdk_window_hide: %p: %s\n",
1025 GDK_WINDOW_HWND (window),
1026 _gdk_win32_window_state_to_string (private->state)));
1028 if (GDK_WINDOW_IS_MAPPED (window))
1029 gdk_synthesize_window_state (window,
1031 GDK_WINDOW_STATE_WITHDRAWN);
1033 _gdk_window_clear_update_area (window);
1035 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1036 ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
1038 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
1040 SetWindowPos(GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
1041 SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
1045 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
1050 gdk_window_withdraw (GdkWindow *window)
1052 GdkWindowObject *private;
1054 g_return_if_fail (window != NULL);
1056 private = (GdkWindowObject*) window;
1057 if (private->destroyed)
1060 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %p: %s\n",
1061 GDK_WINDOW_HWND (window),
1062 _gdk_win32_window_state_to_string (private->state)));
1064 gdk_window_hide (window); /* ??? */
1068 gdk_window_move (GdkWindow *window,
1072 GdkWindowObject *private = (GdkWindowObject *)window;
1073 GdkWindowImplWin32 *impl;
1075 g_return_if_fail (window != NULL);
1076 g_return_if_fail (GDK_IS_WINDOW (window));
1078 if (GDK_WINDOW_DESTROYED (window))
1081 GDK_NOTE (MISC, g_print ("gdk_window_move: %p: +%d+%d\n",
1082 GDK_WINDOW_HWND (window), x, y));
1084 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1086 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1089 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1090 _gdk_window_move_resize_child (window, x, y, impl->width, impl->height);
1095 get_outer_rect (window, impl->width, impl->height, &outer_rect);
1097 adjust_for_gravity_hints (impl, &outer_rect, &x, &y);
1099 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1100 x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
1101 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
1106 gdk_window_resize (GdkWindow *window,
1110 GdkWindowObject *private = (GdkWindowObject*) window;
1111 GdkWindowImplWin32 *impl;
1113 g_return_if_fail (window != NULL);
1114 g_return_if_fail (GDK_IS_WINDOW (window));
1116 if (GDK_WINDOW_DESTROYED (window))
1124 GDK_NOTE (MISC, g_print ("gdk_window_resize: %p: %dx%d\n",
1125 GDK_WINDOW_HWND (window), width, height));
1127 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1129 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1132 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1133 _gdk_window_move_resize_child (window, private->x, private->y, width, height);
1137 get_outer_rect (window, width, height, &outer_rect);
1139 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1141 outer_rect.right - outer_rect.left,
1142 outer_rect.bottom - outer_rect.top,
1143 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
1144 private->resize_count += 1;
1149 gdk_window_move_resize (GdkWindow *window,
1155 GdkWindowObject *private = (GdkWindowObject*) window;
1156 GdkWindowImplWin32 *impl;
1158 g_return_if_fail (window != NULL);
1159 g_return_if_fail (GDK_IS_WINDOW (window));
1161 if (GDK_WINDOW_DESTROYED (window))
1169 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1171 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1174 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %p: %dx%d@+%d+%d\n",
1175 GDK_WINDOW_HWND (window),
1176 width, height, x, y));
1178 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1179 _gdk_window_move_resize_child (window, x, y, width, height);
1184 get_outer_rect (window, width, height, &outer_rect);
1186 adjust_for_gravity_hints (impl, &outer_rect, &x, &y);
1188 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
1189 x - _gdk_offset_x, y - _gdk_offset_y,
1190 outer_rect.right - outer_rect.left,
1191 outer_rect.bottom - outer_rect.top,
1192 SWP_NOACTIVATE | SWP_NOZORDER));
1197 gdk_window_reparent (GdkWindow *window,
1198 GdkWindow *new_parent,
1202 GdkWindowObject *window_private;
1203 GdkWindowObject *parent_private;
1204 GdkWindowObject *old_parent_private;
1205 GdkWindowImplWin32 *impl;
1207 g_return_if_fail (window != NULL);
1208 g_return_if_fail (GDK_IS_WINDOW (window));
1209 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1210 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1213 new_parent = _gdk_parent_root;
1215 window_private = (GdkWindowObject*) window;
1216 old_parent_private = (GdkWindowObject *) window_private->parent;
1217 parent_private = (GdkWindowObject*) new_parent;
1218 impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
1220 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
1222 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %p: %p\n",
1223 GDK_WINDOW_HWND (window),
1224 GDK_WINDOW_HWND (new_parent)));
1226 API_CALL (SetParent, (GDK_WINDOW_HWND (window),
1227 GDK_WINDOW_HWND (new_parent)));
1229 API_CALL (MoveWindow, (GDK_WINDOW_HWND (window),
1230 x, y, impl->width, impl->height, TRUE));
1233 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1236 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1237 new_parent = _gdk_parent_root;
1239 window_private->parent = (GdkWindowObject *)new_parent;
1241 if (old_parent_private)
1242 old_parent_private->children =
1243 g_list_remove (old_parent_private->children, window);
1246 if ((old_parent_private &&
1247 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1248 (!old_parent_private && parent_private->guffaw_gravity))
1249 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1252 parent_private->children = g_list_prepend (parent_private->children, window);
1253 _gdk_window_init_position (GDK_WINDOW (window_private));
1257 _gdk_windowing_window_clear_area (GdkWindow *window,
1263 GdkWindowImplWin32 *impl;
1265 g_return_if_fail (window != NULL);
1266 g_return_if_fail (GDK_IS_WINDOW (window));
1268 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1270 if (!GDK_WINDOW_DESTROYED (window))
1275 width = impl->width - x;
1277 height = impl->height - y;
1278 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area: %p: "
1280 GDK_WINDOW_HWND (window),
1281 width, height, x, y));
1282 hdc = GetDC (GDK_WINDOW_HWND (window));
1283 IntersectClipRect (hdc, x, y, x + width + 1, y + height + 1);
1284 SendMessage (GDK_WINDOW_HWND (window), WM_ERASEBKGND, (WPARAM) hdc, 0);
1285 GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc));
1290 _gdk_windowing_window_clear_area_e (GdkWindow *window,
1296 g_return_if_fail (window != NULL);
1297 g_return_if_fail (GDK_IS_WINDOW (window));
1299 if (!GDK_WINDOW_DESTROYED (window))
1303 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area_e: %p: "
1305 GDK_WINDOW_HWND (window),
1306 width, height, x, y));
1309 rect.right = x + width + 1;
1311 rect.bottom = y + height + 1;
1312 GDI_CALL (InvalidateRect, (GDK_WINDOW_HWND (window), &rect, TRUE));
1313 UpdateWindow (GDK_WINDOW_HWND (window));
1318 gdk_window_raise (GdkWindow *window)
1320 g_return_if_fail (window != NULL);
1321 g_return_if_fail (GDK_IS_WINDOW (window));
1323 if (!GDK_WINDOW_DESTROYED (window))
1325 GDK_NOTE (MISC, g_print ("gdk_window_raise: %p\n",
1326 GDK_WINDOW_HWND (window)));
1328 API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
1333 gdk_window_lower (GdkWindow *window)
1335 g_return_if_fail (window != NULL);
1336 g_return_if_fail (GDK_IS_WINDOW (window));
1338 if (!GDK_WINDOW_DESTROYED (window))
1340 GDK_NOTE (MISC, g_print ("gdk_window_lower: %p\n",
1341 GDK_WINDOW_HWND (window)));
1343 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
1344 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
1349 gdk_window_set_hints (GdkWindow *window,
1358 /* Note that this function is obsolete */
1360 GdkWindowImplWin32 *impl;
1362 g_return_if_fail (window != NULL);
1363 g_return_if_fail (GDK_IS_WINDOW (window));
1365 if (GDK_WINDOW_DESTROYED (window))
1368 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1370 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %p: %dx%d..%dx%d @+%d+%d\n",
1371 GDK_WINDOW_HWND (window),
1372 min_width, min_height, max_width, max_height,
1380 geom.min_width = min_width;
1381 geom.min_height = min_height;
1382 geom.max_width = max_width;
1383 geom.max_height = max_height;
1385 if (flags & GDK_HINT_MIN_SIZE)
1386 geom_mask |= GDK_HINT_MIN_SIZE;
1388 if (flags & GDK_HINT_MAX_SIZE)
1389 geom_mask |= GDK_HINT_MAX_SIZE;
1391 gdk_window_set_geometry_hints (window, &geom, geom_mask);
1396 gdk_window_set_geometry_hints (GdkWindow *window,
1397 GdkGeometry *geometry,
1398 GdkWindowHints geom_mask)
1400 GdkWindowImplWin32 *impl;
1402 WINDOWPLACEMENT size_hints;
1404 gint new_width = 0, new_height = 0;
1407 g_return_if_fail (window != NULL);
1408 g_return_if_fail (GDK_IS_WINDOW (window));
1410 if (GDK_WINDOW_DESTROYED (window))
1413 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints: %p\n",
1414 GDK_WINDOW_HWND (window)));
1416 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1418 impl->hint_flags = geom_mask;
1419 impl->hints = *geometry;
1421 if (geom_mask & GDK_HINT_POS)
1422 ; /* even the X11 mplementation doesn't care */
1424 if (geom_mask & GDK_HINT_MIN_SIZE)
1426 GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n",
1427 geometry->min_width, geometry->min_height));
1430 /* Check if the current size of the window is in bounds */
1431 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1433 if (rect.right < geometry->min_width &&
1434 rect.bottom < geometry->min_height)
1436 new_width = geometry->min_width;
1437 new_height = geometry->min_height;
1439 else if (rect.right < geometry->min_width)
1441 new_width = geometry->min_width;
1442 new_height = rect.bottom;
1444 else if (rect.bottom < geometry->min_height)
1446 new_width = rect.right;
1447 new_height = geometry->min_height;
1452 if (geom_mask & GDK_HINT_MAX_SIZE)
1454 GDK_NOTE (MISC, g_print ("... MAX_SIZE: %dx%d\n",
1455 geometry->max_width, geometry->max_height));
1458 /* Check if the current size of the window is in bounds */
1459 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1461 if (rect.right > geometry->max_width &&
1462 rect.bottom > geometry->max_height)
1464 new_width = geometry->max_width;
1465 new_height = geometry->max_height;
1467 else if (rect.right > geometry->max_width)
1469 new_width = geometry->max_width;
1470 new_height = rect.bottom;
1472 else if (rect.bottom > geometry->max_height)
1474 new_width = rect.right;
1475 new_height = geometry->max_height;
1481 /* Apply new size constraints */
1482 if (new_width != 0 && new_height != 0)
1483 gdk_window_resize (window, new_width, new_height);
1486 if (geom_mask & GDK_HINT_BASE_SIZE)
1488 GDK_NOTE (MISC, g_print ("... BASE_SIZE: %dx%d\n",
1489 geometry->base_width, geometry->base_height));
1492 size_hints.length = sizeof (size_hints);
1494 if (API_CALL (GetWindowPlacement, (GDK_WINDOW_HWND (window), &size_hints)))
1497 g_print ("... rcNormalPosition: (%ld,%ld)--(%ld,%ld)\n",
1498 size_hints.rcNormalPosition.left,
1499 size_hints.rcNormalPosition.top,
1500 size_hints.rcNormalPosition.right,
1501 size_hints.rcNormalPosition.bottom));
1502 size_hints.rcNormalPosition.right =
1503 size_hints.rcNormalPosition.left + geometry->base_width;
1504 size_hints.rcNormalPosition.bottom =
1505 size_hints.rcNormalPosition.top + geometry->base_height;
1506 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%ld,%ld)--(%ld,%ld)\n",
1507 size_hints.rcNormalPosition.left,
1508 size_hints.rcNormalPosition.top,
1509 size_hints.rcNormalPosition.right,
1510 size_hints.rcNormalPosition.bottom));
1511 API_CALL (SetWindowPlacement, (GDK_WINDOW_HWND (window), &size_hints));
1516 if (geom_mask & GDK_HINT_RESIZE_INC)
1518 GDK_NOTE (MISC, g_print ("... RESIZE_INC: (%d,%d)\n",
1519 geometry->width_inc, geometry->height_inc));
1522 if (geom_mask & GDK_HINT_ASPECT)
1524 GDK_NOTE (MISC, g_print ("... ASPECT: %g--%g\n",
1525 geometry->min_aspect, geometry->max_aspect));
1528 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1530 GDK_NOTE (MISC, g_print ("... GRAVITY: %d\n", geometry->win_gravity));
1535 gdk_window_set_title (GdkWindow *window,
1540 g_return_if_fail (window != NULL);
1541 g_return_if_fail (GDK_IS_WINDOW (window));
1542 g_return_if_fail (title != NULL);
1544 /* Empty window titles not allowed, so set it to just a period. */
1548 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
1549 GDK_WINDOW_HWND (window), title));
1551 if (!GDK_WINDOW_DESTROYED (window))
1553 /* As the title is in UTF-8 we must translate it
1554 * to the system codepage.
1556 mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
1557 API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), mbtitle));
1563 gdk_window_set_role (GdkWindow *window,
1566 g_return_if_fail (window != NULL);
1567 g_return_if_fail (GDK_IS_WINDOW (window));
1569 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %p: %s\n",
1570 GDK_WINDOW_HWND (window),
1571 (role ? role : "NULL")));
1576 gdk_window_set_transient_for (GdkWindow *window,
1579 HWND window_id, parent_id;
1581 g_return_if_fail (window != NULL);
1582 g_return_if_fail (GDK_IS_WINDOW (window));
1584 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n",
1585 GDK_WINDOW_HWND (window),
1586 GDK_WINDOW_HWND (parent)));
1588 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (parent))
1591 if (((GdkWindowObject *) window)->window_type == GDK_WINDOW_CHILD)
1593 GDK_NOTE (MISC, g_print ("...a child window!\n"));
1597 window_id = GDK_WINDOW_HWND (window);
1598 parent_id = GDK_WINDOW_HWND (parent);
1600 /* This changes the *owner* of the window, despite the misleading
1601 * name. (Owner and parent are unrelated concepts.) At least that's
1602 * what people who seem to know what they talk about say on
1603 * USENET. Search on Google.
1606 if (SetWindowLong (window_id, GWL_HWNDPARENT, (long) parent_id) == 0 &&
1607 GetLastError () != 0)
1608 WIN32_API_FAILED ("SetWindowLong");
1612 gdk_window_set_background (GdkWindow *window,
1615 GdkWindowObject *private = (GdkWindowObject *)window;
1617 g_return_if_fail (window != NULL);
1618 g_return_if_fail (GDK_IS_WINDOW (window));
1620 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %p: %s\n",
1621 GDK_WINDOW_HWND (window),
1622 _gdk_win32_color_to_string (color)));
1624 private->bg_color = *color;
1626 if (private->bg_pixmap &&
1627 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1628 private->bg_pixmap != GDK_NO_BG)
1630 g_object_unref (private->bg_pixmap);
1631 private->bg_pixmap = NULL;
1636 gdk_window_set_back_pixmap (GdkWindow *window,
1638 gint parent_relative)
1640 GdkWindowObject *private = (GdkWindowObject *)window;
1642 g_return_if_fail (window != NULL);
1643 g_return_if_fail (GDK_IS_WINDOW (window));
1644 g_return_if_fail (pixmap == NULL || !parent_relative);
1645 g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap));
1647 if (private->bg_pixmap &&
1648 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1649 private->bg_pixmap != GDK_NO_BG)
1650 g_object_unref (private->bg_pixmap);
1652 if (parent_relative)
1654 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1655 GDK_NOTE (MISC, g_print (G_STRLOC ": setting background pixmap to parent_relative\n"));
1661 g_object_ref (pixmap);
1662 private->bg_pixmap = pixmap;
1666 private->bg_pixmap = GDK_NO_BG;
1672 gdk_window_set_cursor (GdkWindow *window,
1675 GdkWindowImplWin32 *impl;
1676 GdkCursorPrivate *cursor_private;
1677 GdkWindowObject *parent_window;
1679 HCURSOR hprevcursor;
1681 g_return_if_fail (window != NULL);
1682 g_return_if_fail (GDK_IS_WINDOW (window));
1684 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1685 cursor_private = (GdkCursorPrivate*) cursor;
1687 if (GDK_WINDOW_DESTROYED (window))
1693 hcursor = cursor_private->hcursor;
1695 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %p: %p\n",
1696 GDK_WINDOW_HWND (window),
1699 /* First get the old cursor, if any (we wait to free the old one
1700 * since it may be the current cursor set in the Win32 API right
1703 hprevcursor = impl->hcursor;
1705 if (hcursor == NULL)
1706 impl->hcursor = NULL;
1709 /* We must copy the cursor as it is OK to destroy the GdkCursor
1710 * while still in use for some window. See for instance
1711 * gimp_change_win_cursor() which calls gdk_window_set_cursor
1712 * (win, cursor), and immediately afterwards gdk_cursor_destroy
1715 if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
1716 WIN32_API_FAILED ("CopyCursor");
1717 GDK_NOTE (MISC, g_print ("...CopyCursor (%p) = %p\n",
1718 hcursor, impl->hcursor));
1721 /* If the pointer is over our window, set new cursor if given */
1722 if (gdk_window_get_pointer(window, NULL, NULL, NULL) == window)
1723 if (impl->hcursor != NULL)
1724 SetCursor (impl->hcursor);
1726 /* Destroy the previous cursor: Need to make sure it's no longer in
1727 * use before we destroy it, in case we're not over our window but
1728 * the cursor is still set to our old one.
1730 if (hprevcursor != NULL)
1732 if (GetCursor() == hprevcursor)
1734 /* Look for a suitable cursor to use instead */
1736 parent_window = GDK_WINDOW_OBJECT (window)->parent;
1737 while (hcursor == NULL)
1741 impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl);
1742 hcursor = impl->hcursor;
1743 parent_window = parent_window->parent;
1747 hcursor = LoadCursor (NULL, IDC_ARROW);
1750 SetCursor (hcursor);
1753 GDK_NOTE (MISC, g_print ("...DestroyCursor (%p)\n",
1756 API_CALL (DestroyCursor, (hprevcursor));
1761 gdk_window_get_geometry (GdkWindow *window,
1768 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1771 window = _gdk_parent_root;
1773 if (!GDK_WINDOW_DESTROYED (window))
1777 API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
1779 if (window != _gdk_parent_root)
1782 GdkWindow *parent = gdk_window_get_parent (window);
1786 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1787 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1793 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1794 ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
1798 if (parent == _gdk_parent_root)
1800 rect.left += _gdk_offset_x;
1801 rect.top += _gdk_offset_y;
1802 rect.right += _gdk_offset_x;
1803 rect.bottom += _gdk_offset_y;
1812 *width = rect.right - rect.left;
1814 *height = rect.bottom - rect.top;
1816 *depth = gdk_drawable_get_visual (window)->depth;
1818 GDK_NOTE (MISC, g_print ("gdk_window_get_geometry: %p: %ldx%ldx%d@+%ld+%ld\n",
1819 GDK_WINDOW_HWND (window),
1820 rect.right - rect.left, rect.bottom - rect.top,
1821 gdk_drawable_get_visual (window)->depth,
1822 rect.left, rect.top));
1827 gdk_window_get_origin (GdkWindow *window,
1835 g_return_val_if_fail (window != NULL, 0);
1837 if (!GDK_WINDOW_DESTROYED (window))
1843 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1852 *x = tx + _gdk_offset_x;
1854 *y = ty + _gdk_offset_y;
1856 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %p: +%d+%d\n",
1857 GDK_WINDOW_HWND (window),
1863 gdk_window_get_deskrelative_origin (GdkWindow *window,
1867 return gdk_window_get_origin (window, x, y);
1871 gdk_window_get_root_origin (GdkWindow *window,
1877 g_return_if_fail (GDK_IS_WINDOW (window));
1879 gdk_window_get_frame_extents (window, &rect);
1887 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %p: +%d+%d\n",
1888 GDK_WINDOW_HWND (window), rect.x, rect.y));
1892 gdk_window_get_frame_extents (GdkWindow *window,
1895 GdkWindowObject *private;
1899 g_return_if_fail (GDK_IS_WINDOW (window));
1900 g_return_if_fail (rect != NULL);
1902 private = GDK_WINDOW_OBJECT (window);
1909 if (GDK_WINDOW_DESTROYED (window))
1912 /* FIXME: window is documented to be a toplevel GdkWindow, so is it really
1913 * necessary to walk its parent chain?
1915 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
1916 private = (GdkWindowObject*) private->parent;
1918 hwnd = GDK_WINDOW_HWND (window);
1920 /* find the frame window */
1921 while (HWND_DESKTOP != GetParent (hwnd))
1923 hwnd = GetParent (hwnd);
1924 g_return_if_fail (NULL != hwnd);
1927 API_CALL (GetWindowRect, (hwnd, &r));
1929 rect->x = r.left + _gdk_offset_x;
1930 rect->y = r.top + _gdk_offset_y;
1931 rect->width = r.right - r.left;
1932 rect->height = r.bottom - r.top;
1934 GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@+%ld+%ld\n",
1935 GDK_WINDOW_HWND (window),
1936 r.right - r.left, r.bottom - r.top,
1941 _gdk_windowing_window_get_pointer (GdkDisplay *display,
1945 GdkModifierType *mask)
1947 GdkWindow *return_val;
1948 POINT screen_point, point;
1952 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1955 GetCursorPos (&screen_point);
1956 point = screen_point;
1957 ScreenToClient (GDK_WINDOW_HWND (window), &point);
1962 if (window == _gdk_parent_root)
1964 *x += _gdk_offset_x;
1965 *y += _gdk_offset_y;
1968 hwnd = WindowFromPoint (screen_point);
1971 gboolean done = FALSE;
1975 point = screen_point;
1976 ScreenToClient (hwnd, &point);
1977 hwndc = ChildWindowFromPoint (hwnd, point);
1980 else if (hwndc == hwnd)
1986 return_val = gdk_window_lookup ((GdkNativeWindow) hwnd);
1991 GetKeyboardState (kbd);
1993 if (kbd[VK_SHIFT] & 0x80)
1994 *mask |= GDK_SHIFT_MASK;
1995 if (kbd[VK_CAPITAL] & 0x80)
1996 *mask |= GDK_LOCK_MASK;
1997 if (kbd[VK_CONTROL] & 0x80)
1998 *mask |= GDK_CONTROL_MASK;
1999 if (kbd[VK_MENU] & 0x80)
2000 *mask |= GDK_MOD1_MASK;
2001 if (kbd[VK_LBUTTON] & 0x80)
2002 *mask |= GDK_BUTTON1_MASK;
2003 if (kbd[VK_MBUTTON] & 0x80)
2004 *mask |= GDK_BUTTON2_MASK;
2005 if (kbd[VK_RBUTTON] & 0x80)
2006 *mask |= GDK_BUTTON3_MASK;
2012 _gdk_windowing_get_pointer (GdkDisplay *display,
2016 GdkModifierType *mask)
2018 GdkScreen *default_screen = gdk_display_get_default_screen (display);
2019 GdkWindow *root_window = gdk_screen_get_root_window (default_screen);
2021 *screen = default_screen;
2022 _gdk_windowing_window_get_pointer (display, root_window, x, y, mask);
2026 _gdk_windowing_window_at_pointer (GdkDisplay *display,
2031 POINT point, pointc;
2035 GetCursorPos (&pointc);
2037 hwnd = WindowFromPoint (point);
2041 window = _gdk_parent_root;
2042 *win_x = pointc.x + _gdk_offset_x;
2043 *win_y = pointc.y + _gdk_offset_y;
2047 ScreenToClient (hwnd, &point);
2050 hwndc = ChildWindowFromPoint (hwnd, point);
2051 ClientToScreen (hwnd, &point);
2052 ScreenToClient (hwndc, &point);
2053 } while (hwndc != hwnd && (hwnd = hwndc, 1));
2055 window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
2057 if (window && (win_x || win_y))
2059 GetClientRect (hwnd, &rect);
2060 *win_x = point.x - rect.left;
2061 *win_y = point.y - rect.top;
2064 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_at_pointer: +%d+%d %p%s\n",
2067 (window == NULL ? " NULL" : "")));
2073 gdk_window_get_events (GdkWindow *window)
2075 g_return_val_if_fail (window != NULL, 0);
2076 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2078 if (GDK_WINDOW_DESTROYED (window))
2081 return GDK_WINDOW_OBJECT (window)->event_mask;
2085 gdk_window_set_events (GdkWindow *window,
2086 GdkEventMask event_mask)
2088 g_return_if_fail (window != NULL);
2089 g_return_if_fail (GDK_IS_WINDOW (window));
2091 if (GDK_WINDOW_DESTROYED (window))
2094 /* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
2095 * set it here, too. Not that I know or remember why it is
2096 * necessary, will have to test some day.
2098 GDK_WINDOW_OBJECT (window)->event_mask = GDK_STRUCTURE_MASK | event_mask;
2102 gdk_window_shape_combine_mask (GdkWindow *window,
2106 g_return_if_fail (window != NULL);
2107 g_return_if_fail (GDK_IS_WINDOW (window));
2111 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: none\n",
2112 GDK_WINDOW_HWND (window)));
2113 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
2120 /* Convert mask bitmap to region */
2121 hrgn = _gdk_win32_bitmap_to_hrgn (mask);
2123 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: %p\n",
2124 GDK_WINDOW_HWND (window),
2125 GDK_WINDOW_HWND (mask)));
2127 _gdk_win32_get_adjusted_client_rect (window, &rect);
2129 OffsetRgn (hrgn, -rect.left, -rect.top);
2130 OffsetRgn (hrgn, x, y);
2132 /* If this is a top-level window, add the title bar to the region */
2133 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
2135 HRGN tmp = CreateRectRgn (0, 0, rect.right - rect.left, -rect.top);
2136 CombineRgn (hrgn, hrgn, tmp, RGN_OR);
2140 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
2145 gdk_window_set_override_redirect (GdkWindow *window,
2146 gboolean override_redirect)
2148 g_return_if_fail (window != NULL);
2149 g_return_if_fail (GDK_IS_WINDOW (window));
2151 g_warning ("gdk_window_set_override_redirect not implemented");
2155 gdk_window_set_icon_list (GdkWindow *window,
2158 g_return_if_fail (GDK_IS_WINDOW (window));
2160 if (GDK_WINDOW_DESTROYED (window))
2163 /* We could convert it to a hIcon and DrawIcon () it when getting
2164 * a WM_PAINT with IsIconic, but is it worth it ? Same probably
2165 * goes for gdk_window_set_icon (). Patches accepted :-) --hb
2166 * Or do we only need to deliver the Icon on WM_GETICON ?
2171 gdk_window_set_icon (GdkWindow *window,
2172 GdkWindow *icon_window,
2179 GdkWindowImplWin32 *impl;
2181 g_return_if_fail (window != NULL);
2182 g_return_if_fail (GDK_IS_WINDOW (window));
2184 if (GDK_WINDOW_DESTROYED (window))
2187 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
2192 HBITMAP hbmmask = NULL;
2194 gdk_drawable_get_size (GDK_DRAWABLE(pixmap), &w, &h);
2196 /* we need the inverted mask for the XOR op */
2198 HDC hdc1 = CreateCompatibleDC (NULL);
2201 hbmmask = CreateCompatibleBitmap (hdc1, w, h);
2202 hbmold1 = SelectObject (hdc1, hbmmask);
2205 HDC hdc2 = CreateCompatibleDC (NULL);
2206 HBITMAP hbmold2 = SelectObject (hdc2, GDK_PIXMAP_HBITMAP (mask));
2207 GDI_CALL (BitBlt, (hdc1, 0,0,w,h, hdc2, 0,0, NOTSRCCOPY));
2208 GDI_CALL (SelectObject, (hdc2, hbmold2));
2209 GDI_CALL (DeleteDC, (hdc2));
2214 GetClipBox (hdc1, &rect);
2215 GDI_CALL (FillRect, (hdc1, &rect, GetStockObject (WHITE_BRUSH)));
2217 GDI_CALL (SelectObject, (hdc1, hbmold1));
2218 GDI_CALL (DeleteDC, (hdc1));
2222 ii.xHotspot = ii.yHotspot = 0; /* ignored for icons */
2223 ii.hbmMask = hbmmask;
2224 ii.hbmColor = GDK_PIXMAP_HBITMAP (pixmap);
2225 hIcon = CreateIconIndirect (&ii);
2227 WIN32_API_FAILED ("CreateIconIndirect");
2228 GDI_CALL (DeleteObject, (hbmmask));
2229 #if 0 /* to debug pixmap and mask setting */
2231 GdkPixbuf* pixbuf = NULL;
2234 pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0, w, h);
2237 num = (num + 1) % 999; /* restrict maximim number */
2238 sprintf (name, "c:\\temp\\ico%03dpixm.png", num);
2239 gdk_pixbuf_save (pixbuf, name, "png", NULL, NULL);
2240 gdk_pixbuf_unref (pixbuf);
2242 pixbuf = !mask ? NULL : gdk_pixbuf_get_from_drawable (NULL, mask, NULL, 0, 0, 0, 0, w, h);
2245 sprintf (name, "c:\\temp\\ico%03dmask.png", num);
2246 gdk_pixbuf_save (pixbuf, name, "png", NULL, NULL);
2247 gdk_pixbuf_unref (pixbuf);
2252 SendMessage (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG, (LPARAM)hIcon);
2254 GDI_CALL (DestroyIcon, (impl->hicon));
2255 impl->hicon = hIcon;
2259 /* reseting to default icon */
2262 SendMessage (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG, 0);
2263 GDI_CALL (DestroyIcon, (impl->hicon));
2268 GDK_NOTE (MISC, g_print ("gdk_window_set_icon: %p: %p %dx%d\n", GDK_WINDOW_HWND (window), impl->hicon, w, h));
2272 gdk_window_set_icon_name (GdkWindow *window,
2275 g_return_if_fail (window != NULL);
2276 g_return_if_fail (GDK_IS_WINDOW (window));
2278 if (GDK_WINDOW_DESTROYED (window))
2281 API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
2285 gdk_window_set_group (GdkWindow *window,
2288 g_return_if_fail (window != NULL);
2289 g_return_if_fail (GDK_IS_WINDOW (window));
2290 g_return_if_fail (leader != NULL);
2291 g_return_if_fail (GDK_IS_WINDOW (leader));
2293 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
2296 g_warning ("gdk_window_set_group not implemented");
2300 gdk_window_set_decorations (GdkWindow *window,
2301 GdkWMDecoration decorations)
2304 const LONG settable_bits = WS_BORDER|WS_THICKFRAME|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
2306 g_return_if_fail (window != NULL);
2307 g_return_if_fail (GDK_IS_WINDOW (window));
2309 GDK_NOTE (MISC, g_print ("gdk_window_set_decorations: %p: %s%s%s%s%s%s%s\n",
2310 GDK_WINDOW_HWND (window),
2311 (decorations & GDK_DECOR_ALL ? "ALL " : ""),
2312 (decorations & GDK_DECOR_BORDER ? "BORDER " : ""),
2313 (decorations & GDK_DECOR_RESIZEH ? "RESIZEH " : ""),
2314 (decorations & GDK_DECOR_TITLE ? "TITLE " : ""),
2315 (decorations & GDK_DECOR_MENU ? "MENU " : ""),
2316 (decorations & GDK_DECOR_MINIMIZE ? "MINIMIZE " : ""),
2317 (decorations & GDK_DECOR_MAXIMIZE ? "MAXIMIZE " : "")));
2319 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2323 if (decorations & GDK_DECOR_BORDER)
2325 if (decorations & GDK_DECOR_RESIZEH)
2326 bits |= WS_THICKFRAME;
2327 if (decorations & GDK_DECOR_TITLE)
2329 if (decorations & GDK_DECOR_MENU)
2331 if (decorations & GDK_DECOR_MINIMIZE)
2332 bits |= WS_MINIMIZEBOX;
2333 if (decorations & GDK_DECOR_MAXIMIZE)
2334 bits |= WS_MAXIMIZEBOX;
2336 if (decorations & GDK_DECOR_ALL)
2337 style |= settable_bits, style &= ~bits;
2339 style &= ~settable_bits, style |= bits;
2341 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
2342 SetWindowPos (GDK_WINDOW_HWND (window), NULL, 0, 0, 0, 0,
2343 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
2344 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
2348 gdk_window_get_decorations(GdkWindow *window,
2349 GdkWMDecoration *decorations)
2351 LONG style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2355 if (style & WS_BORDER)
2356 *decorations |= GDK_DECOR_BORDER;
2357 if (style & WS_THICKFRAME)
2358 *decorations |= GDK_DECOR_RESIZEH;
2359 if (style & WS_CAPTION)
2360 *decorations |= GDK_DECOR_TITLE;
2361 if (style & WS_SYSMENU)
2362 *decorations |= GDK_DECOR_MENU;
2363 if (style & WS_MINIMIZEBOX)
2364 *decorations |= GDK_DECOR_MINIMIZE;
2365 if (style & WS_MAXIMIZEBOX)
2366 *decorations |= GDK_DECOR_MAXIMIZE;
2368 return *decorations != 0;
2372 gdk_window_set_functions (GdkWindow *window,
2373 GdkWMFunction functions)
2376 const LONG settable_bits = (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU);
2378 g_return_if_fail (window != NULL);
2379 g_return_if_fail (GDK_IS_WINDOW (window));
2381 GDK_NOTE (MISC, g_print ("gdk_window_set_functions: %p: %s%s%s%s%s%s\n",
2382 GDK_WINDOW_HWND (window),
2383 (functions & GDK_FUNC_ALL ? "ALL " : ""),
2384 (functions & GDK_FUNC_RESIZE ? "RESIZE " : ""),
2385 (functions & GDK_FUNC_MOVE ? "MOVE " : ""),
2386 (functions & GDK_FUNC_MINIMIZE ? "MINIMIZE " : ""),
2387 (functions & GDK_FUNC_MAXIMIZE ? "MAXIMIZE " : ""),
2388 (functions & GDK_FUNC_CLOSE ? "CLOSE " : "")));
2390 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2394 if (functions & GDK_FUNC_RESIZE)
2395 bits |= WS_THICKFRAME;
2396 if (functions & GDK_FUNC_MOVE)
2397 bits |= (WS_THICKFRAME|WS_SYSMENU);
2398 if (functions & GDK_FUNC_MINIMIZE)
2399 bits |= WS_MINIMIZEBOX;
2400 if (functions & GDK_FUNC_MAXIMIZE)
2401 bits |= WS_MAXIMIZEBOX;
2402 if (functions & GDK_FUNC_CLOSE)
2405 if (functions & GDK_FUNC_ALL)
2406 style |= settable_bits, style &= ~bits;
2408 style &= ~settable_bits, style |= bits;
2410 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
2411 SetWindowPos (GDK_WINDOW_HWND (window), NULL, 0, 0, 0, 0,
2412 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
2413 SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
2417 QueryTree (HWND hwnd,
2427 child = GetWindow (hwnd, GW_CHILD);
2429 child = GetWindow (child, GW_HWNDNEXT);
2432 } while (child != NULL);
2436 *children = g_new (HWND, n);
2437 for (i = 0; i < n; i++)
2440 child = GetWindow (hwnd, GW_CHILD);
2442 child = GetWindow (child, GW_HWNDNEXT);
2443 *children[i] = child;
2449 gdk_propagate_shapes (HANDLE win,
2453 HRGN region, childRegion;
2457 SetRectEmpty (&emptyRect);
2458 region = CreateRectRgnIndirect (&emptyRect);
2460 GetWindowRgn (win, region);
2462 QueryTree (win, &list, &num);
2465 WINDOWPLACEMENT placement;
2467 placement.length = sizeof (WINDOWPLACEMENT);
2468 /* go through all child windows and combine regions */
2469 for (i = 0; i < num; i++)
2471 GetWindowPlacement (list[i], &placement);
2472 if (placement.showCmd == SW_SHOWNORMAL)
2474 childRegion = CreateRectRgnIndirect (&emptyRect);
2475 GetWindowRgn (list[i], childRegion);
2476 CombineRgn (region, region, childRegion, RGN_OR);
2477 DeleteObject (childRegion);
2480 SetWindowRgn (win, region, TRUE);
2484 DeleteObject (region);
2488 gdk_window_set_child_shapes (GdkWindow *window)
2490 g_return_if_fail (window != NULL);
2491 g_return_if_fail (GDK_IS_WINDOW (window));
2493 if (GDK_WINDOW_DESTROYED (window))
2496 gdk_propagate_shapes (GDK_WINDOW_HWND (window), FALSE);
2500 gdk_window_merge_child_shapes (GdkWindow *window)
2502 g_return_if_fail (window != NULL);
2503 g_return_if_fail (GDK_IS_WINDOW (window));
2505 if (GDK_WINDOW_DESTROYED (window))
2508 gdk_propagate_shapes (GDK_WINDOW_HWND (window), TRUE);
2512 gdk_window_set_static_gravities (GdkWindow *window,
2513 gboolean use_static)
2515 GdkWindowObject *private = (GdkWindowObject *)window;
2517 g_return_val_if_fail (window != NULL, FALSE);
2518 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2520 if (!use_static == !private->guffaw_gravity)
2526 private->guffaw_gravity = use_static;
2532 * Setting window states
2535 gdk_window_iconify (GdkWindow *window)
2537 HWND old_active_window;
2539 g_return_if_fail (window != NULL);
2540 g_return_if_fail (GDK_IS_WINDOW (window));
2542 if (GDK_WINDOW_DESTROYED (window))
2545 GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
2546 GDK_WINDOW_HWND (window),
2547 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2549 if (GDK_WINDOW_IS_MAPPED (window))
2551 old_active_window = GetActiveWindow ();
2552 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
2553 if (old_active_window != GDK_WINDOW_HWND (window))
2554 SetActiveWindow (old_active_window);
2558 gdk_synthesize_window_state (window,
2560 GDK_WINDOW_STATE_ICONIFIED);
2565 gdk_window_deiconify (GdkWindow *window)
2567 g_return_if_fail (window != NULL);
2568 g_return_if_fail (GDK_IS_WINDOW (window));
2570 if (GDK_WINDOW_DESTROYED (window))
2573 GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
2574 GDK_WINDOW_HWND (window),
2575 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2577 if (GDK_WINDOW_IS_MAPPED (window))
2579 show_window_internal (window, FALSE, TRUE);
2583 gdk_synthesize_window_state (window,
2584 GDK_WINDOW_STATE_ICONIFIED,
2590 gdk_window_stick (GdkWindow *window)
2592 g_return_if_fail (GDK_IS_WINDOW (window));
2594 if (GDK_WINDOW_DESTROYED (window))
2597 /* FIXME: Do something? */
2601 gdk_window_unstick (GdkWindow *window)
2603 g_return_if_fail (GDK_IS_WINDOW (window));
2605 if (GDK_WINDOW_DESTROYED (window))
2608 /* FIXME: Do something? */
2612 gdk_window_maximize (GdkWindow *window)
2614 g_return_if_fail (GDK_IS_WINDOW (window));
2616 if (GDK_WINDOW_DESTROYED (window))
2619 GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
2620 GDK_WINDOW_HWND (window),
2621 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2623 if (GDK_WINDOW_IS_MAPPED (window))
2624 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
2626 gdk_synthesize_window_state (window,
2628 GDK_WINDOW_STATE_MAXIMIZED);
2632 gdk_window_unmaximize (GdkWindow *window)
2634 g_return_if_fail (GDK_IS_WINDOW (window));
2636 if (GDK_WINDOW_DESTROYED (window))
2639 GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
2640 GDK_WINDOW_HWND (window),
2641 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2643 if (GDK_WINDOW_IS_MAPPED (window))
2644 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
2646 gdk_synthesize_window_state (window,
2647 GDK_WINDOW_STATE_MAXIMIZED,
2651 typedef struct _FullscreenInfo FullscreenInfo;
2653 struct _FullscreenInfo
2661 gdk_window_fullscreen (GdkWindow *window)
2665 GdkWindowObject *private = (GdkWindowObject *) window;
2667 g_return_if_fail (GDK_IS_WINDOW (window));
2669 fi = g_new (FullscreenInfo, 1);
2671 if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
2675 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
2677 width = GetSystemMetrics (SM_CXSCREEN);
2678 height = GetSystemMetrics (SM_CYSCREEN);
2680 /* remember for restoring */
2681 fi->hint_flags = impl->hint_flags;
2682 impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
2683 g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
2684 fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2686 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
2687 (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
2688 if (!SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP /*not MOST, taskswitch!*/,
2689 0, 0, width, height,
2690 SWP_NOCOPYBITS | SWP_SHOWWINDOW))
2691 WIN32_API_FAILED ("SetWindowPos");
2693 gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
2698 gdk_window_unfullscreen (GdkWindow *window)
2701 GdkWindowObject *private = (GdkWindowObject *) window;
2703 g_return_if_fail (GDK_IS_WINDOW (window));
2705 fi = g_object_get_data (G_OBJECT(window), "fullscreen-info");
2708 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
2710 impl->hint_flags = fi->hint_flags;
2711 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
2712 if (!SetWindowPos (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
2713 fi->r.left, fi->r.top, fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
2714 SWP_NOCOPYBITS | SWP_SHOWWINDOW))
2715 WIN32_API_FAILED ("SetWindowPos");
2717 g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
2720 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
2725 gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
2727 g_return_if_fail (GDK_IS_WINDOW (window));
2729 if (GDK_WINDOW_DESTROYED (window))
2732 if (GDK_WINDOW_IS_MAPPED (window))
2734 if (!SetWindowPos(GDK_WINDOW_HWND (window), setting ? HWND_TOPMOST : HWND_NOTOPMOST,
2735 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE))
2736 WIN32_API_FAILED ("SetWindowPos");
2739 gdk_synthesize_window_state (window,
2740 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
2741 setting ? GDK_WINDOW_STATE_ABOVE : 0);
2745 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
2747 g_return_if_fail (GDK_IS_WINDOW (window));
2749 if (GDK_WINDOW_DESTROYED (window))
2752 if (GDK_WINDOW_IS_MAPPED (window))
2754 if (!SetWindowPos(GDK_WINDOW_HWND (window), setting ? HWND_BOTTOM : HWND_NOTOPMOST,
2755 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE))
2756 WIN32_API_FAILED ("SetWindowPos");
2759 gdk_synthesize_window_state (window,
2760 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
2761 setting ? GDK_WINDOW_STATE_BELOW : 0);
2765 gdk_window_focus (GdkWindow *window,
2768 g_return_if_fail (GDK_IS_WINDOW (window));
2770 if (GDK_WINDOW_DESTROYED (window))
2773 GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
2774 GDK_WINDOW_HWND (window),
2775 _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
2777 if (((GdkWindowObject *) window)->state & GDK_WINDOW_STATE_MAXIMIZED)
2778 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
2780 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
2781 SetFocus (GDK_WINDOW_HWND (window));
2785 gdk_window_set_modal_hint (GdkWindow *window,
2788 GdkWindowObject *private;
2790 g_return_if_fail (window != NULL);
2791 g_return_if_fail (GDK_IS_WINDOW (window));
2793 if (GDK_WINDOW_DESTROYED (window))
2796 private = (GdkWindowObject*) window;
2798 private->modal_hint = modal;
2800 if (GDK_WINDOW_IS_MAPPED (window))
2801 API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
2802 modal ? HWND_TOPMOST : HWND_NOTOPMOST,
2803 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE));
2807 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
2808 gboolean skips_taskbar)
2810 LONG extended_style;
2812 g_return_if_fail (GDK_IS_WINDOW (window));
2814 GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s\n",
2815 GDK_WINDOW_HWND (window),
2816 skips_taskbar ? "TRUE" : "FALSE"));
2818 extended_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
2821 extended_style |= WS_EX_TOOLWINDOW;
2823 extended_style &= ~WS_EX_TOOLWINDOW;
2825 SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, extended_style);
2829 gdk_window_set_skip_pager_hint (GdkWindow *window,
2830 gboolean skips_pager)
2832 g_return_if_fail (GDK_IS_WINDOW (window));
2836 gdk_window_set_type_hint (GdkWindow *window,
2837 GdkWindowTypeHint hint)
2839 g_return_if_fail (window != NULL);
2840 g_return_if_fail (GDK_IS_WINDOW (window));
2842 if (GDK_WINDOW_DESTROYED (window))
2845 GDK_NOTE (MISC, g_print ("gdk_window_set_type_hint: %p: %d\n",
2846 GDK_WINDOW_HWND (window), hint));
2849 case GDK_WINDOW_TYPE_HINT_DIALOG:
2851 case GDK_WINDOW_TYPE_HINT_MENU:
2852 gdk_window_set_decorations (window,
2855 GDK_DECOR_MINIMIZE |
2856 GDK_DECOR_MAXIMIZE);
2858 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
2859 gdk_window_set_skip_taskbar_hint (window, TRUE);
2861 case GDK_WINDOW_TYPE_HINT_UTILITY:
2863 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
2865 case GDK_WINDOW_TYPE_HINT_DOCK:
2867 case GDK_WINDOW_TYPE_HINT_DESKTOP:
2870 g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
2872 case GDK_WINDOW_TYPE_HINT_NORMAL:
2878 gdk_window_shape_combine_region (GdkWindow *window,
2879 GdkRegion *shape_region,
2883 g_return_if_fail (GDK_IS_WINDOW (window));
2885 if (GDK_WINDOW_DESTROYED (window))
2888 /* XXX: even on X implemented conditional ... */
2892 gdk_window_begin_resize_drag (GdkWindow *window,
2899 g_return_if_fail (GDK_IS_WINDOW (window));
2901 if (GDK_WINDOW_DESTROYED (window))
2904 /* XXX: isn't all this default on win32 ... */
2908 gdk_window_begin_move_drag (GdkWindow *window,
2914 g_return_if_fail (GDK_IS_WINDOW (window));
2916 if (GDK_WINDOW_DESTROYED (window))
2919 /* XXX: isn't all this default on win32 ... */
2923 gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
2925 g_return_val_if_fail (display == gdk_display_get_default(), NULL);
2927 return gdk_window_lookup (anid);