]> Pileus Git - ~andy/gtk/blob - gdk/linux-fb/gdkwindow-fb.c
applied patch from Andreas Persenius <ndap@swipnet.se> that updates the
[~andy/gtk] / gdk / linux-fb / gdkwindow-fb.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 /*
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/. 
25  */
26
27 #include "gdk.h"
28 #include "config.h"
29
30 #include "gdkwindow.h"
31 #include "gdkinputprivate.h"
32 #include "gdkprivate-fb.h"
33 #include "gdkinternals.h"
34
35 #include <limits.h>
36
37 static gpointer parent_class = NULL;
38
39 static void recompute_drawable(GdkDrawable *drawable);
40
41 static void
42 g_free_2nd(gpointer a, gpointer b, gpointer data)
43 {
44   g_free(b);
45 }
46
47 static void
48 gdk_window_impl_fb_finalize (GObject *object)
49 {
50   GdkWindowFBData *fbd = GDK_WINDOW_FBDATA(object);
51
52   if(GDK_WINDOW_P(fbd->drawable_data.wrapper)->mapped)
53     gdk_window_hide(fbd->drawable_data.wrapper);
54
55   if(fbd->cursor)
56     gdk_cursor_unref(fbd->cursor);
57
58   if(fbd->properties)
59     {
60       g_hash_table_foreach(fbd->properties, g_free_2nd, NULL);
61       g_hash_table_destroy(fbd->properties);
62     }
63
64   G_OBJECT_CLASS (parent_class)->finalize (object);
65 }
66
67 static void
68 gdk_window_impl_fb_class_init (GdkWindowFBClass *klass)
69 {
70   GObjectClass *object_class = G_OBJECT_CLASS (klass);
71   //  GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
72   
73   parent_class = g_type_class_peek_parent (klass);
74
75   object_class->finalize = gdk_window_impl_fb_finalize;
76 }
77
78 static void
79 gdk_window_impl_fb_init (GdkWindowFBData *impl)
80 {
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;
84 }
85
86 GType
87 _gdk_window_impl_get_type (void)
88 {
89   static GType object_type = 0;
90
91   if (!object_type)
92     {
93       static const GTypeInfo object_info =
94       {
95         sizeof (GdkWindowFBClass),
96         (GBaseInitFunc) NULL,
97         (GBaseFinalizeFunc) NULL,
98         (GClassInitFunc) gdk_window_impl_fb_class_init,
99         NULL,           /* class_finalize */
100         NULL,           /* class_data */
101         sizeof (GdkWindowFBData),
102         0,              /* n_preallocs */
103         (GInstanceInitFunc) gdk_window_impl_fb_init,
104       };
105       
106       object_type = g_type_register_static (gdk_drawable_impl_fb_get_type(),
107                                             "GdkWindowFB",
108                                             &object_info);
109     }
110   
111   return object_type;
112 }
113
114 #include "/usr/include/X11/bitmaps/left_ptr"
115 #include "/usr/include/X11/bitmaps/left_ptrmsk"
116
117 void
118 _gdk_windowing_window_init (void)
119 {
120   GdkWindowAttr attr;
121
122   GdkBitmap *ptr, *mask;
123   GdkCursor *cursor;
124   GdkWindowPrivate *private;
125
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);
128 #if 1
129   cursor = gdk_cursor_new_from_pixmap(ptr, mask, NULL, NULL, left_ptr_x_hot, left_ptr_y_hot);
130 #else
131   cursor = gdk_cursor_new(GDK_LEFT_PTR);
132 #endif
133
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;
142
143   private->mapped = TRUE;
144
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);
148 }
149
150 GdkWindow*
151 gdk_window_new (GdkWindow     *parent,
152                 GdkWindowAttr *attributes,
153                 gint           attributes_mask)
154 {
155   GdkWindow *window;
156   GdkWindowPrivate *private;
157   GdkWindowPrivate *parent_private;
158   GdkVisual *visual;
159   GdkWindowFBData *impl;
160
161   int x, y, depth;
162   
163   g_return_val_if_fail (attributes != NULL, NULL);
164   
165   if (!parent || attributes->window_type != GDK_WINDOW_CHILD)
166     parent = gdk_parent_root;
167   
168   parent_private = (GdkWindowPrivate*) parent;
169   
170   window = (GdkWindow *)g_type_create_instance(GDK_TYPE_WINDOW);
171   private = (GdkWindowObject *)window;
172
173   private->parent = parent_private;
174
175   if (attributes_mask & GDK_WA_X)
176     x = attributes->x;
177   else
178     x = 0;
179
180   if (attributes_mask & GDK_WA_Y)
181     y = attributes->y;
182   else
183     y = 0;
184
185   gdk_window_set_events(window, attributes->event_mask);
186
187   if (attributes_mask & GDK_WA_VISUAL)
188     visual = attributes->visual;
189   else
190     visual = gdk_visual_get_system();
191
192   impl = (GdkWindowFBData *)private->impl;
193   impl->drawable_data.wrapper = window;
194   private->x = x;
195   private->y = y;
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);
203
204   if (attributes->wclass == GDK_INPUT_OUTPUT)
205     {
206       depth = visual->depth;
207
208       private->input_only = FALSE;
209       private->depth = impl->drawable_data.depth;
210       
211       if ((attributes_mask & GDK_WA_COLORMAP)
212           && attributes->colormap)
213         impl->drawable_data.colormap = attributes->colormap;
214       else
215         impl->drawable_data.colormap = gdk_colormap_get_system();
216       
217       switch (impl->drawable_data.window_type)
218         {
219         case GDK_WINDOW_TOPLEVEL:
220         case GDK_WINDOW_CHILD:
221         case GDK_WINDOW_DIALOG:
222         case GDK_WINDOW_TEMP:
223         default:
224           break;
225           
226         case GDK_WINDOW_ROOT:
227           if(gdk_parent_root)
228             g_error ("cannot make windows of type GDK_WINDOW_ROOT");
229           break;
230         case GDK_DRAWABLE_PIXMAP:
231           g_error ("cannot make windows of type GDK_DRAWABLE_PIXMAP (use gdk_pixmap_new)");
232           break;
233         }
234     }
235   else
236     {
237       depth = 0;
238       private->input_only = TRUE;
239       impl->level = 10000;
240       impl->drawable_data.colormap = NULL;
241     }
242
243   gdk_drawable_ref (window);
244   
245   if (impl->drawable_data.colormap)
246     gdk_colormap_ref (impl->drawable_data.colormap);
247   
248   gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
249                                   (attributes->cursor) :
250                                   NULL));
251   
252   if (parent_private)
253     {
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;
257     }
258   
259   return window;
260 }
261
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
266  * window.
267  */
268 void
269 _gdk_windowing_window_destroy(GdkWindow *window,
270                               gboolean   recursing,
271                               gboolean   foreign_destroy)
272 {
273 #if 0
274   GdkWindowPrivate *private;
275   GdkWindowPrivate *temp_private;
276   GdkWindow *temp_window;
277   GList *children;
278   GList *tmp;
279   gboolean our_destroy = !foreign_destroy;
280   
281   g_return_if_fail (window != NULL);
282   
283   private = (GdkWindowPrivate*) window;
284   
285   switch (private->window_type)
286     {
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)
293         {
294           if (private->parent)
295             {
296               GdkWindowPrivate *parent_private = (GdkWindowPrivate *)private->parent;
297               if (parent_private->children)
298                 parent_private->children = g_list_remove (parent_private->children, window);
299             }
300
301           if (private->bg_pixmap && private->bg_pixmap != GDK_PARENT_RELATIVE_BG && private->bg_pixmap != GDK_NO_BG)
302             {
303               gdk_pixmap_unref (private->bg_pixmap);
304               private->bg_pixmap = NULL;
305             }
306
307           if (GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_FOREIGN)
308             {
309               children = tmp = private->children;
310               private->children = NULL;
311               
312               while (tmp)
313                 {
314                   temp_window = tmp->data;
315                   tmp = tmp->next;
316                   
317                   temp_private = (GdkWindowPrivate*) temp_window;
318                   if (temp_private)
319                     _gdk_windowing_window_destroy (temp_window, !FALSE,
320                                                    !our_destroy);
321                 }
322               
323               g_list_free (children);
324             }
325           
326           if (private->extension_events != 0)
327             gdk_input_window_destroy (window);
328           
329           if (private->filters)
330             {
331               tmp = private->filters;
332               
333               while (tmp)
334                 {
335                   g_free (tmp->data);
336                   tmp = tmp->next;
337                 }
338               
339               g_list_free (private->filters);
340               private->filters = NULL;
341             }
342           
343           if (private->window_type == GDK_WINDOW_FOREIGN)
344             {
345               if (our_destroy && (private->parent != NULL))
346                 {
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
350                    */
351                   gdk_error_trap_push ();
352                   gdk_window_hide (window);
353                   gdk_window_reparent (window, NULL, 0, 0);
354                   
355                   gdk_flush ();
356                   gdk_error_trap_pop ();
357                 }
358             }
359           
360           if (private->colormap)
361             gdk_colormap_unref (private->colormap);
362           
363           private->mapped = FALSE;
364           private->drawable.destroyed = TRUE;
365         }
366       break;
367       
368     case GDK_WINDOW_ROOT:
369       g_error ("attempted to destroy root window");
370       break;
371       
372     case GDK_WINDOW_PIXMAP:
373       g_error ("called gdk_window_destroy on a pixmap (use gdk_pixmap_unref)");
374       break;
375     }
376 #endif
377 }
378
379 /* This function is called when the XWindow is really gone.  */
380
381 static gboolean all_parents_shown(GdkWindowPrivate *private)
382 {
383   while(private->mapped)
384     {
385       if(private->parent)
386         private = (GdkWindowPrivate *)private->parent;
387       else
388         return TRUE;
389     }
390
391   return FALSE;
392 }
393
394 static void
395 send_map_events(GdkWindowPrivate *private, gboolean is_map)
396 {
397   GList *l;
398   GdkWindow *parent = (GdkWindow *)private->parent;
399
400   g_assert(is_map);
401
402   if(!private->mapped)
403     return;
404
405   if(is_map)
406     gdk_event_make((GdkWindow *)private, GDK_MAP, TRUE);
407
408   if(private->input_only)
409     return;
410
411   if(!parent)
412     parent = (GdkWindow *)private;
413
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)))
418      return;
419
420   if(is_map)
421     gdk_window_clear((GdkWindow *)private);
422
423 #if 0
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;
429   else
430     event->expose.area.x = GDK_DRAWABLE_IMPL_FBDATA(parent)->llim_x - GDK_DRAWABLE_IMPL_FBDATA(private)->abs_x;
431
432   if(GDK_DRAWABLE_IMPL_FBDATA(private)->abs_y > GDK_DRAWABLE_IMPL_FBDATA(parent)->llim_y)
433     event->expose.area.y = 0;
434   else
435     event->expose.area.y = GDK_DRAWABLE_IMPL_FBDATA(parent)->llim_y - GDK_DRAWABLE_IMPL_FBDATA(private)->abs_y;
436
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)
443     {
444       gdk_event_queue_append(event);
445     }
446   else
447     gdk_event_free(event);
448 #endif
449   for(l = private->children; l; l = l->next)
450     send_map_events(l->data, is_map);
451 }
452
453 /* Cut & paste versions of the stuff in gdkwindow.c, with the addition of clearing the newly exposed region. */
454 void
455 gdk_window_invalidate_region_clear(GdkWindow *window, GdkRegion *region)
456 {
457   int i;
458   GdkWindowPrivate *private = GDK_WINDOW_P(window);
459
460   if (private->input_only)
461     return;
462
463   if(private->bg_pixmap != GDK_NO_BG)
464     for(i = 0; i < region->numRects; i++)
465       gdk_window_clear_area(window,
466                             region->rects[i].x1,
467                             region->rects[i].y1,
468                             region->rects[i].x2 - region->rects[i].x1,
469                             region->rects[i].y2 - region->rects[i].y1);
470
471   gdk_window_invalidate_region(window, region, FALSE);
472
473   {
474     GList *tmp_list;
475     GdkRectangle child_rect;
476     GdkRegion *child_region;
477
478     tmp_list = private->children;
479     while (tmp_list)
480       {
481         GdkWindowObject *child = tmp_list->data;
482         tmp_list = tmp_list->next;
483
484         if (!child->input_only)
485           {
486             gint width, height;
487
488             gdk_drawable_get_size (GDK_DRAWABLE (child),
489                                    &width, &height);
490               
491             child_rect.x = child->x;
492             child_rect.y = child->y;
493             child_rect.width = width;
494             child_rect.height = height;
495               
496             child_region = gdk_region_rectangle (&child_rect);
497             gdk_region_intersect (child_region, region);
498               
499             if (!gdk_region_empty (child_region))
500               {
501                 gdk_region_offset (child_region, - child_rect.x, - child_rect.y);
502                 gdk_window_invalidate_region_clear ((GdkWindow *)child, child_region);
503               }
504               
505             gdk_region_destroy (child_region);
506           }
507       }
508   }  
509 }
510
511 void
512 gdk_window_invalidate_rect_clear(GdkWindow *window, GdkRectangle *rect)
513 {
514   GdkWindowPrivate *private = GDK_WINDOW_P(window);
515
516   if (private->input_only)
517     return;
518
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);
522
523   {
524     GList *tmp_list;
525     GdkRectangle child_rect, new_rect;
526
527     tmp_list = private->children;
528     while (tmp_list)
529       {
530         GdkWindowObject *child = tmp_list->data;
531         tmp_list = tmp_list->next;
532
533         if (!child->input_only)
534           {
535             gint width, height;
536
537             width = GDK_DRAWABLE_IMPL_FBDATA(child)->width;
538             height = GDK_DRAWABLE_IMPL_FBDATA(child)->height;
539               
540             child_rect.x = child->x;
541             child_rect.y = child->y;
542             child_rect.width = width;
543             child_rect.height = height;
544               
545             if (gdk_rectangle_intersect (rect, &child_rect, &new_rect))
546               {
547                 new_rect.x -= child_rect.x;
548                 new_rect.y -= child_rect.y;
549                   
550                 gdk_window_invalidate_rect_clear ((GdkWindow *)child, &new_rect);
551               }
552           }
553       }
554   }
555
556 }
557
558 void
559 gdk_fb_redraw_all(void)
560 {
561   GdkRectangle r;
562   r.x = r.y = 0;
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();
567 }
568
569 void
570 gdk_window_show (GdkWindow *window)
571 {
572   GdkWindowPrivate *private;
573   
574   g_return_if_fail (window != NULL);
575   
576   private = (GdkWindowPrivate*) window;
577
578   if (!private->destroyed && !private->mapped)
579     {
580       private->mapped = TRUE;
581
582       if(all_parents_shown((GdkWindowPrivate *)private->parent))
583         {
584           GdkRectangle rect;
585
586           recompute_drawable((GdkDrawable *)window);
587
588           send_map_events(private, TRUE);
589
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;
593
594           if(private->input_only)
595             return;
596
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);
602         }
603     }
604 }
605
606 void
607 gdk_window_hide (GdkWindow *window)
608 {
609   GdkWindowPrivate *private;
610   
611   g_return_if_fail (window != NULL);
612   
613   private = (GdkWindowPrivate*) window;
614
615   if (!private->destroyed && private->mapped)
616     {
617       GdkEvent *event;
618       GdkRectangle r;
619       gboolean do_hide;
620
621       event = gdk_event_make(window, GDK_UNMAP, TRUE);
622
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;
627
628       private->mapped = FALSE;
629
630       if(private->parent == GDK_WINDOW_P(gdk_parent_root))
631         gdk_fb_drawable_clear(gdk_parent_root);
632
633       if(all_parents_shown((GdkWindowPrivate *)private->parent))
634         gdk_fb_window_visibility_crossing(window, FALSE);
635
636       do_hide = gdk_fb_cursor_need_hide(&r);
637
638       if(do_hide)
639         gdk_fb_cursor_hide();
640       gdk_window_invalidate_rect_clear(gdk_parent_root, &r);
641       if(do_hide)
642         gdk_fb_cursor_unhide();
643     }
644 }
645
646 void
647 gdk_window_withdraw (GdkWindow *window)
648 {
649   gdk_window_hide(window);
650 }
651
652 void
653 gdk_window_move (GdkWindow *window,
654                  gint       x,
655                  gint       y)
656 {
657   GdkWindowPrivate *private = (GdkWindowPrivate *)window;
658   
659   g_return_if_fail (window != NULL);
660   g_return_if_fail (GDK_IS_WINDOW (window));
661
662   gdk_window_move_resize (window, x, y,
663                           GDK_DRAWABLE_IMPL_FBDATA(private)->width, GDK_DRAWABLE_IMPL_FBDATA(private)->height);
664 }
665
666 void
667 gdk_window_resize (GdkWindow *window,
668                    gint       width,
669                    gint       height)
670 {
671   GdkWindowPrivate *private;
672   
673   g_return_if_fail (window != NULL);
674   g_return_if_fail (GDK_IS_WINDOW (window));
675   
676   private = (GdkWindowPrivate*) window;
677   
678   if (width < 1)
679     width = 1;
680   if (height < 1)
681     height = 1;
682   gdk_window_move_resize(window, private->x, private->y, width, height);
683 }
684
685 static void
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)
689 {
690   GList *l;
691
692   if(GDK_IS_WINDOW(drawable))
693     {
694       GdkWindowPrivate *private = GDK_WINDOW_P(drawable);
695       int x, y;
696
697       if(!private->mapped)
698         return;
699
700       
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;
717
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);
720
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);
725     }
726   else
727     {
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;
734     }
735 }
736
737 static void
738 recompute_drawable(GdkDrawable *drawable)
739 {
740   if(GDK_IS_WINDOW(drawable))
741     {
742       GdkWindowPrivate *private = GDK_WINDOW_P(drawable);
743       GdkWindow *parent;
744
745       parent = (GdkWindow *)private->parent;
746       if(!parent)
747         parent = gdk_parent_root;
748
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);
755     }
756   else
757     recompute_abs_positions(drawable, 0, 0, 0, 0, INT_MAX, INT_MAX);
758 }
759
760 void
761 gdk_fb_window_move_resize (GdkWindow *window,
762                            gint       x,
763                            gint       y,
764                            gint       width,
765                            gint       height,
766                            gboolean   send_expose_events)
767 {
768   GdkWindowPrivate *private;
769   gint dx, dy, dw, dh;
770
771   g_return_if_fail (window != NULL);
772   g_return_if_fail (GDK_IS_WINDOW (window));
773
774   if (width < 1)
775     width = 1;
776   if (height < 1)
777     height = 1;
778
779   private = (GdkWindowPrivate*) window;
780
781   if (!private->destroyed)
782     {
783       GdkRegion *old_region;
784       GdkRectangle old_rect;
785
786       if(private->input_only)
787         send_expose_events = FALSE;
788
789       if(private->mapped && send_expose_events)
790         {
791           old_region = gdk_fb_clip_region(GDK_DRAWABLE_IMPL(window), NULL, TRUE, FALSE);
792
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;
797         }
798
799       dx = x - private->x;
800       dy = y - private->y;
801       dw = width - GDK_DRAWABLE_IMPL_FBDATA(private)->width;
802       dh = height - GDK_DRAWABLE_IMPL_FBDATA(private)->height;
803
804       private->x = x;
805       private->y = y;
806       GDK_DRAWABLE_IMPL_FBDATA(private)->width = width;
807       GDK_DRAWABLE_IMPL_FBDATA(private)->height = height;
808
809       if(private->mapped)
810         {
811           recompute_drawable((GdkDrawable *)window);
812
813           if(send_expose_events)
814             {
815               GdkRectangle new_rect;
816               GdkRegion *new_region, *region;
817               int i;
818               gboolean handle_cursor = FALSE;
819
820               new_region = gdk_fb_clip_region(GDK_DRAWABLE_IMPL(window), NULL, TRUE, FALSE);
821
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;
826
827               region = gdk_region_copy(old_region);
828               gdk_region_offset(region, dx, dy);
829               gdk_region_intersect(region, new_region);
830
831               if(region->numRects)
832                 {
833                   GdkFBDrawingContext fbdc;
834                   GdkRectangle cursor_rect;
835
836                   gdk_fb_get_cursor_rect(&cursor_rect);
837
838                   if(gdk_fb_cursor_region_need_hide(region))
839                     {
840                       gdk_fb_cursor_hide();
841                       handle_cursor = TRUE;
842                     }
843
844                   gdk_fb_drawing_context_init(&fbdc, GDK_DRAWABLE_IMPL(gdk_parent_root), NULL, FALSE, FALSE);
845                   for(i = 0; i < region->numRects; i++)
846                     {
847                       gdk_fb_draw_drawable_3(GDK_DRAWABLE_IMPL(gdk_parent_root), NULL, GDK_DRAWABLE_IMPL(gdk_parent_root),
848                                              &fbdc,
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));
855                     }
856                   gdk_fb_drawing_context_finalize(&fbdc);
857                 }
858
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);
863               if(handle_cursor)
864                 gdk_fb_cursor_unhide();
865
866               gdk_region_destroy(old_region);
867               gdk_region_destroy(new_region);
868             }
869         }
870     }
871 }
872
873 void
874 gdk_window_move_resize (GdkWindow *window,
875                         gint       x,
876                         gint       y,
877                         gint       width,
878                         gint       height)
879 {
880   gdk_fb_window_move_resize(window, x, y, width, height, TRUE);
881 }
882
883 void
884 gdk_window_reparent (GdkWindow *window,
885                      GdkWindow *new_parent,
886                      gint       x,
887                      gint       y)
888 {
889   GdkWindowPrivate *window_private;
890   GdkWindowPrivate *parent_private;
891   GdkWindowPrivate *old_parent_private;
892   
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));
897   
898   if (!new_parent)
899     new_parent = gdk_parent_root;
900
901   window_private = (GdkWindowPrivate*) window;
902   old_parent_private = (GdkWindowPrivate*)window_private->parent;
903   parent_private = (GdkWindowPrivate*) new_parent;
904   
905   g_assert(GDK_DRAWABLE_IMPL_FBDATA(window_private)->colormap);
906
907   window_private->parent = (GdkWindowPrivate *)new_parent;
908   
909   if (old_parent_private)
910     old_parent_private->children = g_list_remove (old_parent_private->children, window);
911
912   parent_private->children = g_list_prepend (parent_private->children, window);
913
914   if(window_private->mapped)
915     {
916       GdkRectangle r;
917       GdkRegion *region;
918
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);
924
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);
931
932       gdk_window_invalidate_region_clear(gdk_parent_root, region);
933       gdk_region_destroy(region);
934     }
935 }
936
937
938 void
939 _gdk_windowing_window_clear_area (GdkWindow *window,
940                                   gint       x,
941                                   gint       y,
942                                   gint       width,
943                                   gint       height)
944 {
945   GdkPixmap *bgpm;
946   GdkWindow *relto;
947
948   if(GDK_WINDOW_P(window)->input_only)
949     return;
950
951   bgpm = GDK_WINDOW_P(window)->bg_pixmap;
952
953 #if 0  
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;
956 #endif
957
958   if(bgpm && bgpm != GDK_NO_BG)
959     {
960       int curx, cury;
961       int xtrans, ytrans;
962       int xstep, ystep;
963       GdkFBDrawingContext fbdc;
964
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 */
967
968       gdk_fb_drawing_context_init(&fbdc, window, NULL, FALSE, TRUE);
969
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;
972
973       for(cury = y - ytrans; cury < (y - ytrans + height); cury += ystep)
974         {
975           int drawh = cury % GDK_DRAWABLE_P(bgpm)->height;
976           ystep = GDK_DRAWABLE_P(bgpm)->height - drawh;
977
978           for(curx = x - xtrans; curx < (x - xtrans + width); curx += xstep)
979             {
980               int draww = curx % GDK_DRAWABLE_IMPL_FBDATA(bgpm)->width;
981               xstep = GDK_DRAWABLE_IMPL_FBDATA(bgpm)->width - draww;
982
983               gdk_fb_draw_drawable_3(GDK_DRAWABLE_IMPL(window), NULL, GDK_DRAWABLE_IMPL(bgpm),
984                                      &fbdc,
985                                      draww, drawh, curx + xtrans, cury + ytrans,
986                                      xstep, ystep);
987             }
988         }
989
990       gdk_fb_drawing_context_finalize(&fbdc);
991     }
992   else if(!bgpm)
993     gdk_fb_draw_rectangle(GDK_DRAWABLE_IMPL(window), NULL, TRUE, x, y, width, height);
994 }
995
996 /* What's the diff? */
997 void
998 _gdk_windowing_window_clear_area_e (GdkWindow *window,
999                                     gint       x,
1000                                     gint       y,
1001                                     gint       width,
1002                                     gint       height)
1003 {
1004   _gdk_windowing_window_clear_area(window, x, y, width, height);
1005 }
1006
1007 static gint
1008 compare_window_levels(gconstpointer a, gconstpointer b)
1009 {
1010   return (GDK_WINDOW_IMPL_FBDATA(b)->level - GDK_WINDOW_IMPL_FBDATA(a)->level);
1011 }
1012
1013 /* Child list is sorted bottom-to-top */
1014 static void
1015 gdk_window_resort_children(GdkWindow *win)
1016 {
1017   GdkWindowPrivate *private = GDK_WINDOW_P(win);
1018
1019   private->children = g_list_sort(private->children, compare_window_levels);
1020
1021   /* Now the fun part - redraw */
1022   if(GDK_WINDOW_P(win)->parent)
1023     {
1024       gdk_window_invalidate_rect(win, NULL, TRUE);
1025     }
1026 }
1027
1028 void
1029 gdk_window_raise (GdkWindow *window)
1030 {
1031   g_return_if_fail (window != NULL);
1032   g_return_if_fail (GDK_IS_WINDOW (window));
1033
1034   GDK_WINDOW_IMPL_FBDATA(window)->level++;
1035
1036   if(GDK_WINDOW_P(window)->parent)
1037     gdk_window_resort_children((GdkWindow *)GDK_WINDOW_P(window)->parent);
1038 }
1039
1040 void
1041 gdk_window_lower (GdkWindow *window)
1042 {
1043   g_return_if_fail (window != NULL);
1044   g_return_if_fail (GDK_IS_WINDOW (window));
1045   
1046   GDK_WINDOW_IMPL_FBDATA(window)->level--;
1047
1048   if(GDK_WINDOW_P(window)->parent)
1049     gdk_window_resort_children((GdkWindow *)GDK_WINDOW_P(window)->parent);
1050 }
1051
1052 void
1053 gdk_window_set_hints (GdkWindow *window,
1054                       gint       x,
1055                       gint       y,
1056                       gint       min_width,
1057                       gint       min_height,
1058                       gint       max_width,
1059                       gint       max_height,
1060                       gint       flags)
1061 {
1062 }
1063
1064 void 
1065 gdk_window_set_geometry_hints (GdkWindow      *window,
1066                                GdkGeometry    *geometry,
1067                                GdkWindowHints  geom_mask)
1068 {
1069 }
1070
1071 void
1072 gdk_window_set_title (GdkWindow   *window,
1073                       const gchar *title)
1074 {
1075 }
1076
1077 void          
1078 gdk_window_set_role (GdkWindow   *window,
1079                      const gchar *role)
1080 {
1081 }
1082
1083 void          
1084 gdk_window_set_transient_for (GdkWindow *window, 
1085                               GdkWindow *parent)
1086 {
1087   GDK_WINDOW_IMPL_FBDATA(window)->level = GDK_WINDOW_IMPL_FBDATA(parent)->level + 1;
1088 }
1089
1090 void
1091 gdk_window_set_background (GdkWindow *window,
1092                            GdkColor  *color)
1093 {
1094   GdkWindowPrivate *private = (GdkWindowPrivate *)window;
1095   
1096   g_return_if_fail (window != NULL);
1097   g_return_if_fail (GDK_IS_WINDOW (window));
1098   
1099   private->bg_color = *color;
1100
1101   if (private->bg_pixmap &&
1102       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1103       private->bg_pixmap != GDK_NO_BG)
1104     {
1105       gdk_pixmap_unref (private->bg_pixmap);
1106       private->bg_pixmap = NULL;
1107     }
1108 }
1109
1110 void
1111 gdk_window_set_back_pixmap (GdkWindow *window,
1112                             GdkPixmap *pixmap,
1113                             gboolean   parent_relative)
1114 {
1115   GdkWindowPrivate *private = (GdkWindowPrivate *)window;
1116   GdkPixmap *old_pixmap;
1117
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);
1121
1122   old_pixmap = private->bg_pixmap;
1123
1124   if (parent_relative)
1125     {
1126       private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1127     }
1128   else
1129     {
1130       if (pixmap)
1131         {
1132           gdk_pixmap_ref (pixmap);
1133           private->bg_pixmap = pixmap;
1134         }
1135       else
1136         {
1137           private->bg_pixmap = GDK_NO_BG;
1138         }
1139     }
1140
1141   if (old_pixmap &&
1142       old_pixmap != GDK_PARENT_RELATIVE_BG &&
1143       old_pixmap != GDK_NO_BG)
1144     gdk_pixmap_unref (old_pixmap);
1145 }
1146
1147 void
1148 gdk_window_set_cursor (GdkWindow *window,
1149                        GdkCursor *cursor)
1150 {
1151   GdkCursor *old_cursor = GDK_WINDOW_IMPL_FBDATA(window)->cursor;
1152   GdkRectangle window_reg;
1153
1154   GDK_WINDOW_IMPL_FBDATA(window)->cursor = cursor?gdk_cursor_ref(cursor):NULL;
1155
1156   if(old_cursor)
1157     gdk_cursor_unref(old_cursor);
1158
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))
1164     {
1165       gdk_fb_cursor_reset();
1166     }
1167 }
1168
1169 void
1170 gdk_window_get_geometry (GdkWindow *window,
1171                          gint      *x,
1172                          gint      *y,
1173                          gint      *width,
1174                          gint      *height,
1175                          gint      *depth)
1176 {
1177   GdkWindowPrivate *private = (GdkWindowPrivate *)window;
1178   
1179   g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
1180   
1181   if (!window)
1182     window = gdk_parent_root;
1183   
1184   if (!private->destroyed)
1185     {
1186
1187       if (x)
1188         *x = private->x;
1189       if (y)
1190         *y = private->y;
1191       if (width)
1192         *width = GDK_DRAWABLE_IMPL_FBDATA(window)->width;
1193       if (height)
1194         *height = GDK_DRAWABLE_IMPL_FBDATA(window)->height;
1195       if (depth)
1196         *depth = gdk_display->modeinfo.bits_per_pixel;
1197     }
1198 }
1199
1200 gboolean
1201 gdk_window_get_origin (GdkWindow *window,
1202                        gint      *x,
1203                        gint      *y)
1204 {
1205   g_return_val_if_fail (window != NULL, 0);
1206   
1207   if (x)
1208     *x = GDK_DRAWABLE_IMPL_FBDATA(window)->abs_x;
1209   if (y)
1210     *y = GDK_DRAWABLE_IMPL_FBDATA(window)->abs_y;
1211
1212   return TRUE;
1213 }
1214
1215 gboolean
1216 gdk_window_get_deskrelative_origin (GdkWindow *window,
1217                                     gint      *x,
1218                                     gint      *y)
1219 {
1220   gint tx = 0;
1221   gint ty = 0;
1222   gboolean return_val;
1223
1224   g_return_val_if_fail (window != NULL, 0);
1225   
1226   if (!GDK_WINDOW_DESTROYED (window))
1227     {
1228       tx = GDK_DRAWABLE_IMPL_FBDATA(window)->abs_x;
1229       ty = GDK_DRAWABLE_IMPL_FBDATA(window)->abs_y;
1230
1231       return_val = TRUE;
1232     }
1233   else
1234     return_val = FALSE;
1235   
1236   if (x)
1237     *x = tx;
1238   if (y)
1239     *y = ty;
1240
1241   return return_val;
1242 }
1243
1244 void
1245 gdk_window_get_root_origin (GdkWindow *window,
1246                             gint      *x,
1247                             gint      *y)
1248 {
1249   gdk_window_get_deskrelative_origin(window, x, y);
1250 }
1251
1252 GdkWindow*
1253 gdk_window_get_pointer (GdkWindow       *window,
1254                         gint            *x,
1255                         gint            *y,
1256                         GdkModifierType *mask)
1257 {
1258   GdkWindow *return_val;
1259   int winx = 0;
1260   int winy = 0;
1261   int x_int, y_int;
1262   GdkModifierType my_mask;
1263
1264   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1265   
1266   if (!window)
1267     window = gdk_parent_root;
1268   
1269   gdk_window_get_root_origin(window, &x_int, &y_int);
1270   gdk_input_ps2_get_mouseinfo(&winx, &winy, &my_mask);
1271
1272   winx -= x_int;
1273   winy -= y_int;
1274
1275   if (x)
1276     *x = winx;
1277   if (y)
1278     *y = winy;
1279   if (mask)
1280     *mask = my_mask;
1281   
1282   return_val = NULL;
1283   
1284   if((winx >= 0) && (winx < GDK_DRAWABLE_IMPL_FBDATA(window)->width)
1285      && (winy >= 0) && (winy < GDK_DRAWABLE_IMPL_FBDATA(window)->height))
1286     {
1287       GdkWindowPrivate *private;
1288       GdkWindowPrivate *sub;
1289       int subx = winx, suby = winy;
1290
1291       for(private = sub = (GdkWindowPrivate *)window; sub; private = sub)
1292         {
1293           GList *ltmp;
1294
1295           for(ltmp = private->children; ltmp; ltmp = ltmp->next)
1296             {
1297               sub = ltmp->data;
1298
1299               if(!sub->mapped)
1300                 continue;
1301
1302               if(subx >= sub->x
1303                  && (subx < (GDK_DRAWABLE_IMPL_FBDATA(sub)->width + sub->x))
1304                  && (suby >= sub->y)
1305                  && (suby < (GDK_DRAWABLE_IMPL_FBDATA(sub)->height + sub->y)))
1306                 {
1307                   subx -= sub->x;
1308                   suby -= sub->y;
1309                   break;
1310                 }
1311             }
1312
1313           if(!ltmp)
1314             {
1315               sub = NULL;
1316               break;
1317             }
1318         }
1319
1320       return_val = (GdkWindow *)private;
1321     }
1322
1323   if(!return_val)
1324     return_val = gdk_parent_root;
1325
1326   return return_val;
1327 }
1328
1329 GdkWindow*
1330 gdk_window_at_pointer (gint *win_x,
1331                        gint *win_y)
1332 {
1333   gint rx, ry;
1334   GdkWindow *retval = gdk_window_get_pointer(NULL, win_x, win_y, NULL);
1335
1336   if(retval)
1337     {
1338       gdk_window_get_origin(retval, &ry, &rx);
1339       if(win_x)
1340         (*win_x) -= rx;
1341       if(win_y)
1342         (*win_y) -= ry;
1343     }
1344
1345   return retval;
1346 }
1347
1348 GdkEventMask  
1349 gdk_window_get_events (GdkWindow *window)
1350 {
1351   g_return_val_if_fail (window != NULL, 0);
1352   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1353
1354   if (GDK_WINDOW_DESTROYED (window))
1355     return 0;
1356   else
1357     return GDK_WINDOW_IMPL_FBDATA(window)->event_mask;
1358 }
1359
1360 void          
1361 gdk_window_set_events (GdkWindow       *window,
1362                        GdkEventMask     event_mask)
1363 {
1364   
1365   g_return_if_fail (window != NULL);
1366   g_return_if_fail (GDK_IS_WINDOW (window));
1367   
1368   if (!GDK_WINDOW_DESTROYED (window))
1369     GDK_WINDOW_IMPL_FBDATA(window)->event_mask = event_mask;
1370 }
1371
1372 void
1373 gdk_window_add_colormap_windows (GdkWindow *window)
1374 {
1375   g_return_if_fail (window != NULL);
1376   g_return_if_fail (GDK_IS_WINDOW (window));
1377   
1378   /* N/A */
1379 }
1380
1381 /*
1382  * This needs the X11 shape extension.
1383  * If not available, shaped windows will look
1384  * ugly, but programs still work.    Stefan Wille
1385  */
1386 void
1387 gdk_window_shape_combine_mask (GdkWindow *window,
1388                                GdkBitmap *mask,
1389                                gint x, gint y)
1390 {
1391   g_return_if_fail (window != NULL);
1392   g_return_if_fail (GDK_IS_WINDOW (window));
1393 }
1394
1395 void
1396 gdk_window_set_override_redirect (GdkWindow *window,
1397                                   gboolean override_redirect)
1398 {
1399   g_return_if_fail (window != NULL);
1400   g_return_if_fail (GDK_IS_WINDOW (window));
1401
1402   /* N/A */
1403 }
1404
1405 void          
1406 gdk_window_set_icon (GdkWindow *window, 
1407                      GdkWindow *icon_window,
1408                      GdkPixmap *pixmap,
1409                      GdkBitmap *mask)
1410 {
1411   g_return_if_fail (window != NULL);
1412   g_return_if_fail (GDK_IS_WINDOW (window));
1413
1414   /* N/A */
1415 }
1416
1417 void          
1418 gdk_window_set_icon_name (GdkWindow *window, 
1419                           const gchar *    name)
1420 {
1421   g_return_if_fail (window != NULL);
1422   g_return_if_fail (GDK_IS_WINDOW (window));
1423
1424   /* N/A */
1425 }
1426
1427 void          
1428 gdk_window_set_group (GdkWindow *window, 
1429                       GdkWindow *leader)
1430 {
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));
1435
1436   /* N/A */
1437 }
1438
1439 void
1440 gdk_window_set_decorations (GdkWindow      *window,
1441                             GdkWMDecoration decorations)
1442 {
1443   g_return_if_fail (window != NULL);
1444   g_return_if_fail (GDK_IS_WINDOW (window));
1445
1446   /* N/A */
1447 }
1448
1449 void
1450 gdk_window_set_functions (GdkWindow    *window,
1451                           GdkWMFunction functions)
1452 {
1453   g_return_if_fail (window != NULL);
1454   g_return_if_fail (GDK_IS_WINDOW (window));
1455
1456   /* N/A */
1457 }
1458
1459 void
1460 gdk_window_set_child_shapes (GdkWindow *window)
1461 {
1462   g_return_if_fail (window != NULL);
1463   g_return_if_fail (GDK_IS_WINDOW (window));
1464   
1465 }
1466
1467 void
1468 gdk_window_merge_child_shapes (GdkWindow *window)
1469 {
1470   g_return_if_fail (window != NULL);
1471   g_return_if_fail (GDK_IS_WINDOW (window));
1472   
1473 }
1474
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
1479  *     gravity.
1480  *   arguments:
1481  *     window: window for which to set static gravity
1482  *     use_static: Whether to turn static gravity on or off.
1483  *   results:
1484  *     Does the XServer support static gravity?
1485  *************************************************************/
1486
1487 gboolean 
1488 gdk_window_set_static_gravities (GdkWindow *window,
1489                                  gboolean   use_static)
1490 {
1491   g_return_val_if_fail (window != NULL, FALSE);
1492   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1493   
1494   return TRUE;
1495 }
1496
1497 void
1498 _gdk_windowing_window_get_offsets      (GdkWindow  *window,
1499                                         gint       *x_offset,
1500                                         gint       *y_offset)
1501 {
1502   *x_offset = *y_offset = 0;
1503 }
1504
1505 gboolean
1506 _gdk_windowing_window_queue_antiexpose (GdkWindow  *window,
1507                                         GdkRegion  *area)
1508 {
1509   return FALSE;
1510 }