00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "eventqueue.h"
00025 #include <X11/Xlib.h>
00026
00027 static gboolean eq_prepare (GSource *source,
00028 gint *timeout);
00029 static gboolean eq_check (GSource *source);
00030 static gboolean eq_dispatch (GSource *source,
00031 GSourceFunc callback,
00032 gpointer user_data);
00033 static void eq_destroy (GSource *source);
00034
00035 static GSourceFuncs eq_funcs = {
00036 eq_prepare,
00037 eq_check,
00038 eq_dispatch,
00039 eq_destroy
00040 };
00041
00042 struct _MetaEventQueue
00043 {
00044 GSource source;
00045
00046 Display *display;
00047 GPollFD poll_fd;
00048 int connection_fd;
00049 GQueue *events;
00050 };
00051
00052 MetaEventQueue*
00053 meta_event_queue_new (Display *display, MetaEventQueueFunc func, gpointer data)
00054 {
00055 GSource *source;
00056 MetaEventQueue *eq;
00057
00058 source = g_source_new (&eq_funcs, sizeof (MetaEventQueue));
00059 eq = (MetaEventQueue*) source;
00060
00061 eq->connection_fd = ConnectionNumber (display);
00062 eq->poll_fd.fd = eq->connection_fd;
00063 eq->poll_fd.events = G_IO_IN;
00064
00065 eq->events = g_queue_new ();
00066
00067 eq->display = display;
00068
00069 g_source_set_priority (source, G_PRIORITY_DEFAULT);
00070 g_source_add_poll (source, &eq->poll_fd);
00071 g_source_set_can_recurse (source, TRUE);
00072
00073 g_source_set_callback (source, (GSourceFunc) func, data, NULL);
00074
00075 g_source_attach (source, NULL);
00076 g_source_unref (source);
00077
00078 return eq;
00079 }
00080
00081 void
00082 meta_event_queue_free (MetaEventQueue *eq)
00083 {
00084 GSource *source;
00085
00086 source = (GSource*) eq;
00087
00088 g_source_destroy (source);
00089 }
00090
00091 static gboolean
00092 eq_events_pending (MetaEventQueue *eq)
00093 {
00094 return eq->events->length > 0 || XPending (eq->display);
00095 }
00096
00097 static void
00098 eq_queue_events (MetaEventQueue *eq)
00099 {
00100 XEvent xevent;
00101
00102 while (XPending (eq->display))
00103 {
00104 XEvent *copy;
00105
00106 XNextEvent (eq->display, &xevent);
00107
00108 copy = g_new (XEvent, 1);
00109 *copy = xevent;
00110
00111 g_queue_push_tail (eq->events, copy);
00112 }
00113 }
00114
00115 static gboolean
00116 eq_prepare (GSource *source, gint *timeout)
00117 {
00118 MetaEventQueue *eq;
00119
00120 eq = (MetaEventQueue*) source;
00121
00122 *timeout = -1;
00123
00124 return eq_events_pending (eq);
00125 }
00126
00127 static gboolean
00128 eq_check (GSource *source)
00129 {
00130 MetaEventQueue *eq;
00131
00132 eq = (MetaEventQueue*) source;
00133
00134 if (eq->poll_fd.revents & G_IO_IN)
00135 return eq_events_pending (eq);
00136 else
00137 return FALSE;
00138 }
00139
00140 static gboolean
00141 eq_dispatch (GSource *source, GSourceFunc callback, gpointer user_data)
00142 {
00143 MetaEventQueue *eq;
00144
00145 eq = (MetaEventQueue*) source;
00146
00147 eq_queue_events (eq);
00148
00149 if (eq->events->length > 0)
00150 {
00151 XEvent *event;
00152 MetaEventQueueFunc func;
00153
00154 event = g_queue_pop_head (eq->events);
00155 func = (MetaEventQueueFunc) callback;
00156
00157 (* func) (event, user_data);
00158
00159 g_free (event);
00160 }
00161
00162 return TRUE;
00163 }
00164
00165 static void
00166 eq_destroy (GSource *source)
00167 {
00168 MetaEventQueue *eq;
00169
00170 eq = (MetaEventQueue*) source;
00171
00172 while (eq->events->length > 0)
00173 {
00174 XEvent *event;
00175
00176 event = g_queue_pop_head (eq->events);
00177
00178 g_free (event);
00179 }
00180
00181 g_queue_free (eq->events);
00182
00183
00184 }