ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Glib-Event/Event.xs
Revision: 1.1
Committed: Sun Nov 27 14:02:23 2005 UTC (20 years, 10 months ago) by root
Branch: MAIN
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     *(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