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