]> Pileus Git - ~andy/gtk/blob - gdk/wayland/gdkeventsource.c
wayland: Improve error message handling in cursor buffer code
[~andy/gtk] / gdk / wayland / gdkeventsource.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
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, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include "config.h"
19
20 #include "gdkinternals.h"
21 #include "gdkprivate-wayland.h"
22
23 typedef struct _GdkWaylandEventSource {
24   GSource source;
25   GPollFD pfd;
26   uint32_t mask;
27   GdkDisplay *display;
28 } GdkWaylandEventSource;
29
30 static GList *event_sources = NULL;
31
32 static gboolean
33 gdk_event_source_prepare(GSource *base, gint *timeout)
34 {
35   GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
36   GdkWaylandDisplay *display = (GdkWaylandDisplay *) source->display;
37
38   *timeout = -1;
39
40   /* We have to add/remove the GPollFD if we want to update our
41    * poll event mask dynamically.  Instead, let's just flush all
42    * write on idle instead, which is what this amounts to. */
43
44   if (_gdk_event_queue_find_first (source->display) != NULL)
45     return TRUE;
46
47   while (source->mask & WL_DISPLAY_WRITABLE)
48     wl_display_iterate(display->wl_display, WL_DISPLAY_WRITABLE);
49
50   return FALSE;
51 }
52
53 static gboolean
54 gdk_event_source_check(GSource *base)
55 {
56   GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
57
58   return _gdk_event_queue_find_first (source->display) != NULL ||
59     source->pfd.revents;
60 }
61
62 static gboolean
63 gdk_event_source_dispatch(GSource *base,
64                           GSourceFunc callback,
65                           gpointer data)
66 {
67   GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
68   GdkDisplay *display = source->display;
69   GdkEvent *event;
70
71   GDK_THREADS_ENTER ();
72
73   event = gdk_display_get_event (display);
74
75   if (event)
76     {
77       _gdk_event_emit (event);
78
79       gdk_event_free (event);
80     }
81
82   GDK_THREADS_LEAVE ();
83
84   return TRUE;
85 }
86
87 static void
88 gdk_event_source_finalize (GSource *source)
89 {
90   event_sources = g_list_remove (event_sources, source);
91 }
92
93 static GSourceFuncs wl_glib_source_funcs = {
94   gdk_event_source_prepare,
95   gdk_event_source_check,
96   gdk_event_source_dispatch,
97   gdk_event_source_finalize
98 };
99
100 static int
101 gdk_event_source_update(uint32_t mask, void *data)
102 {
103   GdkWaylandEventSource *source = data;
104
105   source->mask = mask;
106
107   return 0;
108 }
109
110 void
111 _gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event)
112 {
113   GList *node;
114
115   node = _gdk_event_queue_append (display, event);
116   _gdk_windowing_got_event (display, node, event,
117                             _gdk_display_get_next_serial (display));
118 }
119
120 GSource *
121 _gdk_wayland_display_event_source_new (GdkDisplay *display)
122 {
123   GSource *source;
124   GdkWaylandEventSource *wl_source;
125   GdkWaylandDisplay *display_wayland;
126   char *name;
127
128   source = g_source_new (&wl_glib_source_funcs,
129                          sizeof (GdkWaylandEventSource));
130   name = g_strdup_printf ("GDK Wayland Event source (%s)", "display name");
131   g_source_set_name (source, name);
132   g_free (name);
133   wl_source = (GdkWaylandEventSource *) source;
134
135   display_wayland = GDK_WAYLAND_DISPLAY (display);
136   wl_source->display = display;
137   wl_source->pfd.fd = wl_display_get_fd(display_wayland->wl_display,
138                                         gdk_event_source_update, source);
139   wl_source->pfd.events = G_IO_IN | G_IO_ERR;
140   g_source_add_poll(source, &wl_source->pfd);
141
142   g_source_set_priority (source, GDK_PRIORITY_EVENTS);
143   g_source_set_can_recurse (source, TRUE);
144   g_source_attach (source, NULL);
145
146   event_sources = g_list_prepend (event_sources, source);
147
148   return source;
149 }
150
151 void
152 _gdk_wayland_display_flush (GdkDisplay *display, GSource *source)
153 {
154   GdkWaylandEventSource *wayland_source = (GdkWaylandEventSource *) source;
155
156   while (wayland_source->mask & WL_DISPLAY_WRITABLE)
157     wl_display_iterate(GDK_WAYLAND_DISPLAY (display)->wl_display,
158                        WL_DISPLAY_WRITABLE);
159 }
160
161 void
162 _gdk_wayland_display_queue_events (GdkDisplay *display)
163 {
164   GdkWaylandDisplay *display_wayland;
165   GdkWaylandEventSource *source;
166
167   display_wayland = GDK_WAYLAND_DISPLAY (display);
168   source = (GdkWaylandEventSource *) display_wayland->event_source;
169
170   if (source->pfd.revents)
171     {
172       wl_display_iterate(display_wayland->wl_display, WL_DISPLAY_READABLE);
173       source->pfd.revents = 0;
174     }
175 }