ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Glib-Event/Event.xs
Revision: 1.3
Committed: Tue Nov 29 16:03:24 2005 UTC (18 years, 5 months ago) by root
Branch: MAIN
CVS Tags: rel-0_2, HEAD
Changes since 1.2: +3 -26 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_io_cb (pe_event *pe)
25 {
26 U16 got = ((pe_ioevent *)pe)->got;
27 struct info *i = (struct info *)(pe->up->ext_data);
28
29 i->pfd->revents |= i->pfd->events &
30 ( (got & PE_R ? G_IO_IN : 0)
31 | (got & PE_W ? G_IO_OUT : 0)
32 | (got & PE_E ? G_IO_PRI : 0)
33 );
34
35 if (i->pfd->revents)
36 (*(i->got_events))++;
37 }
38
39 static gint
40 event_poll_func (GPollFD *fds, guint nfds, gint timeout)
41 {
42 dSP;
43 // yes, I use C99. If your compiler barfs here, fix it, but don't
44 // tell me your compiler vendor was too incompetent to implement
45 // the C standard within the last six years.
46 struct info info[nfds];
47 int got_events = 0;
48 int n;
49
50 for (n = 0; n < nfds; n++)
51 {
52 GPollFD *pfd = fds + n;
53 struct info *i = info + n;
54
55 i->pfd = pfd;
56 i->got_events = &got_events;
57
58 pe_io *w = i->w = GEventAPI->new_io (0, 0);
59 w->base.callback = (void *)event_io_cb;
60 w->base.ext_data = (void *)i;
61 w->fd = pfd->fd;
62 w->poll = (pfd->events & G_IO_IN ? PE_R : 0)
63 | (pfd->events & G_IO_OUT ? PE_W : 0)
64 | (pfd->events & G_IO_PRI ? PE_E : 0);
65
66 pfd->revents = 0;
67 GEventAPI->start ((pe_watcher *)w, 0);
68 }
69
70 do {
71 PUSHMARK (SP);
72 XPUSHs (sv_2mortal (newSVnv (timeout >= 0 ? timeout * 0.001 : 86400. * 365.)));
73 PUTBACK;
74 call_pv ("Event::one_event", G_DISCARD | G_EVAL);
75 SPAGAIN;
76 } while (timeout < 0 && !got_events);
77
78 for (n = 0; n < nfds; n++)
79 GEventAPI->cancel ((pe_watcher *)info[n].w);
80
81 if (SvTRUE (ERRSV))
82 croak (0);
83
84 return got_events;
85 }
86
87 MODULE = Glib::Event PACKAGE = Glib::Event
88
89 PROTOTYPES: ENABLE
90
91 BOOT:
92 {
93 I_EVENT_API ("Glib::Event");
94 }
95
96 long
97 install (SV *context)
98 CODE:
99 {
100 GMainContext *ctx = get_gcontext (context);
101
102 RETVAL = (long)g_main_context_get_poll_func (ctx);
103
104 g_main_context_set_poll_func (ctx, event_poll_func);
105 }
106 OUTPUT:
107 RETVAL
108
109 void
110 uninstall (SV *context, long prev_poll_func)
111 CODE:
112 {
113 GMainContext *ctx = get_gcontext (context);
114
115 g_main_context_set_poll_func (ctx, (GPollFunc) prev_poll_func);
116 }
117
118