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 Library 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 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library 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-1999. 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/.
33 #include "gdkevents.h"
34 #include "gdkpixmap.h"
35 #include "gdkwindow.h"
36 #include "gdkprivate.h"
37 #include "gdkinputprivate.h"
39 /* The Win API function AdjustWindowRect may return negative values
40 * resulting in obscured title bars. This helper function is coreccting it.
43 SafeAdjustWindowRectEx (RECT* lpRect,
48 if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
52 lpRect->right -= lpRect->left;
57 lpRect->bottom -= lpRect->top;
63 /* Forward declarations */
64 static gboolean gdk_window_gravity_works (void);
65 static void gdk_window_set_static_win_gravity (GdkWindow *window,
69 * The following fucntion by The Rasterman <raster@redhat.com>
70 * This function returns the X Window ID in which the x y location is in
71 * (x and y being relative to the root window), excluding any windows listed
72 * in the GList excludes (this is a list of X Window ID's - gpointer being
75 * This is primarily designed for internal gdk use - for DND for example
76 * when using a shaped icon window as the drag object - you exclude the
77 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
78 * You can get back an X Window ID as to what X Window ID is infact under
79 * those X,Y co-ordinates.
82 gdk_window_xid_at_coords (gint x,
88 gboolean warned = FALSE;
92 /* This is probably not correct, just a quick hack */
96 g_warning ("gdk_window_xid_at_coords probably not implemented correctly");
101 return WindowFromPoint (pt);
105 gdk_window_init (void)
110 width = GetSystemMetrics (SM_CXSCREEN);
111 height = GetSystemMetrics (SM_CYSCREEN);
113 { RECT r; /* //HB: don't obscure tray window (task bar) */
114 SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
115 width = r.right - r.left;
116 height = r.bottom - r.top;
120 gdk_root_parent.xwindow = gdk_root_window;
121 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
122 gdk_root_parent.window.user_data = NULL;
123 gdk_root_parent.width = width;
124 gdk_root_parent.height = height;
125 gdk_root_parent.children = NULL;
126 gdk_root_parent.colormap = NULL;
127 gdk_root_parent.ref_count = 1;
129 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
133 * is a wrapper function for RegisterWindowClassEx.
134 * It creates at least one unique class for every
135 * GdkWindowType. If support for single window-specific icons
136 * is ever needed (e.g Dialog specific), every such window should
140 RegisterGdkClass(GdkWindowType wtype)
142 static ATOM klassTOPLEVEL = 0;
143 static ATOM klassDIALOG = 0;
144 static ATOM klassCHILD = 0;
145 static ATOM klassTEMP = 0;
146 static HICON hAppIcon = NULL;
147 static WNDCLASSEX wcl;
150 wcl.cbSize = sizeof(WNDCLASSEX);
151 wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
152 * on WM_SIZE and WM_MOVE. Flicker, Performance!
154 wcl.lpfnWndProc = gdk_WindowProc;
157 wcl.hInstance = gdk_ProgInstance;
159 /* initialize once! */
162 gchar sLoc [_MAX_PATH+1];
163 HINSTANCE hInst = GetModuleHandle(NULL);
165 if (0 != GetModuleFileName(hInst, sLoc, _MAX_PATH))
167 hAppIcon = ExtractIcon(hInst, sLoc, 0);
170 char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
172 hAppIcon = ExtractIcon(hInst, gdklibname, 0);
177 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
181 wcl.lpszMenuName = NULL;
184 /* initialize once per class */
185 #define ONCE_PER_CLASS() \
186 wcl.hIcon = CopyIcon (hAppIcon); \
187 wcl.hIconSm = CopyIcon (hAppIcon); \
188 wcl.hbrBackground = CreateSolidBrush( RGB(0,0,0)); \
189 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
193 case GDK_WINDOW_TOPLEVEL:
194 if (0 == klassTOPLEVEL)
196 wcl.lpszClassName = "gdkWindowToplevel";
199 klassTOPLEVEL = RegisterClassEx(&wcl);
201 klass = klassTOPLEVEL;
203 case GDK_WINDOW_CHILD:
206 wcl.lpszClassName = "gdkWindowChild";
208 wcl.style |= CS_PARENTDC; /* MSDN: ... enhances system performance. */
210 klassCHILD = RegisterClassEx(&wcl);
214 case GDK_WINDOW_DIALOG:
215 if (0 == klassDIALOG)
217 wcl.lpszClassName = "gdkWindowDialog";
218 wcl.style |= CS_SAVEBITS;
220 klassDIALOG = RegisterClassEx(&wcl);
224 case GDK_WINDOW_TEMP:
227 wcl.lpszClassName = "gdkWindowTemp";
228 wcl.style |= CS_SAVEBITS;
230 klassTEMP = RegisterClassEx(&wcl);
234 case GDK_WINDOW_ROOT:
235 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
237 case GDK_WINDOW_PIXMAP:
238 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
243 } /* RegisterGdkClass */
247 gdk_window_new (GdkWindow *parent,
248 GdkWindowAttr *attributes,
249 gint attributes_mask)
252 GdkWindowPrivate *private;
253 GdkWindowPrivate *parent_private;
258 DWORD dwStyle, dwExStyle;
264 g_return_val_if_fail (attributes != NULL, NULL);
267 parent = (GdkWindow*) &gdk_root_parent;
269 parent_private = (GdkWindowPrivate*) parent;
270 if (parent_private->destroyed)
273 xparent = parent_private->xwindow;
275 private = g_new (GdkWindowPrivate, 1);
276 window = (GdkWindow*) private;
278 private->parent = parent;
280 private->destroyed = FALSE;
281 private->mapped = FALSE;
282 private->guffaw_gravity = FALSE;
283 private->resize_count = 0;
284 private->ref_count = 1;
286 private->x = (attributes_mask & GDK_WA_X) ? attributes->x : 0;
287 private->y = (attributes_mask & GDK_WA_Y) ? attributes->y : 0;
289 private->width = (attributes->width > 1) ? (attributes->width) : (1);
290 private->height = (attributes->height > 1) ? (attributes->height) : (1);
291 private->window_type = attributes->window_type;
292 private->extension_events = 0;
293 private->extension_events_selected = FALSE;
295 private->filters = NULL;
296 private->children = NULL;
298 window->user_data = NULL;
300 if (attributes_mask & GDK_WA_VISUAL)
301 visual = attributes->visual;
303 visual = gdk_visual_get_system ();
304 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
306 if (attributes_mask & GDK_WA_TITLE)
307 title = attributes->title;
309 title = g_get_prgname ();
311 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
312 private->bg_type = GDK_WIN32_BG_NORMAL;
313 private->hint_flags = 0;
314 private->xcursor = NULL;
316 if (parent_private && parent_private->guffaw_gravity)
321 if (attributes->wclass == GDK_INPUT_OUTPUT)
324 if (attributes_mask & GDK_WA_COLORMAP)
325 private->colormap = attributes->colormap;
327 private->colormap = gdk_colormap_get_system ();
331 dwExStyle = WS_EX_TRANSPARENT;
332 private->colormap = NULL;
333 private->bg_type = GDK_WIN32_BG_TRANSPARENT;
334 private->bg_pixmap = NULL;
337 if (attributes_mask & GDK_WA_X)
342 if (attributes_mask & GDK_WA_Y)
344 else if (attributes_mask & GDK_WA_X)
345 y = 100; /* ??? We must put it somewhere... */
347 y = 500; /* x is CW_USEDEFAULT, y doesn't matter then */
350 parent_private->children = g_list_prepend (parent_private->children, window);
352 switch (private->window_type)
354 case GDK_WINDOW_TOPLEVEL:
355 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
356 xparent = gdk_root_window;
358 case GDK_WINDOW_CHILD:
359 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
361 case GDK_WINDOW_DIALOG:
362 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
363 dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
364 xparent = gdk_root_window;
366 case GDK_WINDOW_TEMP:
367 dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
368 dwExStyle |= WS_EX_TOOLWINDOW;
370 case GDK_WINDOW_ROOT:
371 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
373 case GDK_WINDOW_PIXMAP:
374 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
378 klass = RegisterGdkClass (private->window_type);
380 g_error ("RegisterClassEx failed");
382 if (private->window_type != GDK_WINDOW_CHILD)
384 if (x == CW_USEDEFAULT)
395 rect.right = rect.left + private->width;
396 rect.bottom = rect.top + private->height;
398 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
399 g_warning ("gdk_window_new: AdjustWindowRectEx failed");
401 if (x != CW_USEDEFAULT)
406 width = rect.right - rect.left;
407 height = rect.bottom - rect.top;
411 width = private->width;
412 height = private->height;
416 CreateWindowEx (dwExStyle,
417 MAKEINTRESOURCE(klass),
427 g_print ("gdk_window_create: %s %s %#x %#x %dx%d@+%d+%d %#x = %#x\n",
428 (private->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
429 (private->window_type == GDK_WINDOW_CHILD ? "CHILD" :
430 (private->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
431 (private->window_type == GDK_WINDOW_TEMP ? "TEMP" :
436 width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
440 gdk_window_ref (window);
441 gdk_xid_table_insert (&private->xwindow, window);
443 if (private->colormap)
444 gdk_colormap_ref (private->colormap);
446 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
447 (attributes->cursor) :
454 gdk_window_foreign_new (guint32 anid)
457 GdkWindowPrivate *private;
458 GdkWindowPrivate *parent_private;
463 private = g_new (GdkWindowPrivate, 1);
464 window = (GdkWindow*) private;
466 parent = GetParent ((HWND) anid);
467 private->parent = gdk_xid_table_lookup (parent);
469 parent_private = (GdkWindowPrivate *)private->parent;
472 parent_private->children = g_list_prepend (parent_private->children, window);
474 private->xwindow = (HWND) anid;
475 GetClientRect ((HWND) anid, &rect);
477 point.y = rect.right;
478 ClientToScreen ((HWND) anid, &point);
479 if (parent != HWND_DESKTOP)
480 ScreenToClient (parent, &point);
481 private->x = point.x;
482 private->y = point.y;
483 private->width = rect.right - rect.left;
484 private->height = rect.bottom - rect.top;
485 private->resize_count = 0;
486 private->ref_count = 1;
487 private->window_type = GDK_WINDOW_FOREIGN;
488 private->destroyed = FALSE;
489 private->mapped = IsWindowVisible (private->xwindow);
490 private->guffaw_gravity = FALSE;
491 private->extension_events = 0;
492 private->extension_events_selected = FALSE;
494 private->colormap = NULL;
496 private->filters = NULL;
497 private->children = NULL;
499 window->user_data = NULL;
501 gdk_window_ref (window);
502 gdk_xid_table_insert (&private->xwindow, window);
507 /* Call this function when you want a window and all its children to
508 * disappear. When xdestroy is true, a request to destroy the XWindow
509 * is sent out. When it is false, it is assumed that the XWindow has
510 * been or will be destroyed by destroying some ancestor of this
514 gdk_window_internal_destroy (GdkWindow *window,
516 gboolean our_destroy)
518 GdkWindowPrivate *private;
519 GdkWindowPrivate *temp_private;
520 GdkWindow *temp_window;
524 g_return_if_fail (window != NULL);
526 private = (GdkWindowPrivate*) window;
528 GDK_NOTE (MISC, g_print ("gdk_window_internal_destroy %#x\n",
531 switch (private->window_type)
533 case GDK_WINDOW_TOPLEVEL:
534 case GDK_WINDOW_CHILD:
535 case GDK_WINDOW_DIALOG:
536 case GDK_WINDOW_TEMP:
537 case GDK_WINDOW_FOREIGN:
538 if (!private->destroyed)
542 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
543 if (parent_private->children)
544 parent_private->children = g_list_remove (parent_private->children, window);
547 if (private->window_type != GDK_WINDOW_FOREIGN)
549 children = tmp = private->children;
550 private->children = NULL;
554 temp_window = tmp->data;
557 temp_private = (GdkWindowPrivate*) temp_window;
559 gdk_window_internal_destroy (temp_window, FALSE,
563 g_list_free (children);
566 if (private->extension_events != 0)
567 gdk_input_window_destroy (window);
569 if (private->filters)
571 tmp = private->filters;
579 g_list_free (private->filters);
580 private->filters = NULL;
583 if (private->window_type == GDK_WINDOW_FOREIGN)
585 if (our_destroy && (private->parent != NULL))
587 /* It's somebody elses window, but in our hierarchy,
588 * so reparent it to the root window, and then send
589 * it a delete event, as if we were a WM
591 gdk_window_hide (window);
592 gdk_window_reparent (window, NULL, 0, 0);
594 /* Is this too drastic? Many (most?) applications
595 * quit if any window receives WM_QUIT I think.
596 * OTOH, I don't think foreign windows are much
597 * used, so the question is maybe academic.
599 PostMessage (private->xwindow, WM_QUIT, 0, 0);
603 DestroyWindow (private->xwindow);
605 if (private->colormap)
606 gdk_colormap_unref (private->colormap);
608 private->mapped = FALSE;
609 private->destroyed = TRUE;
613 case GDK_WINDOW_ROOT:
614 g_error ("attempted to destroy root window");
617 case GDK_WINDOW_PIXMAP:
618 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
623 /* Like internal_destroy, but also destroys the reference created by
627 gdk_window_destroy (GdkWindow *window)
629 gdk_window_internal_destroy (window, TRUE, TRUE);
630 gdk_window_unref (window);
633 /* This function is called when the XWindow is really gone. */
636 gdk_window_destroy_notify (GdkWindow *window)
638 GdkWindowPrivate *private;
640 g_return_if_fail (window != NULL);
642 private = (GdkWindowPrivate*) window;
644 GDK_NOTE (EVENTS, g_print ("gdk_window_destroy_notify: %#x %d\n",
645 private->xwindow, private->destroyed));
647 if (!private->destroyed)
649 if (private->window_type == GDK_WINDOW_FOREIGN)
650 gdk_window_internal_destroy (window, FALSE, FALSE);
652 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
655 gdk_xid_table_remove (private->xwindow);
656 gdk_window_unref (window);
660 gdk_window_ref (GdkWindow *window)
662 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
663 g_return_val_if_fail (window != NULL, NULL);
665 private->ref_count += 1;
667 GDK_NOTE (MISC, g_print ("gdk_window_ref %#x %d\n",
668 private->xwindow, private->ref_count));
674 gdk_window_unref (GdkWindow *window)
676 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
677 g_return_if_fail (window != NULL);
679 private->ref_count -= 1;
681 GDK_NOTE (MISC, g_print ("gdk_window_unref %#x %d%s\n",
682 private->xwindow, private->ref_count,
683 (private->ref_count == 0 ? " freeing" : "")));
685 if (private->ref_count == 0)
687 if (private->bg_type == GDK_WIN32_BG_PIXMAP && private->bg_pixmap != NULL)
688 gdk_pixmap_unref (private->bg_pixmap);
690 if (!private->destroyed)
692 if (private->window_type == GDK_WINDOW_FOREIGN)
693 gdk_xid_table_remove (private->xwindow);
695 g_warning ("losing last reference to undestroyed window");
697 g_dataset_destroy (window);
703 gdk_window_show (GdkWindow *window)
705 GdkWindowPrivate *private;
707 g_return_if_fail (window != NULL);
709 private = (GdkWindowPrivate*) window;
710 if (!private->destroyed)
712 GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n", private->xwindow));
714 private->mapped = TRUE;
715 if (private->window_type == GDK_WINDOW_TEMP)
717 ShowWindow (private->xwindow, SW_SHOWNOACTIVATE);
718 SetWindowPos (private->xwindow, HWND_TOPMOST, 0, 0, 0, 0,
719 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
721 ShowWindow (private->xwindow, SW_HIDE); /* Don't put on toolbar */
726 ShowWindow (private->xwindow, SW_SHOWNORMAL);
727 ShowWindow (private->xwindow, SW_RESTORE);
728 SetForegroundWindow (private->xwindow);
730 ShowOwnedPopups (private->xwindow, TRUE);
737 gdk_window_hide (GdkWindow *window)
739 GdkWindowPrivate *private;
741 g_return_if_fail (window != NULL);
743 private = (GdkWindowPrivate*) window;
744 if (!private->destroyed)
746 GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n", private->xwindow));
748 private->mapped = FALSE;
749 if (private->window_type == GDK_WINDOW_TOPLEVEL)
750 ShowOwnedPopups (private->xwindow, FALSE);
752 ShowWindow (private->xwindow, SW_HIDE);
754 ShowWindow (private->xwindow, SW_MINIMIZE);
756 CloseWindow (private->xwindow);
762 gdk_window_withdraw (GdkWindow *window)
764 GdkWindowPrivate *private;
766 g_return_if_fail (window != NULL);
768 private = (GdkWindowPrivate*) window;
769 if (!private->destroyed)
771 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n", private->xwindow));
773 gdk_window_hide (window); /* XXX */
778 gdk_window_move (GdkWindow *window,
782 GdkWindowPrivate *private;
784 g_return_if_fail (window != NULL);
786 private = (GdkWindowPrivate*) window;
787 if (!private->destroyed)
791 GDK_NOTE (MISC, g_print ("gdk_window_move: %#x +%d+%d\n",
792 private->xwindow, x, y));
794 GetClientRect (private->xwindow, &rect);
796 if (private->window_type != GDK_WINDOW_CHILD)
804 ClientToScreen (private->xwindow, &ptTL);
809 ptBR.y = rect.bottom;
810 ClientToScreen (private->xwindow, &ptBR);
811 rect.right = x + ptBR.x - ptTL.x;
812 rect.bottom = y + ptBR.y - ptTL.y;
814 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
815 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
816 if (!SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
817 g_warning ("gdk_window_move: AdjustWindowRectEx failed");
827 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
829 rect.right - rect.left, rect.bottom - rect.top,
831 if (!MoveWindow (private->xwindow,
832 x, y, rect.right - rect.left, rect.bottom - rect.top,
834 g_warning ("gdk_window_move: MoveWindow failed");
839 gdk_window_resize (GdkWindow *window,
843 GdkWindowPrivate *private;
845 g_return_if_fail (window != NULL);
847 if ((gint16) width < 1)
849 if ((gint16) height < 1)
852 private = (GdkWindowPrivate*) window;
854 if (!private->destroyed &&
855 ((private->resize_count > 0) ||
856 (private->width != (guint16) width) ||
857 (private->height != (guint16) height)))
861 GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
862 private->xwindow, width, height));
864 if (private->window_type != GDK_WINDOW_CHILD)
873 ClientToScreen (private->xwindow, &pt);
876 rect.right = pt.x + width;
877 rect.bottom = pt.y + height;
879 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
880 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
881 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
882 g_warning ("gdk_window_resize: AdjustWindowRectEx failed");
886 width = rect.right - rect.left;
887 height = rect.bottom - rect.top;
893 private->width = width;
894 private->height = height;
897 private->resize_count += 1;
899 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
900 private->xwindow, width, height, x, y));
901 if (!MoveWindow (private->xwindow,
904 g_warning ("gdk_window_resize: MoveWindow failed");
909 gdk_window_move_resize (GdkWindow *window,
915 GdkWindowPrivate *private;
917 g_return_if_fail (window != NULL);
919 if ((gint16) width < 1)
921 if ((gint16) height < 1)
924 private = (GdkWindowPrivate*) window;
925 if (!private->destroyed)
931 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
932 private->xwindow, width, height, x, y));
936 rect.right = x + width;
937 rect.bottom = y + height;
939 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
940 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
941 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
942 g_warning ("gdk_window_move_resize: AdjustWindowRectEx failed");
944 if (private->window_type == GDK_WINDOW_CHILD)
948 private->width = width;
949 private->height = height;
951 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
953 rect.right - rect.left, rect.bottom - rect.top,
954 rect.left, rect.top));
955 if (!MoveWindow (private->xwindow,
957 rect.right - rect.left, rect.bottom - rect.top,
959 g_warning ("gdk_window_move_resize: MoveWindow failed");
961 if (private->guffaw_gravity)
963 GList *tmp_list = private->children;
966 GdkWindowPrivate *child_private = tmp_list->data;
968 child_private->x -= x - private->x;
969 child_private->y -= y - private->y;
971 tmp_list = tmp_list->next;
979 gdk_window_reparent (GdkWindow *window,
980 GdkWindow *new_parent,
984 GdkWindowPrivate *window_private;
985 GdkWindowPrivate *parent_private;
986 GdkWindowPrivate *old_parent_private;
988 g_return_if_fail (window != NULL);
991 new_parent = (GdkWindow*) &gdk_root_parent;
993 window_private = (GdkWindowPrivate*) window;
994 old_parent_private = (GdkWindowPrivate*)window_private->parent;
995 parent_private = (GdkWindowPrivate*) new_parent;
997 if (!window_private->destroyed && !parent_private->destroyed)
999 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
1000 window_private->xwindow,
1001 parent_private->xwindow));
1002 if (!SetParent (window_private->xwindow, parent_private->xwindow))
1003 g_warning ("gdk_window_reparent: SetParent failed");
1005 if (!MoveWindow (window_private->xwindow,
1007 window_private->width, window_private->height,
1009 g_warning ("gdk_window_reparent: MoveWindow failed");
1012 window_private->parent = new_parent;
1014 if (old_parent_private)
1015 old_parent_private->children = g_list_remove (old_parent_private->children, window);
1017 if ((old_parent_private &&
1018 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1019 (!old_parent_private && parent_private->guffaw_gravity))
1020 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1022 parent_private->children = g_list_prepend (parent_private->children, window);
1026 gdk_window_clear (GdkWindow *window)
1028 GdkWindowPrivate *private;
1030 g_return_if_fail (window != NULL);
1032 private = (GdkWindowPrivate*) window;
1034 if (!private->destroyed)
1036 gdk_window_clear_area (window, 0, 0, private->width, private->height);
1042 gdk_window_clear_area (GdkWindow *window,
1048 GdkWindowPrivate *private;
1050 g_return_if_fail (window != NULL);
1052 private = (GdkWindowPrivate*) window;
1054 if (!private->destroyed)
1059 width = G_MAXSHORT/2; /* Yeah, right */
1061 height = G_MAXSHORT/2;
1062 GDK_NOTE (MISC, g_print ("gdk_window_clear_area: %#x %dx%d@+%d+%d\n",
1063 private->xwindow, width, height, x, y));
1064 hdc = GetDC (private->xwindow);
1065 IntersectClipRect (hdc, x, y, x + width, y + height);
1066 SendMessage (private->xwindow, WM_ERASEBKGND, (WPARAM) hdc, 0);
1067 ReleaseDC (private->xwindow, hdc);
1072 gdk_window_clear_area_e (GdkWindow *window,
1078 GdkWindowPrivate *private;
1080 g_return_if_fail (window != NULL);
1082 private = (GdkWindowPrivate*) window;
1084 if (!private->destroyed)
1088 GDK_NOTE (MISC, g_print ("gdk_window_clear_area_e: %#x %dx%d@+%d+%d\n",
1089 private->xwindow, width, height, x, y));
1092 rect.right = x + width;
1094 rect.bottom = y + height;
1095 if (!InvalidateRect (private->xwindow, &rect, TRUE))
1096 g_warning ("gdk_window_clear_area_e: InvalidateRect failed");
1097 UpdateWindow (private->xwindow);
1102 gdk_window_copy_area (GdkWindow *window,
1106 GdkWindow *source_window,
1112 GdkWindowPrivate *src_private;
1113 GdkWindowPrivate *dest_private;
1114 GdkGCPrivate *gc_private;
1116 g_return_if_fail (window != NULL);
1117 g_return_if_fail (gc != NULL);
1119 if (source_window == NULL)
1120 source_window = window;
1122 src_private = (GdkWindowPrivate*) source_window;
1123 dest_private = (GdkWindowPrivate*) window;
1124 gc_private = (GdkGCPrivate*) gc;
1126 if (!src_private->destroyed && !dest_private->destroyed)
1128 HDC hdcDest, hdcSrc;
1130 if ((hdcDest = GetDC (dest_private->xwindow)) == NULL)
1131 g_warning ("gdk_window_copy_area: GetDC failed");
1133 if ((hdcSrc = GetDC (src_private->xwindow)) == NULL)
1134 g_warning ("gdk_window_copy_area: GetDC failed");
1136 if (!BitBlt (hdcDest, x, y, width, height, hdcSrc, source_x, source_y, SRCCOPY))
1137 g_warning ("gdk_window_copy_area: BitBlt failed");
1139 ReleaseDC (dest_private->xwindow, hdcDest);
1140 ReleaseDC (src_private->xwindow, hdcSrc);
1145 gdk_window_raise (GdkWindow *window)
1147 GdkWindowPrivate *private;
1149 g_return_if_fail (window != NULL);
1151 private = (GdkWindowPrivate*) window;
1153 if (!private->destroyed)
1155 GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n", private->xwindow));
1157 if (!BringWindowToTop (private->xwindow))
1158 g_warning ("gdk_window_raise: BringWindowToTop failed");
1163 gdk_window_lower (GdkWindow *window)
1165 GdkWindowPrivate *private;
1167 g_return_if_fail (window != NULL);
1169 private = (GdkWindowPrivate*) window;
1171 if (!private->destroyed)
1173 GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n", private->xwindow));
1175 if (!SetWindowPos (private->xwindow, HWND_BOTTOM, 0, 0, 0, 0,
1176 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1177 g_warning ("gdk_window_lower: SetWindowPos failed");
1182 gdk_window_set_user_data (GdkWindow *window,
1185 g_return_if_fail (window != NULL);
1187 window->user_data = user_data;
1191 gdk_window_set_hints (GdkWindow *window,
1200 GdkWindowPrivate *private;
1201 WINDOWPLACEMENT size_hints;
1207 g_return_if_fail (window != NULL);
1209 private = (GdkWindowPrivate*) window;
1210 if (private->destroyed)
1213 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1215 min_width, min_height, max_width, max_height,
1218 private->hint_flags = flags;
1219 size_hints.length = sizeof (size_hints);
1223 if (flags & GDK_HINT_POS)
1224 if (!GetWindowPlacement (private->xwindow, &size_hints))
1225 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1228 GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1229 " (%d,%d)--(%d,%d)\n",
1230 size_hints.rcNormalPosition.left,
1231 size_hints.rcNormalPosition.top,
1232 size_hints.rcNormalPosition.right,
1233 size_hints.rcNormalPosition.bottom));
1234 /* What are the corresponding window coordinates for client
1235 * area coordinates x, y
1239 rect.right = rect.left + 200; /* dummy */
1240 rect.bottom = rect.top + 200;
1241 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1242 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1243 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1244 size_hints.flags = 0;
1245 size_hints.showCmd = SW_SHOWNA;
1247 /* Set the normal position hint to that location, with unchanged
1250 diff = size_hints.rcNormalPosition.left - rect.left;
1251 size_hints.rcNormalPosition.left = rect.left;
1252 size_hints.rcNormalPosition.right -= diff;
1253 diff = size_hints.rcNormalPosition.top - rect.top;
1254 size_hints.rcNormalPosition.top = rect.top;
1255 size_hints.rcNormalPosition.bottom -= diff;
1256 GDK_NOTE (MISC, g_print ("...setting: (%d,%d)--(%d,%d)\n",
1257 size_hints.rcNormalPosition.left,
1258 size_hints.rcNormalPosition.top,
1259 size_hints.rcNormalPosition.right,
1260 size_hints.rcNormalPosition.bottom));
1261 if (!SetWindowPlacement (private->xwindow, &size_hints))
1262 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1263 private->hint_x = rect.left;
1264 private->hint_y = rect.top;
1267 if (flags & GDK_HINT_MIN_SIZE)
1271 rect.right = min_width;
1272 rect.bottom = min_height;
1273 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1274 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1275 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1276 private->hint_min_width = rect.right - rect.left;
1277 private->hint_min_height = rect.bottom - rect.top;
1279 /* Also chek if he current size of the window is in bounds. */
1280 GetClientRect (private->xwindow, &rect);
1281 if (rect.right < min_width && rect.bottom < min_height)
1282 gdk_window_resize (window, min_width, min_height);
1283 else if (rect.right < min_width)
1284 gdk_window_resize (window, min_width, rect.bottom);
1285 else if (rect.bottom < min_height)
1286 gdk_window_resize (window, rect.right, min_height);
1288 if (flags & GDK_HINT_MAX_SIZE)
1292 rect.right = max_width;
1293 rect.bottom = max_height;
1294 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1295 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1296 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1297 private->hint_max_width = rect.right - rect.left;
1298 private->hint_max_height = rect.bottom - rect.top;
1299 /* Again, check if the window is too large currently. */
1300 GetClientRect (private->xwindow, &rect);
1301 if (rect.right > max_width && rect.bottom > max_height)
1302 gdk_window_resize (window, max_width, max_height);
1303 else if (rect.right > max_width)
1304 gdk_window_resize (window, max_width, rect.bottom);
1305 else if (rect.bottom > max_height)
1306 gdk_window_resize (window, rect.right, max_height);
1312 gdk_window_set_geometry_hints (GdkWindow *window,
1313 GdkGeometry *geometry,
1314 GdkWindowHints geom_mask)
1316 GdkWindowPrivate *private;
1317 WINDOWPLACEMENT size_hints;
1323 g_return_if_fail (window != NULL);
1325 private = (GdkWindowPrivate*) window;
1326 if (private->destroyed)
1329 size_hints.length = sizeof (size_hints);
1331 private->hint_flags = geom_mask;
1333 if (geom_mask & GDK_HINT_POS)
1336 if (geom_mask & GDK_HINT_MIN_SIZE)
1340 rect.right = geometry->min_width;
1341 rect.bottom = geometry->min_height;
1342 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1343 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1344 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1345 private->hint_min_width = rect.right - rect.left;
1346 private->hint_min_height = rect.bottom - rect.top;
1348 /* Also check if he current size of the window is in bounds */
1349 GetClientRect (private->xwindow, &rect);
1350 if (rect.right < geometry->min_width
1351 && rect.bottom < geometry->min_height)
1352 gdk_window_resize (window, geometry->min_width, geometry->min_height);
1353 else if (rect.right < geometry->min_width)
1354 gdk_window_resize (window, geometry->min_width, rect.bottom);
1355 else if (rect.bottom < geometry->min_height)
1356 gdk_window_resize (window, rect.right, geometry->min_height);
1359 if (geom_mask & GDK_HINT_MAX_SIZE)
1363 rect.right = geometry->max_width;
1364 rect.bottom = geometry->max_height;
1365 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1366 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1367 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1368 private->hint_max_width = rect.right - rect.left;
1369 private->hint_max_height = rect.bottom - rect.top;
1371 /* Again, check if the window is too large currently. */
1372 GetClientRect (private->xwindow, &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)
1386 if (!GetWindowPlacement (private->xwindow, &size_hints))
1387 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1390 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1391 " rcNormalPosition: (%d,%d)--(%d,%d)\n",
1392 size_hints.rcNormalPosition.left,
1393 size_hints.rcNormalPosition.top,
1394 size_hints.rcNormalPosition.right,
1395 size_hints.rcNormalPosition.bottom));
1396 size_hints.rcNormalPosition.right =
1397 size_hints.rcNormalPosition.left + geometry->base_width;
1398 size_hints.rcNormalPosition.bottom =
1399 size_hints.rcNormalPosition.top + geometry->base_height;
1400 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
1401 size_hints.rcNormalPosition.left,
1402 size_hints.rcNormalPosition.top,
1403 size_hints.rcNormalPosition.right,
1404 size_hints.rcNormalPosition.bottom));
1405 if (!SetWindowPlacement (private->xwindow, &size_hints))
1406 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1409 if (geom_mask & GDK_HINT_RESIZE_INC)
1414 if (geom_mask & GDK_HINT_ASPECT)
1421 gdk_window_set_title (GdkWindow *window,
1424 GdkWindowPrivate *private;
1426 g_return_if_fail (window != NULL);
1428 private = (GdkWindowPrivate*) window;
1429 GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
1430 private->xwindow, title));
1431 if (!private->destroyed)
1433 if (!SetWindowText (private->xwindow, title))
1434 g_warning ("gdk_window_set_title: SetWindowText failed");
1439 gdk_window_set_role (GdkWindow *window,
1442 GdkWindowPrivate *private;
1444 g_return_if_fail (window != NULL);
1446 private = (GdkWindowPrivate*) window;
1448 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1449 private->xwindow, (role ? role : "NULL")));
1454 gdk_window_set_transient_for (GdkWindow *window,
1457 GdkWindowPrivate *private;
1458 GdkWindowPrivate *parent_private;
1460 g_return_if_fail (window != NULL);
1462 private = (GdkWindowPrivate*) window;
1463 parent_private = (GdkWindowPrivate*) parent;
1465 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1466 private->xwindow, parent_private->xwindow));
1471 gdk_window_set_background (GdkWindow *window,
1474 GdkWindowPrivate *private;
1476 g_return_if_fail (window != NULL);
1478 private = (GdkWindowPrivate*) window;
1479 if (!private->destroyed)
1481 GdkColormapPrivate *colormap_private =
1482 (GdkColormapPrivate *) private->colormap;
1484 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1486 gdk_color_to_string (color)));
1488 if (private->bg_type == GDK_WIN32_BG_PIXMAP)
1490 if (private->bg_pixmap != NULL)
1492 gdk_pixmap_unref (private->bg_pixmap);
1493 private->bg_pixmap = NULL;
1495 private->bg_type = GDK_WIN32_BG_NORMAL;
1497 private->bg_type = GDK_WIN32_BG_PIXEL;
1498 private->bg_pixel = *color;
1503 gdk_window_set_back_pixmap (GdkWindow *window,
1505 gint parent_relative)
1507 GdkWindowPrivate *window_private;
1509 g_return_if_fail (window != NULL);
1511 window_private = (GdkWindowPrivate*) window;
1513 if (!window_private->destroyed)
1515 GdkColormapPrivate *colormap_private =
1516 (GdkColormapPrivate *) window_private->colormap;
1517 if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
1519 if (window_private->bg_pixmap != NULL)
1521 gdk_pixmap_unref (window_private->bg_pixmap);
1522 window_private->bg_pixmap = NULL;
1524 window_private->bg_type = GDK_WIN32_BG_NORMAL;
1526 if (parent_relative)
1528 window_private->bg_type = GDK_WIN32_BG_PARENT_RELATIVE;
1536 /* We must cache the pixmap in the WindowPrivate and
1537 * paint it each time we get WM_ERASEBKGND
1539 window_private->bg_type = GDK_WIN32_BG_PIXMAP;
1540 window_private->bg_pixmap = pixmap;
1541 gdk_pixmap_ref (pixmap);
1547 gdk_window_set_cursor (GdkWindow *window,
1550 GdkWindowPrivate *window_private;
1551 GdkCursorPrivate *cursor_private;
1554 g_return_if_fail (window != NULL);
1556 window_private = (GdkWindowPrivate*) window;
1557 cursor_private = (GdkCursorPrivate*) cursor;
1559 if (!window_private->destroyed)
1562 xcursor = LoadCursor (NULL, IDC_ARROW);
1564 xcursor = cursor_private->xcursor;
1566 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1567 window_private->xwindow, xcursor));
1568 window_private->xcursor = xcursor;
1569 SetCursor (xcursor);
1574 gdk_window_set_colormap (GdkWindow *window,
1575 GdkColormap *colormap)
1577 GdkWindowPrivate *window_private;
1578 GdkColormapPrivate *colormap_private;
1580 g_return_if_fail (window != NULL);
1581 g_return_if_fail (colormap != NULL);
1583 window_private = (GdkWindowPrivate*) window;
1584 colormap_private = (GdkColormapPrivate*) colormap;
1586 if (!window_private->destroyed)
1589 GDK_NOTE (MISC, g_print ("gdk_window_set_colormap: %#x %#x\n",
1590 window_private->xwindow,
1591 colormap_private->xcolormap));
1592 if (window_private->colormap)
1593 gdk_colormap_unref (window_private->colormap);
1594 window_private->colormap = colormap;
1595 gdk_colormap_ref (window_private->colormap);
1597 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1598 gdk_window_add_colormap_windows (window);
1603 gdk_window_get_user_data (GdkWindow *window,
1606 g_return_if_fail (window != NULL);
1608 *data = window->user_data;
1612 gdk_window_get_geometry (GdkWindow *window,
1619 GdkWindowPrivate *window_private;
1622 window = (GdkWindow*) &gdk_root_parent;
1624 window_private = (GdkWindowPrivate*) window;
1626 if (!window_private->destroyed)
1630 if (!GetClientRect (window_private->xwindow, &rect))
1631 g_warning ("gdk_window_get_geometry: GetClientRect failed");
1638 *width = rect.right - rect.left;
1640 *height = rect.bottom - rect.top;
1642 *depth = gdk_window_get_visual (window)->depth;
1647 gdk_window_get_position (GdkWindow *window,
1651 GdkWindowPrivate *window_private;
1653 g_return_if_fail (window != NULL);
1655 window_private = (GdkWindowPrivate*) window;
1658 *x = window_private->x;
1660 *y = window_private->y;
1664 gdk_window_get_size (GdkWindow *window,
1668 GdkWindowPrivate *window_private;
1670 g_return_if_fail (window != NULL);
1672 window_private = (GdkWindowPrivate*) window;
1675 *width = window_private->width;
1677 *height = window_private->height;
1681 gdk_window_get_visual (GdkWindow *window)
1683 GdkWindowPrivate *window_private;
1685 g_return_val_if_fail (window != NULL, NULL);
1687 window_private = (GdkWindowPrivate*) window;
1688 /* Huh? ->parent is never set for a pixmap. We should just return
1689 * null immeditately. Well, do it then!
1691 if (window_private->window_type == GDK_WINDOW_PIXMAP)
1694 if (!window_private->destroyed)
1696 if (window_private->colormap == NULL)
1697 return gdk_visual_get_system (); /* XXX ??? */
1699 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1706 gdk_window_get_colormap (GdkWindow *window)
1708 GdkWindowPrivate *window_private;
1710 g_return_val_if_fail (window != NULL, NULL);
1711 window_private = (GdkWindowPrivate*) window;
1713 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1714 if (!window_private->destroyed)
1716 if (window_private->colormap == NULL)
1717 return gdk_colormap_get_system (); /* XXX ??? */
1719 return window_private->colormap;
1726 gdk_window_get_type (GdkWindow *window)
1728 GdkWindowPrivate *window_private;
1730 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1732 window_private = (GdkWindowPrivate*) window;
1733 return window_private->window_type;
1737 gdk_window_get_origin (GdkWindow *window,
1741 GdkWindowPrivate *private;
1746 g_return_val_if_fail (window != NULL, 0);
1748 private = (GdkWindowPrivate*) window;
1750 if (!private->destroyed)
1756 ClientToScreen (private->xwindow, &pt);
1769 GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
1770 private->xwindow, tx, ty));
1775 gdk_window_get_deskrelative_origin (GdkWindow *window,
1779 return gdk_window_get_origin (window, x, y);
1783 gdk_window_get_root_origin (GdkWindow *window,
1787 GdkWindowPrivate *private;
1790 g_return_if_fail (window != NULL);
1792 private = (GdkWindowPrivate*) window;
1797 if (private->destroyed)
1800 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1801 private = (GdkWindowPrivate*) private->parent;
1802 if (private->destroyed)
1807 ClientToScreen (private->xwindow, &pt);
1813 GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%d+%d\n",
1814 ((GdkWindowPrivate *) window)->xwindow,
1815 private->xwindow, pt.x, pt.y));
1819 gdk_window_get_pointer (GdkWindow *window,
1822 GdkModifierType *mask)
1824 GdkWindowPrivate *private;
1825 GdkWindow *return_val;
1826 POINT pointc, point;
1830 window = (GdkWindow*) &gdk_root_parent;
1832 private = (GdkWindowPrivate*) window;
1835 GetCursorPos (&pointc);
1837 ScreenToClient (private->xwindow, &point);
1844 hwnd = WindowFromPoint (point);
1846 ScreenToClient (hwnd, &point);
1849 hwndc = ChildWindowFromPoint (hwnd, point);
1850 ClientToScreen (hwnd, &point);
1851 ScreenToClient (hwndc, &point);
1852 } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1854 return_val = gdk_window_lookup (hwnd);
1860 GetKeyboardState (kbd);
1862 if (kbd[VK_SHIFT] & 0x80)
1863 *mask |= GDK_SHIFT_MASK;
1864 if (kbd[VK_CAPITAL] & 0x80)
1865 *mask |= GDK_LOCK_MASK;
1866 if (kbd[VK_CONTROL] & 0x80)
1867 *mask |= GDK_CONTROL_MASK;
1868 if (kbd[VK_MENU] & 0x80)
1869 *mask |= GDK_MOD1_MASK;
1870 if (kbd[VK_LBUTTON] & 0x80)
1871 *mask |= GDK_BUTTON1_MASK;
1872 if (kbd[VK_MBUTTON] & 0x80)
1873 *mask |= GDK_BUTTON2_MASK;
1874 if (kbd[VK_RBUTTON] & 0x80)
1875 *mask |= GDK_BUTTON3_MASK;
1882 gdk_window_at_pointer (gint *win_x,
1885 GdkWindowPrivate *private;
1887 POINT point, pointc;
1891 private = &gdk_root_parent;
1893 GetCursorPos (&pointc);
1895 hwnd = WindowFromPoint (point);
1899 window = (GdkWindow *) &gdk_root_parent;
1907 ScreenToClient (hwnd, &point);
1910 hwndc = ChildWindowFromPoint (hwnd, point);
1911 ClientToScreen (hwnd, &point);
1912 ScreenToClient (hwndc, &point);
1913 } while (hwndc != hwnd && (hwnd = hwndc, 1));
1915 window = gdk_window_lookup (hwnd);
1917 if (window && (win_x || win_y))
1919 GetClientRect (hwnd, &rect);
1921 *win_x = point.x - rect.left;
1923 *win_y = point.y - rect.top;
1926 GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%d+%d %#x%s\n",
1927 point.x, point.y, hwnd,
1928 (window == NULL ? " NULL" : "")));
1934 gdk_window_get_parent (GdkWindow *window)
1936 g_return_val_if_fail (window != NULL, NULL);
1938 return ((GdkWindowPrivate*) window)->parent;
1942 gdk_window_get_toplevel (GdkWindow *window)
1944 GdkWindowPrivate *private;
1946 g_return_val_if_fail (window != NULL, NULL);
1948 private = (GdkWindowPrivate*) window;
1950 while (private->window_type == GDK_WINDOW_CHILD)
1952 window = ((GdkWindowPrivate*) window)->parent;
1953 private = (GdkWindowPrivate*) window;
1960 gdk_window_get_children (GdkWindow *window)
1962 GdkWindowPrivate *private;
1965 g_return_val_if_fail (window != NULL, NULL);
1967 private = (GdkWindowPrivate*) window;
1968 if (private->destroyed)
1972 g_warning ("gdk_window_get_children ???");
1979 gdk_window_get_events (GdkWindow *window)
1981 GdkWindowPrivate *private;
1983 g_return_val_if_fail (window != NULL, 0);
1985 private = (GdkWindowPrivate*) window;
1986 if (private->destroyed)
1989 return private->event_mask;
1993 gdk_window_set_events (GdkWindow *window,
1994 GdkEventMask event_mask)
1996 GdkWindowPrivate *private;
1998 g_return_if_fail (window != NULL);
2000 private = (GdkWindowPrivate*) window;
2001 if (private->destroyed)
2004 private->event_mask = event_mask;
2008 gdk_window_add_colormap_windows (GdkWindow *window)
2010 g_warning ("gdk_window_add_colormap_windows not implemented"); /* XXX */
2014 * This needs the X11 shape extension.
2015 * If not available, shaped windows will look
2016 * ugly, but programs still work. Stefan Wille
2019 gdk_window_shape_combine_mask (GdkWindow *window,
2023 GdkWindowPrivate *window_private;
2025 g_return_if_fail (window != NULL);
2027 window_private = (GdkWindowPrivate*) window;
2031 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
2032 window_private->xwindow));
2033 SetWindowRgn (window_private->xwindow, NULL, TRUE);
2037 GdkPixmapPrivate *pixmap_private;
2043 /* Convert mask bitmap to region */
2044 pixmap_private = (GdkPixmapPrivate*) mask;
2045 hrgn = BitmapToRegion (pixmap_private->xwindow);
2047 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
2048 window_private->xwindow,
2049 pixmap_private->xwindow));
2051 /* SetWindowRgn wants window (not client) coordinates */
2052 dwStyle = GetWindowLong (window_private->xwindow, GWL_STYLE);
2053 dwExStyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2054 GetClientRect (window_private->xwindow, &rect);
2055 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
2056 OffsetRgn (hrgn, -rect.left, -rect.top);
2058 OffsetRgn (hrgn, x, y);
2060 /* If this is a top-level window, add the title bar to the region */
2061 if (window_private->window_type == GDK_WINDOW_TOPLEVEL)
2063 CombineRgn (hrgn, hrgn,
2064 CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
2068 SetWindowRgn (window_private->xwindow, hrgn, TRUE);
2073 gdk_window_add_filter (GdkWindow *window,
2074 GdkFilterFunc function,
2077 GdkWindowPrivate *private;
2079 GdkEventFilter *filter;
2081 private = (GdkWindowPrivate*) window;
2082 if (private && private->destroyed)
2086 tmp_list = private->filters;
2088 tmp_list = gdk_default_filters;
2092 filter = (GdkEventFilter *)tmp_list->data;
2093 if ((filter->function == function) && (filter->data == data))
2095 tmp_list = tmp_list->next;
2098 filter = g_new (GdkEventFilter, 1);
2099 filter->function = function;
2100 filter->data = data;
2103 private->filters = g_list_append (private->filters, filter);
2105 gdk_default_filters = g_list_append (gdk_default_filters, filter);
2109 gdk_window_remove_filter (GdkWindow *window,
2110 GdkFilterFunc function,
2113 GdkWindowPrivate *private;
2114 GList *tmp_list, *node;
2115 GdkEventFilter *filter;
2117 private = (GdkWindowPrivate*) window;
2120 tmp_list = private->filters;
2122 tmp_list = gdk_default_filters;
2126 filter = (GdkEventFilter *)tmp_list->data;
2128 tmp_list = tmp_list->next;
2130 if ((filter->function == function) && (filter->data == data))
2133 private->filters = g_list_remove_link (private->filters, node);
2135 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
2136 g_list_free_1 (node);
2145 gdk_window_set_override_redirect (GdkWindow *window,
2146 gboolean override_redirect)
2148 g_warning ("gdk_window_set_override_redirect not implemented"); /* XXX */
2152 gdk_window_set_icon (GdkWindow *window,
2153 GdkWindow *icon_window,
2157 g_warning ("gdk_window_set_icon not implemented"); /* XXX */
2161 gdk_window_set_icon_name (GdkWindow *window,
2164 GdkWindowPrivate *window_private;
2166 g_return_if_fail (window != NULL);
2167 window_private = (GdkWindowPrivate*) window;
2168 if (window_private->destroyed)
2171 if (!SetWindowText (window_private->xwindow, name))
2172 g_warning ("gdk_window_set_icon_name: SetWindowText failed");
2176 gdk_window_set_group (GdkWindow *window,
2179 g_warning ("gdk_window_set_group not implemented"); /* XXX */
2183 gdk_window_set_decorations (GdkWindow *window,
2184 GdkWMDecoration decorations)
2186 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2187 LONG style, exstyle;
2189 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2190 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2192 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2193 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
2195 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2197 if (decorations & GDK_DECOR_ALL)
2198 style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2199 if (decorations & GDK_DECOR_BORDER)
2200 style |= (WS_BORDER);
2201 if (decorations & GDK_DECOR_RESIZEH)
2202 style |= (WS_THICKFRAME);
2203 if (decorations & GDK_DECOR_TITLE)
2204 style |= (WS_CAPTION);
2205 if (decorations & GDK_DECOR_MENU)
2206 style |= (WS_SYSMENU);
2207 if (decorations & GDK_DECOR_MINIMIZE)
2208 style |= (WS_MINIMIZEBOX);
2209 if (decorations & GDK_DECOR_MAXIMIZE)
2210 style |= (WS_MAXIMIZEBOX);
2212 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2216 gdk_window_set_functions (GdkWindow *window,
2217 GdkWMFunction functions)
2219 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2220 LONG style, exstyle;
2222 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2223 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2225 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2226 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
2229 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2231 if (functions & GDK_FUNC_ALL)
2232 style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2233 if (functions & GDK_FUNC_RESIZE)
2234 style |= (WS_THICKFRAME);
2235 if (functions & GDK_FUNC_MOVE)
2236 style |= (WS_THICKFRAME);
2237 if (functions & GDK_FUNC_MINIMIZE)
2238 style |= (WS_MINIMIZEBOX);
2239 if (functions & GDK_FUNC_MAXIMIZE)
2240 style |= (WS_MAXIMIZEBOX);
2242 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2246 gdk_window_get_toplevels (void)
2248 GList *new_list = NULL;
2251 tmp_list = gdk_root_parent.children;
2254 new_list = g_list_prepend (new_list, tmp_list->data);
2255 tmp_list = tmp_list->next;
2262 * propagate the shapes from all child windows of a GDK window to the parent
2263 * window. Shamelessly ripped from Enlightenment's code
2269 QueryTree (HWND hwnd,
2279 child = GetWindow (hwnd, GW_CHILD);
2281 child = GetWindow (child, GW_HWNDNEXT);
2284 } while (child != NULL);
2288 *children = g_new (HWND, n);
2289 for (i = 0; i < n; i++)
2292 child = GetWindow (hwnd, GW_CHILD);
2294 child = GetWindow (child, GW_HWNDNEXT);
2295 *children[i] = child;
2301 gdk_propagate_shapes (HANDLE win,
2305 HRGN region, childRegion;
2310 SetRectEmpty (&emptyRect);
2311 region = CreateRectRgnIndirect (&emptyRect);
2313 GetWindowRgn (win, region);
2315 QueryTree (win, &list, &num);
2318 WINDOWPLACEMENT placement;
2320 placement.length = sizeof (WINDOWPLACEMENT);
2321 /* go through all child windows and combine regions */
2322 for (i = 0; i < num; i++)
2324 GetWindowPlacement (list[i], &placement);
2325 if (placement.showCmd = SW_SHOWNORMAL)
2327 childRegion = CreateRectRgnIndirect (&emptyRect);
2328 GetWindowRgn (list[i], childRegion);
2329 CombineRgn (region, region, childRegion, RGN_OR);
2330 DeleteObject (childRegion);
2333 SetWindowRgn (win, region, TRUE);
2336 DeleteObject (region);
2340 gdk_window_set_child_shapes (GdkWindow *window)
2342 GdkWindowPrivate *private;
2344 g_return_if_fail (window != NULL);
2346 private = (GdkWindowPrivate*) window;
2347 if (private->destroyed)
2350 gdk_propagate_shapes ( private->xwindow, FALSE);
2354 gdk_window_merge_child_shapes (GdkWindow *window)
2356 GdkWindowPrivate *private;
2358 g_return_if_fail (window != NULL);
2360 private = (GdkWindowPrivate*) window;
2361 if (private->destroyed)
2364 gdk_propagate_shapes (private->xwindow, TRUE);
2367 /*************************************************************
2368 * gdk_window_is_visible:
2369 * Check if the given window is mapped.
2373 * is the window mapped
2374 *************************************************************/
2377 gdk_window_is_visible (GdkWindow *window)
2379 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2381 g_return_val_if_fail (window != NULL, FALSE);
2383 return private->mapped;
2386 /*************************************************************
2387 * gdk_window_is_viewable:
2388 * Check if the window and all ancestors of the window
2389 * are mapped. (This is not necessarily "viewable" in
2390 * the X sense, since we only check as far as we have
2391 * GDK window parents, not to the root window)
2395 * is the window viewable
2396 *************************************************************/
2399 gdk_window_is_viewable (GdkWindow *window)
2401 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2403 g_return_val_if_fail (window != NULL, FALSE);
2406 (private != &gdk_root_parent) &&
2407 (private->window_type != GDK_WINDOW_FOREIGN))
2409 if (!private->mapped)
2412 private = (GdkWindowPrivate *)private->parent;
2419 gdk_drawable_set_data (GdkDrawable *drawable,
2422 GDestroyNotify destroy_func)
2424 g_dataset_set_data_full (drawable, key, data, destroy_func);
2428 /* Support for windows that can be guffaw-scrolled
2429 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2433 gdk_window_gravity_works (void)
2435 enum { UNKNOWN, NO, YES };
2436 static gint gravity_works = UNKNOWN;
2438 if (gravity_works == UNKNOWN)
2445 attr.window_type = GDK_WINDOW_TEMP;
2446 attr.wclass = GDK_INPUT_OUTPUT;
2451 attr.event_mask = 0;
2453 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2455 attr.window_type = GDK_WINDOW_CHILD;
2456 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2458 gdk_window_set_static_win_gravity (child, TRUE);
2460 gdk_window_resize (parent, 100, 110);
2461 gdk_window_move (parent, 0, -10);
2462 gdk_window_move_resize (parent, 0, 0, 100, 100);
2464 gdk_window_resize (parent, 100, 110);
2465 gdk_window_move (parent, 0, -10);
2466 gdk_window_move_resize (parent, 0, 0, 100, 100);
2468 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2470 gdk_window_destroy (parent);
2471 gdk_window_destroy (child);
2473 gravity_works = ((y == -20) ? YES : NO);
2476 return (gravity_works == YES);
2480 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2482 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2484 g_return_if_fail (window != NULL);
2487 g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2491 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2493 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2495 g_return_if_fail (window != NULL);
2498 g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2501 /*************************************************************
2502 * gdk_window_set_static_gravities:
2503 * Set the bit gravity of the given window to static,
2504 * and flag it so all children get static subwindow
2507 * window: window for which to set static gravity
2508 * use_static: Whether to turn static gravity on or off.
2510 * Does the XServer support static gravity?
2511 *************************************************************/
2514 gdk_window_set_static_gravities (GdkWindow *window,
2515 gboolean use_static)
2517 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2520 g_return_val_if_fail (window != NULL, FALSE);
2522 if (!use_static == !private->guffaw_gravity)
2525 if (use_static && !gdk_window_gravity_works ())
2528 private->guffaw_gravity = use_static;
2530 gdk_window_set_static_bit_gravity (window, use_static);
2532 tmp_list = private->children;
2535 gdk_window_set_static_win_gravity (window, use_static);
2537 tmp_list = tmp_list->next;