1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include "gdkwindow.h"
31 #include "gdkinputprivate.h"
32 #include "gdkprivate-fb.h"
33 #include "gdkinternals.h"
37 static gpointer parent_class = NULL;
39 static void recompute_drawable(GdkDrawable *drawable);
42 g_free_2nd(gpointer a, gpointer b, gpointer data)
48 gdk_window_impl_fb_finalize (GObject *object)
50 GdkWindowFBData *fbd = GDK_WINDOW_FBDATA(object);
52 if(GDK_WINDOW_P(fbd->drawable_data.wrapper)->mapped)
53 gdk_window_hide(fbd->drawable_data.wrapper);
56 gdk_cursor_unref(fbd->cursor);
60 g_hash_table_foreach(fbd->properties, g_free_2nd, NULL);
61 g_hash_table_destroy(fbd->properties);
64 G_OBJECT_CLASS (parent_class)->finalize (object);
68 gdk_window_impl_fb_class_init (GdkWindowFBClass *klass)
70 GObjectClass *object_class = G_OBJECT_CLASS (klass);
71 // GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
73 parent_class = g_type_class_peek_parent (klass);
75 object_class->finalize = gdk_window_impl_fb_finalize;
79 gdk_window_impl_fb_init (GdkWindowFBData *impl)
81 impl->drawable_data.depth = gdk_display->modeinfo.bits_per_pixel;
82 impl->drawable_data.colormap = gdk_colormap_get_system ();
83 impl->event_mask = GDK_STRUCTURE_MASK;
87 _gdk_window_impl_get_type (void)
89 static GType object_type = 0;
93 static const GTypeInfo object_info =
95 sizeof (GdkWindowFBClass),
97 (GBaseFinalizeFunc) NULL,
98 (GClassInitFunc) gdk_window_impl_fb_class_init,
99 NULL, /* class_finalize */
100 NULL, /* class_data */
101 sizeof (GdkWindowFBData),
103 (GInstanceInitFunc) gdk_window_impl_fb_init,
106 object_type = g_type_register_static (gdk_drawable_impl_fb_get_type(),
114 #include "/usr/include/X11/bitmaps/left_ptr"
115 #include "/usr/include/X11/bitmaps/left_ptrmsk"
118 _gdk_windowing_window_init (void)
122 GdkBitmap *ptr, *mask;
124 GdkWindowPrivate *private;
126 ptr = gdk_bitmap_create_from_data(gdk_parent_root, left_ptr_bits, left_ptr_width, left_ptr_height);
127 mask = gdk_bitmap_create_from_data(gdk_parent_root, left_ptrmsk_bits, left_ptrmsk_width, left_ptrmsk_height);
129 cursor = gdk_cursor_new_from_pixmap(ptr, mask, NULL, NULL, left_ptr_x_hot, left_ptr_y_hot);
131 cursor = gdk_cursor_new(GDK_LEFT_PTR);
134 attr.width = gdk_screen_width();
135 attr.height = gdk_screen_height();
136 attr.window_type = GDK_WINDOW_ROOT;
137 attr.cursor = cursor;
138 attr.event_mask = GDK_EXPOSURE_MASK;
139 attr.wclass = GDK_INPUT_OUTPUT;
140 gdk_parent_root = gdk_window_new(NULL, &attr, GDK_WA_CURSOR);
141 private = (GdkWindowPrivate *)gdk_parent_root;
143 private->mapped = TRUE;
145 GDK_DRAWABLE_IMPL_FBDATA(gdk_parent_root)->lim_x = attr.width;
146 GDK_DRAWABLE_IMPL_FBDATA(gdk_parent_root)->lim_y = attr.height;
147 gdk_fb_drawable_clear(gdk_parent_root);
151 gdk_window_new (GdkWindow *parent,
152 GdkWindowAttr *attributes,
153 gint attributes_mask)
156 GdkWindowPrivate *private;
157 GdkWindowPrivate *parent_private;
159 GdkWindowFBData *impl;
163 g_return_val_if_fail (attributes != NULL, NULL);
165 if (!parent || attributes->window_type != GDK_WINDOW_CHILD)
166 parent = gdk_parent_root;
168 parent_private = (GdkWindowPrivate*) parent;
170 window = (GdkWindow *)g_type_create_instance(GDK_TYPE_WINDOW);
171 private = (GdkWindowObject *)window;
173 private->parent = parent_private;
175 if (attributes_mask & GDK_WA_X)
180 if (attributes_mask & GDK_WA_Y)
185 gdk_window_set_events(window, attributes->event_mask);
187 if (attributes_mask & GDK_WA_VISUAL)
188 visual = attributes->visual;
190 visual = gdk_visual_get_system();
192 impl = (GdkWindowFBData *)private->impl;
193 impl->drawable_data.wrapper = window;
196 impl->drawable_data.width = (attributes->width > 1) ? (attributes->width) : (1);
197 impl->drawable_data.height = (attributes->height > 1) ? (attributes->height) : (1);
198 private->window_type = impl->drawable_data.window_type = attributes->window_type;
199 impl->drawable_data.mem = gdk_display->fbmem;
200 impl->drawable_data.rowstride = gdk_display->sinfo.line_length;
201 gdk_window_move_resize (window, x, y,
202 impl->drawable_data.width, impl->drawable_data.height);
204 if (attributes->wclass == GDK_INPUT_OUTPUT)
206 depth = visual->depth;
208 private->input_only = FALSE;
209 private->depth = impl->drawable_data.depth;
211 if ((attributes_mask & GDK_WA_COLORMAP)
212 && attributes->colormap)
213 impl->drawable_data.colormap = attributes->colormap;
215 impl->drawable_data.colormap = gdk_colormap_get_system();
217 switch (impl->drawable_data.window_type)
219 case GDK_WINDOW_TOPLEVEL:
220 case GDK_WINDOW_CHILD:
221 case GDK_WINDOW_DIALOG:
222 case GDK_WINDOW_TEMP:
226 case GDK_WINDOW_ROOT:
228 g_error ("cannot make windows of type GDK_WINDOW_ROOT");
230 case GDK_DRAWABLE_PIXMAP:
231 g_error ("cannot make windows of type GDK_DRAWABLE_PIXMAP (use gdk_pixmap_new)");
238 private->input_only = TRUE;
240 impl->drawable_data.colormap = NULL;
243 gdk_drawable_ref (window);
245 if (impl->drawable_data.colormap)
246 gdk_colormap_ref (impl->drawable_data.colormap);
248 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
249 (attributes->cursor) :
254 parent_private->children = g_list_prepend (parent_private->children, window);
255 if(parent_private->children->next)
256 impl->level = GDK_WINDOW_FBDATA(GDK_WINDOW_P(parent_private->children->next->data)->impl)->level + 1;
262 /* Call this function when you want a window and all its children to
263 * disappear. When xdestroy is true, a request to destroy the XWindow
264 * is sent out. When it is false, it is assumed that the XWindow has
265 * been or will be destroyed by destroying some ancestor of this
269 _gdk_windowing_window_destroy(GdkWindow *window,
271 gboolean foreign_destroy)
274 GdkWindowPrivate *private;
275 GdkWindowPrivate *temp_private;
276 GdkWindow *temp_window;
279 gboolean our_destroy = !foreign_destroy;
281 g_return_if_fail (window != NULL);
283 private = (GdkWindowPrivate*) window;
285 switch (private->window_type)
287 case GDK_WINDOW_TOPLEVEL:
288 case GDK_WINDOW_CHILD:
289 case GDK_WINDOW_DIALOG:
290 case GDK_WINDOW_TEMP:
291 case GDK_WINDOW_FOREIGN:
292 if (!private->destroyed)
296 GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
297 if (parent_private->children)
298 parent_private->children = g_list_remove (parent_private->children, window);
301 if (private->bg_pixmap && private->bg_pixmap != GDK_PARENT_RELATIVE_BG && private->bg_pixmap != GDK_NO_BG)
303 gdk_pixmap_unref (private->bg_pixmap);
304 private->bg_pixmap = NULL;
307 if (GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_FOREIGN)
309 children = tmp = private->children;
310 private->children = NULL;
314 temp_window = tmp->data;
317 temp_private = (GdkWindowPrivate*) temp_window;
319 _gdk_windowing_window_destroy (temp_window, !FALSE,
323 g_list_free (children);
326 if (private->extension_events != 0)
327 gdk_input_window_destroy (window);
329 if (private->filters)
331 tmp = private->filters;
339 g_list_free (private->filters);
340 private->filters = NULL;
343 if (private->window_type == GDK_WINDOW_FOREIGN)
345 if (our_destroy && (private->parent != NULL))
347 /* It's somebody elses window, but in our heirarchy,
348 * so reparent it to the root window, and then send
349 * it a delete event, as if we were a WM
351 gdk_error_trap_push ();
352 gdk_window_hide (window);
353 gdk_window_reparent (window, NULL, 0, 0);
356 gdk_error_trap_pop ();
360 if (private->colormap)
361 gdk_colormap_unref (private->colormap);
363 private->mapped = FALSE;
364 private->drawable.destroyed = TRUE;
368 case GDK_WINDOW_ROOT:
369 g_error ("attempted to destroy root window");
372 case GDK_WINDOW_PIXMAP:
373 g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
379 /* This function is called when the XWindow is really gone. */
381 static gboolean all_parents_shown(GdkWindowPrivate *private)
383 while(private->mapped)
386 private = (GdkWindowPrivate *)private->parent;
395 send_map_events(GdkWindowPrivate *private, gboolean is_map)
398 GdkWindow *parent = (GdkWindow *)private->parent;
406 gdk_event_make((GdkWindow *)private, GDK_MAP, TRUE);
408 if(private->input_only)
412 parent = (GdkWindow *)private;
414 if(((GDK_DRAWABLE_IMPL_FBDATA(private)->abs_x > GDK_DRAWABLE_IMPL_FBDATA(parent)->lim_x)
415 || (GDK_DRAWABLE_IMPL_FBDATA(private)->abs_y > GDK_DRAWABLE_IMPL_FBDATA(parent)->lim_y)
416 || (GDK_DRAWABLE_IMPL_FBDATA(private)->lim_x < GDK_DRAWABLE_IMPL_FBDATA(parent)->llim_x)
417 || (GDK_DRAWABLE_IMPL_FBDATA(private)->lim_y < GDK_DRAWABLE_IMPL_FBDATA(parent)->llim_y)))
421 gdk_window_clear((GdkWindow *)private);
424 event = gdk_event_new();
425 event->expose.type = GDK_EXPOSE;
426 event->expose.window = gdk_window_ref((GdkWindow *)private);
427 if(GDK_DRAWABLE_IMPL_FBDATA(private)->abs_x > GDK_DRAWABLE_IMPL_FBDATA(parent)->llim_x)
428 event->expose.area.x = 0;
430 event->expose.area.x = GDK_DRAWABLE_IMPL_FBDATA(parent)->llim_x - GDK_DRAWABLE_IMPL_FBDATA(private)->abs_x;
432 if(GDK_DRAWABLE_IMPL_FBDATA(private)->abs_y > GDK_DRAWABLE_IMPL_FBDATA(parent)->llim_y)
433 event->expose.area.y = 0;
435 event->expose.area.y = GDK_DRAWABLE_IMPL_FBDATA(parent)->llim_y - GDK_DRAWABLE_IMPL_FBDATA(private)->abs_y;
437 event->expose.area.width = MIN(GDK_DRAWABLE_IMPL_FBDATA(private)->width,
438 GDK_DRAWABLE_IMPL_FBDATA(private)->lim_x - GDK_DRAWABLE_IMPL_FBDATA(private)->abs_x);
439 event->expose.area.height = MIN(GDK_DRAWABLE_IMPL_FBDATA(private)->height,
440 GDK_DRAWABLE_IMPL_FBDATA(private)->lim_y - GDK_DRAWABLE_IMPL_FBDATA(private)->abs_y);
441 if(event->expose.area.width > 0
442 && event->expose.area.height > 0)
444 gdk_event_queue_append(event);
447 gdk_event_free(event);
449 for(l = private->children; l; l = l->next)
450 send_map_events(l->data, is_map);
453 /* Cut & paste versions of the stuff in gdkwindow.c, with the addition of clearing the newly exposed region. */
455 gdk_window_invalidate_region_clear(GdkWindow *window, GdkRegion *region)
458 GdkWindowPrivate *private = GDK_WINDOW_P(window);
460 if (private->input_only)
463 if(private->bg_pixmap != GDK_NO_BG)
464 for(i = 0; i < region->numRects; i++)
465 gdk_window_clear_area(window,
468 region->rects[i].x2 - region->rects[i].x1,
469 region->rects[i].y2 - region->rects[i].y1);
471 gdk_window_invalidate_region(window, region, FALSE);
475 GdkRectangle child_rect;
476 GdkRegion *child_region;
478 tmp_list = private->children;
481 GdkWindowObject *child = tmp_list->data;
482 tmp_list = tmp_list->next;
484 if (!child->input_only)
488 gdk_drawable_get_size (GDK_DRAWABLE (child),
491 child_rect.x = child->x;
492 child_rect.y = child->y;
493 child_rect.width = width;
494 child_rect.height = height;
496 child_region = gdk_region_rectangle (&child_rect);
497 gdk_region_intersect (child_region, region);
499 if (!gdk_region_empty (child_region))
501 gdk_region_offset (child_region, - child_rect.x, - child_rect.y);
502 gdk_window_invalidate_region_clear ((GdkWindow *)child, child_region);
505 gdk_region_destroy (child_region);
512 gdk_window_invalidate_rect_clear(GdkWindow *window, GdkRectangle *rect)
514 GdkWindowPrivate *private = GDK_WINDOW_P(window);
516 if (private->input_only)
519 if(GDK_WINDOW_P(window)->bg_pixmap != GDK_NO_BG)
520 gdk_window_clear_area(window, rect->x, rect->y, rect->width, rect->height);
521 gdk_window_invalidate_rect(window, rect, FALSE);
525 GdkRectangle child_rect, new_rect;
527 tmp_list = private->children;
530 GdkWindowObject *child = tmp_list->data;
531 tmp_list = tmp_list->next;
533 if (!child->input_only)
537 width = GDK_DRAWABLE_IMPL_FBDATA(child)->width;
538 height = GDK_DRAWABLE_IMPL_FBDATA(child)->height;
540 child_rect.x = child->x;
541 child_rect.y = child->y;
542 child_rect.width = width;
543 child_rect.height = height;
545 if (gdk_rectangle_intersect (rect, &child_rect, &new_rect))
547 new_rect.x -= child_rect.x;
548 new_rect.y -= child_rect.y;
550 gdk_window_invalidate_rect_clear ((GdkWindow *)child, &new_rect);
559 gdk_fb_redraw_all(void)
563 r.width = GDK_DRAWABLE_IMPL_FBDATA(gdk_parent_root)->width;
564 r.height = GDK_DRAWABLE_IMPL_FBDATA(gdk_parent_root)->height;
565 gdk_window_invalidate_rect(gdk_parent_root, &r, TRUE);
566 gdk_window_process_all_updates();
570 gdk_window_show (GdkWindow *window)
572 GdkWindowPrivate *private;
574 g_return_if_fail (window != NULL);
576 private = (GdkWindowPrivate*) window;
578 if (!private->destroyed && !private->mapped)
580 private->mapped = TRUE;
582 if(all_parents_shown((GdkWindowPrivate *)private->parent))
586 recompute_drawable((GdkDrawable *)window);
588 send_map_events(private, TRUE);
590 private->mapped = FALSE; /* a hack, ayup, to make gdk_window_get_pointer get the other window */
591 gdk_fb_window_visibility_crossing(window, TRUE);
592 private->mapped = TRUE;
594 if(private->input_only)
597 rect.x = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_x;
598 rect.y = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_y;
599 rect.width = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_x - rect.x;
600 rect.height = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_y - rect.y;
601 gdk_window_invalidate_rect_clear(gdk_parent_root, &rect);
607 gdk_window_hide (GdkWindow *window)
609 GdkWindowPrivate *private;
611 g_return_if_fail (window != NULL);
613 private = (GdkWindowPrivate*) window;
615 if (!private->destroyed && private->mapped)
621 event = gdk_event_make(window, GDK_UNMAP, TRUE);
623 r.x = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_x;
624 r.y = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_y;
625 r.width = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_x - r.x;
626 r.height = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_y - r.y;
628 private->mapped = FALSE;
630 if(private->parent == GDK_WINDOW_P(gdk_parent_root))
631 gdk_fb_drawable_clear(gdk_parent_root);
633 if(all_parents_shown((GdkWindowPrivate *)private->parent))
634 gdk_fb_window_visibility_crossing(window, FALSE);
636 do_hide = gdk_fb_cursor_need_hide(&r);
639 gdk_fb_cursor_hide();
640 gdk_window_invalidate_rect_clear(gdk_parent_root, &r);
642 gdk_fb_cursor_unhide();
647 gdk_window_withdraw (GdkWindow *window)
649 gdk_window_hide(window);
653 gdk_window_move (GdkWindow *window,
657 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
659 g_return_if_fail (window != NULL);
660 g_return_if_fail (GDK_IS_WINDOW (window));
662 gdk_window_move_resize (window, x, y,
663 GDK_DRAWABLE_IMPL_FBDATA(private)->width, GDK_DRAWABLE_IMPL_FBDATA(private)->height);
667 gdk_window_resize (GdkWindow *window,
671 GdkWindowPrivate *private;
673 g_return_if_fail (window != NULL);
674 g_return_if_fail (GDK_IS_WINDOW (window));
676 private = (GdkWindowPrivate*) window;
682 gdk_window_move_resize(window, private->x, private->y, width, height);
686 recompute_abs_positions(GdkDrawable *drawable, gint parent_x, gint parent_y,
687 gint parent_llim_x, gint parent_llim_y,
688 gint parent_lim_x, gint parent_lim_y)
692 if(GDK_IS_WINDOW(drawable))
694 GdkWindowPrivate *private = GDK_WINDOW_P(drawable);
701 GDK_DRAWABLE_IMPL_FBDATA(private)->abs_x = parent_x + private->x;
702 GDK_DRAWABLE_IMPL_FBDATA(private)->abs_y = parent_y + private->y;
703 x = MAX(parent_llim_x, GDK_DRAWABLE_IMPL_FBDATA(private)->abs_x);
704 x = MIN(x, parent_lim_x);
705 GDK_DRAWABLE_IMPL_FBDATA(private)->llim_x = x;
706 y = MAX(parent_llim_y, GDK_DRAWABLE_IMPL_FBDATA(private)->abs_y);
707 y = MIN(y, parent_lim_y);
708 GDK_DRAWABLE_IMPL_FBDATA(private)->llim_y = y;
709 x = MIN(parent_lim_x,
710 GDK_DRAWABLE_IMPL_FBDATA(private)->abs_x + GDK_DRAWABLE_IMPL_FBDATA(private)->width);
711 x = MAX(x, GDK_DRAWABLE_IMPL_FBDATA(private)->llim_x);
712 GDK_DRAWABLE_IMPL_FBDATA(private)->lim_x = x;
713 y = MIN(parent_lim_y,
714 GDK_DRAWABLE_IMPL_FBDATA(private)->abs_y + GDK_DRAWABLE_IMPL_FBDATA(private)->height);
715 y = MAX(y, GDK_DRAWABLE_IMPL_FBDATA(private)->llim_y);
716 GDK_DRAWABLE_IMPL_FBDATA(private)->lim_y = y;
718 g_assert(GDK_DRAWABLE_IMPL_FBDATA(private)->llim_x <= GDK_DRAWABLE_IMPL_FBDATA(private)->lim_x);
719 g_assert(GDK_DRAWABLE_IMPL_FBDATA(private)->llim_y <= GDK_DRAWABLE_IMPL_FBDATA(private)->lim_y);
721 for(l = private->children; l; l = l->next)
722 recompute_abs_positions(l->data, GDK_DRAWABLE_IMPL_FBDATA(private)->abs_x, GDK_DRAWABLE_IMPL_FBDATA(private)->abs_y,
723 GDK_DRAWABLE_IMPL_FBDATA(private)->llim_x, GDK_DRAWABLE_IMPL_FBDATA(private)->llim_y,
724 GDK_DRAWABLE_IMPL_FBDATA(private)->lim_x, GDK_DRAWABLE_IMPL_FBDATA(private)->lim_y);
728 GDK_DRAWABLE_IMPL_FBDATA(drawable)->abs_x = 0;
729 GDK_DRAWABLE_IMPL_FBDATA(drawable)->abs_y = 0;
730 GDK_DRAWABLE_IMPL_FBDATA(drawable)->llim_x = 0;
731 GDK_DRAWABLE_IMPL_FBDATA(drawable)->llim_y = 0;
732 GDK_DRAWABLE_IMPL_FBDATA(drawable)->lim_x = GDK_DRAWABLE_IMPL_FBDATA(drawable)->width;
733 GDK_DRAWABLE_IMPL_FBDATA(drawable)->lim_y = GDK_DRAWABLE_IMPL_FBDATA(drawable)->height;
738 recompute_drawable(GdkDrawable *drawable)
740 if(GDK_IS_WINDOW(drawable))
742 GdkWindowPrivate *private = GDK_WINDOW_P(drawable);
745 parent = (GdkWindow *)private->parent;
747 parent = gdk_parent_root;
749 recompute_abs_positions(drawable, GDK_DRAWABLE_IMPL_FBDATA(parent)->abs_x,
750 GDK_DRAWABLE_IMPL_FBDATA(parent)->abs_y,
751 GDK_DRAWABLE_IMPL_FBDATA(parent)->llim_x,
752 GDK_DRAWABLE_IMPL_FBDATA(parent)->llim_y,
753 GDK_DRAWABLE_IMPL_FBDATA(parent)->lim_x,
754 GDK_DRAWABLE_IMPL_FBDATA(parent)->lim_y);
757 recompute_abs_positions(drawable, 0, 0, 0, 0, INT_MAX, INT_MAX);
761 gdk_fb_window_move_resize (GdkWindow *window,
766 gboolean send_expose_events)
768 GdkWindowPrivate *private;
771 g_return_if_fail (window != NULL);
772 g_return_if_fail (GDK_IS_WINDOW (window));
779 private = (GdkWindowPrivate*) window;
781 if (!private->destroyed)
783 GdkRegion *old_region;
784 GdkRectangle old_rect;
786 if(private->input_only)
787 send_expose_events = FALSE;
789 if(private->mapped && send_expose_events)
791 old_region = gdk_fb_clip_region(GDK_DRAWABLE_IMPL(window), NULL, TRUE, FALSE);
793 old_rect.x = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_x;
794 old_rect.y = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_y;
795 old_rect.width = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_x - old_rect.x;
796 old_rect.height = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_y - old_rect.y;
801 dw = width - GDK_DRAWABLE_IMPL_FBDATA(private)->width;
802 dh = height - GDK_DRAWABLE_IMPL_FBDATA(private)->height;
806 GDK_DRAWABLE_IMPL_FBDATA(private)->width = width;
807 GDK_DRAWABLE_IMPL_FBDATA(private)->height = height;
811 recompute_drawable((GdkDrawable *)window);
813 if(send_expose_events)
815 GdkRectangle new_rect;
816 GdkRegion *new_region, *region;
818 gboolean handle_cursor = FALSE;
820 new_region = gdk_fb_clip_region(GDK_DRAWABLE_IMPL(window), NULL, TRUE, FALSE);
822 new_rect.x = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_x;
823 new_rect.y = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_y;
824 new_rect.width = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_x - new_rect.x;
825 new_rect.height = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_y - new_rect.y;
827 region = gdk_region_copy(old_region);
828 gdk_region_offset(region, dx, dy);
829 gdk_region_intersect(region, new_region);
833 GdkFBDrawingContext fbdc;
834 GdkRectangle cursor_rect;
836 gdk_fb_get_cursor_rect(&cursor_rect);
838 if(gdk_fb_cursor_region_need_hide(region))
840 gdk_fb_cursor_hide();
841 handle_cursor = TRUE;
844 gdk_fb_drawing_context_init(&fbdc, GDK_DRAWABLE_IMPL(gdk_parent_root), NULL, FALSE, FALSE);
845 for(i = 0; i < region->numRects; i++)
847 gdk_fb_draw_drawable_3(GDK_DRAWABLE_IMPL(gdk_parent_root), NULL, GDK_DRAWABLE_IMPL(gdk_parent_root),
849 (region->rects[i].x1 - dx),
850 (region->rects[i].y1 - dy),
851 (region->rects[i].x1),
852 (region->rects[i].y1),
853 (region->rects[i].x2 - region->rects[i].x1),
854 (region->rects[i].y2 - region->rects[i].y1));
856 gdk_fb_drawing_context_finalize(&fbdc);
859 gdk_region_union(new_region, old_region);
860 gdk_region_subtract(new_region, region);
861 gdk_region_destroy(region);
862 gdk_window_invalidate_region_clear(gdk_parent_root, new_region);
864 gdk_fb_cursor_unhide();
866 gdk_region_destroy(old_region);
867 gdk_region_destroy(new_region);
874 gdk_window_move_resize (GdkWindow *window,
880 gdk_fb_window_move_resize(window, x, y, width, height, TRUE);
884 gdk_window_reparent (GdkWindow *window,
885 GdkWindow *new_parent,
889 GdkWindowPrivate *window_private;
890 GdkWindowPrivate *parent_private;
891 GdkWindowPrivate *old_parent_private;
893 g_return_if_fail (window != NULL);
894 g_return_if_fail (GDK_IS_WINDOW (window));
895 g_return_if_fail (new_parent != NULL);
896 g_return_if_fail (GDK_IS_WINDOW (new_parent));
899 new_parent = gdk_parent_root;
901 window_private = (GdkWindowPrivate*) window;
902 old_parent_private = (GdkWindowPrivate*)window_private->parent;
903 parent_private = (GdkWindowPrivate*) new_parent;
905 g_assert(GDK_DRAWABLE_IMPL_FBDATA(window_private)->colormap);
907 window_private->parent = (GdkWindowPrivate *)new_parent;
909 if (old_parent_private)
910 old_parent_private->children = g_list_remove (old_parent_private->children, window);
912 parent_private->children = g_list_prepend (parent_private->children, window);
914 if(window_private->mapped)
919 r.x = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_x;
920 r.y = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_y;
921 r.width = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_x - r.x;
922 r.height = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_y - r.y;
923 region = gdk_region_rectangle(&r);
925 recompute_drawable((GdkDrawable *)window);
926 r.x = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_x;
927 r.y = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_y;
928 r.width = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_x - r.x;
929 r.height = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_y - r.y;
930 gdk_region_union_with_rect(region, &r);
932 gdk_window_invalidate_region_clear(gdk_parent_root, region);
933 gdk_region_destroy(region);
939 _gdk_windowing_window_clear_area (GdkWindow *window,
948 if(GDK_WINDOW_P(window)->input_only)
951 bgpm = GDK_WINDOW_P(window)->bg_pixmap;
954 for(relto = window; bgpm == GDK_PARENT_RELATIVE_BG && relto; relto = (GdkWindow *)GDK_WINDOW_P(relto)->parent)
955 bgpm = GDK_WINDOW_P(relto)->bg_pixmap;
958 if(bgpm && bgpm != GDK_NO_BG)
963 GdkFBDrawingContext fbdc;
965 return; /* Don't bother doing this - gtk+ will do it itself using GC tiles. If removing this line,
966 then also remove the #if 0 stuff */
968 gdk_fb_drawing_context_init(&fbdc, window, NULL, FALSE, TRUE);
970 xtrans = GDK_DRAWABLE_IMPL_FBDATA(relto)->abs_x - GDK_DRAWABLE_IMPL_FBDATA(window)->abs_x;
971 ytrans = GDK_DRAWABLE_IMPL_FBDATA(relto)->abs_y - GDK_DRAWABLE_IMPL_FBDATA(window)->abs_y;
973 for(cury = y - ytrans; cury < (y - ytrans + height); cury += ystep)
975 int drawh = cury % GDK_DRAWABLE_P(bgpm)->height;
976 ystep = GDK_DRAWABLE_P(bgpm)->height - drawh;
978 for(curx = x - xtrans; curx < (x - xtrans + width); curx += xstep)
980 int draww = curx % GDK_DRAWABLE_IMPL_FBDATA(bgpm)->width;
981 xstep = GDK_DRAWABLE_IMPL_FBDATA(bgpm)->width - draww;
983 gdk_fb_draw_drawable_3(GDK_DRAWABLE_IMPL(window), NULL, GDK_DRAWABLE_IMPL(bgpm),
985 draww, drawh, curx + xtrans, cury + ytrans,
990 gdk_fb_drawing_context_finalize(&fbdc);
993 gdk_fb_draw_rectangle(GDK_DRAWABLE_IMPL(window), NULL, TRUE, x, y, width, height);
996 /* What's the diff? */
998 _gdk_windowing_window_clear_area_e (GdkWindow *window,
1004 _gdk_windowing_window_clear_area(window, x, y, width, height);
1008 compare_window_levels(gconstpointer a, gconstpointer b)
1010 return (GDK_WINDOW_IMPL_FBDATA(b)->level - GDK_WINDOW_IMPL_FBDATA(a)->level);
1013 /* Child list is sorted bottom-to-top */
1015 gdk_window_resort_children(GdkWindow *win)
1017 GdkWindowPrivate *private = GDK_WINDOW_P(win);
1019 private->children = g_list_sort(private->children, compare_window_levels);
1021 /* Now the fun part - redraw */
1022 if(GDK_WINDOW_P(win)->parent)
1024 gdk_window_invalidate_rect(win, NULL, TRUE);
1029 gdk_window_raise (GdkWindow *window)
1031 g_return_if_fail (window != NULL);
1032 g_return_if_fail (GDK_IS_WINDOW (window));
1034 GDK_WINDOW_IMPL_FBDATA(window)->level++;
1036 if(GDK_WINDOW_P(window)->parent)
1037 gdk_window_resort_children((GdkWindow *)GDK_WINDOW_P(window)->parent);
1041 gdk_window_lower (GdkWindow *window)
1043 g_return_if_fail (window != NULL);
1044 g_return_if_fail (GDK_IS_WINDOW (window));
1046 GDK_WINDOW_IMPL_FBDATA(window)->level--;
1048 if(GDK_WINDOW_P(window)->parent)
1049 gdk_window_resort_children((GdkWindow *)GDK_WINDOW_P(window)->parent);
1053 gdk_window_set_hints (GdkWindow *window,
1065 gdk_window_set_geometry_hints (GdkWindow *window,
1066 GdkGeometry *geometry,
1067 GdkWindowHints geom_mask)
1072 gdk_window_set_title (GdkWindow *window,
1078 gdk_window_set_role (GdkWindow *window,
1084 gdk_window_set_transient_for (GdkWindow *window,
1087 GDK_WINDOW_IMPL_FBDATA(window)->level = GDK_WINDOW_IMPL_FBDATA(parent)->level + 1;
1091 gdk_window_set_background (GdkWindow *window,
1094 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
1096 g_return_if_fail (window != NULL);
1097 g_return_if_fail (GDK_IS_WINDOW (window));
1099 private->bg_color = *color;
1101 if (private->bg_pixmap &&
1102 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1103 private->bg_pixmap != GDK_NO_BG)
1105 gdk_pixmap_unref (private->bg_pixmap);
1106 private->bg_pixmap = NULL;
1111 gdk_window_set_back_pixmap (GdkWindow *window,
1113 gboolean parent_relative)
1115 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
1116 GdkPixmap *old_pixmap;
1118 g_return_if_fail (window != NULL);
1119 g_return_if_fail (GDK_IS_WINDOW (window));
1120 g_return_if_fail (pixmap == NULL || !parent_relative);
1122 old_pixmap = private->bg_pixmap;
1124 if (parent_relative)
1126 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1132 gdk_pixmap_ref (pixmap);
1133 private->bg_pixmap = pixmap;
1137 private->bg_pixmap = GDK_NO_BG;
1142 old_pixmap != GDK_PARENT_RELATIVE_BG &&
1143 old_pixmap != GDK_NO_BG)
1144 gdk_pixmap_unref (old_pixmap);
1148 gdk_window_set_cursor (GdkWindow *window,
1151 GdkCursor *old_cursor = GDK_WINDOW_IMPL_FBDATA(window)->cursor;
1152 GdkRectangle window_reg;
1154 GDK_WINDOW_IMPL_FBDATA(window)->cursor = cursor?gdk_cursor_ref(cursor):NULL;
1157 gdk_cursor_unref(old_cursor);
1159 window_reg.x = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_x;
1160 window_reg.y = GDK_DRAWABLE_IMPL_FBDATA(window)->llim_y;
1161 window_reg.width = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_x - window_reg.x;
1162 window_reg.height = GDK_DRAWABLE_IMPL_FBDATA(window)->lim_y - window_reg.y;
1163 if(gdk_fb_cursor_need_hide(&window_reg))
1165 gdk_fb_cursor_reset();
1170 gdk_window_get_geometry (GdkWindow *window,
1177 GdkWindowPrivate *private = (GdkWindowPrivate *)window;
1179 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1182 window = gdk_parent_root;
1184 if (!private->destroyed)
1192 *width = GDK_DRAWABLE_IMPL_FBDATA(window)->width;
1194 *height = GDK_DRAWABLE_IMPL_FBDATA(window)->height;
1196 *depth = gdk_display->modeinfo.bits_per_pixel;
1201 gdk_window_get_origin (GdkWindow *window,
1205 g_return_val_if_fail (window != NULL, 0);
1208 *x = GDK_DRAWABLE_IMPL_FBDATA(window)->abs_x;
1210 *y = GDK_DRAWABLE_IMPL_FBDATA(window)->abs_y;
1216 gdk_window_get_deskrelative_origin (GdkWindow *window,
1222 gboolean return_val;
1224 g_return_val_if_fail (window != NULL, 0);
1226 if (!GDK_WINDOW_DESTROYED (window))
1228 tx = GDK_DRAWABLE_IMPL_FBDATA(window)->abs_x;
1229 ty = GDK_DRAWABLE_IMPL_FBDATA(window)->abs_y;
1245 gdk_window_get_root_origin (GdkWindow *window,
1249 gdk_window_get_deskrelative_origin(window, x, y);
1253 gdk_window_get_pointer (GdkWindow *window,
1256 GdkModifierType *mask)
1258 GdkWindow *return_val;
1262 GdkModifierType my_mask;
1264 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1267 window = gdk_parent_root;
1269 gdk_window_get_root_origin(window, &x_int, &y_int);
1270 gdk_input_ps2_get_mouseinfo(&winx, &winy, &my_mask);
1284 if((winx >= 0) && (winx < GDK_DRAWABLE_IMPL_FBDATA(window)->width)
1285 && (winy >= 0) && (winy < GDK_DRAWABLE_IMPL_FBDATA(window)->height))
1287 GdkWindowPrivate *private;
1288 GdkWindowPrivate *sub;
1289 int subx = winx, suby = winy;
1291 for(private = sub = (GdkWindowPrivate *)window; sub; private = sub)
1295 for(ltmp = private->children; ltmp; ltmp = ltmp->next)
1303 && (subx < (GDK_DRAWABLE_IMPL_FBDATA(sub)->width + sub->x))
1305 && (suby < (GDK_DRAWABLE_IMPL_FBDATA(sub)->height + sub->y)))
1320 return_val = (GdkWindow *)private;
1324 return_val = gdk_parent_root;
1330 gdk_window_at_pointer (gint *win_x,
1334 GdkWindow *retval = gdk_window_get_pointer(NULL, win_x, win_y, NULL);
1338 gdk_window_get_origin(retval, &ry, &rx);
1349 gdk_window_get_events (GdkWindow *window)
1351 g_return_val_if_fail (window != NULL, 0);
1352 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1354 if (GDK_WINDOW_DESTROYED (window))
1357 return GDK_WINDOW_IMPL_FBDATA(window)->event_mask;
1361 gdk_window_set_events (GdkWindow *window,
1362 GdkEventMask event_mask)
1365 g_return_if_fail (window != NULL);
1366 g_return_if_fail (GDK_IS_WINDOW (window));
1368 if (!GDK_WINDOW_DESTROYED (window))
1369 GDK_WINDOW_IMPL_FBDATA(window)->event_mask = event_mask;
1373 gdk_window_add_colormap_windows (GdkWindow *window)
1375 g_return_if_fail (window != NULL);
1376 g_return_if_fail (GDK_IS_WINDOW (window));
1382 * This needs the X11 shape extension.
1383 * If not available, shaped windows will look
1384 * ugly, but programs still work. Stefan Wille
1387 gdk_window_shape_combine_mask (GdkWindow *window,
1391 g_return_if_fail (window != NULL);
1392 g_return_if_fail (GDK_IS_WINDOW (window));
1396 gdk_window_set_override_redirect (GdkWindow *window,
1397 gboolean override_redirect)
1399 g_return_if_fail (window != NULL);
1400 g_return_if_fail (GDK_IS_WINDOW (window));
1406 gdk_window_set_icon (GdkWindow *window,
1407 GdkWindow *icon_window,
1411 g_return_if_fail (window != NULL);
1412 g_return_if_fail (GDK_IS_WINDOW (window));
1418 gdk_window_set_icon_name (GdkWindow *window,
1421 g_return_if_fail (window != NULL);
1422 g_return_if_fail (GDK_IS_WINDOW (window));
1428 gdk_window_set_group (GdkWindow *window,
1431 g_return_if_fail (window != NULL);
1432 g_return_if_fail (GDK_IS_WINDOW (window));
1433 g_return_if_fail (leader != NULL);
1434 g_return_if_fail (GDK_IS_WINDOW (leader));
1440 gdk_window_set_decorations (GdkWindow *window,
1441 GdkWMDecoration decorations)
1443 g_return_if_fail (window != NULL);
1444 g_return_if_fail (GDK_IS_WINDOW (window));
1450 gdk_window_set_functions (GdkWindow *window,
1451 GdkWMFunction functions)
1453 g_return_if_fail (window != NULL);
1454 g_return_if_fail (GDK_IS_WINDOW (window));
1460 gdk_window_set_child_shapes (GdkWindow *window)
1462 g_return_if_fail (window != NULL);
1463 g_return_if_fail (GDK_IS_WINDOW (window));
1468 gdk_window_merge_child_shapes (GdkWindow *window)
1470 g_return_if_fail (window != NULL);
1471 g_return_if_fail (GDK_IS_WINDOW (window));
1475 /*************************************************************
1476 * gdk_window_set_static_gravities:
1477 * Set the bit gravity of the given window to static,
1478 * and flag it so all children get static subwindow
1481 * window: window for which to set static gravity
1482 * use_static: Whether to turn static gravity on or off.
1484 * Does the XServer support static gravity?
1485 *************************************************************/
1488 gdk_window_set_static_gravities (GdkWindow *window,
1489 gboolean use_static)
1491 g_return_val_if_fail (window != NULL, FALSE);
1492 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1498 _gdk_windowing_window_get_offsets (GdkWindow *window,
1502 *x_offset = *y_offset = 0;
1506 _gdk_windowing_window_queue_antiexpose (GdkWindow *window,