ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Glib-Event/Event.xs
Revision: 1.1
Committed: Sun Nov 27 14:02:23 2005 UTC (18 years, 6 months ago) by root
Branch: MAIN
Log Message:
*** empty log message ***

File Contents

# Content
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include <glib.h>
6 #include "EventAPI.h"
7
8 static GMainContext *
9 get_gcontext (SV *context)
10 {
11 if (!SvOK (context))
12 return g_main_context_default ();
13
14 croak ("only the default context is currently supported.");
15 }
16
17 struct info {
18 int *got_events;
19 pe_io *w;
20 GPollFD *pfd;
21 };
22
23 static void
24 event_timer_cb (pe_event *pe)
25 {
26 *(int *)(pe->up->ext_data) = -1;
27 }
28
29 static void
30 event_io_cb (pe_event *pe)
31 {
32 U16 got = ((pe_ioevent *)pe)->got;
33 struct info *i = (struct info *)(pe->up->ext_data);
34
35 i->pfd->revents |= i->pfd->events &
36 ( (got & PE_R ? G_IO_IN : 0)
37 | (got & PE_W ? G_IO_OUT : 0)
38 | (got & PE_E ? G_IO_PRI : 0)
39 );
40
41 if (i->pfd->revents)
42 *(i->got_events)++;
43 }
44
45 static gint
46 event_poll_func (GPollFD *fds, guint nfds, gint timeout)
47 {
48 dSP;
49 // yes, I use C99. If your compiler barfs here, fix it, but don't
50 // tell me your compiler vendor was too incompetent to implement
51 // the C standard within the last six years.
52 struct info info[nfds];
53 pe_timer *w_timeout = 0;
54 int got_events = 0, got_timeout = 0;
55 int n;
56
57 for (n = 0; n < nfds; n++)
58 {
59 GPollFD *pfd = fds + n;
60 struct info *i = info + n;
61
62 i->got_events = &got_events;
63
64 pe_io *w = i->w = GEventAPI->new_io (0, 0);
65 w->base.callback = (void *)event_io_cb;
66 w->base.ext_data = (void *)i;
67 w->fd = pfd->fd;
68 w->poll = (pfd->events & G_IO_IN ? PE_R : 0)
69 | (pfd->events & G_IO_OUT ? PE_W : 0)
70 | (pfd->events & G_IO_PRI ? PE_E : 0);
71
72 pfd->revents = 0;
73 GEventAPI->start ((pe_watcher *)w, 0);
74 }
75
76 if (timeout >= 0)
77 {
78 w_timeout = GEventAPI->new_timer (0, 0);
79 w_timeout->base.callback = (void *)event_timer_cb;
80 w_timeout->base.ext_data = (void *)&got_timeout;
81 w_timeout->tm.at = GEventAPI->NVtime () + timeout * 0.001;
82 }
83
84 do {
85 PUSHMARK (SP);
86 call_pv ("Event::one_event", G_DISCARD | G_EVAL);
87 } while (!got_events && !got_timeout);
88
89 if (w_timeout)
90 GEventAPI->cancel ((pe_watcher *)w_timeout);
91
92 for (n = 0; n < nfds; n++)
93 GEventAPI->cancel ((pe_watcher *)info[n].w);
94
95 if (SvOK (ERRSV))
96 croak (0);
97
98 if (got_timeout)
99 return 0;
100
101 return got_events;
102 }
103
104 MODULE = Glib::Event PACKAGE = Glib::Event
105
106 PROTOTYPES: ENABLE
107
108 BOOT:
109 {
110 I_EVENT_API ("Glib::Event");
111 }
112
113 long
114 install (SV *context)
115 CODE:
116 {
117 GMainContext *ctx = get_gcontext (context);
118
119 RETVAL = (long)g_main_context_get_poll_func (ctx);
120
121 g_main_context_set_poll_func (ctx, event_poll_func);
122 }
123 OUTPUT:
124 RETVAL
125
126 void
127 uninstall (SV *context, long prev_poll_func)
128 CODE:
129 {
130 GMainContext *ctx = get_gcontext (context);
131
132 g_main_context_set_poll_func (ctx, (GPollFunc) prev_poll_func);
133 }
134
135