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