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

# User Rev Content
1 root 1.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 root 1.2 (*(i->got_events))++;
43 root 1.1 }
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 root 1.2 i->pfd = pfd;
63 root 1.1 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 root 1.2
84     GEventAPI->start ((pe_watcher *)w_timeout, 0);
85 root 1.1 }
86    
87     do {
88     PUSHMARK (SP);
89 root 1.2 XPUSHs (sv_2mortal (newSVnv (86400)));
90     PUTBACK;
91 root 1.1 call_pv ("Event::one_event", G_DISCARD | G_EVAL);
92 root 1.2 SPAGAIN;
93 root 1.1 } 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 root 1.2 if (SvTRUE (ERRSV))
102 root 1.1 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