]> Pileus Git - ~andy/gtk/blob - gtk/gtklayout.c
Remove all references to offscreen flag which was no longer used.
[~andy/gtk] / gtk / gtklayout.c
1 /* GTK - The GIMP Toolkit
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 Library 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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  * GtkLayout: Widget for scrolling of arbitrary-sized areas.
20  *
21  * Copyright Owen Taylor, 1998
22  */
23
24 /*
25  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
26  * file for a list of people on the GTK+ Team.  See the ChangeLog
27  * files for a list of changes.  These files are distributed with
28  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
29  */
30
31 #include "gdkconfig.h"
32
33 #include "gtklayout.h"
34 #include "gtksignal.h"
35 #include "gtkprivate.h"
36
37 typedef struct _GtkLayoutChild   GtkLayoutChild;
38
39 struct _GtkLayoutChild {
40   GtkWidget *widget;
41   gint x;
42   gint y;
43 };
44
45 static void     gtk_layout_class_init         (GtkLayoutClass *class);
46 static void     gtk_layout_init               (GtkLayout      *layout);
47
48 static void     gtk_layout_finalize           (GObject        *object);
49 static void     gtk_layout_realize            (GtkWidget      *widget);
50 static void     gtk_layout_unrealize          (GtkWidget      *widget);
51 static void     gtk_layout_map                (GtkWidget      *widget);
52 static void     gtk_layout_size_request       (GtkWidget      *widget,
53                                                GtkRequisition *requisition);
54 static void     gtk_layout_size_allocate      (GtkWidget      *widget,
55                                                GtkAllocation  *allocation);
56 static void     gtk_layout_draw               (GtkWidget      *widget, 
57                                                GdkRectangle   *area);
58 static gint     gtk_layout_expose             (GtkWidget      *widget, 
59                                                GdkEventExpose *event);
60
61 static void     gtk_layout_remove             (GtkContainer *container, 
62                                                GtkWidget    *widget);
63 static void     gtk_layout_forall             (GtkContainer *container,
64                                                gboolean      include_internals,
65                                                GtkCallback   callback,
66                                                gpointer      callback_data);
67 static void     gtk_layout_set_adjustments    (GtkLayout     *layout,
68                                                GtkAdjustment *hadj,
69                                                GtkAdjustment *vadj);
70
71 static void     gtk_layout_allocate_child     (GtkLayout      *layout,
72                                                GtkLayoutChild *child);
73
74
75 static void     gtk_layout_adjustment_changed (GtkAdjustment  *adjustment,
76                                                GtkLayout      *layout);
77
78 static GtkWidgetClass *parent_class = NULL;
79
80 /* Public interface
81  */
82   
83 GtkWidget*    
84 gtk_layout_new (GtkAdjustment *hadjustment,
85                 GtkAdjustment *vadjustment)
86 {
87   GtkLayout *layout;
88
89   layout = gtk_type_new (GTK_TYPE_LAYOUT);
90
91   gtk_layout_set_adjustments (layout, hadjustment, vadjustment);
92
93   return GTK_WIDGET (layout);
94 }
95
96 GtkAdjustment* 
97 gtk_layout_get_hadjustment (GtkLayout     *layout)
98 {
99   g_return_val_if_fail (layout != NULL, NULL);
100   g_return_val_if_fail (GTK_IS_LAYOUT (layout), NULL);
101
102   return layout->hadjustment;
103 }
104 GtkAdjustment* 
105 gtk_layout_get_vadjustment (GtkLayout     *layout)
106 {
107   g_return_val_if_fail (layout != NULL, NULL);
108   g_return_val_if_fail (GTK_IS_LAYOUT (layout), NULL);
109
110   return layout->vadjustment;
111 }
112
113 static void           
114 gtk_layout_set_adjustments (GtkLayout     *layout,
115                             GtkAdjustment *hadj,
116                             GtkAdjustment *vadj)
117 {
118   gboolean need_adjust = FALSE;
119
120   g_return_if_fail (layout != NULL);
121   g_return_if_fail (GTK_IS_LAYOUT (layout));
122
123   if (hadj)
124     g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
125   else
126     hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
127   if (vadj)
128     g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
129   else
130     vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
131   
132   if (layout->hadjustment && (layout->hadjustment != hadj))
133     {
134       gtk_signal_disconnect_by_data (GTK_OBJECT (layout->hadjustment), layout);
135       gtk_object_unref (GTK_OBJECT (layout->hadjustment));
136     }
137   
138   if (layout->vadjustment && (layout->vadjustment != vadj))
139     {
140       gtk_signal_disconnect_by_data (GTK_OBJECT (layout->vadjustment), layout);
141       gtk_object_unref (GTK_OBJECT (layout->vadjustment));
142     }
143   
144   if (layout->hadjustment != hadj)
145     {
146       layout->hadjustment = hadj;
147       gtk_object_ref (GTK_OBJECT (layout->hadjustment));
148       gtk_object_sink (GTK_OBJECT (layout->hadjustment));
149       
150       gtk_signal_connect (GTK_OBJECT (layout->hadjustment), "value_changed",
151                           (GtkSignalFunc) gtk_layout_adjustment_changed,
152                           layout);
153       need_adjust = TRUE;
154     }
155   
156   if (layout->vadjustment != vadj)
157     {
158       layout->vadjustment = vadj;
159       gtk_object_ref (GTK_OBJECT (layout->vadjustment));
160       gtk_object_sink (GTK_OBJECT (layout->vadjustment));
161       
162       gtk_signal_connect (GTK_OBJECT (layout->vadjustment), "value_changed",
163                           (GtkSignalFunc) gtk_layout_adjustment_changed,
164                           layout);
165       need_adjust = TRUE;
166     }
167
168   if (need_adjust)
169     gtk_layout_adjustment_changed (NULL, layout);
170 }
171
172 static void
173 gtk_layout_finalize (GObject *object)
174 {
175   GtkLayout *layout = GTK_LAYOUT (object);
176
177   gtk_object_unref (GTK_OBJECT (layout->hadjustment));
178   gtk_object_unref (GTK_OBJECT (layout->vadjustment));
179
180   G_OBJECT_CLASS (parent_class)->finalize (object);
181 }
182
183 void           
184 gtk_layout_set_hadjustment (GtkLayout     *layout,
185                             GtkAdjustment *adjustment)
186 {
187   g_return_if_fail (layout != NULL);
188   g_return_if_fail (GTK_IS_LAYOUT (layout));
189
190   gtk_layout_set_adjustments (layout, adjustment, layout->vadjustment);
191 }
192  
193
194 void           
195 gtk_layout_set_vadjustment (GtkLayout     *layout,
196                             GtkAdjustment *adjustment)
197 {
198   g_return_if_fail (layout != NULL);
199   g_return_if_fail (GTK_IS_LAYOUT (layout));
200   
201   gtk_layout_set_adjustments (layout, layout->hadjustment, adjustment);
202 }
203
204
205 void           
206 gtk_layout_put (GtkLayout     *layout, 
207                 GtkWidget     *child_widget, 
208                 gint           x, 
209                 gint           y)
210 {
211   GtkLayoutChild *child;
212
213   g_return_if_fail (layout != NULL);
214   g_return_if_fail (GTK_IS_LAYOUT (layout));
215   g_return_if_fail (child_widget != NULL);
216   g_return_if_fail (GTK_IS_WIDGET (child_widget));
217   
218   child = g_new (GtkLayoutChild, 1);
219
220   child->widget = child_widget;
221   child->x = x;
222   child->y = y;
223
224   layout->children = g_list_append (layout->children, child);
225   
226   gtk_widget_set_parent (child_widget, GTK_WIDGET (layout));
227   if (GTK_WIDGET_REALIZED (layout))
228     gtk_widget_set_parent_window (child->widget, layout->bin_window);
229
230   if (GTK_WIDGET_REALIZED (layout))
231     gtk_widget_realize (child_widget);
232     
233   if (GTK_WIDGET_VISIBLE (layout) && GTK_WIDGET_VISIBLE (child_widget))
234     {
235       if (GTK_WIDGET_MAPPED (layout))
236         gtk_widget_map (child_widget);
237
238       gtk_widget_queue_resize (child_widget);
239     }
240 }
241
242 void           
243 gtk_layout_move (GtkLayout     *layout, 
244                  GtkWidget     *child_widget, 
245                  gint           x, 
246                  gint           y)
247 {
248   GList *tmp_list;
249   GtkLayoutChild *child;
250   
251   g_return_if_fail (layout != NULL);
252   g_return_if_fail (GTK_IS_LAYOUT (layout));
253
254   tmp_list = layout->children;
255   while (tmp_list)
256     {
257       child = tmp_list->data;
258       tmp_list = tmp_list->next;
259
260       if (child->widget == child_widget)
261         {
262           child->x = x;
263           child->y = y;
264
265           if (GTK_WIDGET_VISIBLE (child_widget) && GTK_WIDGET_VISIBLE (layout))
266             gtk_widget_queue_resize (child_widget);
267
268           return;
269         }
270     }
271 }
272
273 static void
274 gtk_layout_set_adjustment_upper (GtkAdjustment *adj, gfloat upper)
275 {
276   if (upper != adj->upper)
277     {
278       gfloat min = MAX (0., upper - adj->page_size);
279       gboolean value_changed = FALSE;
280       
281       adj->upper = upper;
282       
283       if (adj->value > min)
284         {
285           adj->value = min;
286           value_changed = TRUE;
287         }
288       
289       gtk_signal_emit_by_name (GTK_OBJECT (adj), "changed");
290       if (value_changed)
291         gtk_signal_emit_by_name (GTK_OBJECT (adj), "value_changed");
292     }
293 }
294
295 void
296 gtk_layout_set_size (GtkLayout     *layout, 
297                      guint          width,
298                      guint          height)
299 {
300   GtkWidget *widget;
301   
302   g_return_if_fail (layout != NULL);
303   g_return_if_fail (GTK_IS_LAYOUT (layout));
304
305   widget = GTK_WIDGET (layout);
306   
307   layout->width = width;
308   layout->height = height;
309
310   gtk_layout_set_adjustment_upper (layout->hadjustment, layout->width);
311   gtk_layout_set_adjustment_upper (layout->vadjustment, layout->height);
312
313   if (GTK_WIDGET_REALIZED (layout))
314     {
315       width = MAX (width, widget->allocation.width);
316       height = MAX (height, widget->allocation.height);
317       gdk_window_resize (layout->bin_window, width, height);
318     }
319 }
320
321 void
322 gtk_layout_freeze (GtkLayout *layout)
323 {
324   g_return_if_fail (layout != NULL);
325   g_return_if_fail (GTK_IS_LAYOUT (layout));
326
327   layout->freeze_count++;
328 }
329
330 void
331 gtk_layout_thaw (GtkLayout *layout)
332 {
333   g_return_if_fail (layout != NULL);
334   g_return_if_fail (GTK_IS_LAYOUT (layout));
335
336   if (layout->freeze_count)
337     if (!(--layout->freeze_count))
338       gtk_widget_draw (GTK_WIDGET (layout), NULL);
339 }
340
341 /* Basic Object handling procedures
342  */
343 GtkType
344 gtk_layout_get_type (void)
345 {
346   static GtkType layout_type = 0;
347
348   if (!layout_type)
349     {
350       static const GTypeInfo layout_info =
351       {
352         sizeof (GtkLayoutClass),
353         NULL,           /* base_init */
354         NULL,           /* base_finalize */
355         (GClassInitFunc) gtk_layout_class_init,
356         NULL,           /* class_finalize */
357         NULL,           /* class_data */
358         sizeof (GtkLayout),
359         16,             /* n_preallocs */
360         (GInstanceInitFunc) gtk_layout_init,
361       };
362
363       layout_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkLayout", &layout_info);
364     }
365
366   return layout_type;
367 }
368
369 static void
370 gtk_layout_class_init (GtkLayoutClass *class)
371 {
372   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
373   GtkObjectClass *object_class;
374   GtkWidgetClass *widget_class;
375   GtkContainerClass *container_class;
376
377   object_class = (GtkObjectClass*) class;
378   widget_class = (GtkWidgetClass*) class;
379   container_class = (GtkContainerClass*) class;
380
381   parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
382
383   gobject_class->finalize = gtk_layout_finalize;
384
385   widget_class->realize = gtk_layout_realize;
386   widget_class->unrealize = gtk_layout_unrealize;
387   widget_class->map = gtk_layout_map;
388   widget_class->size_request = gtk_layout_size_request;
389   widget_class->size_allocate = gtk_layout_size_allocate;
390   widget_class->draw = gtk_layout_draw;
391   widget_class->expose_event = gtk_layout_expose;
392
393   container_class->remove = gtk_layout_remove;
394   container_class->forall = gtk_layout_forall;
395
396   class->set_scroll_adjustments = gtk_layout_set_adjustments;
397
398   widget_class->set_scroll_adjustments_signal =
399     gtk_signal_new ("set_scroll_adjustments",
400                     GTK_RUN_LAST,
401                     GTK_CLASS_TYPE (object_class),
402                     GTK_SIGNAL_OFFSET (GtkLayoutClass, set_scroll_adjustments),
403                     gtk_marshal_NONE__POINTER_POINTER,
404                     GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
405 }
406
407 static void
408 gtk_layout_init (GtkLayout *layout)
409 {
410   layout->children = NULL;
411
412   layout->width = 100;
413   layout->height = 100;
414
415   layout->hadjustment = NULL;
416   layout->vadjustment = NULL;
417
418   layout->bin_window = NULL;
419
420   layout->configure_serial = 0;
421   layout->scroll_x = 0;
422   layout->scroll_y = 0;
423   layout->visibility = GDK_VISIBILITY_PARTIAL;
424
425   layout->freeze_count = 0;
426 }
427
428 /* Widget methods
429  */
430
431 static void 
432 gtk_layout_realize (GtkWidget *widget)
433 {
434   GList *tmp_list;
435   GtkLayout *layout;
436   GdkWindowAttr attributes;
437   gint attributes_mask;
438
439   g_return_if_fail (widget != NULL);
440   g_return_if_fail (GTK_IS_LAYOUT (widget));
441
442   layout = GTK_LAYOUT (widget);
443   GTK_WIDGET_SET_FLAGS (layout, GTK_REALIZED);
444
445   attributes.window_type = GDK_WINDOW_CHILD;
446   attributes.x = widget->allocation.x;
447   attributes.y = widget->allocation.y;
448   attributes.width = widget->allocation.width;
449   attributes.height = widget->allocation.height;
450   attributes.wclass = GDK_INPUT_OUTPUT;
451   attributes.visual = gtk_widget_get_visual (widget);
452   attributes.colormap = gtk_widget_get_colormap (widget);
453   attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
454
455   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
456
457   widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
458                                    &attributes, attributes_mask);
459   gdk_window_set_user_data (widget->window, widget);
460
461   attributes.x = 0;
462   attributes.y = 0;
463   attributes.width = MAX (layout->width, widget->allocation.width);
464   attributes.height = MAX (layout->height, widget->allocation.height);
465   attributes.event_mask = GDK_EXPOSURE_MASK | GDK_SCROLL_MASK | 
466                           gtk_widget_get_events (widget);
467
468   layout->bin_window = gdk_window_new (widget->window,
469                                         &attributes, attributes_mask);
470   gdk_window_set_user_data (layout->bin_window, widget);
471
472   widget->style = gtk_style_attach (widget->style, widget->window);
473   gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
474   gtk_style_set_background (widget->style, layout->bin_window, GTK_STATE_NORMAL);
475
476   tmp_list = layout->children;
477   while (tmp_list)
478     {
479       GtkLayoutChild *child = tmp_list->data;
480       tmp_list = tmp_list->next;
481
482       gtk_widget_set_parent_window (child->widget, layout->bin_window);
483     }
484 }
485
486 static void 
487 gtk_layout_map (GtkWidget *widget)
488 {
489   GList *tmp_list;
490   GtkLayout *layout;
491
492   g_return_if_fail (widget != NULL);
493   g_return_if_fail (GTK_IS_LAYOUT (widget));
494
495   layout = GTK_LAYOUT (widget);
496
497   GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
498
499   tmp_list = layout->children;
500   while (tmp_list)
501     {
502       GtkLayoutChild *child = tmp_list->data;
503       tmp_list = tmp_list->next;
504
505       if (GTK_WIDGET_VISIBLE (child->widget))
506         {
507           if (!GTK_WIDGET_MAPPED (child->widget))
508             gtk_widget_map (child->widget);
509         }
510     }
511
512   gdk_window_show (layout->bin_window);
513   gdk_window_show (widget->window);
514 }
515
516 static void 
517 gtk_layout_unrealize (GtkWidget *widget)
518 {
519   GtkLayout *layout;
520
521   g_return_if_fail (widget != NULL);
522   g_return_if_fail (GTK_IS_LAYOUT (widget));
523
524   layout = GTK_LAYOUT (widget);
525
526   gdk_window_set_user_data (layout->bin_window, NULL);
527   gdk_window_destroy (layout->bin_window);
528   layout->bin_window = NULL;
529
530   if (GTK_WIDGET_CLASS (parent_class)->unrealize)
531     (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
532 }
533
534 static void     
535 gtk_layout_size_request (GtkWidget     *widget,
536                          GtkRequisition *requisition)
537 {
538   GList *tmp_list;
539   GtkLayout *layout;
540
541   g_return_if_fail (widget != NULL);
542   g_return_if_fail (GTK_IS_LAYOUT (widget));
543
544   layout = GTK_LAYOUT (widget);
545
546   requisition->width = 0;
547   requisition->height = 0;
548
549   tmp_list = layout->children;
550
551   while (tmp_list)
552     {
553       GtkLayoutChild *child = tmp_list->data;
554       GtkRequisition child_requisition;
555       
556       tmp_list = tmp_list->next;
557
558       gtk_widget_size_request (child->widget, &child_requisition);
559     }
560 }
561
562 static void     
563 gtk_layout_size_allocate (GtkWidget     *widget,
564                           GtkAllocation *allocation)
565 {
566   GList *tmp_list;
567   GtkLayout *layout;
568
569   g_return_if_fail (widget != NULL);
570   g_return_if_fail (GTK_IS_LAYOUT (widget));
571
572   widget->allocation = *allocation;
573   
574   layout = GTK_LAYOUT (widget);
575
576   tmp_list = layout->children;
577
578   while (tmp_list)
579     {
580       GtkLayoutChild *child = tmp_list->data;
581       tmp_list = tmp_list->next;
582
583       gtk_layout_allocate_child (layout, child);
584     }
585
586   if (GTK_WIDGET_REALIZED (widget))
587     {
588       gdk_window_move_resize (widget->window,
589                               allocation->x, allocation->y,
590                               allocation->width, allocation->height);
591
592       gdk_window_resize (layout->bin_window,
593                          MAX (layout->width, allocation->width),
594                          MAX (layout->height, allocation->height));
595     }
596
597   layout->hadjustment->page_size = allocation->width;
598   layout->hadjustment->page_increment = allocation->width / 2;
599   layout->hadjustment->lower = 0;
600   layout->hadjustment->upper = MAX (allocation->width, layout->width);
601   gtk_signal_emit_by_name (GTK_OBJECT (layout->hadjustment), "changed");
602
603   layout->vadjustment->page_size = allocation->height;
604   layout->vadjustment->page_increment = allocation->height / 2;
605   layout->vadjustment->lower = 0;
606   layout->vadjustment->upper = MAX (allocation->height, layout->height);
607   gtk_signal_emit_by_name (GTK_OBJECT (layout->vadjustment), "changed");
608 }
609
610 static void 
611 gtk_layout_draw (GtkWidget *widget, GdkRectangle *area)
612 {
613   GList *tmp_list;
614   GtkLayout *layout;
615   GdkRectangle child_area;
616
617   g_return_if_fail (widget != NULL);
618   g_return_if_fail (GTK_IS_LAYOUT (widget));
619
620   layout = GTK_LAYOUT (widget);
621
622   /* We don't have any way of telling themes about this properly,
623    * so we just assume a background pixmap
624    */
625   if (!GTK_WIDGET_APP_PAINTABLE (widget))
626     gdk_window_clear_area (layout->bin_window,
627                            area->x, area->y, area->width, area->height);
628   
629   tmp_list = layout->children;
630   while (tmp_list)
631     {
632       GtkLayoutChild *child = tmp_list->data;
633       tmp_list = tmp_list->next;
634
635       if (gtk_widget_intersect (child->widget, area, &child_area))
636         gtk_widget_draw (child->widget, &child_area);
637     }
638 }
639
640 static gint 
641 gtk_layout_expose (GtkWidget *widget, GdkEventExpose *event)
642 {
643   GList *tmp_list;
644   GtkLayout *layout;
645   GdkEventExpose child_event;
646
647   g_return_val_if_fail (widget != NULL, FALSE);
648   g_return_val_if_fail (GTK_IS_LAYOUT (widget), FALSE);
649
650   layout = GTK_LAYOUT (widget);
651
652   if (event->window != layout->bin_window)
653     return FALSE;
654   
655   tmp_list = layout->children;
656   while (tmp_list)
657     {
658       GtkLayoutChild *child = tmp_list->data;
659       tmp_list = tmp_list->next;
660
661       child_event = *event;
662       if (GTK_WIDGET_DRAWABLE (child->widget) &&
663           GTK_WIDGET_NO_WINDOW (child->widget) &&
664           gtk_widget_intersect (child->widget, &event->area, &child_event.area))
665         gtk_widget_event (child->widget, (GdkEvent*) &child_event);
666     }
667
668   return FALSE;
669 }
670
671 /* Container method
672  */
673 static void
674 gtk_layout_remove (GtkContainer *container, 
675                    GtkWidget    *widget)
676 {
677   GList *tmp_list;
678   GtkLayout *layout;
679   GtkLayoutChild *child = NULL;
680   
681   g_return_if_fail (container != NULL);
682   g_return_if_fail (GTK_IS_LAYOUT (container));
683   
684   layout = GTK_LAYOUT (container);
685
686   tmp_list = layout->children;
687   while (tmp_list)
688     {
689       child = tmp_list->data;
690       if (child->widget == widget)
691         break;
692       tmp_list = tmp_list->next;
693     }
694
695   if (tmp_list)
696     {
697       gtk_widget_unparent (widget);
698
699       layout->children = g_list_remove_link (layout->children, tmp_list);
700       g_list_free_1 (tmp_list);
701       g_free (child);
702     }
703 }
704
705 static void
706 gtk_layout_forall (GtkContainer *container,
707                    gboolean      include_internals,
708                    GtkCallback   callback,
709                    gpointer      callback_data)
710 {
711   GtkLayout *layout;
712   GtkLayoutChild *child;
713   GList *tmp_list;
714
715   g_return_if_fail (container != NULL);
716   g_return_if_fail (GTK_IS_LAYOUT (container));
717   g_return_if_fail (callback != NULL);
718
719   layout = GTK_LAYOUT (container);
720
721   tmp_list = layout->children;
722   while (tmp_list)
723     {
724       child = tmp_list->data;
725       tmp_list = tmp_list->next;
726
727       (* callback) (child->widget, callback_data);
728     }
729 }
730
731 /* Operations on children
732  */
733
734 static void
735 gtk_layout_allocate_child (GtkLayout      *layout,
736                            GtkLayoutChild *child)
737 {
738   GtkAllocation allocation;
739   GtkRequisition requisition;
740
741   allocation.x = child->x - layout->xoffset;
742   allocation.y = child->y - layout->yoffset;
743   gtk_widget_get_child_requisition (child->widget, &requisition);
744   allocation.width = requisition.width;
745   allocation.height = requisition.height;
746   
747   gtk_widget_size_allocate (child->widget, &allocation);
748 }
749
750 /* Callbacks */
751
752 static void
753 gtk_layout_adjustment_changed (GtkAdjustment *adjustment,
754                                GtkLayout     *layout)
755 {
756   GtkWidget *widget;
757
758   widget = GTK_WIDGET (layout);
759
760   if (layout->freeze_count)
761     return;
762
763   if (GTK_WIDGET_REALIZED (layout))
764     {
765       gdk_window_move (layout->bin_window,
766                        - layout->hadjustment->value,
767                        - layout->vadjustment->value);
768       
769       gdk_window_process_updates (layout->bin_window, TRUE);
770     }
771 }