9ad3ec5490ad9a12678a436a217c165a077a00cc
[platform/upstream/at-spi2-core.git] / registryd / event-source.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2009 Nokia.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include <glib.h>
24
25 #include "event-source.h"
26
27 typedef struct _DisplaySource
28 {
29   GSource source;
30   
31   Display *display;
32   GPollFD  event_poll_fd;
33 } DisplaySource;
34
35 /*---------------------------------------------------------------------------*/
36
37 static void (*_spi_default_filter) (XEvent*, void*) = NULL;
38 static void* _spi_default_filter_data = NULL;
39
40 /*---------------------------------------------------------------------------*/
41
42 static gboolean  
43 event_prepare (GSource *source, gint *timeout)
44 {
45   Display *display = ((DisplaySource *)source)->display;
46   gboolean retval;
47   
48   *timeout = -1;
49   retval = XPending (display);
50   
51   return retval;
52 }
53
54 static gboolean  
55 event_check (GSource *source) 
56 {
57   DisplaySource *display_source = (DisplaySource*)source;
58   gboolean retval;
59
60   if (display_source->event_poll_fd.revents & G_IO_IN)
61     retval = XPending (display_source->display);
62   else
63     retval = FALSE;
64
65   return retval;
66 }
67
68 static gboolean  
69 event_dispatch (GSource *source, GSourceFunc callback, gpointer  user_data)
70 {
71   Display *display = ((DisplaySource*)source)->display;
72   XEvent xevent;
73  
74   /* TODO - Should this be "if (XPending (display))"?
75    *        The effect of this might be to run other main loop functions
76    *        before dispatching the next XEvent.
77    */
78   while (XPending (display))
79     {
80       XNextEvent (display, &xevent);
81
82       switch (xevent.type)
83         {
84         case KeyPress:
85         case KeyRelease:
86           break;
87         default:
88           if (XFilterEvent (&xevent, None))
89             continue;
90         }
91       
92       if (_spi_default_filter)
93         {
94           _spi_default_filter (&xevent, _spi_default_filter_data);
95         }  
96     }
97
98   return TRUE;
99 }
100
101 /*---------------------------------------------------------------------------*/
102
103 static GSourceFuncs event_funcs = {
104   event_prepare,
105   event_check,
106   event_dispatch,
107   NULL
108 };
109
110 static GSource *
111 display_source_new (Display *display)
112 {
113   GSource *source = g_source_new (&event_funcs, sizeof (DisplaySource));
114   DisplaySource *display_source = (DisplaySource *) source;
115   g_source_set_name (source, "[at-spi2-core] display_source_funcs");
116   
117   display_source->display = display;
118   
119   return source;
120 }
121
122 /*---------------------------------------------------------------------------*/
123
124 static DisplaySource *spi_display_source = NULL;
125
126 void 
127 spi_events_init (Display *display)
128 {
129   GSource *source;
130
131   int connection_number = ConnectionNumber (display);
132
133   source = display_source_new (display);
134   spi_display_source = (DisplaySource*) source;
135
136   g_source_set_priority (source, G_PRIORITY_DEFAULT);
137   
138   spi_display_source->event_poll_fd.fd = connection_number;
139   spi_display_source->event_poll_fd.events = G_IO_IN;
140   
141   g_source_add_poll (source, &spi_display_source->event_poll_fd);
142   g_source_set_can_recurse (source, TRUE);
143   g_source_attach (source, NULL);
144 }
145
146 void
147 spi_events_uninit ()
148 {
149   if (spi_display_source)
150     {
151       g_source_destroy ((GSource *) spi_display_source);
152       g_source_unref ((GSource *) spi_display_source);
153       spi_display_source = NULL;
154     }
155 }
156
157 void
158 spi_set_events (long event_mask)
159 {
160   long xevent_mask = StructureNotifyMask | PropertyChangeMask;
161   xevent_mask |= event_mask;
162       
163   XSelectInput (spi_display_source->display, 
164                 DefaultRootWindow (spi_display_source->display),
165                 xevent_mask);
166 }
167
168 void
169 spi_set_filter (void (*filter) (XEvent*, void*), void* data)
170 {
171   _spi_default_filter = filter;
172   _spi_default_filter_data = data;
173 }
174
175 /*END------------------------------------------------------------------------*/