1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * Copyright (C) 1998-1999 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 "gdkinternals.h"
35 #include "gdkprivate-win32.h"
36 #include "gdkinput-win32.h"
38 static gboolean gdk_window_gravity_works (void);
39 static void gdk_window_set_static_win_gravity (GdkWindow *window,
42 static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable);
43 static void gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
45 static void gdk_window_impl_win32_get_size (GdkDrawable *drawable,
48 static GdkRegion* gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable);
49 static void gdk_window_impl_win32_init (GdkWindowImplWin32 *window);
50 static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass);
51 static void gdk_window_impl_win32_finalize (GObject *object);
53 static gpointer parent_class = NULL;
56 gdk_window_impl_win32_get_type (void)
58 static GType object_type = 0;
62 static const GTypeInfo object_info =
64 sizeof (GdkWindowImplWin32Class),
66 (GBaseFinalizeFunc) NULL,
67 (GClassInitFunc) gdk_window_impl_win32_class_init,
68 NULL, /* class_finalize */
69 NULL, /* class_data */
70 sizeof (GdkWindowImplWin32),
72 (GInstanceInitFunc) gdk_window_impl_win32_init,
75 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_WIN32,
84 _gdk_window_impl_get_type (void)
86 return gdk_window_impl_win32_get_type ();
90 gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
98 impl->extension_events_selected = FALSE;
99 impl->input_locale = GetKeyboardLayout (0);
100 TranslateCharsetInfo ((DWORD FAR *) GetACP (), &impl->charset_info,
105 gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
107 GObjectClass *object_class = G_OBJECT_CLASS (klass);
108 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
110 parent_class = g_type_class_peek_parent (klass);
112 object_class->finalize = gdk_window_impl_win32_finalize;
114 drawable_class->set_colormap = gdk_window_impl_win32_set_colormap;
115 drawable_class->get_colormap = gdk_window_impl_win32_get_colormap;
116 drawable_class->get_size = gdk_window_impl_win32_get_size;
118 /* Visible and clip regions are the same */
119 drawable_class->get_clip_region = gdk_window_impl_win32_get_visible_region;
120 drawable_class->get_visible_region = gdk_window_impl_win32_get_visible_region;
124 gdk_window_impl_win32_finalize (GObject *object)
126 GdkWindowObject *wrapper;
127 GdkDrawableImplWin32 *draw_impl;
128 GdkWindowImplWin32 *window_impl;
130 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (object));
132 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (object);
133 window_impl = GDK_WINDOW_IMPL_WIN32 (object);
135 wrapper = (GdkWindowObject*) draw_impl->wrapper;
137 if (!GDK_WINDOW_DESTROYED (wrapper))
139 gdk_win32_handle_table_remove (draw_impl->handle);
142 if (window_impl->hcursor != NULL)
144 if (!DestroyCursor (window_impl->hcursor))
145 WIN32_GDI_FAILED("DestroyCursor");
146 window_impl->hcursor = NULL;
149 G_OBJECT_CLASS (parent_class)->finalize (object);
153 gdk_window_impl_win32_get_colormap (GdkDrawable *drawable)
155 GdkDrawableImplWin32 *drawable_impl;
156 GdkWindowImplWin32 *window_impl;
158 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable), NULL);
160 drawable_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
161 window_impl = GDK_WINDOW_IMPL_WIN32 (drawable);
163 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
164 drawable_impl->colormap == NULL)
166 drawable_impl->colormap = gdk_colormap_get_system ();
167 gdk_colormap_ref (drawable_impl->colormap);
170 return drawable_impl->colormap;
174 gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
177 GdkWindowImplWin32 *impl;
178 GdkDrawableImplWin32 *draw_impl;
180 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
181 g_return_if_fail (gdk_colormap_get_visual (cmap) != gdk_drawable_get_visual (drawable));
183 impl = GDK_WINDOW_IMPL_WIN32 (drawable);
184 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
186 GDK_DRAWABLE_GET_CLASS (draw_impl)->set_colormap (drawable, cmap);
189 g_print("gdk_window_impl_win32_set_colormap: XXX\n");
193 gdk_window_impl_win32_get_size (GdkDrawable *drawable,
197 g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
200 *width = GDK_WINDOW_IMPL_WIN32 (drawable)->width;
202 *height = GDK_WINDOW_IMPL_WIN32 (drawable)->height;
206 gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable)
208 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (drawable);
209 GdkRectangle result_rect;
213 result_rect.width = impl->width;
214 result_rect.height = impl->height;
216 gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
218 return gdk_region_rectangle (&result_rect);
222 _gdk_windowing_window_init (void)
224 GdkWindowObject *private;
225 GdkWindowImplWin32 *impl;
226 GdkDrawableImplWin32 *draw_impl;
231 g_assert (gdk_parent_root == NULL);
233 SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
234 width = rect.right - rect.left;
235 height = rect.bottom - rect.top;
237 gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
238 private = (GdkWindowObject *)gdk_parent_root;
239 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
240 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
242 draw_impl->handle = gdk_root_window;
243 draw_impl->wrapper = GDK_DRAWABLE (private);
245 private->window_type = GDK_WINDOW_ROOT;
246 private->depth = gdk_visual_get_system ()->depth;
248 impl->height = height;
250 gdk_win32_handle_table_insert (&gdk_root_window, gdk_parent_root);
253 /* The Win API function AdjustWindowRect may return negative values
254 * resulting in obscured title bars. This helper function is coreccting it.
257 SafeAdjustWindowRectEx (RECT* lpRect,
262 if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
264 WIN32_API_FAILED ("AdjustWindowRectEx");
267 if (lpRect->left < 0)
269 lpRect->right -= lpRect->left;
274 lpRect->bottom -= lpRect->top;
281 * is a wrapper function for RegisterWindowClassEx.
282 * It creates at least one unique class for every
283 * GdkWindowType. If support for single window-specific icons
284 * is ever needed (e.g Dialog specific), every such window should
288 RegisterGdkClass (GdkWindowType wtype)
290 static ATOM klassTOPLEVEL = 0;
291 static ATOM klassDIALOG = 0;
292 static ATOM klassCHILD = 0;
293 static ATOM klassTEMP = 0;
294 static HICON hAppIcon = NULL;
295 static WNDCLASSEX wcl;
298 wcl.cbSize = sizeof(WNDCLASSEX);
299 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
300 * on WM_SIZE and WM_MOVE. Flicker, Performance!
302 wcl.lpfnWndProc = gdk_window_procedure;
305 wcl.hInstance = gdk_app_hmodule;
307 /* initialize once! */
310 gchar sLoc [_MAX_PATH+1];
312 if (0 != GetModuleFileName (gdk_app_hmodule, sLoc, _MAX_PATH))
314 hAppIcon = ExtractIcon (gdk_app_hmodule, sLoc, 0);
317 char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
319 hAppIcon = ExtractIcon (gdk_app_hmodule, gdklibname, 0);
324 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
328 wcl.lpszMenuName = NULL;
331 /* initialize once per class */
333 * HB: Setting the background brush leads to flicker, because we
334 * don't get asked how to clear the background. This is not what
335 * we want, at least not for input_only windows ...
337 #define ONCE_PER_CLASS() \
338 wcl.hIcon = CopyIcon (hAppIcon); \
339 wcl.hIconSm = CopyIcon (hAppIcon); \
340 wcl.hbrBackground = NULL; /* CreateSolidBrush (RGB (0,0,0)); */ \
341 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
345 case GDK_WINDOW_TOPLEVEL:
346 if (0 == klassTOPLEVEL)
348 wcl.lpszClassName = "gdkWindowToplevel";
351 klassTOPLEVEL = RegisterClassEx (&wcl);
353 klass = klassTOPLEVEL;
356 case GDK_WINDOW_CHILD:
359 wcl.lpszClassName = "gdkWindowChild";
361 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
363 klassCHILD = RegisterClassEx (&wcl);
368 case GDK_WINDOW_DIALOG:
369 if (0 == klassDIALOG)
371 wcl.lpszClassName = "gdkWindowDialog";
372 wcl.style |= CS_SAVEBITS;
374 klassDIALOG = RegisterClassEx (&wcl);
379 case GDK_WINDOW_TEMP:
382 wcl.lpszClassName = "gdkWindowTemp";
383 wcl.style |= CS_SAVEBITS;
385 klassTEMP = RegisterClassEx (&wcl);
391 g_assert_not_reached ();
397 WIN32_API_FAILED ("RegisterClassEx");
398 g_error ("That is a fatal error");
404 gdk_window_new (GdkWindow *parent,
405 GdkWindowAttr *attributes,
406 gint attributes_mask)
409 GdkWindowObject *private;
410 GdkWindowObject *parent_private;
411 GdkWindowImplWin32 *impl;
412 GdkDrawableImplWin32 *draw_impl;
418 DWORD dwStyle, dwExStyle;
427 g_return_val_if_fail (attributes != NULL, NULL);
430 parent = gdk_parent_root;
432 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
435 g_print ("gdk_window_new: %s\n",
436 (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
437 (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" :
438 (attributes->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
439 (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
442 parent_private = (GdkWindowObject*) parent;
443 if (GDK_WINDOW_DESTROYED (parent))
446 hparent = GDK_WINDOW_HWND (parent);
448 window = g_object_new (GDK_TYPE_WINDOW, NULL);
449 private = (GdkWindowObject *)window;
450 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
451 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
452 draw_impl->wrapper = GDK_DRAWABLE (window);
454 private->parent = (GdkWindowObject *)parent;
456 if (attributes_mask & GDK_WA_X)
461 if (attributes_mask & GDK_WA_Y)
463 else if (attributes_mask & GDK_WA_X)
464 y = 100; /* ??? We must put it somewhere... */
466 y = 0; /* x is CW_USEDEFAULT, y doesn't matter then */
470 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
471 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
472 impl->extension_events_selected = FALSE;
473 private->window_type = attributes->window_type;
475 _gdk_window_init_position (GDK_WINDOW (private));
476 if (impl->position_info.big)
477 private->guffaw_gravity = TRUE;
479 if (attributes_mask & GDK_WA_VISUAL)
480 visual = attributes->visual;
482 visual = gdk_visual_get_system ();
483 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
485 if (attributes_mask & GDK_WA_TITLE)
486 title = attributes->title;
488 title = g_get_prgname ();
489 if (!title || !*title)
490 title = "GDK client window";
492 impl->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
494 if (parent_private && parent_private->guffaw_gravity)
499 if (attributes->wclass == GDK_INPUT_OUTPUT)
503 private->input_only = FALSE;
504 private->depth = visual->depth;
506 if (attributes_mask & GDK_WA_COLORMAP)
508 draw_impl->colormap = attributes->colormap;
509 gdk_colormap_ref (attributes->colormap);
513 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
515 draw_impl->colormap = gdk_colormap_get_system ();
516 gdk_colormap_ref (draw_impl->colormap);
517 GDK_NOTE (MISC, g_print ("...using system colormap %p\n",
518 draw_impl->colormap));
522 draw_impl->colormap = gdk_colormap_new (visual, FALSE);
523 GDK_NOTE (MISC, g_print ("...using new colormap %p\n",
524 draw_impl->colormap));
530 dwExStyle = WS_EX_TRANSPARENT;
532 private->input_only = TRUE;
533 draw_impl->colormap = NULL;
534 GDK_NOTE (MISC, g_print ("...GDK_INPUT_ONLY, NULL colormap\n"));
538 parent_private->children = g_list_prepend (parent_private->children, window);
540 switch (private->window_type)
542 case GDK_WINDOW_TOPLEVEL:
543 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
544 hparent = gdk_root_window;
547 case GDK_WINDOW_CHILD:
548 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
551 case GDK_WINDOW_DIALOG:
552 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
554 dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
556 hparent = gdk_root_window;
559 case GDK_WINDOW_TEMP:
560 dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
561 dwExStyle |= WS_EX_TOOLWINDOW;
564 case GDK_WINDOW_ROOT:
565 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
569 klass = RegisterGdkClass (private->window_type);
571 if (private->window_type != GDK_WINDOW_CHILD)
573 if (x == CW_USEDEFAULT)
584 rect.right = rect.left + impl->width;
585 rect.bottom = rect.top + impl->height;
587 SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
589 if (x != CW_USEDEFAULT)
594 width = rect.right - rect.left;
595 height = rect.bottom - rect.top;
600 height = impl->height;
603 mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
605 #ifdef WITHOUT_WM_CREATE
606 draw_impl->handle = CreateWindowEx (dwExStyle,
607 MAKEINTRESOURCE(klass),
619 CreateWindowEx (dwExStyle,
620 MAKEINTRESOURCE(klass),
629 if (GDK_WINDOW_HWND (window) != hwndNew)
631 g_warning("gdk_window_new: gdk_event_translate::WM_CREATE (%#x, %#x) HWND mismatch.",
632 (guint) GDK_WINDOW_HWND (window),
635 /* HB: IHMO due to a race condition the handle was increased by
636 * one, which causes much trouble. Because I can't find the
637 * real bug, try to workaround it ...
638 * To reproduce: compile with MSVC 5, DEBUG=1
641 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
642 GDK_WINDOW_HWND (window) = hwndNew;
643 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
645 /* the old behaviour, but with warning */
646 GDK_WINDOW_HWND (window) = hwndNew;
651 gdk_drawable_ref (window);
652 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
656 g_print ("... \"%s\" %dx%d@+%d+%d %#x = %#x\n"
657 "... locale %#x codepage %d\n",
659 width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
661 (guint) GDK_WINDOW_HWND (window),
662 (guint) impl->input_locale,
663 (guint) impl->charset_info.ciACP));
667 if (draw_impl->handle == NULL)
669 WIN32_API_FAILED ("CreateWindowEx");
670 g_object_unref ((GObject *) window);
674 #ifdef WITHOUT_WM_CREATE
675 gdk_drawable_ref (window);
676 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
679 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
680 (attributes->cursor) :
687 gdk_window_foreign_new (GdkNativeWindow anid)
690 GdkWindowObject *private;
691 GdkWindowObject *parent_private;
692 GdkWindowImplWin32 *impl;
693 GdkDrawableImplWin32 *draw_impl;
699 window = g_object_new (GDK_TYPE_WINDOW, NULL);
700 private = (GdkWindowObject *)window;
701 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
702 draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
703 draw_impl->wrapper = GDK_DRAWABLE (window);
704 parent = GetParent ((HWND)anid);
706 private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
708 parent_private = (GdkWindowObject *)private->parent;
711 parent_private->children = g_list_prepend (parent_private->children, window);
713 draw_impl->handle = (HWND) anid;
714 GetClientRect ((HWND) anid, &rect);
716 point.y = rect.right;
717 ClientToScreen ((HWND) anid, &point);
718 if (parent != gdk_root_window)
719 ScreenToClient (parent, &point);
720 private->x = point.x;
721 private->y = point.y;
722 impl->width = rect.right - rect.left;
723 impl->height = rect.bottom - rect.top;
724 private->window_type = GDK_WINDOW_FOREIGN;
725 private->destroyed = FALSE;
726 if (IsWindowVisible ((HWND) anid))
727 private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
729 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
730 private->depth = gdk_visual_get_system ()->depth;
732 gdk_drawable_ref (window);
733 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
739 _gdk_windowing_window_destroy (GdkWindow *window,
741 gboolean foreign_destroy)
743 GdkWindowObject *private = (GdkWindowObject *)window;
745 g_return_if_fail (GDK_IS_WINDOW (window));
747 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy %#x\n",
748 (guint) GDK_WINDOW_HWND (window)));
750 if (private->extension_events != 0)
751 gdk_input_window_destroy (window);
753 if (private->window_type == GDK_WINDOW_FOREIGN)
755 if (!foreign_destroy && (private->parent != NULL))
757 /* It's somebody else's window, but in our hierarchy,
758 * so reparent it to the root window, and then call
759 * DestroyWindow() on it.
761 gdk_window_hide (window);
762 gdk_window_reparent (window, NULL, 0, 0);
764 /* Is this too drastic? Many (most?) applications
765 * quit if any window receives WM_QUIT I think.
766 * OTOH, I don't think foreign windows are much
767 * used, so the question is maybe academic.
769 PostMessage (GDK_WINDOW_HWND (window), WM_QUIT, 0, 0);
772 else if (!recursing && !foreign_destroy)
773 DestroyWindow (GDK_WINDOW_HWND (window));
776 /* This function is called when the window really gone.
779 gdk_window_destroy_notify (GdkWindow *window)
781 g_return_if_fail (window != NULL);
782 g_return_if_fail (GDK_IS_WINDOW (window));
785 g_print ("gdk_window_destroy_notify: %#x %s\n",
786 (guint) GDK_WINDOW_HWND (window),
787 (GDK_WINDOW_DESTROYED (window) ? "(destroyed)" : "")));
789 if (!GDK_WINDOW_DESTROYED (window))
791 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
792 g_warning ("window %#x unexpectedly destroyed",
793 (guint) GDK_WINDOW_HWND (window));
795 _gdk_window_destroy (window, TRUE);
798 gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
799 gdk_drawable_unref (window);
803 gdk_window_show (GdkWindow *window)
805 GdkWindowObject *private;
807 g_return_if_fail (GDK_IS_WINDOW (window));
809 private = (GdkWindowObject*) window;
810 if (!private->destroyed)
812 GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n",
813 (guint) GDK_WINDOW_HWND (window)));
815 private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
816 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
818 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
819 SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST, 0, 0, 0, 0,
820 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
822 /* Don't put on toolbar */
823 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
828 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
830 SetWindowPos(GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0,
831 SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE);
835 GdkWindow *parent = GDK_WINDOW (private->parent);
837 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
838 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
839 if (parent == gdk_parent_root)
840 SetForegroundWindow (GDK_WINDOW_HWND (window));
841 BringWindowToTop (GDK_WINDOW_HWND (window));
843 ShowOwnedPopups (GDK_WINDOW_HWND (window), TRUE);
851 gdk_window_hide (GdkWindow *window)
853 GdkWindowObject *private;
855 g_return_if_fail (window != NULL);
857 private = (GdkWindowObject*) window;
858 if (!private->destroyed)
860 GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n",
861 (guint) GDK_WINDOW_HWND (window)));
863 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
864 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
865 ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
867 if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
869 SetWindowPos(GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
870 SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
874 ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
880 gdk_window_withdraw (GdkWindow *window)
882 GdkWindowObject *private;
884 g_return_if_fail (window != NULL);
886 private = (GdkWindowObject*) window;
887 if (!private->destroyed)
889 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n",
890 (guint) GDK_WINDOW_HWND (window)));
892 gdk_window_hide (window); /* ??? */
897 gdk_window_move (GdkWindow *window,
901 GdkWindowObject *private = (GdkWindowObject *)window;
902 GdkWindowImplWin32 *impl;
904 g_return_if_fail (window != NULL);
905 g_return_if_fail (GDK_IS_WINDOW (window));
907 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
909 gdk_window_move_resize (window, x, y, impl->width, impl->height);
913 gdk_window_resize (GdkWindow *window,
917 GdkWindowObject *private = (GdkWindowObject*) window;
918 GdkWindowImplWin32 *impl;
921 g_return_if_fail (window != NULL);
922 g_return_if_fail (GDK_IS_WINDOW (window));
929 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
931 if (!private->destroyed)
933 GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
934 (guint) GDK_WINDOW_HWND (window),
937 if (GDK_WINDOW_TYPE (private) != GDK_WINDOW_CHILD)
946 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
949 rect.right = pt.x + width;
950 rect.bottom = pt.y + height;
952 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
953 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
954 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
955 WIN32_API_FAILED ("AdjustWindowRectEx");
959 width = rect.right - rect.left;
960 height = rect.bottom - rect.top;
967 impl->height = height;
970 private->resize_count += 1;
972 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
973 (guint) GDK_WINDOW_HWND (window),
974 width, height, x, y));
975 if (!MoveWindow (GDK_WINDOW_HWND (window), x, y, width, height, TRUE))
976 WIN32_API_FAILED ("MoveWindow");
981 gdk_window_move_resize (GdkWindow *window,
987 GdkWindowObject *private = (GdkWindowObject*) window;
988 GdkWindowImplWin32 *impl;
990 g_return_if_fail (window != NULL);
991 g_return_if_fail (GDK_IS_WINDOW (window));
998 impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
1000 if (!private->destroyed)
1006 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
1007 (guint) GDK_WINDOW_HWND (window),
1008 width, height, x, y));
1010 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1011 _gdk_window_move_resize_child (window, x, y, width, height);
1016 rect.right = x + width;
1017 rect.bottom = y + height;
1019 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1020 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1021 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
1022 WIN32_API_FAILED ("AdjustWindowRectEx");
1024 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%ldx%ld@+%ld+%ld)\n",
1025 (guint) GDK_WINDOW_HWND (window),
1026 rect.right - rect.left, rect.bottom - rect.top,
1027 rect.left, rect.top));
1028 if (!MoveWindow (GDK_WINDOW_HWND (window),
1029 rect.left, rect.top,
1030 rect.right - rect.left, rect.bottom - rect.top,
1032 WIN32_API_FAILED ("MoveWindow");
1038 gdk_window_reparent (GdkWindow *window,
1039 GdkWindow *new_parent,
1043 GdkWindowObject *window_private;
1044 GdkWindowObject *parent_private;
1045 GdkWindowObject *old_parent_private;
1046 GdkWindowImplWin32 *impl;
1048 g_return_if_fail (window != NULL);
1051 new_parent = gdk_parent_root;
1053 window_private = (GdkWindowObject*) window;
1054 old_parent_private = (GdkWindowObject *) window_private->parent;
1055 parent_private = (GdkWindowObject*) new_parent;
1056 impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
1058 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
1060 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
1061 (guint) GDK_WINDOW_HWND (window),
1062 (guint) GDK_WINDOW_HWND (new_parent)));
1063 if (!SetParent (GDK_WINDOW_HWND (window),
1064 GDK_WINDOW_HWND (new_parent)))
1065 WIN32_API_FAILED ("SetParent");
1067 if (!MoveWindow (GDK_WINDOW_HWND (window),
1068 x, y, impl->width, impl->height, TRUE))
1069 WIN32_API_FAILED ("MoveWindow");
1072 window_private->parent = (GdkWindowObject *)new_parent;
1074 if (old_parent_private)
1075 old_parent_private->children =
1076 g_list_remove (old_parent_private->children, window);
1078 if ((old_parent_private &&
1079 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1080 (!old_parent_private && parent_private->guffaw_gravity))
1081 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1083 parent_private->children = g_list_prepend (parent_private->children, window);
1087 _gdk_windowing_window_clear_area (GdkWindow *window,
1093 GdkWindowImplWin32 *impl;
1095 g_return_if_fail (window != NULL);
1096 g_return_if_fail (GDK_IS_WINDOW (window));
1098 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1100 if (!GDK_WINDOW_DESTROYED (window))
1105 width = impl->width - x;
1107 height = impl->height - y;
1108 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area: "
1109 "%#x %dx%d@+%d+%d\n",
1110 (guint) GDK_WINDOW_HWND (window),
1111 width, height, x, y));
1112 hdc = GetDC (GDK_WINDOW_HWND (window));
1113 IntersectClipRect (hdc, x, y, x + width + 1, y + height + 1);
1114 SendMessage (GDK_WINDOW_HWND (window), WM_ERASEBKGND, (WPARAM) hdc, 0);
1115 ReleaseDC (GDK_WINDOW_HWND (window), hdc);
1120 _gdk_windowing_window_clear_area_e (GdkWindow *window,
1126 g_return_if_fail (window != NULL);
1127 g_return_if_fail (GDK_IS_WINDOW (window));
1129 if (!GDK_WINDOW_DESTROYED (window))
1133 GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area_e: "
1134 "%#x %dx%d@+%d+%d\n",
1135 (guint) GDK_WINDOW_HWND (window),
1136 width, height, x, y));
1139 rect.right = x + width + 1;
1141 rect.bottom = y + height + 1;
1142 if (!InvalidateRect (GDK_WINDOW_HWND (window), &rect, TRUE))
1143 WIN32_GDI_FAILED ("InvalidateRect");
1144 UpdateWindow (GDK_WINDOW_HWND (window));
1149 gdk_window_raise (GdkWindow *window)
1151 g_return_if_fail (window != NULL);
1152 g_return_if_fail (GDK_IS_WINDOW (window));
1154 if (!GDK_WINDOW_DESTROYED (window))
1156 GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n",
1157 (guint) GDK_WINDOW_HWND (window)));
1159 if (!BringWindowToTop (GDK_WINDOW_HWND (window)))
1160 WIN32_API_FAILED ("BringWindowToTop");
1165 gdk_window_lower (GdkWindow *window)
1167 g_return_if_fail (window != NULL);
1168 g_return_if_fail (GDK_IS_WINDOW (window));
1170 if (!GDK_WINDOW_DESTROYED (window))
1172 GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n",
1173 (guint) GDK_WINDOW_HWND (window)));
1175 if (!SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
1176 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1177 WIN32_API_FAILED ("SetWindowPos");
1182 gdk_window_set_hints (GdkWindow *window,
1191 GdkWindowImplWin32 *impl;
1192 WINDOWPLACEMENT size_hints;
1198 g_return_if_fail (window != NULL);
1199 g_return_if_fail (GDK_IS_WINDOW (window));
1201 if (GDK_WINDOW_DESTROYED (window))
1204 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1206 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1207 (guint) GDK_WINDOW_HWND (window),
1208 min_width, min_height, max_width, max_height,
1211 impl->hint_flags = flags;
1212 size_hints.length = sizeof (size_hints);
1216 if (flags & GDK_HINT_POS)
1218 if (!GetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
1219 WIN32_API_FAILED ("GetWindowPlacement");
1222 GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1223 " (%ld,%ld)--(%ld,%ld)\n",
1224 size_hints.rcNormalPosition.left,
1225 size_hints.rcNormalPosition.top,
1226 size_hints.rcNormalPosition.right,
1227 size_hints.rcNormalPosition.bottom));
1228 /* What are the corresponding window coordinates for client
1229 * area coordinates x, y
1233 rect.right = rect.left + 200; /* dummy */
1234 rect.bottom = rect.top + 200;
1235 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1236 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1237 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1238 size_hints.flags = 0;
1239 size_hints.showCmd = SW_SHOWNA;
1241 /* Set the normal position hint to that location, with unchanged
1244 diff = size_hints.rcNormalPosition.left - rect.left;
1245 size_hints.rcNormalPosition.left = rect.left;
1246 size_hints.rcNormalPosition.right -= diff;
1247 diff = size_hints.rcNormalPosition.top - rect.top;
1248 size_hints.rcNormalPosition.top = rect.top;
1249 size_hints.rcNormalPosition.bottom -= diff;
1250 GDK_NOTE (MISC, g_print ("...setting: (%ld,%ld)--(%ld,%ld)\n",
1251 size_hints.rcNormalPosition.left,
1252 size_hints.rcNormalPosition.top,
1253 size_hints.rcNormalPosition.right,
1254 size_hints.rcNormalPosition.bottom));
1255 if (!SetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
1256 WIN32_API_FAILED ("SetWindowPlacement");
1257 impl->hint_x = rect.left;
1258 impl->hint_y = rect.top;
1262 if (flags & GDK_HINT_MIN_SIZE)
1266 rect.right = min_width;
1267 rect.bottom = min_height;
1268 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1269 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1270 SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1271 impl->hint_min_width = rect.right - rect.left;
1272 impl->hint_min_height = rect.bottom - rect.top;
1274 /* Also chek if he current size of the window is in bounds. */
1275 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1276 if (rect.right < min_width && rect.bottom < min_height)
1277 gdk_window_resize (window, min_width, min_height);
1278 else if (rect.right < min_width)
1279 gdk_window_resize (window, min_width, rect.bottom);
1280 else if (rect.bottom < min_height)
1281 gdk_window_resize (window, rect.right, min_height);
1284 if (flags & GDK_HINT_MAX_SIZE)
1288 rect.right = max_width;
1289 rect.bottom = max_height;
1290 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1291 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1292 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1293 impl->hint_max_width = rect.right - rect.left;
1294 impl->hint_max_height = rect.bottom - rect.top;
1295 /* Again, check if the window is too large currently. */
1296 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1297 if (rect.right > max_width && rect.bottom > max_height)
1298 gdk_window_resize (window, max_width, max_height);
1299 else if (rect.right > max_width)
1300 gdk_window_resize (window, max_width, rect.bottom);
1301 else if (rect.bottom > max_height)
1302 gdk_window_resize (window, rect.right, max_height);
1308 gdk_window_set_geometry_hints (GdkWindow *window,
1309 GdkGeometry *geometry,
1310 GdkWindowHints geom_mask)
1312 GdkWindowImplWin32 *impl;
1313 WINDOWPLACEMENT size_hints;
1318 g_return_if_fail (window != NULL);
1319 g_return_if_fail (GDK_IS_WINDOW (window));
1321 if (GDK_WINDOW_DESTROYED (window))
1324 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1325 size_hints.length = sizeof (size_hints);
1327 impl->hint_flags = geom_mask;
1329 if (geom_mask & GDK_HINT_POS)
1332 if (geom_mask & GDK_HINT_MIN_SIZE)
1336 rect.right = geometry->min_width;
1337 rect.bottom = geometry->min_height;
1338 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1339 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1340 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1341 impl->hint_min_width = rect.right - rect.left;
1342 impl->hint_min_height = rect.bottom - rect.top;
1344 /* Also check if he current size of the window is in bounds */
1345 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1346 if (rect.right < geometry->min_width
1347 && rect.bottom < geometry->min_height)
1348 gdk_window_resize (window, geometry->min_width, geometry->min_height);
1349 else if (rect.right < geometry->min_width)
1350 gdk_window_resize (window, geometry->min_width, rect.bottom);
1351 else if (rect.bottom < geometry->min_height)
1352 gdk_window_resize (window, rect.right, geometry->min_height);
1355 if (geom_mask & GDK_HINT_MAX_SIZE)
1359 rect.right = geometry->max_width;
1360 rect.bottom = geometry->max_height;
1361 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1362 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1363 /* HB: dont' know why AdjustWindowRectEx is called here, ... */
1364 SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1365 impl->hint_max_width = rect.right - rect.left;
1366 impl->hint_max_height = rect.bottom - rect.top;
1367 /* ... but negative sizes are always wrong */
1368 if (impl->hint_max_width < 0) impl->hint_max_width = G_MAXSHORT;
1369 if (impl->hint_max_height < 0) impl->hint_max_height = G_MAXSHORT;
1371 /* Again, check if the window is too large currently. */
1372 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1373 if (rect.right > geometry->max_width
1374 && rect.bottom > geometry->max_height)
1375 gdk_window_resize (window, geometry->max_width, geometry->max_height);
1376 else if (rect.right > geometry->max_width)
1377 gdk_window_resize (window, geometry->max_width, rect.bottom);
1378 else if (rect.bottom > geometry->max_height)
1379 gdk_window_resize (window, rect.right, geometry->max_height);
1382 /* I don't know what to do when called with zero base_width and height. */
1383 if (geom_mask & GDK_HINT_BASE_SIZE
1384 && geometry->base_width > 0
1385 && geometry->base_height > 0)
1387 if (!GetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
1388 WIN32_API_FAILED ("GetWindowPlacement");
1391 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1392 " rcNormalPosition: (%ld,%ld)--(%ld,%ld)\n",
1393 size_hints.rcNormalPosition.left,
1394 size_hints.rcNormalPosition.top,
1395 size_hints.rcNormalPosition.right,
1396 size_hints.rcNormalPosition.bottom));
1397 size_hints.rcNormalPosition.right =
1398 size_hints.rcNormalPosition.left + geometry->base_width;
1399 size_hints.rcNormalPosition.bottom =
1400 size_hints.rcNormalPosition.top + geometry->base_height;
1401 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%ld,%ld)--(%ld,%ld)\n",
1402 size_hints.rcNormalPosition.left,
1403 size_hints.rcNormalPosition.top,
1404 size_hints.rcNormalPosition.right,
1405 size_hints.rcNormalPosition.bottom));
1406 if (!SetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
1407 WIN32_API_FAILED ("SetWindowPlacement");
1411 if (geom_mask & GDK_HINT_RESIZE_INC)
1416 if (geom_mask & GDK_HINT_ASPECT)
1423 gdk_window_set_title (GdkWindow *window,
1428 g_return_if_fail (window != NULL);
1429 g_return_if_fail (GDK_IS_WINDOW (window));
1430 g_return_if_fail (title != NULL);
1432 /* Empty window titles not allowed, so set it to just a period. */
1436 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
1437 (guint) GDK_WINDOW_HWND (window), title));
1439 if (!GDK_WINDOW_DESTROYED (window))
1441 /* As the title is in UTF-8 we must translate it
1442 * to the system codepage.
1444 mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
1445 if (!SetWindowText (GDK_WINDOW_HWND (window), mbtitle))
1446 WIN32_API_FAILED ("SetWindowText");
1453 gdk_window_set_role (GdkWindow *window,
1456 g_return_if_fail (window != NULL);
1457 g_return_if_fail (GDK_IS_WINDOW (window));
1459 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1460 (guint) GDK_WINDOW_HWND (window),
1461 (role ? role : "NULL")));
1466 gdk_window_set_transient_for (GdkWindow *window,
1469 g_return_if_fail (window != NULL);
1470 g_return_if_fail (GDK_IS_WINDOW (window));
1472 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1473 (guint) GDK_WINDOW_HWND (window),
1474 (guint) GDK_WINDOW_HWND (parent)));
1479 gdk_window_set_background (GdkWindow *window,
1482 GdkWindowObject *private = (GdkWindowObject *)window;
1484 g_return_if_fail (window != NULL);
1485 g_return_if_fail (GDK_IS_WINDOW (window));
1487 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1488 (guint) GDK_WINDOW_HWND (window),
1489 gdk_win32_color_to_string (color)));
1491 private->bg_color = *color;
1493 if (private->bg_pixmap &&
1494 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1495 private->bg_pixmap != GDK_NO_BG)
1497 gdk_drawable_unref (private->bg_pixmap);
1498 private->bg_pixmap = NULL;
1503 gdk_window_set_back_pixmap (GdkWindow *window,
1505 gint parent_relative)
1507 GdkWindowObject *private = (GdkWindowObject *)window;
1509 g_return_if_fail (window != NULL);
1510 g_return_if_fail (GDK_IS_WINDOW (window));
1511 g_return_if_fail (pixmap == NULL || !parent_relative);
1513 if (private->bg_pixmap &&
1514 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1515 private->bg_pixmap != GDK_NO_BG)
1516 gdk_drawable_unref (private->bg_pixmap);
1518 if (parent_relative)
1520 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1526 gdk_drawable_ref (pixmap);
1527 private->bg_pixmap = pixmap;
1531 private->bg_pixmap = GDK_NO_BG;
1537 gdk_window_set_cursor (GdkWindow *window,
1540 GdkWindowImplWin32 *impl;
1541 GdkCursorPrivate *cursor_private;
1543 HCURSOR hprevcursor;
1546 g_return_if_fail (window != NULL);
1547 g_return_if_fail (GDK_IS_WINDOW (window));
1549 impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
1550 cursor_private = (GdkCursorPrivate*) cursor;
1552 if (!GDK_WINDOW_DESTROYED (window))
1557 hcursor = cursor_private->hcursor;
1559 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1560 (guint) GDK_WINDOW_HWND (window),
1562 hprevcursor = impl->hcursor;
1563 if (hcursor == NULL)
1564 impl->hcursor = NULL;
1567 /* We must copy the cursor as it is OK to destroy the GdkCursor
1568 * while still in use for some window. See for instance
1569 * gimp_change_win_cursor() which calls
1570 * gdk_window_set_cursor (win, cursor), and immediately
1571 * afterwards gdk_cursor_destroy (cursor).
1573 impl->hcursor = CopyCursor (hcursor);
1574 GDK_NOTE (MISC, g_print ("...CopyCursor (%#x) = %#x\n",
1575 (guint) hcursor, (guint) impl->hcursor));
1577 if (hprevcursor != NULL && GetCursor () == hprevcursor)
1578 SetCursor (impl->hcursor);
1580 if (hprevcursor != NULL)
1582 GDK_NOTE (MISC, g_print ("...DestroyCursor (%#x)\n",
1583 (guint) hprevcursor));
1585 if (!DestroyCursor (hprevcursor))
1586 WIN32_API_FAILED ("DestroyCursor");
1593 gdk_window_get_geometry (GdkWindow *window,
1600 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1603 window = gdk_parent_root;
1605 if (!GDK_WINDOW_DESTROYED (window))
1609 if (!GetClientRect (GDK_WINDOW_HWND (window), &rect))
1610 WIN32_API_FAILED ("GetClientRect");
1617 *width = rect.right - rect.left;
1619 *height = rect.bottom - rect.top;
1621 *depth = gdk_drawable_get_visual (window)->depth;
1626 gdk_window_get_origin (GdkWindow *window,
1634 g_return_val_if_fail (window != NULL, 0);
1636 if (!GDK_WINDOW_DESTROYED (window))
1642 ClientToScreen (GDK_WINDOW_HWND (window), &pt);
1655 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
1656 (guint) GDK_WINDOW_HWND (window),
1662 gdk_window_get_deskrelative_origin (GdkWindow *window,
1666 return gdk_window_get_origin (window, x, y);
1670 gdk_window_get_root_origin (GdkWindow *window,
1674 GdkWindowObject *rover;
1677 g_return_if_fail (window != NULL);
1678 g_return_if_fail (GDK_IS_WINDOW (window));
1680 rover = (GdkWindowObject*) window;
1686 if (GDK_WINDOW_DESTROYED (window))
1689 while (rover->parent && ((GdkWindowObject*) rover->parent)->parent)
1690 rover = (GdkWindowObject *) rover->parent;
1691 if (rover->destroyed)
1696 ClientToScreen (GDK_WINDOW_HWND (rover), &pt);
1702 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%ld+%ld\n",
1703 (guint) GDK_WINDOW_HWND (window),
1704 (guint) GDK_WINDOW_HWND (rover),
1709 gdk_window_get_frame_extents (GdkWindow *window,
1712 GdkWindowObject *private;
1721 if (GDK_WINDOW_DESTROYED (window))
1724 hwnd = GDK_WINDOW_HWND (window);
1725 /* find the frame window */
1726 while (HWND_DESKTOP != GetParent (hwnd))
1728 hwnd = GetParent (hwnd);
1729 g_return_if_fail (NULL != hwnd);
1732 if (GetWindowRect (hwnd, &r))
1733 WIN32_API_FAILED ("GetWindowRect");
1737 rect->width = r.right - r.left;
1738 rect->height = r.bottom - r.top;
1742 _gdk_windowing_window_get_pointer (GdkWindow *window,
1745 GdkModifierType *mask)
1747 GdkWindow *return_val;
1748 POINT pointc, point;
1751 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1754 window = gdk_parent_root;
1757 GetCursorPos (&pointc);
1759 ScreenToClient (GDK_WINDOW_HWND (window), &point);
1766 hwnd = WindowFromPoint (point);
1768 ScreenToClient (hwnd, &point);
1771 hwndc = ChildWindowFromPoint (hwnd, point);
1772 ClientToScreen (hwnd, &point);
1773 ScreenToClient (hwndc, &point);
1774 } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1776 return_val = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
1782 GetKeyboardState (kbd);
1784 if (kbd[VK_SHIFT] & 0x80)
1785 *mask |= GDK_SHIFT_MASK;
1786 if (kbd[VK_CAPITAL] & 0x80)
1787 *mask |= GDK_LOCK_MASK;
1788 if (kbd[VK_CONTROL] & 0x80)
1789 *mask |= GDK_CONTROL_MASK;
1790 if (kbd[VK_MENU] & 0x80)
1791 *mask |= GDK_MOD1_MASK;
1792 if (kbd[VK_LBUTTON] & 0x80)
1793 *mask |= GDK_BUTTON1_MASK;
1794 if (kbd[VK_MBUTTON] & 0x80)
1795 *mask |= GDK_BUTTON2_MASK;
1796 if (kbd[VK_RBUTTON] & 0x80)
1797 *mask |= GDK_BUTTON3_MASK;
1804 _gdk_windowing_window_at_pointer (gint *win_x,
1808 POINT point, pointc;
1812 GetCursorPos (&pointc);
1814 hwnd = WindowFromPoint (point);
1818 window = gdk_parent_root;
1826 ScreenToClient (hwnd, &point);
1829 hwndc = ChildWindowFromPoint (hwnd, point);
1830 ClientToScreen (hwnd, &point);
1831 ScreenToClient (hwndc, &point);
1832 } while (hwndc != hwnd && (hwnd = hwndc, 1));
1834 window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
1836 if (window && (win_x || win_y))
1838 GetClientRect (hwnd, &rect);
1840 *win_x = point.x - rect.left;
1842 *win_y = point.y - rect.top;
1845 GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%ld+%ld %#x%s\n",
1848 (window == NULL ? " NULL" : "")));
1854 gdk_window_get_events (GdkWindow *window)
1856 g_return_val_if_fail (window != NULL, 0);
1857 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1859 if (GDK_WINDOW_DESTROYED (window))
1862 return GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->event_mask;
1866 gdk_window_set_events (GdkWindow *window,
1867 GdkEventMask event_mask)
1869 g_return_if_fail (window != NULL);
1870 g_return_if_fail (GDK_IS_WINDOW (window));
1872 if (GDK_WINDOW_DESTROYED (window))
1875 GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->event_mask = event_mask;
1879 gdk_window_shape_combine_mask (GdkWindow *window,
1883 g_return_if_fail (window != NULL);
1884 g_return_if_fail (GDK_IS_WINDOW (window));
1888 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
1889 (guint) GDK_WINDOW_HWND (window)));
1890 SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
1899 /* Convert mask bitmap to region */
1900 hrgn = BitmapToRegion (GDK_WINDOW_HWND (mask));
1902 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
1903 (guint) GDK_WINDOW_HWND (window),
1904 (guint) GDK_WINDOW_HWND (mask)));
1906 /* SetWindowRgn wants window (not client) coordinates */
1907 dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1908 dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1909 GetClientRect (GDK_WINDOW_HWND (window), &rect);
1910 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1911 OffsetRgn (hrgn, -rect.left, -rect.top);
1913 OffsetRgn (hrgn, x, y);
1915 /* If this is a top-level window, add the title bar to the region */
1916 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
1918 CombineRgn (hrgn, hrgn,
1919 CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
1923 SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
1928 gdk_window_set_override_redirect (GdkWindow *window,
1929 gboolean override_redirect)
1931 g_return_if_fail (window != NULL);
1932 g_return_if_fail (GDK_IS_WINDOW (window));
1934 g_warning ("gdk_window_set_override_redirect not implemented");
1938 gdk_window_set_icon (GdkWindow *window,
1939 GdkWindow *icon_window,
1943 g_return_if_fail (window != NULL);
1944 g_return_if_fail (GDK_IS_WINDOW (window));
1946 if (GDK_WINDOW_DESTROYED (window))
1949 /* Nothing to do, really. As we share window classes between windows
1950 * we can't have window-specific icons, sorry. Don't print any warning
1956 gdk_window_set_icon_name (GdkWindow *window,
1959 g_return_if_fail (window != NULL);
1960 g_return_if_fail (GDK_IS_WINDOW (window));
1962 if (GDK_WINDOW_DESTROYED (window))
1965 if (!SetWindowText (GDK_WINDOW_HWND (window), name))
1966 WIN32_API_FAILED ("SetWindowText");
1970 gdk_window_set_group (GdkWindow *window,
1973 g_return_if_fail (window != NULL);
1974 g_return_if_fail (GDK_IS_WINDOW (window));
1975 g_return_if_fail (leader != NULL);
1976 g_return_if_fail (GDK_IS_WINDOW (leader));
1978 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
1981 g_warning ("gdk_window_set_group not implemented");
1985 gdk_window_set_decorations (GdkWindow *window,
1986 GdkWMDecoration decorations)
1988 LONG style, exstyle;
1990 g_return_if_fail (window != NULL);
1991 g_return_if_fail (GDK_IS_WINDOW (window));
1993 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
1994 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
1996 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
1997 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
1999 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2001 if (decorations & GDK_DECOR_ALL)
2002 style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2003 if (decorations & GDK_DECOR_BORDER)
2004 style |= (WS_BORDER);
2005 if (decorations & GDK_DECOR_RESIZEH)
2006 style |= (WS_THICKFRAME);
2007 if (decorations & GDK_DECOR_TITLE)
2008 style |= (WS_CAPTION);
2009 if (decorations & GDK_DECOR_MENU)
2010 style |= (WS_SYSMENU);
2011 if (decorations & GDK_DECOR_MINIMIZE)
2012 style |= (WS_MINIMIZEBOX);
2013 if (decorations & GDK_DECOR_MAXIMIZE)
2014 style |= (WS_MAXIMIZEBOX);
2016 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
2020 gdk_window_set_functions (GdkWindow *window,
2021 GdkWMFunction functions)
2023 LONG style, exstyle;
2025 g_return_if_fail (window != NULL);
2026 g_return_if_fail (GDK_IS_WINDOW (window));
2028 style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
2029 exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
2031 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2032 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
2035 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2037 if (functions & GDK_FUNC_ALL)
2038 style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2039 if (functions & GDK_FUNC_RESIZE)
2040 style |= (WS_THICKFRAME);
2041 if (functions & GDK_FUNC_MOVE)
2042 style |= (WS_THICKFRAME);
2043 if (functions & GDK_FUNC_MINIMIZE)
2044 style |= (WS_MINIMIZEBOX);
2045 if (functions & GDK_FUNC_MAXIMIZE)
2046 style |= (WS_MAXIMIZEBOX);
2048 SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
2052 * propagate the shapes from all child windows of a GDK window to the parent
2053 * window. Shamelessly ripped from Enlightenment's code
2059 QueryTree (HWND hwnd,
2069 child = GetWindow (hwnd, GW_CHILD);
2071 child = GetWindow (child, GW_HWNDNEXT);
2074 } while (child != NULL);
2078 *children = g_new (HWND, n);
2079 for (i = 0; i < n; i++)
2082 child = GetWindow (hwnd, GW_CHILD);
2084 child = GetWindow (child, GW_HWNDNEXT);
2085 *children[i] = child;
2091 gdk_propagate_shapes (HANDLE win,
2095 HRGN region, childRegion;
2099 SetRectEmpty (&emptyRect);
2100 region = CreateRectRgnIndirect (&emptyRect);
2102 GetWindowRgn (win, region);
2104 QueryTree (win, &list, &num);
2107 WINDOWPLACEMENT placement;
2109 placement.length = sizeof (WINDOWPLACEMENT);
2110 /* go through all child windows and combine regions */
2111 for (i = 0; i < num; i++)
2113 GetWindowPlacement (list[i], &placement);
2114 if (placement.showCmd == SW_SHOWNORMAL)
2116 childRegion = CreateRectRgnIndirect (&emptyRect);
2117 GetWindowRgn (list[i], childRegion);
2118 CombineRgn (region, region, childRegion, RGN_OR);
2119 DeleteObject (childRegion);
2122 SetWindowRgn (win, region, TRUE);
2125 DeleteObject (region);
2129 gdk_window_set_child_shapes (GdkWindow *window)
2131 g_return_if_fail (window != NULL);
2132 g_return_if_fail (GDK_IS_WINDOW (window));
2134 if (GDK_WINDOW_DESTROYED (window))
2137 gdk_propagate_shapes (GDK_WINDOW_HWND (window), FALSE);
2141 gdk_window_merge_child_shapes (GdkWindow *window)
2143 g_return_if_fail (window != NULL);
2144 g_return_if_fail (GDK_IS_WINDOW (window));
2146 if (GDK_WINDOW_DESTROYED (window))
2149 gdk_propagate_shapes (GDK_WINDOW_HWND (window), TRUE);
2152 /* Support for windows that can be guffaw-scrolled
2153 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2157 gdk_window_gravity_works (void)
2159 enum { UNKNOWN, NO, YES };
2160 static gint gravity_works = UNKNOWN;
2162 if (gravity_works == UNKNOWN)
2169 attr.window_type = GDK_WINDOW_TEMP;
2170 attr.wclass = GDK_INPUT_OUTPUT;
2175 attr.event_mask = 0;
2177 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2179 attr.window_type = GDK_WINDOW_CHILD;
2180 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2182 gdk_window_set_static_win_gravity (child, TRUE);
2184 gdk_window_resize (parent, 100, 110);
2185 gdk_window_move (parent, 0, -10);
2186 gdk_window_move_resize (parent, 0, 0, 100, 100);
2188 gdk_window_resize (parent, 100, 110);
2189 gdk_window_move (parent, 0, -10);
2190 gdk_window_move_resize (parent, 0, 0, 100, 100);
2192 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2194 gdk_window_destroy (parent);
2195 gdk_window_destroy (child);
2197 gravity_works = ((y == -20) ? YES : NO);
2200 return (gravity_works == YES);
2204 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2206 g_return_if_fail (window != NULL);
2208 GDK_NOTE (MISC, g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2212 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2214 g_return_if_fail (window != NULL);
2217 g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2220 /*************************************************************
2221 * gdk_window_set_static_gravities:
2222 * Set the bit gravity of the given window to static,
2223 * and flag it so all children get static subwindow
2226 * window: window for which to set static gravity
2227 * use_static: Whether to turn static gravity on or off.
2229 * Does the XServer support static gravity?
2230 *************************************************************/
2233 gdk_window_set_static_gravities (GdkWindow *window,
2234 gboolean use_static)
2236 GdkWindowObject *private = (GdkWindowObject *)window;
2239 g_return_val_if_fail (window != NULL, FALSE);
2240 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2242 if (!use_static == !private->guffaw_gravity)
2245 if (use_static && !gdk_window_gravity_works ())
2248 private->guffaw_gravity = use_static;
2250 if (!GDK_WINDOW_DESTROYED (window))
2252 gdk_window_set_static_bit_gravity (window, use_static);
2254 tmp_list = private->children;
2257 gdk_window_set_static_win_gravity (window, use_static);
2259 tmp_list = tmp_list->next;
2267 * Setting window states
2270 gdk_window_iconify (GdkWindow *window)
2272 g_return_if_fail (window != NULL);
2273 g_return_if_fail (GDK_IS_WINDOW (window));
2275 if (GDK_WINDOW_DESTROYED (window))
2278 if (GDK_WINDOW_IS_MAPPED (window))
2280 ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
2284 /* Flip our client side flag, the real work happens on map. */
2285 gdk_synthesize_window_state (window,
2287 GDK_WINDOW_STATE_ICONIFIED);
2292 gdk_window_deiconify (GdkWindow *window)
2294 g_return_if_fail (window != NULL);
2295 g_return_if_fail (GDK_IS_WINDOW (window));
2297 if (GDK_WINDOW_DESTROYED (window))
2300 if (GDK_WINDOW_IS_MAPPED (window))
2302 gdk_window_show (window);
2306 /* Flip our client side flag, the real work happens on map. */
2307 gdk_synthesize_window_state (window,
2308 GDK_WINDOW_STATE_ICONIFIED,
2314 gdk_window_stick (GdkWindow *window)
2316 g_return_if_fail (GDK_IS_WINDOW (window));
2318 if (GDK_WINDOW_DESTROYED (window))
2321 if (GDK_WINDOW_IS_MAPPED (window))
2323 /* "stick" means stick to all desktops _and_ do not scroll with the
2324 * viewport. i.e. glue to the monitor glass in all cases.
2326 g_warning ("gdk_window_stick (0x%X) ???", GDK_WINDOW_HWND (window));
2330 /* Flip our client side flag, the real work happens on map. */
2331 gdk_synthesize_window_state (window,
2333 GDK_WINDOW_STATE_STICKY);
2338 gdk_window_unstick (GdkWindow *window)
2340 g_return_if_fail (GDK_IS_WINDOW (window));
2342 if (GDK_WINDOW_DESTROYED (window))
2345 if (GDK_WINDOW_IS_MAPPED (window))
2347 g_warning ("gdk_window_unstick (0x%X) ???", GDK_WINDOW_HWND (window));
2351 /* Flip our client side flag, the real work happens on map. */
2352 gdk_synthesize_window_state (window,
2353 GDK_WINDOW_STATE_STICKY,
2360 gdk_window_maximize (GdkWindow *window)
2362 g_return_if_fail (GDK_IS_WINDOW (window));
2364 if (GDK_WINDOW_DESTROYED (window))
2367 if (GDK_WINDOW_IS_MAPPED (window))
2368 ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
2370 gdk_synthesize_window_state (window,
2372 GDK_WINDOW_STATE_MAXIMIZED);
2376 gdk_window_unmaximize (GdkWindow *window)
2378 g_return_if_fail (GDK_IS_WINDOW (window));
2380 if (GDK_WINDOW_DESTROYED (window))
2383 if (GDK_WINDOW_IS_MAPPED (window))
2384 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
2386 gdk_synthesize_window_state (window,
2387 GDK_WINDOW_STATE_MAXIMIZED,
2392 gdk_window_focus (GdkWindow *window,
2395 g_return_if_fail (GDK_IS_WINDOW (window));
2397 if (GDK_WINDOW_DESTROYED (window))
2400 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
2404 gdk_window_set_modal_hint (GdkWindow *window,
2407 GdkWindowObject *private;
2409 g_return_if_fail (window != NULL);
2410 g_return_if_fail (GDK_IS_WINDOW (window));
2412 if (GDK_WINDOW_DESTROYED (window))
2415 private = (GdkWindowObject*) window;
2417 private->modal_hint = modal;
2419 if (GDK_WINDOW_IS_MAPPED (window))
2420 if (!SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST,
2421 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE))
2422 WIN32_API_FAILED ("SetWindowPos");
2426 gdk_window_set_type_hint (GdkWindow *window,
2427 GdkWindowTypeHint hint)
2431 g_return_if_fail (window != NULL);
2432 g_return_if_fail (GDK_IS_WINDOW (window));
2434 if (GDK_WINDOW_DESTROYED (window))
2439 case GDK_WINDOW_TYPE_HINT_DIALOG:
2440 atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_DIALOG", FALSE);
2442 case GDK_WINDOW_TYPE_HINT_MENU:
2443 atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_MENU", FALSE);
2445 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
2446 atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_TOOLBAR", FALSE);
2449 g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
2451 case GDK_WINDOW_TYPE_HINT_NORMAL:
2452 atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_NORMAL", FALSE);
2459 g_print ("gdk_window_set_type_hint (0x%0X)\n",
2460 GDK_WINDOW_HWND (window)));
2464 gdk_window_shape_combine_region (GdkWindow *window,
2465 GdkRegion *shape_region,
2469 gint xoffset, yoffset;
2471 g_return_if_fail (GDK_IS_WINDOW (window));
2473 if (GDK_WINDOW_DESTROYED (window))
2476 /* XXX: even on X implemented conditional ... */
2480 gdk_window_begin_resize_drag (GdkWindow *window,
2487 g_return_if_fail (GDK_IS_WINDOW (window));
2489 if (GDK_WINDOW_DESTROYED (window))
2492 /* XXX: isn't all this default on win32 ... */
2496 gdk_window_begin_move_drag (GdkWindow *window,
2502 g_return_if_fail (GDK_IS_WINDOW (window));
2504 if (GDK_WINDOW_DESTROYED (window))
2507 /* XXX: isn't all this default on win32 ... */