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