ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Glib-Event/Event.xs
Revision: 1.2
Committed: Sun Nov 27 19:23:43 2005 UTC (18 years, 6 months ago) by root
Branch: MAIN
CVS Tags: rel-0_1
Changes since 1.1: +8 -2 lines
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->pfd = pfd;
63 i->got_events = &got_events;
64
65 pe_io *w = i->w = GEventAPI->new_io (0, 0);
66 w->base.callback = (void *)event_io_cb;
67 w->base.ext_data = (void *)i;
68 w->fd = pfd->fd;
69 w->poll = (pfd->events & G_IO_IN ? PE_R : 0)
70 | (pfd->events & G_IO_OUT ? PE_W : 0)
71 | (pfd->events & G_IO_PRI ? PE_E : 0);
72
73 pfd->revents = 0;
74 GEventAPI->start ((pe_watcher *)w, 0);
75 }
76
77 if (timeout >= 0)
78 {
79 w_timeout = GEventAPI->new_timer (0, 0);
80 w_timeout->base.callback = (void *)event_timer_cb;
81 w_timeout->base.ext_data = (void *)&got_timeout;
82 w_timeout->tm.at = GEventAPI->NVtime () + timeout * 0.001;
83
84 GEventAPI->start ((pe_watcher *)w_timeout, 0);
85 }
86
87 do {
88 PUSHMARK (SP);
89 XPUSHs (sv_2mortal (newSVnv (86400)));
90 PUTBACK;
91 call_pv ("Event::one_event", G_DISCARD | G_EVAL);
92 SPAGAIN;
93 } while (!got_events && !got_timeout);
94
95 if (w_timeout)
96 GEventAPI->cancel ((pe_watcher *)w_timeout);
97
98 for (n = 0; n < nfds; n++)
99 GEventAPI->cancel ((pe_watcher *)info[n].w);
100
101 if (SvTRUE (ERRSV))
102 croak (0);
103
104 if (got_timeout)
105 return 0;
106
107 return got_events;
108 }
109
110 MODULE = Glib::Event PACKAGE = Glib::Event
111
112 PROTOTYPES: ENABLE
113
114 BOOT:
115 {
116 I_EVENT_API ("Glib::Event");
117 }
118
119 long
120 install (SV *context)
121 CODE:
122 {
123 GMainContext *ctx = get_gcontext (context);
124
125 RETVAL = (long)g_main_context_get_poll_func (ctx);
126
127 g_main_context_set_poll_func (ctx, event_poll_func);
128 }
129 OUTPUT:
130 RETVAL
131
132 void
133 uninstall (SV *context, long prev_poll_func)
134 CODE:
135 {
136 GMainContext *ctx = get_gcontext (context);
137
138 g_main_context_set_poll_func (ctx, (GPollFunc) prev_poll_func);
139 }
140
141