]> Pileus Git - ~andy/gtk/blob - gdk/directfb/gdkevents-directfb.c
gdk/directfb: fix _gdk_windowing_pointer_grab()
[~andy/gtk] / gdk / directfb / gdkevents-directfb.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.
23  */
24
25 /*
26  * GTK+ DirectFB backend
27  * Copyright (C) 2001-2002  convergence integrated media GmbH
28  * Copyright (C) 2002-2004  convergence GmbH
29  * Written by Denis Oliver Kropp <dok@convergence.de> and
30  *            Sven Neumann <sven@convergence.de>
31  */
32
33 #include "config.h"
34 #include "gdk.h"
35 #include "gdkdirectfb.h"
36 #include "gdkprivate-directfb.h"
37
38 #include "gdkinternals.h"
39
40 #include "gdkkeysyms.h"
41
42 #include "gdkinput-directfb.h"
43 #include <string.h>
44
45 #ifndef __GDK_X_H__
46 #define __GDK_X_H__
47 gboolean gdk_net_wm_supports (GdkAtom property);
48 #endif
49
50 #include "gdkalias.h"
51
52 #define EventBuffer _gdk_display->buffer
53 #define DirectFB _gdk_display->directfb
54
55
56
57
58 #include "gdkaliasdef.c"
59
60 /*********************************************
61  * Functions for maintaining the event queue *
62  *********************************************/
63
64 static GdkEvent * gdk_event_translate  (DFBWindowEvent  *dfbevent,
65                                         GdkWindow       *window);
66
67 /*
68  * Private variable declarations
69  */
70 static GList *client_filters;  /* Filters for client messages */
71
72
73 static void
74 fixup_event (GdkEvent *event)
75 {
76   if (event->any.window)
77     g_object_ref (event->any.window);
78   if (((event->any.type == GDK_ENTER_NOTIFY) ||
79        (event->any.type == GDK_LEAVE_NOTIFY)) &&
80       (event->crossing.subwindow != NULL))
81     g_object_ref (event->crossing.subwindow);
82   event->any.send_event = FALSE;
83 }
84
85 static GdkFilterReturn
86 apply_filters (GdkWindow      *window,
87                DFBWindowEvent *dfbevent,
88                GList          *filters)
89 {
90   GdkFilterReturn result = GDK_FILTER_CONTINUE;
91   GdkEvent *event;
92   GList *node;
93   GList *tmp_list;
94
95   event = gdk_event_new (GDK_NOTHING);
96   if (window != NULL)
97     event->any.window = g_object_ref (window);
98   ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
99
100   /* I think GdkFilterFunc semantics require the passed-in event
101    * to already be in the queue. The filter func can generate
102    * more events and append them after it if it likes.
103    */
104   node = _gdk_event_queue_append ((GdkDisplay*)_gdk_display, event);
105   
106   tmp_list = filters;
107   while (tmp_list)
108     {
109       GdkEventFilter *filter = (GdkEventFilter *) tmp_list->data;
110       
111       tmp_list = tmp_list->next;
112       result = filter->function (dfbevent, event, filter->data);
113       if (result != GDK_FILTER_CONTINUE)
114         break;
115     }
116
117   if (result == GDK_FILTER_CONTINUE || result == GDK_FILTER_REMOVE)
118     {
119       _gdk_event_queue_remove_link ((GdkDisplay*)_gdk_display, node);
120       g_list_free_1 (node);
121       gdk_event_free (event);
122     }
123   else /* GDK_FILTER_TRANSLATE */
124     {
125       ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
126       fixup_event (event);
127     }
128   return result;
129 }
130
131 static void
132 dfb_events_process_window_event (DFBWindowEvent *event)
133 {
134   GdkWindow *window;
135
136   /*
137    * Apply global filters
138    *
139    * If result is GDK_FILTER_CONTINUE, we continue as if nothing
140    * happened. If it is GDK_FILTER_REMOVE or GDK_FILTER_TRANSLATE,
141    * we return TRUE and won't dispatch the event.
142    */
143   if (_gdk_default_filters)
144     {
145       switch (apply_filters (NULL, event, _gdk_default_filters))
146         {
147         case GDK_FILTER_REMOVE:
148         case GDK_FILTER_TRANSLATE:
149           return;
150
151         default:
152           break;
153         }
154     }
155
156   window = gdk_directfb_window_id_table_lookup (event->window_id);
157   if (!window)
158     return;
159
160   gdk_event_translate (event, window);
161 }
162
163 static gboolean
164 gdk_event_send_client_message_by_window (GdkEvent *event,
165                                          GdkWindow *window)
166 {
167   DFBUserEvent evt;
168
169   g_return_val_if_fail(event != NULL, FALSE);
170   g_return_val_if_fail(GDK_IS_WINDOW(window), FALSE);
171
172   evt.clazz = DFEC_USER;
173   evt.type = GPOINTER_TO_UINT (GDK_ATOM_TO_POINTER (event->client.message_type));
174   evt.data = (void *) event->client.data.l[0];
175
176   _gdk_display->buffer->PostEvent(_gdk_display->buffer, DFB_EVENT (&evt));
177
178   return TRUE;
179 }
180
181 static void
182 dfb_events_dispatch (void)
183 {
184   GdkDisplay *display = gdk_display_get_default ();
185   GdkEvent   *event;
186
187   GDK_THREADS_ENTER ();
188
189   while ((event = _gdk_event_unqueue (display)) != NULL)
190     {
191       if (_gdk_event_func)
192         (*_gdk_event_func) (event, _gdk_event_data);
193
194       gdk_event_free (event);
195     }
196
197   GDK_THREADS_LEAVE ();
198 }
199
200 static gboolean
201 dfb_events_io_func (GIOChannel   *channel,
202                     GIOCondition  condition,
203                     gpointer      data)
204 {
205   gsize      i;
206   gsize      read;
207   GIOStatus  result;
208   DFBEvent   buf[23];
209   DFBEvent  *event;
210
211   result = g_io_channel_read_chars (channel,
212                                     (gchar *) buf, sizeof (buf), &read, NULL);
213
214   if (result == G_IO_STATUS_ERROR)
215     {
216       g_warning ("%s: GIOError occured", G_STRFUNC);
217       return TRUE;
218     }
219
220   read /= sizeof (DFBEvent);
221
222   for (i = 0, event = buf; i < read; i++, event++)
223     {
224       switch (event->clazz)
225         {
226         case DFEC_WINDOW:
227           /* TODO workaround to prevent two DWET_ENTER in a row from being delivered */
228           if (event->window.type == DWET_ENTER ) {
229             if ( i>0 && buf[i-1].window.type != DWET_ENTER )
230               dfb_events_process_window_event (&event->window);
231           }
232           else
233             dfb_events_process_window_event (&event->window);
234           break;
235
236         case DFEC_USER:
237           {
238             GList *list;
239
240             GDK_NOTE (EVENTS, g_print (" client_message"));
241
242             for (list = client_filters; list; list = list->next)
243               {
244                 GdkClientFilter *filter     = list->data;
245                 DFBUserEvent    *user_event = (DFBUserEvent *) event;
246                 GdkAtom          type;
247
248                 type = GDK_POINTER_TO_ATOM (GUINT_TO_POINTER (user_event->type));
249
250                 if (filter->type == type)
251                   {
252                     if (filter->function (user_event,
253                                           NULL,
254                                           filter->data) != GDK_FILTER_CONTINUE)
255                       break;
256                   }
257               }
258           }
259           break;
260
261         default:
262           break;
263         }
264     }
265
266   EventBuffer->Reset (EventBuffer);
267
268   dfb_events_dispatch ();
269
270   return TRUE;
271 }
272
273 void
274 _gdk_events_init (void)
275 {
276   GIOChannel *channel;
277   GSource    *source;
278   DFBResult   ret;
279   gint        fd;
280
281   ret = DirectFB->CreateEventBuffer (DirectFB, &EventBuffer);
282   if (ret)
283     {
284       DirectFBError ("_gdk_events_init: "
285                      "IDirectFB::CreateEventBuffer() failed", ret);
286       return;
287     }
288
289   ret = EventBuffer->CreateFileDescriptor (EventBuffer, &fd);
290   if (ret)
291     {
292       DirectFBError ("_gdk_events_init: "
293                      "IDirectFBEventBuffer::CreateFileDescriptor() failed",
294                      ret);
295       return;
296     }
297
298   channel = g_io_channel_unix_new (fd);
299
300   g_io_channel_set_encoding (channel, NULL, NULL);
301   g_io_channel_set_buffered (channel, FALSE);
302
303   source = g_io_create_watch (channel, G_IO_IN);
304
305   g_source_set_priority (source, G_PRIORITY_DEFAULT);
306   g_source_set_can_recurse (source, TRUE);
307   g_source_set_callback (source, (GSourceFunc) dfb_events_io_func, NULL, NULL);
308
309   g_source_attach (source, NULL);
310   g_source_unref (source);
311 }
312
313 gboolean
314 gdk_events_pending (void)
315 {
316   GdkDisplay *display = gdk_display_get_default ();
317
318   return _gdk_event_queue_find_first (display) ? TRUE : FALSE;
319 }
320
321 GdkEvent *
322 gdk_event_get_graphics_expose (GdkWindow *window)
323 {
324   GdkDisplay *display;
325   GList      *list;
326
327   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
328
329   display = gdk_drawable_get_display (GDK_DRAWABLE (window));
330
331   for (list = _gdk_event_queue_find_first (display); list; list = list->next)
332     {
333       GdkEvent *event = list->data;
334       if (event->type == GDK_EXPOSE && event->expose.window == window)
335         break;
336     }
337
338   if (list)
339     {
340       GdkEvent *retval = list->data;
341
342       _gdk_event_queue_remove_link (display, list);
343       g_list_free_1 (list);
344
345       return retval;
346     }
347
348   return NULL;
349 }
350
351 void
352 _gdk_events_queue (GdkDisplay *display)
353 {
354 }
355
356 void
357 gdk_flush (void)
358 {
359 gdk_display_flush ( GDK_DISPLAY_OBJECT(_gdk_display));
360 }
361
362 /* Sends a ClientMessage to all toplevel client windows */
363 gboolean
364 gdk_event_send_client_message_for_display (GdkDisplay *display,
365                                            GdkEvent   *event,
366                                            guint32     xid)
367 {
368   GdkWindow *win = NULL;
369   gboolean ret = TRUE;
370
371   g_return_val_if_fail(event != NULL, FALSE);
372
373   win = gdk_window_lookup_for_display (display, (GdkNativeWindow) xid);
374
375   g_return_val_if_fail(win != NULL, FALSE);
376
377   if ((GDK_WINDOW_OBJECT(win)->window_type != GDK_WINDOW_CHILD) &&
378       (g_object_get_data (G_OBJECT (win), "gdk-window-child-handler")))
379     {
380       /* Managed window, check children */
381       GList *ltmp = NULL;
382       for (ltmp = GDK_WINDOW_OBJECT(win)->children; ltmp; ltmp = ltmp->next)
383        {
384          ret &= gdk_event_send_client_message_by_window (event,
385                                                          GDK_WINDOW(ltmp->data));
386        }
387     }
388   else
389     {
390       ret &= gdk_event_send_client_message_by_window (event, win);
391     }
392
393   return ret;
394 }
395
396 /*****/
397
398 guint32
399 gdk_directfb_get_time (void)
400 {
401   GTimeVal tv;
402
403   g_get_current_time (&tv);
404
405   return (guint32) tv.tv_sec * 1000 + tv.tv_usec / 1000;
406 }
407
408 void
409 gdk_directfb_event_windows_add (GdkWindow *window)
410 {
411   GdkWindowImplDirectFB *impl;
412
413   g_return_if_fail (GDK_IS_WINDOW (window));
414
415   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
416
417   if (!impl->window)
418     return;
419
420   if (EventBuffer)
421     impl->window->AttachEventBuffer (impl->window, EventBuffer);
422   else
423     impl->window->CreateEventBuffer (impl->window, &EventBuffer);
424 }
425
426 void
427 gdk_directfb_event_windows_remove (GdkWindow *window)
428 {
429   GdkWindowImplDirectFB *impl;
430
431   g_return_if_fail (GDK_IS_WINDOW (window));
432
433   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
434
435   if (!impl->window)
436     return;
437
438   if (EventBuffer)
439     impl->window->DetachEventBuffer (impl->window, EventBuffer);
440 /* FIXME: should we warn if (! EventBuffer) ? */
441 }
442
443 GdkWindow *
444 gdk_directfb_child_at (GdkWindow *window,
445                        gint      *winx,
446                        gint      *winy)
447 {
448   GdkWindowObject *private;
449   GList           *list;
450
451   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
452
453   private = GDK_WINDOW_OBJECT (window);
454   for (list = private->children; list; list = list->next)
455     {
456       GdkWindowObject *win = list->data;
457
458       if (GDK_WINDOW_IS_MAPPED (win) &&
459           *winx >= win->x  &&
460           *winx <  win->x + GDK_DRAWABLE_IMPL_DIRECTFB (win->impl)->width  &&
461           *winy >= win->y  &&
462           *winy <  win->y + GDK_DRAWABLE_IMPL_DIRECTFB (win->impl)->height)
463         {
464           *winx -= win->x;
465           *winy -= win->y;
466
467           return gdk_directfb_child_at (GDK_WINDOW (win), winx, winy );
468         }
469     }
470
471   return window;
472 }
473
474 static GdkEvent *
475 gdk_event_translate (DFBWindowEvent *dfbevent,
476                      GdkWindow      *window)
477 {
478   GdkWindowObject *private;
479   GdkDisplay      *display;
480   GdkEvent        *event    = NULL;
481
482   g_return_val_if_fail (dfbevent != NULL, NULL);
483   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
484
485   private = GDK_WINDOW_OBJECT (window);
486
487   g_object_ref (G_OBJECT (window));
488
489   /*
490    * Apply per-window filters
491    *
492    * If result is GDK_FILTER_CONTINUE, we continue as if nothing
493    * happened. If it is GDK_FILTER_REMOVE or GDK_FILTER_TRANSLATE,
494    * we return TRUE and won't dispatch the event.
495    */
496   if (private->filters)
497     {
498       switch (apply_filters (window, dfbevent, private->filters))
499         {
500         case GDK_FILTER_REMOVE:
501         case GDK_FILTER_TRANSLATE:
502           g_object_unref (G_OBJECT (window));
503           return NULL;
504
505         default:
506           break;
507         }
508     }
509
510   display = gdk_drawable_get_display (GDK_DRAWABLE (window));
511
512   switch (dfbevent->type)
513     {
514     case DWET_BUTTONDOWN:
515     case DWET_BUTTONUP:
516       {
517         static gboolean  click_grab = FALSE;
518         GdkWindow       *child;
519         gint             wx, wy;
520         guint            mask;
521         guint            button;
522
523         _gdk_directfb_mouse_x = wx = dfbevent->cx;
524         _gdk_directfb_mouse_y = wy = dfbevent->cy;
525
526         switch (dfbevent->button)
527           {
528           case DIBI_LEFT:
529             button = 1;
530             mask   = GDK_BUTTON1_MASK;
531             break;
532           case DIBI_MIDDLE:
533             button = 2;
534             mask   = GDK_BUTTON2_MASK;
535             break;
536           case DIBI_RIGHT:
537             button = 3;
538             mask   = GDK_BUTTON3_MASK;
539             break;
540           default:
541             button = dfbevent->button + 1;
542             mask   = 0;
543             break;
544           }
545
546         child = gdk_directfb_child_at (_gdk_parent_root, &wx, &wy);
547
548         if (_gdk_directfb_pointer_grab_window &&
549             (_gdk_directfb_pointer_grab_events & (dfbevent->type ==
550                                                   DWET_BUTTONDOWN ?
551                                                   GDK_BUTTON_PRESS_MASK :
552                                                   GDK_BUTTON_RELEASE_MASK)) &&
553             (_gdk_directfb_pointer_grab_owner_events == FALSE ||
554              child == _gdk_parent_root) )
555           {
556             GdkDrawableImplDirectFB *impl;
557
558             child = _gdk_directfb_pointer_grab_window;
559             impl  = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (child)->impl);
560
561             dfbevent->x = dfbevent->cx - impl->abs_x;
562             dfbevent->y = dfbevent->cy - impl->abs_y;
563           }
564         else if (!_gdk_directfb_pointer_grab_window ||
565                  (_gdk_directfb_pointer_grab_owner_events == TRUE))
566           {
567             dfbevent->x = wx;
568             dfbevent->y = wy;
569           }
570         else
571           {
572             child = NULL;
573           }
574
575         if (dfbevent->type == DWET_BUTTONDOWN)
576           _gdk_directfb_modifiers |= mask;
577         else
578           _gdk_directfb_modifiers &= ~mask;
579
580         if (child)
581           {
582             event =
583               gdk_directfb_event_make (child,
584                                        dfbevent->type == DWET_BUTTONDOWN ?
585                                        GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
586
587             event->button.x_root = _gdk_directfb_mouse_x;
588             event->button.y_root = _gdk_directfb_mouse_y;
589
590             event->button.x = dfbevent->x;
591             event->button.y = dfbevent->y;
592
593             event->button.state  = _gdk_directfb_modifiers;
594             event->button.button = button;
595             event->button.device = display->core_pointer;
596
597             GDK_NOTE (EVENTS,
598                       g_message ("button: %d at %d,%d %s with state 0x%08x",
599                                  event->button.button,
600                                  (int)event->button.x, (int)event->button.y,
601                                  dfbevent->type == DWET_BUTTONDOWN ?
602                                  "pressed" : "released",
603                                  _gdk_directfb_modifiers));
604
605             if (dfbevent->type == DWET_BUTTONDOWN)
606               _gdk_event_button_generate (display, event);
607           }
608
609         /* Handle implicit button grabs: */
610         if (dfbevent->type == DWET_BUTTONDOWN  &&  !click_grab  &&  child)
611           {
612             if (gdk_directfb_pointer_grab (child, FALSE,
613                                            gdk_window_get_events (child),
614                                            NULL, NULL,
615                                            GDK_CURRENT_TIME,
616                                            TRUE) == GDK_GRAB_SUCCESS)
617               click_grab = TRUE;
618           }
619         else if (dfbevent->type == DWET_BUTTONUP &&
620                  !(_gdk_directfb_modifiers & (GDK_BUTTON1_MASK |
621                                               GDK_BUTTON2_MASK |
622                                               GDK_BUTTON3_MASK)) && click_grab)
623           {
624             gdk_directfb_pointer_ungrab (GDK_CURRENT_TIME, TRUE);
625             click_grab = FALSE;
626           }
627       }
628       break;
629
630     case DWET_MOTION:
631       {
632         GdkWindow *event_win=NULL;
633         GdkWindow *child;
634
635         _gdk_directfb_mouse_x = dfbevent->cx;
636         _gdk_directfb_mouse_y = dfbevent->cy;
637
638         //child = gdk_directfb_child_at (window, &dfbevent->x, &dfbevent->y);
639     /* Go all the way to root to catch popup menus */
640     int wx=_gdk_directfb_mouse_x;
641     int wy=_gdk_directfb_mouse_y;
642         child = gdk_directfb_child_at (_gdk_parent_root, &wx, &wy);
643
644     /* first let's see if any cossing event has to be send */
645     gdk_directfb_window_send_crossing_events (NULL, child, GDK_CROSSING_NORMAL);
646
647     /* then dispatch the motion event to the window the cursor it's inside */
648         event_win = gdk_directfb_pointer_event_window (child, GDK_MOTION_NOTIFY);
649
650
651         if (event_win)
652           {
653
654             if (event_win == _gdk_directfb_pointer_grab_window) {
655                 GdkDrawableImplDirectFB *impl;
656
657                 child = _gdk_directfb_pointer_grab_window;
658                 impl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (child)->impl);
659
660                 dfbevent->x = _gdk_directfb_mouse_x - impl->abs_x;
661                 dfbevent->y = _gdk_directfb_mouse_y - impl->abs_y;
662               }
663
664             event = gdk_directfb_event_make (child, GDK_MOTION_NOTIFY);
665
666             event->motion.x_root = _gdk_directfb_mouse_x;
667             event->motion.y_root = _gdk_directfb_mouse_y;
668
669             //event->motion.x = dfbevent->x;
670             //event->motion.y = dfbevent->y;
671             event->motion.x = wx;
672             event->motion.y = wy;
673
674             event->motion.state   = _gdk_directfb_modifiers;
675             event->motion.is_hint = FALSE;
676             event->motion.device  = display->core_pointer;
677
678             if (GDK_WINDOW_OBJECT (event_win)->event_mask &
679                 GDK_POINTER_MOTION_HINT_MASK)
680               {
681                 while (EventBuffer->PeekEvent (EventBuffer,
682                                                DFB_EVENT (dfbevent)) == DFB_OK
683                        && dfbevent->type == DWET_MOTION)
684                   {
685                     EventBuffer->GetEvent (EventBuffer, DFB_EVENT (dfbevent));
686                     event->motion.is_hint = TRUE;
687                   }
688               }
689           }
690           /* make sure crossing events go to the event window found */
691 /*        GdkWindow *ev_win = ( event_win == NULL ) ? gdk_window_at_pointer (NULL,NULL) :event_win;
692              gdk_directfb_window_send_crossing_events (NULL,ev_win,GDK_CROSSING_NORMAL);
693 */
694       }
695       break;
696
697     case DWET_GOTFOCUS:
698       gdk_directfb_change_focus (window);
699
700       break;
701
702     case DWET_LOSTFOCUS:
703       gdk_directfb_change_focus (_gdk_parent_root);
704
705       break;
706
707     case DWET_POSITION:
708       {
709         GdkWindow *event_win;
710
711         private->x = dfbevent->x;
712         private->y = dfbevent->y;
713
714         event_win = gdk_directfb_other_event_window (window, GDK_CONFIGURE);
715
716         if (event_win)
717           {
718             event = gdk_directfb_event_make (event_win, GDK_CONFIGURE);
719             event->configure.x = dfbevent->x;
720             event->configure.y = dfbevent->y;
721             event->configure.width =
722               GDK_DRAWABLE_IMPL_DIRECTFB (private->impl)->width;
723             event->configure.height =
724               GDK_DRAWABLE_IMPL_DIRECTFB (private->impl)->height;
725           }
726
727         _gdk_directfb_calc_abs (window);
728       }
729       break;
730
731     case DWET_POSITION_SIZE:
732       private->x = dfbevent->x;
733       private->y = dfbevent->y;
734       /* fallthru */
735
736     case DWET_SIZE:
737       {
738         GdkDrawableImplDirectFB *impl;
739         GdkWindow               *event_win;
740         GList                   *list;
741
742         impl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl);
743
744         event_win = gdk_directfb_other_event_window (window, GDK_CONFIGURE);
745
746         if (event_win)
747           {
748             event = gdk_directfb_event_make (event_win, GDK_CONFIGURE);
749             event->configure.x      = private->x;
750             event->configure.y      = private->y;
751             event->configure.width  = dfbevent->w;
752             event->configure.height = dfbevent->h;
753           }
754
755         impl->width  = dfbevent->w;
756         impl->height = dfbevent->h;
757
758         for (list = private->children; list; list = list->next)
759           {
760             GdkWindowObject         *win;
761             GdkDrawableImplDirectFB *impl;
762
763             win  = GDK_WINDOW_OBJECT (list->data);
764             impl = GDK_DRAWABLE_IMPL_DIRECTFB (win->impl);
765
766             _gdk_directfb_move_resize_child (GDK_WINDOW (win),
767                                              win->x, win->y,
768                                              impl->width, impl->height);
769           }
770
771         _gdk_directfb_calc_abs (window);
772
773         gdk_window_clear (window);
774         gdk_window_invalidate_rect (window, NULL, TRUE);
775       }
776       break;
777
778     case DWET_KEYDOWN:
779     case DWET_KEYUP:
780       {
781
782         GdkEventType type = (dfbevent->type == DWET_KEYUP ?
783                              GDK_KEY_RELEASE : GDK_KEY_PRESS);
784         GdkWindow *event_win =
785           gdk_directfb_keyboard_event_window (gdk_directfb_window_find_focus (),
786                                               type);
787         if (event_win)
788           {
789             event = gdk_directfb_event_make (event_win, type);
790             gdk_directfb_translate_key_event (dfbevent, &event->key);
791           }
792       }
793       break;
794
795     case DWET_LEAVE:
796       _gdk_directfb_mouse_x = dfbevent->cx;
797       _gdk_directfb_mouse_y = dfbevent->cy;
798
799       gdk_directfb_window_send_crossing_events (NULL, _gdk_parent_root,
800                                                 GDK_CROSSING_NORMAL);
801
802       if (gdk_directfb_apply_focus_opacity)
803         {
804           if (GDK_WINDOW_IS_MAPPED (window))
805             GDK_WINDOW_IMPL_DIRECTFB (private->impl)->window->SetOpacity
806               (GDK_WINDOW_IMPL_DIRECTFB (private->impl)->window,
807                (GDK_WINDOW_IMPL_DIRECTFB (private->impl)->opacity >> 1) +
808                (GDK_WINDOW_IMPL_DIRECTFB (private->impl)->opacity >> 2));
809         }
810       break;
811
812     case DWET_ENTER:
813       {
814         GdkWindow *child;
815
816         _gdk_directfb_mouse_x = dfbevent->cx;
817         _gdk_directfb_mouse_y = dfbevent->cy;
818
819         child = gdk_directfb_child_at (window, &dfbevent->x, &dfbevent->y);
820
821         /* this makes sure pointer is set correctly when it previously left
822          * a window being not standard shaped
823          */
824         gdk_window_set_cursor (window, NULL);
825         gdk_directfb_window_send_crossing_events (NULL, child,
826                                                   GDK_CROSSING_NORMAL);
827
828         if (gdk_directfb_apply_focus_opacity)
829           {
830             GDK_WINDOW_IMPL_DIRECTFB (private->impl)->window->SetOpacity
831               (GDK_WINDOW_IMPL_DIRECTFB (private->impl)->window,
832                GDK_WINDOW_IMPL_DIRECTFB (private->impl)->opacity);
833           }
834       }
835       break;
836
837     case DWET_CLOSE:
838       {
839  
840         GdkWindow *event_win;
841
842         event_win = gdk_directfb_other_event_window (window, GDK_DELETE);
843
844         if (event_win)
845           event = gdk_directfb_event_make (event_win, GDK_DELETE);
846       }
847       break;
848
849     case DWET_DESTROYED:
850       {
851         GdkWindow *event_win;
852
853         event_win = gdk_directfb_other_event_window (window, GDK_DESTROY);
854
855         if (event_win)
856           event = gdk_directfb_event_make (event_win, GDK_DESTROY);
857
858         gdk_window_destroy_notify (window);
859       }
860       break;
861
862     case DWET_WHEEL:
863       {
864         GdkWindow *event_win;
865
866         _gdk_directfb_mouse_x = dfbevent->cx;
867         _gdk_directfb_mouse_y = dfbevent->cy;
868
869         if (_gdk_directfb_pointer_grab_window)
870           {
871             GdkDrawableImplDirectFB *impl;
872
873             event_win = _gdk_directfb_pointer_grab_window;
874             impl =
875               GDK_DRAWABLE_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (event_win)->impl);
876
877             dfbevent->x = dfbevent->cx - impl->abs_x;
878             dfbevent->y = dfbevent->cy - impl->abs_y;
879           }
880         else
881           {
882             event_win = gdk_directfb_child_at (window,
883                                                &dfbevent->x, &dfbevent->y);
884           }
885
886         if (event_win)
887           {
888             event = gdk_directfb_event_make (event_win, GDK_SCROLL);
889
890             event->scroll.direction = (dfbevent->step < 0 ?
891                                        GDK_SCROLL_DOWN : GDK_SCROLL_UP);
892
893             event->scroll.x_root = _gdk_directfb_mouse_x;
894             event->scroll.y_root = _gdk_directfb_mouse_y;
895             event->scroll.x      = dfbevent->x;
896             event->scroll.y      = dfbevent->y;
897             event->scroll.state  = _gdk_directfb_modifiers;
898             event->scroll.device = display->core_pointer;
899           }
900       }
901       break;
902
903     default:
904       g_message ("unhandled DirectFB windowing event 0x%08x", dfbevent->type);
905     }
906
907   g_object_unref (G_OBJECT (window));
908
909   return event;
910 }
911
912 gboolean
913 gdk_screen_get_setting (GdkScreen   *screen,
914                         const gchar *name,
915                         GValue      *value)
916 {
917   return FALSE;
918 }
919
920 void
921 gdk_display_add_client_message_filter (GdkDisplay   *display,
922                                        GdkAtom       message_type,
923                                        GdkFilterFunc func,
924                                        gpointer      data)
925 {
926   /* XXX: display should be used */
927   GdkClientFilter *filter = g_new (GdkClientFilter, 1);
928
929   filter->type = message_type;
930   filter->function = func;
931   filter->data = data;
932   client_filters = g_list_append (client_filters, filter);
933 }
934
935
936 void
937 gdk_add_client_message_filter (GdkAtom       message_type,
938                                GdkFilterFunc func,
939                                gpointer      data)
940 {
941   gdk_display_add_client_message_filter (gdk_display_get_default (),
942                                          message_type, func, data);
943 }
944
945 void
946 gdk_screen_broadcast_client_message (GdkScreen *screen,
947                                      GdkEvent  *sev)
948 {
949   GdkWindow *root_window;
950   GdkWindowObject *private;
951   GList *top_level = NULL;
952
953   g_return_if_fail (GDK_IS_SCREEN (screen));
954   g_return_if_fail(sev != NULL);
955
956   root_window = gdk_screen_get_root_window (screen);
957
958   g_return_if_fail(GDK_IS_WINDOW(root_window));
959
960   private = GDK_WINDOW_OBJECT (root_window);
961
962   for (top_level = private->children; top_level; top_level = top_level->next)
963     {
964       gdk_event_send_client_message_for_display (gdk_drawable_get_display(GDK_DRAWABLE(root_window)),
965                                                 sev,
966                                                 (guint32)(GDK_WINDOW_DFB_ID(GDK_WINDOW(top_level->data))));
967    }
968 }
969
970
971 /**
972  * gdk_net_wm_supports:
973  * @property: a property atom.
974  *
975  * This function is specific to the X11 backend of GDK, and indicates
976  * whether the window manager for the default screen supports a certain
977  * hint from the Extended Window Manager Hints Specification. See
978  * gdk_x11_screen_supports_net_wm_hint() for complete details.
979  *
980  * Return value: %TRUE if the window manager supports @property
981  **/
982
983
984 gboolean
985 gdk_net_wm_supports (GdkAtom property)
986 {
987    return FALSE;
988 }
989
990 void
991 _gdk_windowing_event_data_copy (const GdkEvent *src,
992                                 GdkEvent       *dst)
993 {
994 }
995
996 void
997 _gdk_windowing_event_data_free (GdkEvent *event)
998 {
999 }
1000
1001 #define __GDK_EVENTS_X11_C__
1002 #include "gdkaliasdef.c"