]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/win_gtk.c
remove the #warning for VisualAge
[wxWidgets.git] / src / gtk / win_gtk.c
CommitLineData
c67daf87 1/* ///////////////////////////////////////////////////////////////////////////
c67d8618 2// Name: win_gtk.c
ed673c6a
RR
3// Purpose: Native GTK+ widget for wxWindows, based on GtkLayout and
4// GtkFixed. It makes use of the gravity window property and
5// therefore does not work with GTK 1.0.
c801d85f 6// Author: Robert Roebling
c67d8618 7// Id: $Id$
01111366 8// Copyright: (c) 1998 Robert Roebling
bf3dab48 9// Licence: wxWindows licence
c67daf87 10/////////////////////////////////////////////////////////////////////////// */
c801d85f
KB
11
12#include "wx/gtk/win_gtk.h"
3fa056ab
JJ
13#ifdef __VMS
14#define gtk_widget_get_child_requisition gtk_widget_get_child_requisitio
15#define gtk_marshal_NONE__POINTER_POINTER gtk_marshal_NONE__POINTER_POINT
16#endif
034be888 17#include "gtk/gtksignal.h"
ed673c6a
RR
18#include "gtk/gtkprivate.h"
19#include "gdk/gdkx.h"
38c7b3d3 20
c801d85f
KB
21#ifdef __cplusplus
22extern "C" {
23#endif /* __cplusplus */
24
c916e13b
RR
25#include <X11/Xlib.h>
26#include <X11/Xutil.h>
27#include <X11/Xatom.h>
28
ed673c6a
RR
29#define IS_ONSCREEN(x,y) ((x >= G_MINSHORT) && (x <= G_MAXSHORT) && \
30 (y >= G_MINSHORT) && (y <= G_MAXSHORT))
31
da048e3d
RR
32typedef struct _GtkPizzaAdjData GtkPizzaAdjData;
33typedef struct _GtkPizzaChild GtkPizzaChild;
ed673c6a 34
bf3dab48 35struct _GtkPizzaAdjData
ed673c6a
RR
36{
37 gint dx;
38 gint dy;
39};
40
da048e3d 41struct _GtkPizzaChild
ed673c6a
RR
42{
43 GtkWidget *widget;
44 gint x;
45 gint y;
46 gint width;
47 gint height;
48};
49
da048e3d
RR
50static void gtk_pizza_class_init (GtkPizzaClass *klass);
51static void gtk_pizza_init (GtkPizza *pizza);
ed673c6a 52
da048e3d
RR
53static void gtk_pizza_realize (GtkWidget *widget);
54static void gtk_pizza_unrealize (GtkWidget *widget);
ed673c6a 55
da048e3d 56static void gtk_pizza_map (GtkWidget *widget);
ed673c6a 57
da048e3d 58static void gtk_pizza_size_request (GtkWidget *widget,
bf3dab48 59 GtkRequisition *requisition);
da048e3d 60static void gtk_pizza_size_allocate (GtkWidget *widget,
bf3dab48 61 GtkAllocation *allocation);
da048e3d 62static void gtk_pizza_draw (GtkWidget *widget,
bf3dab48 63 GdkRectangle *area);
da048e3d 64static gint gtk_pizza_expose (GtkWidget *widget,
bf3dab48 65 GdkEventExpose *event);
da048e3d 66static void gtk_pizza_add (GtkContainer *container,
bf3dab48 67 GtkWidget *widget);
da048e3d 68static void gtk_pizza_remove (GtkContainer *container,
bf3dab48 69 GtkWidget *widget);
da048e3d 70static void gtk_pizza_forall (GtkContainer *container,
bf3dab48
VZ
71 gboolean include_internals,
72 GtkCallback callback,
73 gpointer callback_data);
ed673c6a 74
da048e3d 75static void gtk_pizza_position_child (GtkPizza *pizza,
bf3dab48 76 GtkPizzaChild *child);
da048e3d 77static void gtk_pizza_allocate_child (GtkPizza *pizza,
bf3dab48 78 GtkPizzaChild *child);
da048e3d 79static void gtk_pizza_position_children (GtkPizza *pizza);
ed673c6a 80
da048e3d 81static void gtk_pizza_adjust_allocations_recurse (GtkWidget *widget,
bf3dab48 82 gpointer cb_data);
da048e3d 83static void gtk_pizza_adjust_allocations (GtkPizza *pizza,
bf3dab48
VZ
84 gint dx,
85 gint dy);
ed673c6a
RR
86
87
da048e3d 88static void gtk_pizza_expose_area (GtkPizza *pizza,
bf3dab48
VZ
89 gint x,
90 gint y,
91 gint width,
92 gint height);
da048e3d 93static void gtk_pizza_adjustment_changed (GtkAdjustment *adjustment,
bf3dab48 94 GtkPizza *pizza);
da048e3d 95static GdkFilterReturn gtk_pizza_filter (GdkXEvent *gdk_xevent,
bf3dab48
VZ
96 GdkEvent *event,
97 gpointer data);
da048e3d 98static GdkFilterReturn gtk_pizza_main_filter (GdkXEvent *gdk_xevent,
bf3dab48
VZ
99 GdkEvent *event,
100 gpointer data);
ed673c6a
RR
101
102
da048e3d 103static GtkType gtk_pizza_child_type (GtkContainer *container);
c801d85f 104
da048e3d 105static void gtk_pizza_scroll_set_adjustments (GtkPizza *pizza,
bf3dab48
VZ
106 GtkAdjustment *hadj,
107 GtkAdjustment *vadj);
c801d85f
KB
108
109
034be888 110static GtkContainerClass *parent_class = NULL;
ed673c6a 111static gboolean gravity_works;
034be888 112
c801d85f 113guint
da048e3d 114gtk_pizza_get_type ()
c801d85f 115{
da048e3d 116 static guint pizza_type = 0;
c801d85f 117
da048e3d 118 if (!pizza_type)
c801d85f 119 {
da048e3d 120 GtkTypeInfo pizza_info =
053f9cc1 121 {
bf3dab48
VZ
122 "GtkPizza",
123 sizeof (GtkPizza),
124 sizeof (GtkPizzaClass),
125 (GtkClassInitFunc) gtk_pizza_class_init,
126 (GtkObjectInitFunc) gtk_pizza_init,
127 /* reserved_1 */ NULL,
053f9cc1
RR
128 /* reserved_2 */ NULL,
129 (GtkClassInitFunc) NULL,
053f9cc1 130 };
da048e3d 131 pizza_type = gtk_type_unique (gtk_container_get_type (), &pizza_info);
c801d85f 132 }
bf3dab48 133
da048e3d 134 return pizza_type;
c801d85f
KB
135}
136
137static void
da048e3d 138gtk_pizza_class_init (GtkPizzaClass *klass)
c801d85f 139{
053f9cc1
RR
140 GtkObjectClass *object_class;
141 GtkWidgetClass *widget_class;
142 GtkContainerClass *container_class;
c801d85f 143
053f9cc1
RR
144 object_class = (GtkObjectClass*) klass;
145 widget_class = (GtkWidgetClass*) klass;
146 container_class = (GtkContainerClass*) klass;
053f9cc1 147 parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
c801d85f 148
da048e3d
RR
149 widget_class->map = gtk_pizza_map;
150 widget_class->realize = gtk_pizza_realize;
151 widget_class->unrealize = gtk_pizza_unrealize;
152 widget_class->size_request = gtk_pizza_size_request;
153 widget_class->size_allocate = gtk_pizza_size_allocate;
154 widget_class->draw = gtk_pizza_draw;
155 widget_class->expose_event = gtk_pizza_expose;
053f9cc1 156
da048e3d
RR
157 container_class->add = gtk_pizza_add;
158 container_class->remove = gtk_pizza_remove;
159 container_class->forall = gtk_pizza_forall;
38c7b3d3 160
da048e3d 161 container_class->child_type = gtk_pizza_child_type;
034be888 162
da048e3d 163 klass->set_scroll_adjustments = gtk_pizza_scroll_set_adjustments;
034be888 164
053f9cc1 165 widget_class->set_scroll_adjustments_signal =
034be888 166 gtk_signal_new ("set_scroll_adjustments",
bf3dab48
VZ
167 GTK_RUN_LAST,
168 object_class->type,
169 GTK_SIGNAL_OFFSET (GtkPizzaClass, set_scroll_adjustments),
170 gtk_marshal_NONE__POINTER_POINTER,
171 GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
38c7b3d3
RR
172}
173
38c7b3d3 174static GtkType
da048e3d 175gtk_pizza_child_type (GtkContainer *container)
38c7b3d3 176{
053f9cc1 177 return GTK_TYPE_WIDGET;
c801d85f
KB
178}
179
180static void
da048e3d 181gtk_pizza_init (GtkPizza *pizza)
c801d85f 182{
da048e3d 183 GTK_WIDGET_UNSET_FLAGS (pizza, GTK_NO_WINDOW);
bf3dab48 184
da048e3d 185 pizza->shadow_type = GTK_MYSHADOW_NONE;
034be888 186
da048e3d 187 pizza->children = NULL;
bf3dab48 188
da048e3d
RR
189 pizza->width = 20;
190 pizza->height = 20;
ed673c6a 191
da048e3d 192 pizza->bin_window = NULL;
8e217128
RR
193
194 pizza->xoffset = 0;
195 pizza->yoffset = 0;
ed673c6a 196
da048e3d
RR
197 pizza->configure_serial = 0;
198 pizza->scroll_x = 0;
199 pizza->scroll_y = 0;
200 pizza->visibility = GDK_VISIBILITY_PARTIAL;
bf3dab48 201
da048e3d 202 pizza->clear_on_draw = TRUE;
0e09f76e 203 pizza->use_filter = FALSE;
c801d85f
KB
204}
205
206GtkWidget*
da048e3d 207gtk_pizza_new ()
c801d85f 208{
da048e3d 209 GtkPizza *pizza;
c801d85f 210
da048e3d 211 pizza = gtk_type_new (gtk_pizza_get_type ());
bf3dab48 212
da048e3d 213 return GTK_WIDGET (pizza);
c801d85f
KB
214}
215
bf3dab48 216static void
da048e3d 217gtk_pizza_scroll_set_adjustments (GtkPizza *pizza,
bf3dab48
VZ
218 GtkAdjustment *hadj,
219 GtkAdjustment *vadj)
034be888 220{
ed673c6a 221 /* We handle scrolling in the wxScrolledWindow, not here. */
034be888
RR
222}
223
bf3dab48 224void
da048e3d 225gtk_pizza_set_shadow_type (GtkPizza *pizza,
0e09f76e 226 GtkMyShadowType type)
034be888 227{
da048e3d
RR
228 g_return_if_fail (pizza != NULL);
229 g_return_if_fail (GTK_IS_PIZZA (pizza));
034be888 230
da048e3d 231 if ((GtkMyShadowType) pizza->shadow_type != type)
034be888 232 {
da048e3d 233 pizza->shadow_type = type;
034be888 234
da048e3d 235 if (GTK_WIDGET_VISIBLE (pizza))
bf3dab48
VZ
236 {
237 gtk_widget_size_allocate (GTK_WIDGET (pizza), &(GTK_WIDGET (pizza)->allocation));
238 gtk_widget_queue_draw (GTK_WIDGET (pizza));
239 }
034be888
RR
240 }
241}
034be888 242
bf3dab48 243void
da048e3d 244gtk_pizza_set_clear (GtkPizza *pizza,
0e09f76e 245 gboolean clear)
147bc491 246{
da048e3d
RR
247 g_return_if_fail (pizza != NULL);
248 g_return_if_fail (GTK_IS_PIZZA (pizza));
bf3dab48 249
da048e3d 250 pizza->clear_on_draw = clear;
bf3dab48
VZ
251}
252
0e09f76e
RR
253void
254gtk_pizza_set_filter (GtkPizza *pizza,
255 gboolean use)
256{
257 g_return_if_fail (pizza != NULL);
258 g_return_if_fail (GTK_IS_PIZZA (pizza));
259
260 pizza->use_filter = use;
261}
262
c801d85f 263void
da048e3d 264gtk_pizza_put (GtkPizza *pizza,
053f9cc1 265 GtkWidget *widget,
ed673c6a
RR
266 gint x,
267 gint y,
bf3dab48
VZ
268 gint width,
269 gint height)
c801d85f 270{
da048e3d 271 GtkPizzaChild *child_info;
053f9cc1 272
da048e3d
RR
273 g_return_if_fail (pizza != NULL);
274 g_return_if_fail (GTK_IS_PIZZA (pizza));
053f9cc1
RR
275 g_return_if_fail (widget != NULL);
276
da048e3d 277 child_info = g_new (GtkPizzaChild, 1);
bf3dab48 278
053f9cc1
RR
279 child_info->widget = widget;
280 child_info->x = x;
281 child_info->y = y;
282 child_info->width = width;
283 child_info->height = height;
bf3dab48
VZ
284
285 pizza->children = g_list_append (pizza->children, child_info);
ed673c6a 286
da048e3d 287 gtk_widget_set_parent (widget, GTK_WIDGET (pizza));
c801d85f 288
da048e3d
RR
289 if (GTK_WIDGET_REALIZED (pizza))
290 gtk_widget_set_parent_window (widget, pizza->bin_window);
bf3dab48 291
ed673c6a
RR
292 if (!IS_ONSCREEN (x, y))
293 GTK_PRIVATE_SET_FLAG (widget, GTK_IS_OFFSCREEN);
c801d85f 294
0e09f76e 295/*
da048e3d 296 if (GTK_WIDGET_REALIZED (pizza))
053f9cc1 297 gtk_widget_realize (widget);
0e09f76e 298*/
c801d85f 299
ed673c6a 300 gtk_widget_set_usize (widget, width, height);
bf3dab48 301
0e09f76e 302/*
da048e3d 303 if (GTK_WIDGET_VISIBLE (pizza) && GTK_WIDGET_VISIBLE (widget))
326f9654 304 {
da048e3d 305 if (GTK_WIDGET_MAPPED (pizza))
bf3dab48
VZ
306 gtk_widget_map (widget);
307
ed673c6a 308 gtk_widget_queue_resize (widget);
326f9654 309 }
0e09f76e 310*/
c801d85f
KB
311}
312
313void
da048e3d 314gtk_pizza_move (GtkPizza *pizza,
053f9cc1 315 GtkWidget *widget,
ed673c6a
RR
316 gint x,
317 gint y)
c801d85f 318{
da048e3d 319 GtkPizzaChild *child;
053f9cc1 320 GList *children;
c801d85f 321
da048e3d
RR
322 g_return_if_fail (pizza != NULL);
323 g_return_if_fail (GTK_IS_PIZZA (pizza));
053f9cc1 324 g_return_if_fail (widget != NULL);
c801d85f 325
da048e3d 326 children = pizza->children;
053f9cc1 327 while (children)
fdd3ed7a 328 {
053f9cc1
RR
329 child = children->data;
330 children = children->next;
bf3dab48 331
053f9cc1 332 if (child->widget == widget)
fdd3ed7a 333 {
bf3dab48
VZ
334 if ((child->x == x) && (child->y == y))
335 break;
336
ed673c6a
RR
337 child->x = x;
338 child->y = y;
bf3dab48
VZ
339
340 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (pizza))
341 gtk_widget_queue_resize (widget);
342 break;
343 }
fdd3ed7a
RR
344 }
345}
346
347void
da048e3d 348gtk_pizza_resize (GtkPizza *pizza,
fdd3ed7a 349 GtkWidget *widget,
bf3dab48
VZ
350 gint width,
351 gint height)
fdd3ed7a 352{
da048e3d 353 GtkPizzaChild *child;
053f9cc1 354 GList *children;
fdd3ed7a 355
da048e3d
RR
356 g_return_if_fail (pizza != NULL);
357 g_return_if_fail (GTK_IS_PIZZA (pizza));
053f9cc1 358 g_return_if_fail (widget != NULL);
fdd3ed7a 359
da048e3d 360 children = pizza->children;
053f9cc1 361 while (children)
fdd3ed7a 362 {
053f9cc1
RR
363 child = children->data;
364 children = children->next;
bf3dab48 365
053f9cc1 366 if (child->widget == widget)
fdd3ed7a 367 {
bf3dab48
VZ
368 if ((child->width == width) && (child->height == height))
369 break;
370
ed673c6a
RR
371 child->width = width;
372 child->height = height;
bf3dab48
VZ
373
374 gtk_widget_set_usize (widget, width, height);
375
da048e3d 376 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (pizza))
bf3dab48
VZ
377 gtk_widget_queue_resize (widget);
378 break;
379 }
fdd3ed7a
RR
380 }
381}
382
383void
da048e3d 384gtk_pizza_set_size (GtkPizza *pizza,
053f9cc1 385 GtkWidget *widget,
ed673c6a
RR
386 gint x,
387 gint y,
bf3dab48
VZ
388 gint width,
389 gint height)
fdd3ed7a 390{
da048e3d 391 GtkPizzaChild *child;
053f9cc1 392 GList *children;
fdd3ed7a 393
da048e3d
RR
394 g_return_if_fail (pizza != NULL);
395 g_return_if_fail (GTK_IS_PIZZA (pizza));
053f9cc1 396 g_return_if_fail (widget != NULL);
fdd3ed7a 397
da048e3d 398 children = pizza->children;
053f9cc1 399 while (children)
c801d85f 400 {
053f9cc1
RR
401 child = children->data;
402 children = children->next;
c801d85f 403
053f9cc1 404 if (child->widget == widget)
c801d85f 405 {
bf3dab48
VZ
406 if ((child->x == x) &&
407 (child->y == y) &&
408 (child->width == width) &&
409 (child->height == height)) return;
410
053f9cc1
RR
411 child->x = x;
412 child->y = y;
413 child->width = width;
414 child->height = height;
bf3dab48
VZ
415
416 gtk_widget_set_usize (widget, width, height);
417
da048e3d 418 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (pizza))
bf3dab48
VZ
419 gtk_widget_queue_resize (widget);
420
6d693bb4 421 return;
c801d85f
KB
422 }
423 }
424}
425
426static void
da048e3d 427gtk_pizza_map (GtkWidget *widget)
c801d85f 428{
da048e3d
RR
429 GtkPizza *pizza;
430 GtkPizzaChild *child;
053f9cc1 431 GList *children;
c801d85f 432
053f9cc1 433 g_return_if_fail (widget != NULL);
da048e3d 434 g_return_if_fail (GTK_IS_PIZZA (widget));
c801d85f 435
053f9cc1 436 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
da048e3d 437 pizza = GTK_PIZZA (widget);
c801d85f 438
da048e3d 439 children = pizza->children;
053f9cc1 440 while (children)
c801d85f 441 {
053f9cc1
RR
442 child = children->data;
443 children = children->next;
c801d85f 444
bf3dab48
VZ
445 if ( GTK_WIDGET_VISIBLE (child->widget) &&
446 !GTK_WIDGET_MAPPED (child->widget) &&
447 !GTK_WIDGET_IS_OFFSCREEN (child->widget))
448 {
449 gtk_widget_map (child->widget);
450 }
c801d85f 451 }
bf3dab48 452
053f9cc1 453 gdk_window_show (widget->window);
da048e3d 454 gdk_window_show (pizza->bin_window);
c801d85f
KB
455}
456
c801d85f 457static void
da048e3d 458gtk_pizza_realize (GtkWidget *widget)
c801d85f 459{
da048e3d 460 GtkPizza *pizza;
053f9cc1
RR
461 GdkWindowAttr attributes;
462 gint attributes_mask;
da048e3d 463 GtkPizzaChild *child;
ed673c6a 464 GList *children;
c801d85f 465
053f9cc1 466 g_return_if_fail (widget != NULL);
da048e3d 467 g_return_if_fail (GTK_IS_PIZZA (widget));
c801d85f 468
da048e3d 469 pizza = GTK_PIZZA (widget);
bf3dab48 470
053f9cc1 471 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
c801d85f 472
053f9cc1 473 attributes.window_type = GDK_WINDOW_CHILD;
bf3dab48 474
053f9cc1
RR
475 attributes.x = widget->allocation.x;
476 attributes.y = widget->allocation.y;
477 attributes.width = widget->allocation.width;
478 attributes.height = widget->allocation.height;
479
da048e3d 480 if (pizza->shadow_type == GTK_MYSHADOW_NONE)
053f9cc1 481 {
5e014a0c
RR
482 /* no border, no changes to sizes */
483 } else
da048e3d 484 if (pizza->shadow_type == GTK_MYSHADOW_THIN)
5e014a0c
RR
485 {
486 /* GTK_MYSHADOW_THIN == wxSIMPLE_BORDER */
487 attributes.x += 1;
488 attributes.y += 1;
489 attributes.width -= 2;
490 attributes.height -= 2;
491 } else
492 {
493 /* GTK_MYSHADOW_IN == wxSUNKEN_BORDER */
494 /* GTK_MYSHADOW_OUT == wxRAISED_BORDER */
053f9cc1
RR
495 attributes.x += 2;
496 attributes.y += 2;
497 attributes.width -= 4;
498 attributes.height -= 4;
499 }
bf3dab48 500
ed673c6a 501 /* minimal size */
053f9cc1
RR
502 if (attributes.width < 2) attributes.width = 2;
503 if (attributes.height < 2) attributes.height = 2;
bf3dab48 504
053f9cc1
RR
505 attributes.wclass = GDK_INPUT_OUTPUT;
506 attributes.visual = gtk_widget_get_visual (widget);
507 attributes.colormap = gtk_widget_get_colormap (widget);
bf3dab48 508 attributes.event_mask =
ed673c6a
RR
509 GDK_VISIBILITY_NOTIFY_MASK;
510 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
bf3dab48 511
c916e13b 512 widget->window = gdk_window_new(gtk_widget_get_parent_window (widget),
bf3dab48 513 &attributes, attributes_mask);
ed673c6a
RR
514 gdk_window_set_user_data (widget->window, widget);
515
516 attributes.x = 0;
517 attributes.y = 0;
bf3dab48 518
053f9cc1 519 attributes.event_mask = gtk_widget_get_events (widget);
bf3dab48
VZ
520 attributes.event_mask |=
521 GDK_EXPOSURE_MASK |
522 GDK_POINTER_MOTION_MASK |
053f9cc1 523 GDK_POINTER_MOTION_HINT_MASK |
bf3dab48
VZ
524 GDK_BUTTON_MOTION_MASK |
525 GDK_BUTTON1_MOTION_MASK |
526 GDK_BUTTON2_MOTION_MASK |
527 GDK_BUTTON3_MOTION_MASK |
528 GDK_BUTTON_PRESS_MASK |
529 GDK_BUTTON_RELEASE_MASK |
530 GDK_KEY_PRESS_MASK |
531 GDK_KEY_RELEASE_MASK |
532 GDK_ENTER_NOTIFY_MASK |
533 GDK_LEAVE_NOTIFY_MASK |
053f9cc1 534 GDK_FOCUS_CHANGE_MASK;
053f9cc1 535
c916e13b 536 pizza->bin_window = gdk_window_new(widget->window,
bf3dab48 537 &attributes, attributes_mask);
da048e3d 538 gdk_window_set_user_data (pizza->bin_window, widget);
bf3dab48 539
053f9cc1
RR
540 widget->style = gtk_style_attach (widget->style, widget->window);
541 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
da048e3d 542 gtk_style_set_background (widget->style, pizza->bin_window, GTK_STATE_NORMAL);
bf3dab48 543
ed673c6a 544 /* add filters for intercepting visibility and expose events */
da048e3d
RR
545 gdk_window_add_filter (widget->window, gtk_pizza_main_filter, pizza);
546 gdk_window_add_filter (pizza->bin_window, gtk_pizza_filter, pizza);
ed673c6a
RR
547
548 /* we NEED gravity or we'll give up */
da048e3d 549 gravity_works = gdk_window_set_static_gravities (pizza->bin_window, TRUE);
ed673c6a
RR
550
551 /* cannot be done before realisation */
da048e3d 552 children = pizza->children;
ed673c6a
RR
553 while (children)
554 {
555 child = children->data;
556 children = children->next;
557
da048e3d 558 gtk_widget_set_parent_window (child->widget, pizza->bin_window);
ed673c6a
RR
559 }
560}
561
bf3dab48 562static void
da048e3d 563gtk_pizza_unrealize (GtkWidget *widget)
ed673c6a 564{
da048e3d 565 GtkPizza *pizza;
ed673c6a
RR
566
567 g_return_if_fail (widget != NULL);
da048e3d 568 g_return_if_fail (GTK_IS_PIZZA (widget));
ed673c6a 569
da048e3d 570 pizza = GTK_PIZZA (widget);
ed673c6a 571
da048e3d
RR
572 gdk_window_set_user_data (pizza->bin_window, NULL);
573 gdk_window_destroy (pizza->bin_window);
574 pizza->bin_window = NULL;
ed673c6a
RR
575
576 if (GTK_WIDGET_CLASS (parent_class)->unrealize)
577 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
c801d85f
KB
578}
579
580static void
da048e3d 581gtk_pizza_size_request (GtkWidget *widget,
bf3dab48 582 GtkRequisition *requisition)
c801d85f 583{
da048e3d
RR
584 GtkPizza *pizza;
585 GtkPizzaChild *child;
053f9cc1
RR
586 GList *children;
587 GtkRequisition child_requisition;
bf3dab48 588
053f9cc1 589 g_return_if_fail (widget != NULL);
da048e3d 590 g_return_if_fail (GTK_IS_PIZZA (widget));
053f9cc1 591 g_return_if_fail (requisition != NULL);
c801d85f 592
da048e3d 593 pizza = GTK_PIZZA (widget);
bf3dab48 594
da048e3d 595 children = pizza->children;
053f9cc1 596 while (children)
c801d85f 597 {
053f9cc1
RR
598 child = children->data;
599 children = children->next;
c801d85f 600
053f9cc1 601 if (GTK_WIDGET_VISIBLE (child->widget))
bf3dab48 602 {
053f9cc1 603 gtk_widget_size_request (child->widget, &child_requisition);
bf3dab48 604 }
c801d85f 605 }
bf3dab48 606
053f9cc1
RR
607 /* request very little, I'm not sure if requesting nothing
608 will always have positive effects on stability... */
609 requisition->width = 2;
610 requisition->height = 2;
c801d85f
KB
611}
612
613static void
da048e3d 614gtk_pizza_size_allocate (GtkWidget *widget,
bf3dab48 615 GtkAllocation *allocation)
c801d85f 616{
da048e3d 617 GtkPizza *pizza;
053f9cc1 618 gint border;
ed673c6a 619 gint x,y,w,h;
da048e3d 620 GtkPizzaChild *child;
ed673c6a 621 GList *children;
c801d85f 622
053f9cc1 623 g_return_if_fail (widget != NULL);
da048e3d 624 g_return_if_fail (GTK_IS_PIZZA(widget));
053f9cc1 625 g_return_if_fail (allocation != NULL);
c801d85f 626
da048e3d 627 pizza = GTK_PIZZA (widget);
bf3dab48 628
227e5e99 629 widget->allocation = *allocation;
bf3dab48 630
da048e3d 631 if (pizza->shadow_type == GTK_MYSHADOW_NONE)
053f9cc1 632 border = 0;
5e014a0c 633 else
da048e3d 634 if (pizza->shadow_type == GTK_MYSHADOW_THIN)
5e014a0c 635 border = 1;
053f9cc1
RR
636 else
637 border = 2;
bf3dab48 638
ed673c6a
RR
639 x = allocation->x + border;
640 y = allocation->y + border;
641 w = allocation->width - border*2;
642 h = allocation->height - border*2;
034be888 643
053f9cc1
RR
644 if (GTK_WIDGET_REALIZED (widget))
645 {
ed673c6a 646 gdk_window_move_resize( widget->window, x, y, w, h );
da048e3d 647 gdk_window_move_resize( pizza->bin_window, 0, 0, w, h );
053f9cc1 648 }
bf3dab48 649
da048e3d 650 children = pizza->children;
6d693bb4
RR
651 while (children)
652 {
653 child = children->data;
654 children = children->next;
bf3dab48 655
da048e3d
RR
656 gtk_pizza_position_child (pizza, child);
657 gtk_pizza_allocate_child (pizza, child);
6d693bb4 658 }
c801d85f
KB
659}
660
661static void
da048e3d 662gtk_pizza_draw (GtkWidget *widget,
bf3dab48 663 GdkRectangle *area)
c801d85f 664{
da048e3d
RR
665 GtkPizza *pizza;
666 GtkPizzaChild *child;
ed673c6a
RR
667 GdkRectangle child_area;
668 GList *children;
669
053f9cc1 670 g_return_if_fail (widget != NULL);
da048e3d 671 g_return_if_fail (GTK_IS_PIZZA (widget));
053f9cc1 672
da048e3d 673 pizza = GTK_PIZZA (widget);
bf3dab48 674
da048e3d 675 children = pizza->children;
147bc491 676 if ( !(GTK_WIDGET_APP_PAINTABLE (widget)) &&
da048e3d 677 (pizza->clear_on_draw))
ed673c6a 678 {
da048e3d 679 gdk_window_clear_area( pizza->bin_window,
bf3dab48 680 area->x, area->y, area->width, area->height);
ed673c6a
RR
681 }
682
683 while (children)
684 {
bf3dab48
VZ
685 child = children->data;
686 children = children->next;
ed673c6a 687
bf3dab48
VZ
688 if (gtk_widget_intersect (child->widget, area, &child_area))
689 gtk_widget_draw (child->widget, &child_area);
ed673c6a 690 }
c801d85f
KB
691}
692
c801d85f 693static gint
da048e3d 694gtk_pizza_expose (GtkWidget *widget,
bf3dab48 695 GdkEventExpose *event)
c801d85f 696{
da048e3d
RR
697 GtkPizza *pizza;
698 GtkPizzaChild *child;
ed673c6a
RR
699 GdkEventExpose child_event;
700 GList *children;
c801d85f 701
ed673c6a 702 g_return_val_if_fail (widget != NULL, FALSE);
da048e3d 703 g_return_val_if_fail (GTK_IS_PIZZA (widget), FALSE);
ed673c6a
RR
704 g_return_val_if_fail (event != NULL, FALSE);
705
da048e3d 706 pizza = GTK_PIZZA (widget);
c801d85f 707
da048e3d 708 if (event->window != pizza->bin_window)
ed673c6a 709 return FALSE;
c801d85f 710
da048e3d 711 children = pizza->children;
ed673c6a
RR
712 while (children)
713 {
bf3dab48
VZ
714 child = children->data;
715 children = children->next;
c801d85f 716
ed673c6a
RR
717 child_event = *event;
718
bf3dab48
VZ
719 if (GTK_WIDGET_NO_WINDOW (child->widget) &&
720 GTK_WIDGET_DRAWABLE (child->widget) &&
721 gtk_widget_intersect (child->widget, &event->area, &child_event.area))
722 {
723 gtk_widget_event (child->widget, (GdkEvent*) &child_event);
724 }
c801d85f
KB
725 }
726
ed673c6a 727 return FALSE;
c801d85f
KB
728}
729
730static void
da048e3d 731gtk_pizza_add (GtkContainer *container,
bf3dab48 732 GtkWidget *widget)
c801d85f 733{
ed673c6a 734 g_return_if_fail (container != NULL);
da048e3d 735 g_return_if_fail (GTK_IS_PIZZA (container));
ed673c6a 736 g_return_if_fail (widget != NULL);
c801d85f 737
da048e3d 738 gtk_pizza_put (GTK_PIZZA (container), widget, 0, 0, 20, 20 );
c801d85f
KB
739}
740
741static void
da048e3d 742gtk_pizza_remove (GtkContainer *container,
bf3dab48 743 GtkWidget *widget)
c801d85f 744{
da048e3d
RR
745 GtkPizza *pizza;
746 GtkPizzaChild *child;
ed673c6a 747 GList *children;
c801d85f 748
ed673c6a 749 g_return_if_fail (container != NULL);
da048e3d 750 g_return_if_fail (GTK_IS_PIZZA (container));
ed673c6a 751 g_return_if_fail (widget != NULL);
c801d85f 752
da048e3d 753 pizza = GTK_PIZZA (container);
c801d85f 754
da048e3d 755 children = pizza->children;
ed673c6a 756 while (children)
c801d85f 757 {
ed673c6a 758 child = children->data;
c801d85f 759
ed673c6a 760 if (child->widget == widget)
bf3dab48
VZ
761 {
762 gtk_widget_unparent (widget);
c801d85f 763
ed673c6a
RR
764 /* security checks */
765 g_return_if_fail (GTK_IS_WIDGET (widget));
bf3dab48
VZ
766
767 pizza->children = g_list_remove_link (pizza->children, children);
768 g_list_free (children);
769 g_free (child);
c801d85f 770
ed673c6a 771 /* security checks */
bf3dab48
VZ
772 g_return_if_fail (GTK_IS_WIDGET (widget));
773
ed673c6a 774 GTK_PRIVATE_UNSET_FLAG (widget, GTK_IS_OFFSCREEN);
bf3dab48
VZ
775
776 break;
777 }
c801d85f 778
ed673c6a 779 children = children->next;
c801d85f
KB
780 }
781}
782
783static void
da048e3d 784gtk_pizza_forall (GtkContainer *container,
bf3dab48
VZ
785 gboolean include_internals,
786 GtkCallback callback,
787 gpointer callback_data)
c801d85f 788{
da048e3d
RR
789 GtkPizza *pizza;
790 GtkPizzaChild *child;
6d693bb4 791 GList *children;
c801d85f 792
6d693bb4 793 g_return_if_fail (container != NULL);
da048e3d 794 g_return_if_fail (GTK_IS_PIZZA (container));
6d693bb4 795 g_return_if_fail (callback != NULL);
c801d85f 796
da048e3d 797 pizza = GTK_PIZZA (container);
c801d85f 798
da048e3d 799 children = pizza->children;
6d693bb4 800 while (children)
c801d85f 801 {
6d693bb4
RR
802 child = children->data;
803 children = children->next;
c801d85f 804
6d693bb4 805 (* callback) (child->widget, callback_data);
c801d85f
KB
806 }
807}
808
809
ed673c6a
RR
810/* Operations on children
811 */
812
813static void
da048e3d 814gtk_pizza_position_child (GtkPizza *pizza,
bf3dab48 815 GtkPizzaChild *child)
ed673c6a 816{
6d693bb4
RR
817 gint x;
818 gint y;
ed673c6a 819
da048e3d
RR
820 x = child->x - pizza->xoffset;
821 y = child->y - pizza->yoffset;
ed673c6a 822
6d693bb4 823 if (IS_ONSCREEN (x,y))
ed673c6a 824 {
da048e3d 825 if (GTK_WIDGET_MAPPED (pizza) &&
bf3dab48
VZ
826 GTK_WIDGET_VISIBLE (child->widget))
827 {
828 if (!GTK_WIDGET_MAPPED (child->widget))
829 gtk_widget_map (child->widget);
830 }
ed673c6a 831
6d693bb4 832 if (GTK_WIDGET_IS_OFFSCREEN (child->widget))
bf3dab48 833 GTK_PRIVATE_UNSET_FLAG (child->widget, GTK_IS_OFFSCREEN);
ed673c6a 834 }
6d693bb4 835 else
ed673c6a 836 {
6d693bb4 837 if (!GTK_WIDGET_IS_OFFSCREEN (child->widget))
bf3dab48 838 GTK_PRIVATE_SET_FLAG (child->widget, GTK_IS_OFFSCREEN);
ed673c6a 839
6d693bb4 840 if (GTK_WIDGET_MAPPED (child->widget))
bf3dab48 841 gtk_widget_unmap (child->widget);
ed673c6a
RR
842 }
843}
844
845static void
da048e3d 846gtk_pizza_allocate_child (GtkPizza *pizza,
bf3dab48 847 GtkPizzaChild *child)
ed673c6a 848{
6d693bb4
RR
849 GtkAllocation allocation;
850 GtkRequisition requisition;
851
da048e3d
RR
852 allocation.x = child->x - pizza->xoffset;
853 allocation.y = child->y - pizza->yoffset;
6d693bb4
RR
854 gtk_widget_get_child_requisition (child->widget, &requisition);
855 allocation.width = requisition.width;
856 allocation.height = requisition.height;
bf3dab48 857
6d693bb4 858 gtk_widget_size_allocate (child->widget, &allocation);
ed673c6a
RR
859}
860
861static void
da048e3d 862gtk_pizza_position_children (GtkPizza *pizza)
ed673c6a 863{
6d693bb4 864 GList *tmp_list;
ed673c6a 865
da048e3d 866 tmp_list = pizza->children;
6d693bb4 867 while (tmp_list)
ed673c6a 868 {
da048e3d 869 GtkPizzaChild *child = tmp_list->data;
6d693bb4 870 tmp_list = tmp_list->next;
bf3dab48 871
da048e3d 872 gtk_pizza_position_child (pizza, child);
ed673c6a
RR
873 }
874}
875
876static void
da048e3d 877gtk_pizza_adjust_allocations_recurse (GtkWidget *widget,
bf3dab48 878 gpointer cb_data)
ed673c6a 879{
da048e3d 880 GtkPizzaAdjData *data = cb_data;
ed673c6a 881
6d693bb4
RR
882 widget->allocation.x += data->dx;
883 widget->allocation.y += data->dy;
ed673c6a 884
6d693bb4
RR
885 if (GTK_WIDGET_NO_WINDOW (widget) && GTK_IS_CONTAINER (widget))
886 {
bf3dab48
VZ
887 gtk_container_forall (GTK_CONTAINER (widget),
888 gtk_pizza_adjust_allocations_recurse,
889 cb_data);
6d693bb4 890 }
ed673c6a
RR
891}
892
893static void
da048e3d 894gtk_pizza_adjust_allocations (GtkPizza *pizza,
bf3dab48
VZ
895 gint dx,
896 gint dy)
ed673c6a 897{
0e09f76e
RR
898 GList *tmp_list;
899 GtkPizzaAdjData data;
ed673c6a 900
0e09f76e
RR
901 data.dx = dx;
902 data.dy = dy;
ed673c6a 903
0e09f76e
RR
904 tmp_list = pizza->children;
905 while (tmp_list)
ed673c6a 906 {
0e09f76e
RR
907 GtkPizzaChild *child = tmp_list->data;
908 tmp_list = tmp_list->next;
bf3dab48 909
0e09f76e
RR
910 child->widget->allocation.x += dx;
911 child->widget->allocation.y += dy;
ed673c6a 912
0e09f76e
RR
913 if (GTK_WIDGET_NO_WINDOW (child->widget) &&
914 GTK_IS_CONTAINER (child->widget))
915 {
916 gtk_container_forall (GTK_CONTAINER (child->widget),
917 gtk_pizza_adjust_allocations_recurse,
918 &data);
919 }
ed673c6a
RR
920 }
921}
bf3dab48 922
ed673c6a
RR
923/* Callbacks */
924
925/* Send a synthetic expose event to the widget
926 */
927static void
da048e3d 928gtk_pizza_expose_area (GtkPizza *pizza,
bf3dab48 929 gint x, gint y, gint width, gint height)
ed673c6a 930{
0e09f76e 931 if (pizza->visibility == GDK_VISIBILITY_UNOBSCURED)
ed673c6a 932 {
0e09f76e 933 GdkEventExpose event;
bf3dab48 934
0e09f76e
RR
935 event.type = GDK_EXPOSE;
936 event.send_event = TRUE;
937 event.window = pizza->bin_window;
938 event.count = 0;
bf3dab48 939
0e09f76e
RR
940 event.area.x = x;
941 event.area.y = y;
942 event.area.width = width;
943 event.area.height = height;
bf3dab48 944
0e09f76e
RR
945 gdk_window_ref (event.window);
946 gtk_widget_event (GTK_WIDGET (pizza), (GdkEvent *)&event);
947 gdk_window_unref (event.window);
ed673c6a
RR
948 }
949}
950
951/* This function is used to find events to process while scrolling
952 */
953
bf3dab48
VZ
954static Bool
955gtk_pizza_expose_predicate (Display *display,
956 XEvent *xevent,
957 XPointer arg)
ed673c6a 958{
bf3dab48 959 if ((xevent->type == Expose) ||
ed673c6a
RR
960 ((xevent->xany.window == *(Window *)arg) &&
961 (xevent->type == ConfigureNotify)))
962 return True;
963 else
964 return False;
965}
966
967/* This is the main routine to do the scrolling. Scrolling is
968 * done by "Guffaw" scrolling, as in the Mozilla XFE, with
969 * a few modifications.
bf3dab48 970 *
ed673c6a
RR
971 * The main improvement is that we keep track of whether we
972 * are obscured or not. If not, we ignore the generated expose
973 * events and instead do the exposes ourself, without having
974 * to wait for a roundtrip to the server. This also provides
975 * a limited form of expose-event compression, since we do
976 * the affected area as one big chunk.
977 */
978
979void
da048e3d 980gtk_pizza_scroll (GtkPizza *pizza, gint dx, gint dy)
ed673c6a
RR
981{
982 GtkWidget *widget;
983 XEvent xevent;
984
985 gint x,y,w,h,border;
bf3dab48 986
da048e3d 987 widget = GTK_WIDGET (pizza);
ed673c6a 988
da048e3d
RR
989 pizza->xoffset += dx;
990 pizza->yoffset += dy;
ed673c6a 991
da048e3d 992 if (!GTK_WIDGET_MAPPED (pizza))
ed673c6a 993 {
da048e3d 994 gtk_pizza_position_children (pizza);
ed673c6a
RR
995 return;
996 }
997
da048e3d 998 gtk_pizza_adjust_allocations (pizza, -dx, -dy);
ed673c6a 999
da048e3d 1000 if (pizza->shadow_type == GTK_MYSHADOW_NONE)
ed673c6a
RR
1001 border = 0;
1002 else
da048e3d 1003 if (pizza->shadow_type == GTK_MYSHADOW_THIN)
ed673c6a
RR
1004 border = 1;
1005 else
1006 border = 2;
bf3dab48 1007
ed673c6a
RR
1008 x = 0;
1009 y = 0;
1010 w = widget->allocation.width - 2*border;
1011 h = widget->allocation.height - 2*border;
bf3dab48 1012
ed673c6a
RR
1013 if (dx > 0)
1014 {
1015 if (gravity_works)
bf3dab48
VZ
1016 {
1017 gdk_window_resize (pizza->bin_window,
1018 w + dx,
1019 h);
1020 gdk_window_move (pizza->bin_window, x-dx, y);
1021 gdk_window_move_resize (pizza->bin_window, x, y, w, h );
1022 }
ed673c6a 1023 else
bf3dab48
VZ
1024 {
1025 /* FIXME */
1026 }
1027
1028 gtk_pizza_expose_area (pizza,
1029 MAX ((gint)w - dx, 0),
1030 0,
1031 MIN (dx, w),
1032 h);
ed673c6a
RR
1033 }
1034 else if (dx < 0)
1035 {
1036 if (gravity_works)
bf3dab48
VZ
1037 {
1038 gdk_window_move_resize (pizza->bin_window,
1039 x + dx,
1040 y,
1041 w - dx,
1042 h);
1043 gdk_window_move (pizza->bin_window, x, y);
1044 gdk_window_resize (pizza->bin_window, w, h );
1045 }
ed673c6a 1046 else
bf3dab48
VZ
1047 {
1048 /* FIXME */
1049 }
ed673c6a 1050
da048e3d 1051 gtk_pizza_expose_area (pizza,
bf3dab48
VZ
1052 0,
1053 0,
1054 MIN (-dx, w),
1055 h);
ed673c6a
RR
1056 }
1057
1058 if (dy > 0)
1059 {
1060 if (gravity_works)
bf3dab48
VZ
1061 {
1062 gdk_window_resize (pizza->bin_window, w, h + dy);
1063 gdk_window_move (pizza->bin_window, x, y-dy);
1064 gdk_window_move_resize (pizza->bin_window,
1065 x, y, w, h );
1066 }
ed673c6a 1067 else
bf3dab48
VZ
1068 {
1069 /* FIXME */
1070 }
1071
1072 gtk_pizza_expose_area (pizza,
1073 0,
1074 MAX ((gint)h - dy, 0),
1075 w,
1076 MIN (dy, h));
ed673c6a
RR
1077 }
1078 else if (dy < 0)
1079 {
1080 if (gravity_works)
bf3dab48
VZ
1081 {
1082 gdk_window_move_resize (pizza->bin_window,
1083 x, y+dy, w, h - dy );
1084 gdk_window_move (pizza->bin_window, x, y);
1085 gdk_window_resize (pizza->bin_window, w, h );
1086 }
ed673c6a 1087 else
bf3dab48
VZ
1088 {
1089 /* FIXME */
1090 }
1091 gtk_pizza_expose_area (pizza,
1092 0,
1093 0,
1094 w,
1095 MIN (-dy, (gint)h));
ed673c6a
RR
1096 }
1097
da048e3d 1098 gtk_pizza_position_children (pizza);
ed673c6a
RR
1099
1100 /* We have to make sure that all exposes from this scroll get
1101 * processed before we scroll again, or the expose events will
1102 * have invalid coordinates.
1103 *
1104 * We also do expose events for other windows, since otherwise
bf3dab48 1105 * their updating will fall behind the scrolling
ed673c6a
RR
1106 *
1107 * This also avoids a problem in pre-1.0 GTK where filters don't
1108 * have access to configure events that were compressed.
1109 */
1110
1111 gdk_flush();
da048e3d 1112 while (XCheckIfEvent(GDK_WINDOW_XDISPLAY (pizza->bin_window),
bf3dab48
VZ
1113 &xevent,
1114 gtk_pizza_expose_predicate,
1115 (XPointer)&GDK_WINDOW_XWINDOW (pizza->bin_window)))
ed673c6a
RR
1116 {
1117 GdkEvent event;
1118 GtkWidget *event_widget;
1119
da048e3d 1120 if ((xevent.xany.window == GDK_WINDOW_XWINDOW (pizza->bin_window)) &&
bf3dab48
VZ
1121 (gtk_pizza_filter (&xevent, &event, pizza) == GDK_FILTER_REMOVE))
1122 continue;
1123
ed673c6a 1124 if (xevent.type == Expose)
bf3dab48
VZ
1125 {
1126 event.expose.window = gdk_window_lookup (xevent.xany.window);
1127 gdk_window_get_user_data (event.expose.window,
1128 (gpointer *)&event_widget);
1129
1130 if (event_widget)
1131 {
1132 event.expose.type = GDK_EXPOSE;
1133 event.expose.area.x = xevent.xexpose.x;
1134 event.expose.area.y = xevent.xexpose.y;
1135 event.expose.area.width = xevent.xexpose.width;
1136 event.expose.area.height = xevent.xexpose.height;
1137 event.expose.count = xevent.xexpose.count;
1138
1139 gdk_window_ref (event.expose.window);
1140 gtk_widget_event (event_widget, &event);
1141 gdk_window_unref (event.expose.window);
1142 }
1143 }
ed673c6a
RR
1144 }
1145}
1146
1147/* The main event filter. Actually, we probably don't really need
1148 * to install this as a filter at all, since we are calling it
1149 * directly above in the expose-handling hack. But in case scrollbars
1150 * are fixed up in some manner...
1151 *
1152 * This routine identifies expose events that are generated when
1153 * we've temporarily moved the bin_window_origin, and translates
1154 * them or discards them, depending on whether we are obscured
1155 * or not.
1156 */
bf3dab48 1157static GdkFilterReturn
da048e3d 1158gtk_pizza_filter (GdkXEvent *gdk_xevent,
bf3dab48
VZ
1159 GdkEvent *event,
1160 gpointer data)
ed673c6a 1161{
0e09f76e
RR
1162 XEvent *xevent;
1163 GtkPizza *pizza;
ed673c6a 1164
0e09f76e
RR
1165 xevent = (XEvent *)gdk_xevent;
1166
1167 pizza = GTK_PIZZA (data);
1168
ed673c6a
RR
1169 switch (xevent->type)
1170 {
1171 case Expose:
da048e3d 1172 if (xevent->xexpose.serial == pizza->configure_serial)
bf3dab48
VZ
1173 {
1174 if (pizza->visibility == GDK_VISIBILITY_UNOBSCURED)
1175 return GDK_FILTER_REMOVE;
1176 else
1177 {
1178 xevent->xexpose.x += pizza->scroll_x;
1179 xevent->xexpose.y += pizza->scroll_y;
1180
1181 break;
1182 }
1183 }
ed673c6a 1184 break;
bf3dab48 1185
ed673c6a
RR
1186 case ConfigureNotify:
1187 if ((xevent->xconfigure.x != 0) || (xevent->xconfigure.y != 0))
bf3dab48
VZ
1188 {
1189 pizza->configure_serial = xevent->xconfigure.serial;
1190 pizza->scroll_x = xevent->xconfigure.x;
1191 pizza->scroll_y = xevent->xconfigure.y;
1192 }
ed673c6a
RR
1193 break;
1194 }
bf3dab48 1195
0e09f76e 1196 return GDK_FILTER_CONTINUE;
ed673c6a
RR
1197}
1198
1199/* Although GDK does have a GDK_VISIBILITY_NOTIFY event,
1200 * there is no corresponding event in GTK, so we have
1201 * to get the events from a filter
1202 */
bf3dab48 1203static GdkFilterReturn
da048e3d 1204gtk_pizza_main_filter (GdkXEvent *gdk_xevent,
bf3dab48
VZ
1205 GdkEvent *event,
1206 gpointer data)
ed673c6a 1207{
0e09f76e
RR
1208 XEvent *xevent;
1209 GtkPizza *pizza;
ed673c6a 1210
0e09f76e
RR
1211 xevent = (XEvent *)gdk_xevent;
1212 pizza = GTK_PIZZA (data);
ed673c6a 1213
0e09f76e 1214 if (xevent->type == VisibilityNotify)
ed673c6a 1215 {
0e09f76e 1216 switch (xevent->xvisibility.state)
bf3dab48 1217 {
0e09f76e
RR
1218 case VisibilityFullyObscured:
1219 pizza->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
1220 break;
ed673c6a 1221
0e09f76e
RR
1222 case VisibilityPartiallyObscured:
1223 pizza->visibility = GDK_VISIBILITY_PARTIAL;
1224 break;
ed673c6a 1225
0e09f76e
RR
1226 case VisibilityUnobscured:
1227 pizza->visibility = GDK_VISIBILITY_UNOBSCURED;
1228 break;
bf3dab48 1229 }
0e09f76e
RR
1230
1231 return GDK_FILTER_REMOVE;
ed673c6a
RR
1232 }
1233
0e09f76e 1234 return GDK_FILTER_CONTINUE;
ed673c6a
RR
1235}
1236
1237
1238
1239
c801d85f
KB
1240#ifdef __cplusplus
1241}
1242#endif /* __cplusplus */
1243