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/.
31 #include "gdkprivate.h"
36 /* The Win API function AdjustWindowRect may return negative values
37 * resulting in obscured title bars. This helper function is coreccting it.
39 BOOL AdjustWindowRectEx2(RECT* lpRect,
44 if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
48 lpRect->right -= lpRect->left;
53 lpRect->bottom -= lpRect->top;
59 #define AdjustWindowRectEx AdjustWindowRectEx2
61 /* Forward declarations */
62 static gboolean gdk_window_gravity_works (void);
63 static void gdk_window_set_static_win_gravity (GdkWindow *window,
67 * The following fucntion by The Rasterman <raster@redhat.com>
68 * This function returns the X Window ID in which the x y location is in
69 * (x and y being relative to the root window), excluding any windows listed
70 * in the GList excludes (this is a list of X Window ID's - gpointer being
73 * This is primarily designed for internal gdk use - for DND for example
74 * when using a shaped icon window as the drag object - you exclude the
75 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
76 * You can get back an X Window ID as to what X Window ID is infact under
77 * those X,Y co-ordinates.
80 gdk_window_xid_at_coords (gint x,
86 gboolean warned = FALSE;
90 /* This is probably not correct, just a quick hack */
94 g_warning ("gdk_window_xid_at_coords probably not implemented correctly");
99 return WindowFromPoint (pt);
103 gdk_window_init (void)
108 width = GetSystemMetrics (SM_CXSCREEN);
109 height = GetSystemMetrics (SM_CYSCREEN);
111 { RECT r; /* //HB: don't obscure tray window (task bar) */
112 SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
113 width = r.right - r.left;
114 height = r.bottom - r.top;
118 gdk_root_parent.xwindow = gdk_root_window;
119 gdk_root_parent.window_type = GDK_WINDOW_ROOT;
120 gdk_root_parent.window.user_data = NULL;
121 gdk_root_parent.width = width;
122 gdk_root_parent.height = height;
123 gdk_root_parent.children = NULL;
124 gdk_root_parent.colormap = NULL;
125 gdk_root_parent.ref_count = 1;
127 gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
131 gdk_window_new (GdkWindow *parent,
132 GdkWindowAttr *attributes,
133 gint attributes_mask)
136 GdkWindowPrivate *private;
137 GdkWindowPrivate *parent_private;
141 #ifdef MULTIPLE_WINDOW_CLASSES
144 char wcl_name_buf[20];
145 static int wcl_cnt = 0;
147 static WNDCLASSEX wcl;
148 static ATOM klass = 0;
150 static HICON hAppIcon = NULL;
151 DWORD dwStyle, dwExStyle;
157 g_return_val_if_fail (attributes != NULL, NULL);
160 parent = (GdkWindow*) &gdk_root_parent;
162 parent_private = (GdkWindowPrivate*) parent;
163 if (parent_private->destroyed)
166 xparent = parent_private->xwindow;
168 private = g_new (GdkWindowPrivate, 1);
169 window = (GdkWindow*) private;
171 private->parent = parent;
173 private->destroyed = FALSE;
174 private->mapped = FALSE;
175 private->guffaw_gravity = FALSE;
176 private->resize_count = 0;
177 private->ref_count = 1;
179 if (attributes_mask & GDK_WA_X)
184 if (attributes_mask & GDK_WA_Y)
191 private->width = (attributes->width > 1) ? (attributes->width) : (1);
192 private->height = (attributes->height > 1) ? (attributes->height) : (1);
193 private->window_type = attributes->window_type;
194 private->extension_events = 0;
195 private->extension_events_selected = FALSE;
197 private->filters = NULL;
198 private->children = NULL;
200 window->user_data = NULL;
202 if (attributes_mask & GDK_WA_VISUAL)
203 visual = attributes->visual;
205 visual = gdk_visual_get_system ();
206 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
208 if (attributes_mask & GDK_WA_TITLE)
209 title = attributes->title;
211 title = g_get_prgname ();
213 private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
214 private->bg_type = GDK_WIN32_BG_NORMAL;
215 private->hint_flags = 0;
217 #ifndef MULTIPLE_WINDOW_CLASSES
221 wcl.cbSize = sizeof (WNDCLASSEX);
223 wcl.style = CS_HREDRAW | CS_VREDRAW;
227 wcl.lpfnWndProc = gdk_WindowProc;
230 wcl.hInstance = gdk_ProgInstance;
231 wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
233 #if 0 /* tml: orig -> generates SetClassLong errors in set background */
234 wcl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
235 wcl.hbrBackground = NULL;
237 /* initialize once! */
240 gchar sLoc [_MAX_PATH+1];
241 HINSTANCE hInst = GetModuleHandle(NULL);
243 if (0 != GetModuleFileName(hInst, sLoc, _MAX_PATH))
245 hAppIcon = ExtractIcon(hInst, sLoc, 0);
248 char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
250 hAppIcon = ExtractIcon(hInst, gdklibname, 0);
255 hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
258 wcl.hIcon = CopyIcon (hAppIcon);
259 wcl.hIconSm = CopyIcon (hAppIcon);
260 /* HB: starting with black to have something to release ... */
261 wcl.hbrBackground = CreateSolidBrush( RGB(0,0,0));
264 wcl.lpszMenuName = NULL;
265 #ifdef MULTIPLE_WINDOW_CLASSES
266 sprintf (wcl_name_buf, "gdk-wcl-%d", wcl_cnt++);
267 wcl.lpszClassName = g_strdup (wcl_name_buf);
268 /* wcl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); */
270 wcl.lpszClassName = "GDK-window-class";
271 klass = RegisterClassEx (&wcl);
273 g_error ("RegisterClassEx failed");
276 private->xcursor = NULL;
279 if (parent_private && parent_private->guffaw_gravity)
284 if (attributes->wclass == GDK_INPUT_OUTPUT)
287 if (attributes_mask & GDK_WA_COLORMAP)
288 private->colormap = attributes->colormap;
290 private->colormap = gdk_colormap_get_system ();
294 dwExStyle = WS_EX_TRANSPARENT;
295 private->colormap = NULL;
296 private->bg_type = GDK_WIN32_BG_TRANSPARENT;
297 private->bg_pixmap = NULL;
300 if (attributes_mask & GDK_WA_X)
305 if (attributes_mask & GDK_WA_Y)
307 else if (attributes_mask & GDK_WA_X)
308 y = 100; /* ??? We must put it somewhere... */
310 y = 500; /* x is CW_USEDEFAULT, y doesn't matter then */
313 parent_private->children = g_list_prepend (parent_private->children, window);
315 switch (private->window_type)
317 case GDK_WINDOW_TOPLEVEL:
318 dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
319 xparent = gdk_root_window;
321 case GDK_WINDOW_CHILD:
322 dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
324 case GDK_WINDOW_DIALOG:
325 dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
326 xparent = gdk_root_window;
328 case GDK_WINDOW_TEMP:
329 dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
330 #ifdef MULTIPLE_WINDOW_CLASSES
331 wcl.style |= CS_SAVEBITS;
333 dwExStyle |= WS_EX_TOOLWINDOW;
335 case GDK_WINDOW_ROOT:
336 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
338 case GDK_WINDOW_PIXMAP:
339 g_error ("cannot make windows of type GDK_WINDOW_PIXMAP (use gdk_pixmap_new)");
343 #ifdef MULTIPLE_WINDOW_CLASSES
344 klass = RegisterClassEx (&wcl);
346 g_error ("RegisterClassEx failed");
349 if (private->window_type != GDK_WINDOW_CHILD)
351 if (x == CW_USEDEFAULT)
362 rect.right = rect.left + private->width;
363 rect.bottom = rect.top + private->height;
365 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
366 g_warning ("gdk_window_new: AdjustWindowRectEx failed");
368 if (x != CW_USEDEFAULT)
373 width = rect.right - rect.left;
374 height = rect.bottom - rect.top;
378 width = private->width;
379 height = private->height;
383 CreateWindowEx (dwExStyle,
394 g_print ("gdk_window_create: %s %s %#x %dx%d@+%d+%d %#x = %#x\n",
395 (private->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
396 (private->window_type == GDK_WINDOW_CHILD ? "CHILD" :
397 (private->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
398 (private->window_type == GDK_WINDOW_TEMP ? "TEMP" :
402 width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
406 gdk_window_ref (window);
407 gdk_xid_table_insert (&private->xwindow, window);
409 if (private->colormap)
410 gdk_colormap_ref (private->colormap);
412 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
413 (attributes->cursor) :
420 gdk_window_foreign_new (guint32 anid)
423 GdkWindowPrivate *private;
424 GdkWindowPrivate *parent_private;
429 private = g_new (GdkWindowPrivate, 1);
430 window = (GdkWindow*) private;
432 parent = GetParent ((HWND) anid);
433 private->parent = gdk_xid_table_lookup (parent);
435 parent_private = (GdkWindowPrivate *)private->parent;
438 parent_private->children = g_list_prepend (parent_private->children, window);
440 private->xwindow = (HWND) anid;
441 GetClientRect ((HWND) anid, &rect);
443 point.y = rect.right;
444 ClientToScreen ((HWND) anid, &point);
445 if (parent != HWND_DESKTOP)
446 ScreenToClient (parent, &point);
447 private->x = point.x;
448 private->y = point.y;
449 private->width = rect.right - rect.left;
450 private->height = rect.bottom - rect.top;
451 private->resize_count = 0;
452 private->ref_count = 1;
453 private->window_type = GDK_WINDOW_FOREIGN;
454 private->destroyed = FALSE;
455 private->mapped = IsWindowVisible (private->xwindow);
456 private->guffaw_gravity = FALSE;
457 private->extension_events = 0;
458 private->extension_events_selected = FALSE;
460 private->colormap = NULL;
462 private->filters = NULL;
463 private->children = NULL;
465 window->user_data = NULL;
467 gdk_window_ref (window);
468 gdk_xid_table_insert (&private->xwindow, window);
473 /* Call this function when you want a window and all its children to
474 * disappear. When xdestroy is true, a request to destroy the XWindow
475 * is sent out. When it is false, it is assumed that the XWindow has
476 * been or will be destroyed by destroying some ancestor of this
480 gdk_window_internal_destroy (GdkWindow *window,
482 gboolean our_destroy)
484 GdkWindowPrivate *private;
485 GdkWindowPrivate *temp_private;
486 GdkWindow *temp_window;
490 g_return_if_fail (window != NULL);
492 private = (GdkWindowPrivate*) window;
494 GDK_NOTE (MISC, g_print ("gdk_window_internal_destroy %#x\n",
497 switch (private->window_type)
499 case GDK_WINDOW_TOPLEVEL:
500 case GDK_WINDOW_CHILD:
501 case GDK_WINDOW_DIALOG:
502 case GDK_WINDOW_TEMP:
503 case GDK_WINDOW_FOREIGN:
504 if (!private->destroyed)
508 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
509 if (parent_private->children)
510 parent_private->children = g_list_remove (parent_private->children, window);
513 if (private->window_type != GDK_WINDOW_FOREIGN)
515 children = tmp = private->children;
516 private->children = NULL;
520 temp_window = tmp->data;
523 temp_private = (GdkWindowPrivate*) temp_window;
525 gdk_window_internal_destroy (temp_window, FALSE,
529 g_list_free (children);
532 if (private->extension_events != 0)
533 gdk_input_window_destroy (window);
535 if (private->filters)
537 tmp = private->filters;
545 g_list_free (private->filters);
546 private->filters = NULL;
549 if (private->window_type == GDK_WINDOW_FOREIGN)
551 if (our_destroy && (private->parent != NULL))
553 /* It's somebody elses window, but in our hierarchy,
554 * so reparent it to the root window, and then send
555 * it a delete event, as if we were a WM
557 gdk_window_hide (window);
558 gdk_window_reparent (window, NULL, 0, 0);
560 /* Is this too drastic? Many (most?) applications
561 * quit if any window receives WM_QUIT I think.
562 * OTOH, I don't think foreign windows are much
563 * used, so the question is maybe academic.
565 PostMessage (private->xwindow, WM_QUIT, 0, 0);
569 DestroyWindow (private->xwindow);
571 if (private->colormap)
572 gdk_colormap_unref (private->colormap);
574 private->mapped = FALSE;
575 private->destroyed = TRUE;
579 case GDK_WINDOW_ROOT:
580 g_error ("attempted to destroy root window");
583 case GDK_WINDOW_PIXMAP:
584 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
589 /* Like internal_destroy, but also destroys the reference created by
593 gdk_window_destroy (GdkWindow *window)
595 gdk_window_internal_destroy (window, TRUE, TRUE);
596 gdk_window_unref (window);
599 /* This function is called when the XWindow is really gone. */
602 gdk_window_destroy_notify (GdkWindow *window)
604 GdkWindowPrivate *private;
606 g_return_if_fail (window != NULL);
608 private = (GdkWindowPrivate*) window;
610 GDK_NOTE (EVENTS, g_print ("gdk_window_destroy_notify: %#x %d\n",
611 private->xwindow, private->destroyed));
613 if (!private->destroyed)
615 if (private->window_type == GDK_WINDOW_FOREIGN)
616 gdk_window_internal_destroy (window, FALSE, FALSE);
618 g_warning ("GdkWindow %#lx unexpectedly destroyed", private->xwindow);
621 gdk_xid_table_remove (private->xwindow);
622 gdk_window_unref (window);
626 gdk_window_ref (GdkWindow *window)
628 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
629 g_return_val_if_fail (window != NULL, NULL);
631 private->ref_count += 1;
633 GDK_NOTE (MISC, g_print ("gdk_window_ref %#x %d\n",
634 private->xwindow, private->ref_count));
640 gdk_window_unref (GdkWindow *window)
642 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
643 g_return_if_fail (window != NULL);
645 private->ref_count -= 1;
647 GDK_NOTE (MISC, g_print ("gdk_window_unref %#x %d%s\n",
648 private->xwindow, private->ref_count,
649 (private->ref_count == 0 ? " freeing" : "")));
651 if (private->ref_count == 0)
653 if (private->bg_type == GDK_WIN32_BG_PIXMAP && private->bg_pixmap != NULL)
654 gdk_pixmap_unref (private->bg_pixmap);
656 if (!private->destroyed)
658 if (private->window_type == GDK_WINDOW_FOREIGN)
659 gdk_xid_table_remove (private->xwindow);
661 g_warning ("losing last reference to undestroyed window");
663 g_dataset_destroy (window);
669 gdk_window_show (GdkWindow *window)
671 GdkWindowPrivate *private;
673 g_return_if_fail (window != NULL);
675 private = (GdkWindowPrivate*) window;
676 if (!private->destroyed)
678 GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n", private->xwindow));
680 private->mapped = TRUE;
681 if (private->window_type == GDK_WINDOW_TEMP)
683 ShowWindow (private->xwindow, SW_SHOWNOACTIVATE);
684 SetWindowPos (private->xwindow, HWND_TOPMOST, 0, 0, 0, 0,
685 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
687 ShowWindow (private->xwindow, SW_HIDE); /* Don't put on toolbar */
692 ShowWindow (private->xwindow, SW_SHOWNORMAL);
693 ShowWindow (private->xwindow, SW_RESTORE);
694 SetForegroundWindow (private->xwindow);
696 ShowOwnedPopups (private->xwindow, TRUE);
703 gdk_window_hide (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_hide: %#x\n", private->xwindow));
714 private->mapped = FALSE;
715 if (private->window_type == GDK_WINDOW_TOPLEVEL)
716 ShowOwnedPopups (private->xwindow, FALSE);
718 ShowWindow (private->xwindow, SW_HIDE);
720 ShowWindow (private->xwindow, SW_MINIMIZE);
722 CloseWindow (private->xwindow);
728 gdk_window_withdraw (GdkWindow *window)
730 GdkWindowPrivate *private;
732 g_return_if_fail (window != NULL);
734 private = (GdkWindowPrivate*) window;
735 if (!private->destroyed)
737 GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n", private->xwindow));
739 gdk_window_hide (window); /* XXX */
744 gdk_window_move (GdkWindow *window,
748 GdkWindowPrivate *private;
750 g_return_if_fail (window != NULL);
752 private = (GdkWindowPrivate*) window;
753 if (!private->destroyed)
759 GDK_NOTE (MISC, g_print ("gdk_window_move: %#x +%d+%d\n",
760 private->xwindow, x, y));
761 GetClientRect (private->xwindow, &rect);
763 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
764 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
765 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
766 g_warning ("gdk_window_move: AdjustWindowRectEx failed");
767 if (private->window_type == GDK_WINDOW_CHILD)
772 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
774 rect.right - rect.left, rect.bottom - rect.top,
775 x + rect.left, y + rect.top));
776 if (!MoveWindow (private->xwindow,
777 x + rect.left, y + rect.top,
778 rect.right - rect.left, rect.bottom - rect.top,
780 g_warning ("gdk_window_move: MoveWindow failed");
785 gdk_window_resize (GdkWindow *window,
789 GdkWindowPrivate *private;
791 g_return_if_fail (window != NULL);
793 if ((gint16) width < 1)
795 if ((gint16) height < 1)
798 private = (GdkWindowPrivate*) window;
800 if (!private->destroyed &&
801 ((private->resize_count > 0) ||
802 (private->width != (guint16) width) ||
803 (private->height != (guint16) height)))
811 GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
812 private->xwindow, width, height));
816 ClientToScreen (private->xwindow, &pt);
819 rect.right = pt.x + width;
820 rect.bottom = pt.y + height;
822 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
823 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
824 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
825 g_warning ("gdk_window_resize: AdjustWindowRectEx failed");
826 if (private->window_type != GDK_WINDOW_CHILD)
837 private->resize_count += 1;
839 if (private->window_type == GDK_WINDOW_CHILD)
841 private->width = width;
842 private->height = height;
844 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
846 rect.right - rect.left, rect.bottom - rect.top,
848 if (!MoveWindow (private->xwindow,
850 rect.right - rect.left, rect.bottom - rect.top,
852 g_warning ("gdk_window_resize: MoveWindow failed");
857 gdk_window_move_resize (GdkWindow *window,
863 GdkWindowPrivate *private;
865 g_return_if_fail (window != NULL);
867 if ((gint16) width < 1)
869 if ((gint16) height < 1)
872 private = (GdkWindowPrivate*) window;
873 if (!private->destroyed)
879 GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
880 private->xwindow, width, height, x, y));
884 rect.right = x + width;
885 rect.bottom = y + height;
887 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
888 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
889 if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
890 g_warning ("gdk_window_move_resize: AdjustWindowRectEx failed");
892 if (private->window_type == GDK_WINDOW_CHILD)
896 private->width = width;
897 private->height = height;
899 GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
901 rect.right - rect.left, rect.bottom - rect.top,
902 rect.left, rect.top));
903 if (!MoveWindow (private->xwindow,
905 rect.right - rect.left, rect.bottom - rect.top,
907 g_warning ("gdk_window_move_resize: MoveWindow failed");
909 if (private->guffaw_gravity)
911 GList *tmp_list = private->children;
914 GdkWindowPrivate *child_private = tmp_list->data;
916 child_private->x -= x - private->x;
917 child_private->y -= y - private->y;
919 tmp_list = tmp_list->next;
927 gdk_window_reparent (GdkWindow *window,
928 GdkWindow *new_parent,
932 GdkWindowPrivate *window_private;
933 GdkWindowPrivate *parent_private;
934 GdkWindowPrivate *old_parent_private;
936 g_return_if_fail (window != NULL);
939 new_parent = (GdkWindow*) &gdk_root_parent;
941 window_private = (GdkWindowPrivate*) window;
942 old_parent_private = (GdkWindowPrivate*)window_private->parent;
943 parent_private = (GdkWindowPrivate*) new_parent;
945 if (!window_private->destroyed && !parent_private->destroyed)
947 GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
948 window_private->xwindow,
949 parent_private->xwindow));
950 if (!SetParent (window_private->xwindow, parent_private->xwindow))
951 g_warning ("gdk_window_reparent: SetParent failed");
953 if (!MoveWindow (window_private->xwindow,
955 window_private->width, window_private->height,
957 g_warning ("gdk_window_reparent: MoveWindow failed");
960 window_private->parent = new_parent;
962 if (old_parent_private)
963 old_parent_private->children = g_list_remove (old_parent_private->children, window);
965 if ((old_parent_private &&
966 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
967 (!old_parent_private && parent_private->guffaw_gravity))
968 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
970 parent_private->children = g_list_prepend (parent_private->children, window);
974 gdk_window_clear (GdkWindow *window)
976 GdkWindowPrivate *private;
978 g_return_if_fail (window != NULL);
980 private = (GdkWindowPrivate*) window;
982 if (!private->destroyed)
984 gdk_window_clear_area (window, 0, 0, private->width, private->height);
990 gdk_window_clear_area (GdkWindow *window,
996 GdkWindowPrivate *private;
998 g_return_if_fail (window != NULL);
1000 private = (GdkWindowPrivate*) window;
1002 if (!private->destroyed)
1007 width = G_MAXSHORT/2; /* Yeah, right */
1009 height = G_MAXSHORT/2;
1010 GDK_NOTE (MISC, g_print ("gdk_window_clear_area: %#x %dx%d@+%d+%d\n",
1011 private->xwindow, width, height, x, y));
1012 hdc = GetDC (private->xwindow);
1013 IntersectClipRect (hdc, x, y, x + width, y + height);
1014 SendMessage (private->xwindow, WM_ERASEBKGND, (WPARAM) hdc, 0);
1015 ReleaseDC (private->xwindow, hdc);
1020 gdk_window_clear_area_e (GdkWindow *window,
1026 GdkWindowPrivate *private;
1028 g_return_if_fail (window != NULL);
1030 private = (GdkWindowPrivate*) window;
1032 if (!private->destroyed)
1036 GDK_NOTE (MISC, g_print ("gdk_window_clear_area_e: %#x %dx%d@+%d+%d\n",
1037 private->xwindow, width, height, x, y));
1040 rect.right = x + width;
1042 rect.bottom = y + height;
1043 if (!InvalidateRect (private->xwindow, &rect, TRUE))
1044 g_warning ("gdk_window_clear_area_e: InvalidateRect failed");
1045 UpdateWindow (private->xwindow);
1050 gdk_window_copy_area (GdkWindow *window,
1054 GdkWindow *source_window,
1060 GdkWindowPrivate *src_private;
1061 GdkWindowPrivate *dest_private;
1062 GdkGCPrivate *gc_private;
1064 g_return_if_fail (window != NULL);
1065 g_return_if_fail (gc != NULL);
1067 if (source_window == NULL)
1068 source_window = window;
1070 src_private = (GdkWindowPrivate*) source_window;
1071 dest_private = (GdkWindowPrivate*) window;
1072 gc_private = (GdkGCPrivate*) gc;
1074 if (!src_private->destroyed && !dest_private->destroyed)
1076 HDC hdcDest, hdcSrc;
1078 if ((hdcDest = GetDC (dest_private->xwindow)) == NULL)
1079 g_warning ("gdk_window_copy_area: GetDC failed");
1081 if ((hdcSrc = GetDC (src_private->xwindow)) == NULL)
1082 g_warning ("gdk_window_copy_area: GetDC failed");
1084 if (!BitBlt (hdcDest, x, y, width, height, hdcSrc, source_x, source_y, SRCCOPY))
1085 g_warning ("gdk_window_copy_area: BitBlt failed");
1087 ReleaseDC (dest_private->xwindow, hdcDest);
1088 ReleaseDC (src_private->xwindow, hdcSrc);
1093 gdk_window_raise (GdkWindow *window)
1095 GdkWindowPrivate *private;
1097 g_return_if_fail (window != NULL);
1099 private = (GdkWindowPrivate*) window;
1101 if (!private->destroyed)
1103 GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n", private->xwindow));
1105 if (!BringWindowToTop (private->xwindow))
1106 g_warning ("gdk_window_raise: BringWindowToTop failed");
1111 gdk_window_lower (GdkWindow *window)
1113 GdkWindowPrivate *private;
1115 g_return_if_fail (window != NULL);
1117 private = (GdkWindowPrivate*) window;
1119 if (!private->destroyed)
1121 GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n", private->xwindow));
1123 if (!SetWindowPos (private->xwindow, HWND_BOTTOM, 0, 0, 0, 0,
1124 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
1125 g_warning ("gdk_window_lower: SetWindowPos failed");
1130 gdk_window_set_user_data (GdkWindow *window,
1133 g_return_if_fail (window != NULL);
1135 window->user_data = user_data;
1139 gdk_window_set_hints (GdkWindow *window,
1148 GdkWindowPrivate *private;
1149 WINDOWPLACEMENT size_hints;
1155 g_return_if_fail (window != NULL);
1157 private = (GdkWindowPrivate*) window;
1158 if (private->destroyed)
1161 GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
1163 min_width, min_height, max_width, max_height,
1166 private->hint_flags = flags;
1167 size_hints.length = sizeof (size_hints);
1171 if (flags & GDK_HINT_POS)
1172 if (!GetWindowPlacement (private->xwindow, &size_hints))
1173 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1176 GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
1177 " (%d,%d)--(%d,%d)\n",
1178 size_hints.rcNormalPosition.left,
1179 size_hints.rcNormalPosition.top,
1180 size_hints.rcNormalPosition.right,
1181 size_hints.rcNormalPosition.bottom));
1182 /* What are the corresponding window coordinates for client
1183 * area coordinates x, y
1187 rect.right = rect.left + 200; /* dummy */
1188 rect.bottom = rect.top + 200;
1189 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1190 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1191 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1192 size_hints.flags = 0;
1193 size_hints.showCmd = SW_SHOWNA;
1195 /* Set the normal position hint to that location, with unchanged
1198 diff = size_hints.rcNormalPosition.left - rect.left;
1199 size_hints.rcNormalPosition.left = rect.left;
1200 size_hints.rcNormalPosition.right -= diff;
1201 diff = size_hints.rcNormalPosition.top - rect.top;
1202 size_hints.rcNormalPosition.top = rect.top;
1203 size_hints.rcNormalPosition.bottom -= diff;
1204 GDK_NOTE (MISC, g_print ("...setting: (%d,%d)--(%d,%d)\n",
1205 size_hints.rcNormalPosition.left,
1206 size_hints.rcNormalPosition.top,
1207 size_hints.rcNormalPosition.right,
1208 size_hints.rcNormalPosition.bottom));
1209 if (!SetWindowPlacement (private->xwindow, &size_hints))
1210 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1211 private->hint_x = rect.left;
1212 private->hint_y = rect.top;
1215 if (flags & GDK_HINT_MIN_SIZE)
1219 rect.right = min_width;
1220 rect.bottom = min_height;
1221 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1222 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1223 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1224 private->hint_min_width = rect.right - rect.left;
1225 private->hint_min_height = rect.bottom - rect.top;
1227 /* Also chek if he current size of the window is in bounds. */
1228 GetClientRect (private->xwindow, &rect);
1229 if (rect.right < min_width && rect.bottom < min_height)
1230 gdk_window_resize (window, min_width, min_height);
1231 else if (rect.right < min_width)
1232 gdk_window_resize (window, min_width, rect.bottom);
1233 else if (rect.bottom < min_height)
1234 gdk_window_resize (window, rect.right, min_height);
1236 if (flags & GDK_HINT_MAX_SIZE)
1240 rect.right = max_width;
1241 rect.bottom = max_height;
1242 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1243 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1244 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1245 private->hint_max_width = rect.right - rect.left;
1246 private->hint_max_height = rect.bottom - rect.top;
1247 /* Again, check if the window is too large currently. */
1248 GetClientRect (private->xwindow, &rect);
1249 if (rect.right > max_width && rect.bottom > max_height)
1250 gdk_window_resize (window, max_width, max_height);
1251 else if (rect.right > max_width)
1252 gdk_window_resize (window, max_width, rect.bottom);
1253 else if (rect.bottom > max_height)
1254 gdk_window_resize (window, rect.right, max_height);
1260 gdk_window_set_geometry_hints (GdkWindow *window,
1261 GdkGeometry *geometry,
1262 GdkWindowHints geom_mask)
1264 GdkWindowPrivate *private;
1265 WINDOWPLACEMENT size_hints;
1271 g_return_if_fail (window != NULL);
1273 private = (GdkWindowPrivate*) window;
1274 if (private->destroyed)
1277 size_hints.length = sizeof (size_hints);
1279 private->hint_flags = geom_mask;
1281 if (geom_mask & GDK_HINT_POS)
1284 if (geom_mask & GDK_HINT_MIN_SIZE)
1288 rect.right = geometry->min_width;
1289 rect.bottom = geometry->min_height;
1290 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1291 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1292 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1293 private->hint_min_width = rect.right - rect.left;
1294 private->hint_min_height = rect.bottom - rect.top;
1296 /* Also check if he current size of the window is in bounds */
1297 GetClientRect (private->xwindow, &rect);
1298 if (rect.right < geometry->min_width
1299 && rect.bottom < geometry->min_height)
1300 gdk_window_resize (window, geometry->min_width, geometry->min_height);
1301 else if (rect.right < geometry->min_width)
1302 gdk_window_resize (window, geometry->min_width, rect.bottom);
1303 else if (rect.bottom < geometry->min_height)
1304 gdk_window_resize (window, rect.right, geometry->min_height);
1307 if (geom_mask & GDK_HINT_MAX_SIZE)
1311 rect.right = geometry->max_width;
1312 rect.bottom = geometry->max_height;
1313 dwStyle = GetWindowLong (private->xwindow, GWL_STYLE);
1314 dwExStyle = GetWindowLong (private->xwindow, GWL_EXSTYLE);
1315 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
1316 private->hint_max_width = rect.right - rect.left;
1317 private->hint_max_height = rect.bottom - rect.top;
1319 /* Again, check if the window is too large currently. */
1320 GetClientRect (private->xwindow, &rect);
1321 if (rect.right > geometry->max_width
1322 && rect.bottom > geometry->max_height)
1323 gdk_window_resize (window, geometry->max_width, geometry->max_height);
1324 else if (rect.right > geometry->max_width)
1325 gdk_window_resize (window, geometry->max_width, rect.bottom);
1326 else if (rect.bottom > geometry->max_height)
1327 gdk_window_resize (window, rect.right, geometry->max_height);
1330 /* I don't know what to do when called with zero base_width and height. */
1331 if (geom_mask & GDK_HINT_BASE_SIZE
1332 && geometry->base_width > 0
1333 && geometry->base_height > 0)
1334 if (!GetWindowPlacement (private->xwindow, &size_hints))
1335 g_warning ("gdk_window_set_hints: GetWindowPlacement failed");
1338 GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
1339 " rcNormalPosition: (%d,%d)--(%d,%d)\n",
1340 size_hints.rcNormalPosition.left,
1341 size_hints.rcNormalPosition.top,
1342 size_hints.rcNormalPosition.right,
1343 size_hints.rcNormalPosition.bottom));
1344 size_hints.rcNormalPosition.right =
1345 size_hints.rcNormalPosition.left + geometry->base_width;
1346 size_hints.rcNormalPosition.bottom =
1347 size_hints.rcNormalPosition.top + geometry->base_height;
1348 GDK_NOTE (MISC, g_print ("...setting: rcNormal: (%d,%d)--(%d,%d)\n",
1349 size_hints.rcNormalPosition.left,
1350 size_hints.rcNormalPosition.top,
1351 size_hints.rcNormalPosition.right,
1352 size_hints.rcNormalPosition.bottom));
1353 if (!SetWindowPlacement (private->xwindow, &size_hints))
1354 g_warning ("gdk_window_set_hints: SetWindowPlacement failed");
1357 if (geom_mask & GDK_HINT_RESIZE_INC)
1362 if (geom_mask & GDK_HINT_ASPECT)
1369 gdk_window_set_title (GdkWindow *window,
1372 GdkWindowPrivate *private;
1374 g_return_if_fail (window != NULL);
1376 private = (GdkWindowPrivate*) window;
1377 if (!private->destroyed)
1379 if (!SetWindowText (private->xwindow, title))
1380 g_warning ("gdk_window_set_title: SetWindowText failed");
1385 gdk_window_set_role (GdkWindow *window,
1388 GdkWindowPrivate *private;
1390 g_return_if_fail (window != NULL);
1392 private = (GdkWindowPrivate*) window;
1394 GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
1395 private->xwindow, (role ? role : "NULL")));
1400 gdk_window_set_transient_for (GdkWindow *window,
1403 GdkWindowPrivate *private;
1404 GdkWindowPrivate *parent_private;
1406 g_return_if_fail (window != NULL);
1408 private = (GdkWindowPrivate*) window;
1409 parent_private = (GdkWindowPrivate*) parent;
1411 GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
1412 private->xwindow, parent_private->xwindow));
1417 gdk_window_set_background (GdkWindow *window,
1420 GdkWindowPrivate *private;
1422 g_return_if_fail (window != NULL);
1424 private = (GdkWindowPrivate*) window;
1425 if (!private->destroyed)
1427 GdkColormapPrivate *colormap_private =
1428 (GdkColormapPrivate *) private->colormap;
1430 GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
1432 gdk_color_to_string (color)));
1434 if (private->bg_type == GDK_WIN32_BG_PIXMAP)
1436 if (private->bg_pixmap != NULL)
1438 gdk_pixmap_unref (private->bg_pixmap);
1439 private->bg_pixmap = NULL;
1441 private->bg_type = GDK_WIN32_BG_NORMAL;
1443 #ifdef MULTIPLE_WINDOW_CLASSES
1444 if (colormap_private != NULL
1445 && colormap_private->xcolormap->rc_palette)
1447 /* If we are on a palettized display we can't use the window
1448 * class background brush, but must handle WM_ERASEBKGND.
1449 * At least, I think so.
1452 private->bg_type = GDK_WIN32_BG_PIXEL;
1453 private->bg_pixel = *color;
1454 #ifdef MULTIPLE_WINDOW_CLASSES
1458 /* Non-palettized display; just set the window class background
1462 COLORREF background;
1464 background = RGB (color->red >> 8,
1468 if ((hbr = CreateSolidBrush (GetNearestColor (gdk_DC,
1469 background))) == NULL)
1471 g_warning ("gdk_window_set_background: CreateSolidBrush failed");
1475 oldbrush = (HGDIOBJ) GetClassLong (private->xwindow,
1478 if (SetClassLong (private->xwindow, GCL_HBRBACKGROUND,
1480 g_warning ("gdk_window_set_background: SetClassLong failed");
1482 if (!DeleteObject (oldbrush))
1483 g_warning ("gdk_window_set_background: DeleteObject failed");
1490 gdk_window_set_back_pixmap (GdkWindow *window,
1492 gint parent_relative)
1494 GdkWindowPrivate *window_private;
1495 #ifdef MULTIPLE_WINDOW_CLASSES
1496 GdkPixmapPrivate *pixmap_private;
1499 g_return_if_fail (window != NULL);
1501 window_private = (GdkWindowPrivate*) window;
1502 #ifdef MULTIPLE_WINDOW_CLASSES
1503 pixmap_private = (GdkPixmapPrivate*) pixmap;
1506 if (!window_private->destroyed)
1508 GdkColormapPrivate *colormap_private =
1509 (GdkColormapPrivate *) window_private->colormap;
1510 if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
1512 if (window_private->bg_pixmap != NULL)
1514 gdk_pixmap_unref (window_private->bg_pixmap);
1515 window_private->bg_pixmap = NULL;
1517 window_private->bg_type = GDK_WIN32_BG_NORMAL;
1519 if (parent_relative)
1521 window_private->bg_type = GDK_WIN32_BG_PARENT_RELATIVE;
1525 #ifdef MULTIPLE_WINDOW_CLASSES
1526 SetClassLong (window_private->xwindow, GCL_HBRBACKGROUND,
1527 (LONG) GetStockObject (BLACK_BRUSH));
1530 #ifdef MULTIPLE_WINDOW_CLASSES
1531 else if (colormap_private->xcolormap->rc_palette)
1533 /* Must do the background painting in the
1534 * WM_ERASEBKGND handler.
1536 window_private->bg_type = GDK_WIN32_BG_PIXMAP;
1537 window_private->bg_pixmap = pixmap;
1538 gdk_pixmap_ref (pixmap);
1540 else if (pixmap_private->width <= 8
1541 && pixmap_private->height <= 8)
1543 /* We can use small pixmaps directly as background brush */
1544 SetClassLong (window_private->xwindow, GCL_HBRBACKGROUND,
1545 (LONG) CreatePatternBrush (pixmap_private->xwindow));
1550 /* We must cache the pixmap in the WindowPrivate and
1551 * paint it each time we get WM_ERASEBKGND
1553 window_private->bg_type = GDK_WIN32_BG_PIXMAP;
1554 window_private->bg_pixmap = pixmap;
1555 gdk_pixmap_ref (pixmap);
1561 gdk_window_set_cursor (GdkWindow *window,
1564 GdkWindowPrivate *window_private;
1565 GdkCursorPrivate *cursor_private;
1568 g_return_if_fail (window != NULL);
1570 window_private = (GdkWindowPrivate*) window;
1571 cursor_private = (GdkCursorPrivate*) cursor;
1573 if (!window_private->destroyed)
1576 xcursor = LoadCursor (NULL, IDC_ARROW);
1578 xcursor = cursor_private->xcursor;
1580 GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
1581 window_private->xwindow, xcursor));
1582 #ifdef MULTIPLE_WINDOW_CLASSES
1583 if (!SetClassLong (window_private->xwindow, GCL_HCURSOR, (LONG) xcursor))
1584 g_warning ("gdk_window_set_cursor: SetClassLong failed");
1586 window_private->xcursor = xcursor;
1588 SetCursor (xcursor);
1593 gdk_window_set_colormap (GdkWindow *window,
1594 GdkColormap *colormap)
1596 GdkWindowPrivate *window_private;
1597 GdkColormapPrivate *colormap_private;
1599 g_return_if_fail (window != NULL);
1600 g_return_if_fail (colormap != NULL);
1602 window_private = (GdkWindowPrivate*) window;
1603 colormap_private = (GdkColormapPrivate*) colormap;
1605 if (!window_private->destroyed)
1608 GDK_NOTE (MISC, g_print ("gdk_window_set_colormap: %#x %#x\n",
1609 window_private->xwindow,
1610 colormap_private->xcolormap));
1611 if (window_private->colormap)
1612 gdk_colormap_unref (window_private->colormap);
1613 window_private->colormap = colormap;
1614 gdk_colormap_ref (window_private->colormap);
1616 if (window_private->window_type != GDK_WINDOW_TOPLEVEL)
1617 gdk_window_add_colormap_windows (window);
1622 gdk_window_get_user_data (GdkWindow *window,
1625 g_return_if_fail (window != NULL);
1627 *data = window->user_data;
1631 gdk_window_get_geometry (GdkWindow *window,
1638 GdkWindowPrivate *window_private;
1641 window = (GdkWindow*) &gdk_root_parent;
1643 window_private = (GdkWindowPrivate*) window;
1645 if (!window_private->destroyed)
1649 if (!GetClientRect (window_private->xwindow, &rect))
1650 g_warning ("gdk_window_get_geometry: GetClientRect failed");
1657 *width = rect.right - rect.left;
1659 *height = rect.bottom - rect.top;
1661 *depth = gdk_window_get_visual (window)->depth;
1666 gdk_window_get_position (GdkWindow *window,
1670 GdkWindowPrivate *window_private;
1672 g_return_if_fail (window != NULL);
1674 window_private = (GdkWindowPrivate*) window;
1677 *x = window_private->x;
1679 *y = window_private->y;
1683 gdk_window_get_size (GdkWindow *window,
1687 GdkWindowPrivate *window_private;
1689 g_return_if_fail (window != NULL);
1691 window_private = (GdkWindowPrivate*) window;
1694 *width = window_private->width;
1696 *height = window_private->height;
1700 gdk_window_get_visual (GdkWindow *window)
1702 GdkWindowPrivate *window_private;
1704 g_return_val_if_fail (window != NULL, NULL);
1706 window_private = (GdkWindowPrivate*) window;
1707 /* Huh? ->parent is never set for a pixmap. We should just return
1708 * null immeditately. Well, do it then!
1710 if (window_private->window_type == GDK_WINDOW_PIXMAP)
1713 if (!window_private->destroyed)
1715 if (window_private->colormap == NULL)
1716 return gdk_visual_get_system (); /* XXX ??? */
1718 return ((GdkColormapPrivate *)window_private->colormap)->visual;
1725 gdk_window_get_colormap (GdkWindow *window)
1727 GdkWindowPrivate *window_private;
1729 g_return_val_if_fail (window != NULL, NULL);
1730 window_private = (GdkWindowPrivate*) window;
1732 g_return_val_if_fail (window_private->window_type != GDK_WINDOW_PIXMAP, NULL);
1733 if (!window_private->destroyed)
1735 if (window_private->colormap == NULL)
1736 return gdk_colormap_get_system (); /* XXX ??? */
1738 return window_private->colormap;
1745 gdk_window_get_type (GdkWindow *window)
1747 GdkWindowPrivate *window_private;
1749 g_return_val_if_fail (window != NULL, (GdkWindowType) -1);
1751 window_private = (GdkWindowPrivate*) window;
1752 return window_private->window_type;
1756 gdk_window_get_origin (GdkWindow *window,
1760 GdkWindowPrivate *private;
1765 g_return_val_if_fail (window != NULL, 0);
1767 private = (GdkWindowPrivate*) window;
1769 if (!private->destroyed)
1775 ClientToScreen (private->xwindow, &pt);
1792 gdk_window_get_deskrelative_origin (GdkWindow *window,
1796 return gdk_window_get_origin (window, x, y);
1800 gdk_window_get_root_origin (GdkWindow *window,
1804 GdkWindowPrivate *private;
1807 g_return_if_fail (window != NULL);
1809 private = (GdkWindowPrivate*) window;
1814 if (private->destroyed)
1817 while (private->parent && ((GdkWindowPrivate*) private->parent)->parent)
1818 private = (GdkWindowPrivate*) private->parent;
1819 if (private->destroyed)
1824 ClientToScreen (private->xwindow, &pt);
1832 gdk_window_get_pointer (GdkWindow *window,
1835 GdkModifierType *mask)
1837 GdkWindowPrivate *private;
1838 GdkWindow *return_val;
1839 POINT pointc, point;
1843 window = (GdkWindow*) &gdk_root_parent;
1845 private = (GdkWindowPrivate*) window;
1848 GetCursorPos (&pointc);
1850 ScreenToClient (private->xwindow, &point);
1857 hwnd = WindowFromPoint (point);
1859 ScreenToClient (hwnd, &point);
1862 hwndc = ChildWindowFromPoint (hwnd, point);
1863 ClientToScreen (hwnd, &point);
1864 ScreenToClient (hwndc, &point);
1865 } while (hwndc != hwnd && (hwnd = hwndc, 1)); /* Ouch! */
1867 return_val = gdk_window_lookup (hwnd);
1873 GetKeyboardState (kbd);
1875 if (kbd[VK_SHIFT] & 0x80)
1876 *mask |= GDK_SHIFT_MASK;
1877 if (kbd[VK_CAPITAL] & 0x80)
1878 *mask |= GDK_LOCK_MASK;
1879 if (kbd[VK_CONTROL] & 0x80)
1880 *mask |= GDK_CONTROL_MASK;
1881 if (kbd[VK_MENU] & 0x80)
1882 *mask |= GDK_MOD1_MASK;
1883 if (kbd[VK_LBUTTON] & 0x80)
1884 *mask |= GDK_BUTTON1_MASK;
1885 if (kbd[VK_MBUTTON] & 0x80)
1886 *mask |= GDK_BUTTON2_MASK;
1887 if (kbd[VK_RBUTTON] & 0x80)
1888 *mask |= GDK_BUTTON3_MASK;
1895 gdk_window_at_pointer (gint *win_x,
1898 GdkWindowPrivate *private;
1900 POINT point, pointc;
1904 private = &gdk_root_parent;
1906 GetCursorPos (&pointc);
1908 hwnd = WindowFromPoint (point);
1912 window = (GdkWindow *) &gdk_root_parent;
1920 ScreenToClient (hwnd, &point);
1923 hwndc = ChildWindowFromPoint (hwnd, point);
1924 ClientToScreen (hwnd, &point);
1925 ScreenToClient (hwndc, &point);
1926 } while (hwndc != hwnd && (hwnd = hwndc, 1));
1928 window = gdk_window_lookup (hwnd);
1930 if (window && (win_x || win_y))
1932 GetClientRect (hwnd, &rect);
1934 *win_x = point.x - rect.left;
1936 *win_y = point.y - rect.top;
1939 GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%d+%d %#x%s\n",
1940 point.x, point.y, hwnd,
1941 (window == NULL ? " NULL" : "")));
1947 gdk_window_get_parent (GdkWindow *window)
1949 g_return_val_if_fail (window != NULL, NULL);
1951 return ((GdkWindowPrivate*) window)->parent;
1955 gdk_window_get_toplevel (GdkWindow *window)
1957 GdkWindowPrivate *private;
1959 g_return_val_if_fail (window != NULL, NULL);
1961 private = (GdkWindowPrivate*) window;
1963 while (private->window_type == GDK_WINDOW_CHILD)
1965 window = ((GdkWindowPrivate*) window)->parent;
1966 private = (GdkWindowPrivate*) window;
1973 gdk_window_get_children (GdkWindow *window)
1975 GdkWindowPrivate *private;
1978 g_return_val_if_fail (window != NULL, NULL);
1980 private = (GdkWindowPrivate*) window;
1981 if (private->destroyed)
1985 g_warning ("gdk_window_get_children ???");
1992 gdk_window_get_events (GdkWindow *window)
1994 GdkWindowPrivate *private;
1995 GdkEventMask event_mask;
1997 g_return_val_if_fail (window != NULL, 0);
1999 private = (GdkWindowPrivate*) window;
2000 if (private->destroyed)
2005 event_mask = private->event_mask;
2011 gdk_window_set_events (GdkWindow *window,
2012 GdkEventMask event_mask)
2014 GdkWindowPrivate *private;
2016 g_return_if_fail (window != NULL);
2018 private = (GdkWindowPrivate*) window;
2019 if (private->destroyed)
2022 private->event_mask = event_mask;
2026 gdk_window_add_colormap_windows (GdkWindow *window)
2028 g_warning ("gdk_window_add_colormap_windows not implemented"); /* XXX */
2032 * This needs the X11 shape extension.
2033 * If not available, shaped windows will look
2034 * ugly, but programs still work. Stefan Wille
2037 gdk_window_shape_combine_mask (GdkWindow *window,
2041 GdkWindowPrivate *window_private;
2043 g_return_if_fail (window != NULL);
2045 window_private = (GdkWindowPrivate*) window;
2049 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
2050 window_private->xwindow));
2051 SetWindowRgn (window_private->xwindow, NULL, TRUE);
2055 GdkPixmapPrivate *pixmap_private;
2061 /* Convert mask bitmap to region */
2062 pixmap_private = (GdkPixmapPrivate*) mask;
2063 hrgn = BitmapToRegion (pixmap_private->xwindow);
2065 GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
2066 window_private->xwindow,
2067 pixmap_private->xwindow));
2069 /* SetWindowRgn wants window (not client) coordinates */
2070 dwStyle = GetWindowLong (window_private->xwindow, GWL_STYLE);
2071 dwExStyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2072 GetClientRect (window_private->xwindow, &rect);
2073 AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
2074 OffsetRgn (hrgn, -rect.left, -rect.top);
2076 OffsetRgn (hrgn, x, y);
2078 /* If this is a top-level window, add the title bar to the region */
2079 if (window_private->window_type == GDK_WINDOW_TOPLEVEL)
2081 CombineRgn (hrgn, hrgn,
2082 CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
2086 SetWindowRgn (window_private->xwindow, hrgn, TRUE);
2091 gdk_window_add_filter (GdkWindow *window,
2092 GdkFilterFunc function,
2095 GdkWindowPrivate *private;
2097 GdkEventFilter *filter;
2099 private = (GdkWindowPrivate*) window;
2100 if (private && private->destroyed)
2104 tmp_list = private->filters;
2106 tmp_list = gdk_default_filters;
2110 filter = (GdkEventFilter *)tmp_list->data;
2111 if ((filter->function == function) && (filter->data == data))
2113 tmp_list = tmp_list->next;
2116 filter = g_new (GdkEventFilter, 1);
2117 filter->function = function;
2118 filter->data = data;
2121 private->filters = g_list_append (private->filters, filter);
2123 gdk_default_filters = g_list_append (gdk_default_filters, filter);
2127 gdk_window_remove_filter (GdkWindow *window,
2128 GdkFilterFunc function,
2131 GdkWindowPrivate *private;
2132 GList *tmp_list, *node;
2133 GdkEventFilter *filter;
2135 private = (GdkWindowPrivate*) window;
2138 tmp_list = private->filters;
2140 tmp_list = gdk_default_filters;
2144 filter = (GdkEventFilter *)tmp_list->data;
2146 tmp_list = tmp_list->next;
2148 if ((filter->function == function) && (filter->data == data))
2151 private->filters = g_list_remove_link (private->filters, node);
2153 gdk_default_filters = g_list_remove_link (gdk_default_filters, tmp_list);
2154 g_list_free_1 (node);
2163 gdk_window_set_override_redirect (GdkWindow *window,
2164 gboolean override_redirect)
2166 g_warning ("gdk_window_set_override_redirect not implemented"); /* XXX */
2170 gdk_window_set_icon (GdkWindow *window,
2171 GdkWindow *icon_window,
2175 g_warning ("gdk_window_set_icon not implemented"); /* XXX */
2179 gdk_window_set_icon_name (GdkWindow *window,
2182 GdkWindowPrivate *window_private;
2184 g_return_if_fail (window != NULL);
2185 window_private = (GdkWindowPrivate*) window;
2186 if (window_private->destroyed)
2189 if (!SetWindowText (window_private->xwindow, name))
2190 g_warning ("gdk_window_set_icon_name: SetWindowText failed");
2194 gdk_window_set_group (GdkWindow *window,
2197 g_warning ("gdk_window_set_group not implemented"); /* XXX */
2201 gdk_window_set_decorations (GdkWindow *window,
2202 GdkWMDecoration decorations)
2204 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2205 LONG style, exstyle;
2207 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2208 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2210 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2211 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
2213 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2215 if (decorations & GDK_DECOR_ALL)
2216 style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2217 if (decorations & GDK_DECOR_BORDER)
2218 style |= (WS_BORDER);
2219 if (decorations & GDK_DECOR_RESIZEH)
2220 style |= (WS_THICKFRAME);
2221 if (decorations & GDK_DECOR_TITLE)
2222 style |= (WS_CAPTION);
2223 if (decorations & GDK_DECOR_MENU)
2224 style |= (WS_SYSMENU);
2225 if (decorations & GDK_DECOR_MINIMIZE)
2226 style |= (WS_MINIMIZEBOX);
2227 if (decorations & GDK_DECOR_MAXIMIZE)
2228 style |= (WS_MAXIMIZEBOX);
2230 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2234 gdk_window_set_functions (GdkWindow *window,
2235 GdkWMFunction functions)
2237 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
2238 LONG style, exstyle;
2240 style = GetWindowLong (window_private->xwindow, GWL_STYLE);
2241 exstyle = GetWindowLong (window_private->xwindow, GWL_EXSTYLE);
2243 style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
2244 |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
2247 exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
2249 if (functions & GDK_FUNC_ALL)
2250 style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
2251 if (functions & GDK_FUNC_RESIZE)
2252 style |= (WS_THICKFRAME);
2253 if (functions & GDK_FUNC_MOVE)
2254 style |= (WS_THICKFRAME);
2255 if (functions & GDK_FUNC_MINIMIZE)
2256 style |= (WS_MINIMIZEBOX);
2257 if (functions & GDK_FUNC_MAXIMIZE)
2258 style |= (WS_MAXIMIZEBOX);
2260 SetWindowLong (window_private->xwindow, GWL_STYLE, style);
2264 gdk_window_get_toplevels (void)
2266 GList *new_list = NULL;
2269 tmp_list = gdk_root_parent.children;
2272 new_list = g_list_prepend (new_list, tmp_list->data);
2273 tmp_list = tmp_list->next;
2280 * propagate the shapes from all child windows of a GDK window to the parent
2281 * window. Shamelessly ripped from Enlightenment's code
2287 QueryTree (HWND hwnd,
2297 child = GetWindow (hwnd, GW_CHILD);
2299 child = GetWindow (child, GW_HWNDNEXT);
2302 } while (child != NULL);
2306 *children = g_new (HWND, n);
2307 for (i = 0; i < n; i++)
2310 child = GetWindow (hwnd, GW_CHILD);
2312 child = GetWindow (child, GW_HWNDNEXT);
2313 *children[i] = child;
2319 gdk_propagate_shapes (HANDLE win,
2323 HRGN region, childRegion;
2328 SetRectEmpty (&emptyRect);
2329 region = CreateRectRgnIndirect (&emptyRect);
2331 GetWindowRgn (win, region);
2333 QueryTree (win, &list, &num);
2336 WINDOWPLACEMENT placement;
2338 placement.length = sizeof (WINDOWPLACEMENT);
2339 /* go through all child windows and create/insert spans */
2340 for (i = 0; i < num; i++)
2342 GetWindowPlacement (list[i], &placement);
2343 if (placement.showCmd = SW_SHOWNORMAL)
2345 childRegion = CreateRectRgnIndirect (&emptyRect);
2346 GetWindowRgn (list[i], childRegion);
2347 CombineRgn (region, region, childRegion, RGN_OR);
2350 SetWindowRgn (win, region, TRUE);
2355 gdk_window_set_child_shapes (GdkWindow *window)
2357 GdkWindowPrivate *private;
2359 g_return_if_fail (window != NULL);
2361 private = (GdkWindowPrivate*) window;
2362 if (private->destroyed)
2365 gdk_propagate_shapes ( private->xwindow, FALSE);
2369 gdk_window_merge_child_shapes (GdkWindow *window)
2371 GdkWindowPrivate *private;
2373 g_return_if_fail (window != NULL);
2375 private = (GdkWindowPrivate*) window;
2376 if (private->destroyed)
2379 gdk_propagate_shapes (private->xwindow, TRUE);
2382 /*************************************************************
2383 * gdk_window_is_visible:
2384 * Check if the given window is mapped.
2388 * is the window mapped
2389 *************************************************************/
2392 gdk_window_is_visible (GdkWindow *window)
2394 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2396 g_return_val_if_fail (window != NULL, FALSE);
2398 return private->mapped;
2401 /*************************************************************
2402 * gdk_window_is_viewable:
2403 * Check if the window and all ancestors of the window
2404 * are mapped. (This is not necessarily "viewable" in
2405 * the X sense, since we only check as far as we have
2406 * GDK window parents, not to the root window)
2410 * is the window viewable
2411 *************************************************************/
2414 gdk_window_is_viewable (GdkWindow *window)
2416 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2418 g_return_val_if_fail (window != NULL, FALSE);
2421 (private != &gdk_root_parent) &&
2422 (private->window_type != GDK_WINDOW_FOREIGN))
2424 if (!private->mapped)
2427 private = (GdkWindowPrivate *)private->parent;
2434 gdk_drawable_set_data (GdkDrawable *drawable,
2437 GDestroyNotify destroy_func)
2439 g_dataset_set_data_full (drawable, key, data, destroy_func);
2443 /* Support for windows that can be guffaw-scrolled
2444 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
2448 gdk_window_gravity_works (void)
2450 enum { UNKNOWN, NO, YES };
2451 static gint gravity_works = UNKNOWN;
2453 if (gravity_works == UNKNOWN)
2460 attr.window_type = GDK_WINDOW_TEMP;
2461 attr.wclass = GDK_INPUT_OUTPUT;
2466 attr.event_mask = 0;
2468 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
2470 attr.window_type = GDK_WINDOW_CHILD;
2471 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
2473 gdk_window_set_static_win_gravity (child, TRUE);
2475 gdk_window_resize (parent, 100, 110);
2476 gdk_window_move (parent, 0, -10);
2477 gdk_window_move_resize (parent, 0, 0, 100, 100);
2479 gdk_window_resize (parent, 100, 110);
2480 gdk_window_move (parent, 0, -10);
2481 gdk_window_move_resize (parent, 0, 0, 100, 100);
2483 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
2485 gdk_window_destroy (parent);
2486 gdk_window_destroy (child);
2488 gravity_works = ((y == -20) ? YES : NO);
2491 return (gravity_works == YES);
2495 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
2497 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2499 g_return_if_fail (window != NULL);
2502 g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
2506 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
2508 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2510 g_return_if_fail (window != NULL);
2513 g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
2516 /*************************************************************
2517 * gdk_window_set_static_gravities:
2518 * Set the bit gravity of the given window to static,
2519 * and flag it so all children get static subwindow
2522 * window: window for which to set static gravity
2523 * use_static: Whether to turn static gravity on or off.
2525 * Does the XServer support static gravity?
2526 *************************************************************/
2529 gdk_window_set_static_gravities (GdkWindow *window,
2530 gboolean use_static)
2532 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
2535 g_return_val_if_fail (window != NULL, FALSE);
2537 if (!use_static == !private->guffaw_gravity)
2540 if (use_static && !gdk_window_gravity_works ())
2543 private->guffaw_gravity = use_static;
2545 gdk_window_set_static_bit_gravity (window, use_static);
2547 tmp_list = private->children;
2550 gdk_window_set_static_win_gravity (window, use_static);
2552 tmp_list = tmp_list->next;