]> git.proxmox.com Git - spiceterm.git/blame - basic_event_loop.c
code cleanup - compile with -Wall
[spiceterm.git] / basic_event_loop.c
CommitLineData
cc04455b
DM
1#include <stdlib.h>
2#include <stdio.h>
3#include <sys/time.h>
4#include <signal.h>
5#include <string.h>
6
7#include <glib.h>
8
9#include <spice/macros.h>
cc04455b
DM
10#include "basic_event_loop.h"
11
0535e191
DM
12int debug = 1;
13
cc04455b
DM
14#define DPRINTF(x, format, ...) { \
15 if (x <= debug) { \
16 printf("%s: " format "\n" , __FUNCTION__, ## __VA_ARGS__); \
17 } \
18}
19
0535e191 20static GMainLoop *main_loop;
cc04455b
DM
21
22static SpiceCoreInterface core;
23
24typedef struct SpiceTimer {
0535e191 25 GSource *source;
cc04455b 26 SpiceTimerFunc func;
cc04455b
DM
27 int ms;
28 void *opaque;
29} Timer;
30
cc04455b
DM
31static SpiceTimer* timer_add(SpiceTimerFunc func, void *opaque)
32{
0535e191
DM
33 g_return_val_if_fail(func != NULL, NULL);
34
db8e5ef8 35 SpiceTimer *timer = g_new0(SpiceTimer, 1);
cc04455b
DM
36
37 timer->func = func;
38 timer->opaque = opaque;
0535e191 39
cc04455b
DM
40 return timer;
41}
42
0535e191 43static gboolean timer_callback(gpointer data)
cc04455b 44{
0535e191
DM
45 SpiceTimer *timer = (SpiceTimer *)data;
46 g_assert(timer != NULL);
47 g_assert(timer->func != NULL);
48
49 timer->func(timer->opaque);
50
51 return FALSE;
cc04455b
DM
52}
53
54static void timer_start(SpiceTimer *timer, uint32_t ms)
55{
0535e191
DM
56 g_return_if_fail(timer != NULL);
57 g_return_if_fail(ms != 0);
58
59 if (timer->source != NULL) {
60 g_source_destroy(timer->source);
61 }
62
63 timer->source = g_timeout_source_new(ms);
64 g_assert(timer->source != NULL);
65
66 g_source_set_callback(timer->source, timer_callback, timer, NULL);
67
68 g_source_attach(timer->source, NULL);
cc04455b
DM
69}
70
71static void timer_cancel(SpiceTimer *timer)
72{
0535e191
DM
73 g_return_if_fail(timer != NULL);
74
75 if (timer->source != NULL) {
76 g_source_destroy(timer->source);
77 timer->source = NULL;
78 }
79
cc04455b
DM
80 timer->ms = 0;
81}
82
83static void timer_remove(SpiceTimer *timer)
84{
0535e191
DM
85 g_return_if_fail(timer != NULL);
86
87 timer_cancel(timer);
88 g_free(timer);
cc04455b
DM
89}
90
91struct SpiceWatch {
0535e191
DM
92 GIOChannel *channel;
93 guint evid;
cc04455b
DM
94 int fd;
95 int event_mask;
96 SpiceWatchFunc func;
cc04455b
DM
97 void *opaque;
98};
99
0535e191
DM
100static gboolean watch_callback(GIOChannel *source, GIOCondition condition, gpointer data)
101{
102 SpiceWatch *watch = (SpiceWatch *)data;
103
104 g_assert(watch != NULL);
105 g_assert(watch->func != NULL);
106
107 if (condition & G_IO_OUT) {
108 watch->func(watch->fd, SPICE_WATCH_EVENT_WRITE, watch->opaque);
109 }
110
111 if (condition & G_IO_IN) {
112 watch->func(watch->fd, SPICE_WATCH_EVENT_READ, watch->opaque);
113 }
114
115 return TRUE;
116}
117
118static GIOCondition event_mask_to_condition(int event_mask)
119{
120 GIOCondition condition = 0;
121
122 if (event_mask & SPICE_WATCH_EVENT_READ) {
123 condition |= G_IO_IN;
124 }
125
126 if (event_mask & SPICE_WATCH_EVENT_WRITE) {
127 condition |= G_IO_OUT;
128 }
cc04455b 129
0535e191
DM
130 return condition;
131}
cc04455b
DM
132
133static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *opaque)
134{
db8e5ef8 135 SpiceWatch *watch = g_new0(SpiceWatch, 1);
cc04455b 136
0535e191
DM
137 DPRINTF(0, "adding %p, fd=%d", watch, fd);
138
cc04455b
DM
139 watch->fd = fd;
140 watch->event_mask = event_mask;
141 watch->func = func;
142 watch->opaque = opaque;
0535e191
DM
143 watch->channel = g_io_channel_unix_new(fd);
144
145 g_assert(watch->channel != NULL);
146 g_io_channel_set_encoding(watch->channel, NULL, NULL);
147
148 GIOCondition condition = event_mask_to_condition(event_mask);
149 watch->evid = g_io_add_watch(watch->channel, condition, watch_callback, watch);
150
cc04455b
DM
151 return watch;
152}
153
154static void watch_update_mask(SpiceWatch *watch, int event_mask)
155{
0535e191
DM
156 g_assert(watch != NULL);
157
cc04455b 158 DPRINTF(0, "fd %d to %d", watch->fd, event_mask);
0535e191 159
cc04455b 160 watch->event_mask = event_mask;
cc04455b 161
0535e191 162 g_source_remove(watch->evid);
cc04455b 163
0535e191
DM
164 GIOCondition condition = event_mask_to_condition(event_mask);
165 watch->evid = g_io_add_watch(watch->channel, condition, watch_callback, watch);
cc04455b
DM
166}
167
0535e191 168static void watch_remove(SpiceWatch *watch)
cc04455b 169{
0535e191 170 g_assert(watch != NULL);
cc04455b 171
0535e191 172 DPRINTF(0, "remove %p (fd %d)", watch, watch->fd);
cc04455b 173
0535e191
DM
174 g_source_remove(watch->evid);
175 g_io_channel_unref(watch->channel);
cc04455b 176
0535e191 177 g_free(watch);
cc04455b
DM
178}
179
0535e191 180static void channel_event(int event, SpiceChannelEventInfo *info)
cc04455b 181{
abc13312 182 DPRINTF(0, "channel event con, type, id, event: %d, %d, %d, %d",
0535e191 183 info->connection_id, info->type, info->id, event);
cc04455b
DM
184}
185
186void basic_event_loop_mainloop(void)
187{
0535e191 188 g_main_loop_run(main_loop);
cc04455b
DM
189}
190
191static void ignore_sigpipe(void)
192{
193 struct sigaction act;
194
195 memset(&act, 0, sizeof(act));
196 sigfillset(&act.sa_mask);
197 act.sa_handler = SIG_IGN;
198 sigaction(SIGPIPE, &act, NULL);
199}
200
201SpiceCoreInterface *basic_event_loop_init(void)
202{
0535e191
DM
203 main_loop = g_main_loop_new(NULL, FALSE);
204
cc04455b
DM
205 memset(&core, 0, sizeof(core));
206 core.base.major_version = SPICE_INTERFACE_CORE_MAJOR;
0535e191 207 core.base.minor_version = SPICE_INTERFACE_CORE_MINOR;
cc04455b
DM
208 core.timer_add = timer_add;
209 core.timer_start = timer_start;
210 core.timer_cancel = timer_cancel;
211 core.timer_remove = timer_remove;
212 core.watch_add = watch_add;
213 core.watch_update_mask = watch_update_mask;
214 core.watch_remove = watch_remove;
215 core.channel_event = channel_event;
0535e191 216
cc04455b 217 ignore_sigpipe();
0535e191 218
cc04455b
DM
219 return &core;
220}