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, 6 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

# 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_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 root 1.2 (*(i->got_events))++;
37 root 1.1 }
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 root 1.3 int got_events = 0;
48 root 1.1 int n;
49    
50     for (n = 0; n < nfds; n++)
51     {
52     GPollFD *pfd = fds + n;
53     struct info *i = info + n;
54    
55 root 1.2 i->pfd = pfd;
56 root 1.1 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 root 1.3 XPUSHs (sv_2mortal (newSVnv (timeout >= 0 ? timeout * 0.001 : 86400. * 365.)));
73 root 1.2 PUTBACK;
74 root 1.1 call_pv ("Event::one_event", G_DISCARD | G_EVAL);
75 root 1.2 SPAGAIN;
76 root 1.3 } while (timeout < 0 && !got_events);
77 root 1.1
78     for (n = 0; n < nfds; n++)
79     GEventAPI->cancel ((pe_watcher *)info[n].w);
80    
81 root 1.2 if (SvTRUE (ERRSV))
82 root 1.1 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