first.c compilet en draait!
[rodin/chimara.git] / src / event.c
1 #include "event.h"
2
3 static GQueue *event_queue = NULL;
4 static GMutex *event_lock = NULL;
5 static GCond *event_queue_not_empty = NULL;
6 static GCond *event_queue_not_full = NULL;
7
8 void
9 events_init()
10 {
11         event_queue = g_queue_new();
12         event_lock = g_mutex_new();
13         event_queue_not_empty = g_cond_new();
14         event_queue_not_full = g_cond_new();
15 }
16
17 static void
18 event_free(gpointer data, gpointer user_data)
19 {
20         g_free(data);
21 }
22
23 void
24 events_free()
25 {
26         g_queue_foreach(event_queue, event_free, NULL);
27         g_queue_free(event_queue);
28         g_mutex_free(event_lock);
29         g_cond_free(event_queue_not_empty);
30         g_cond_free(event_queue_not_full);
31 }
32
33 void
34 event_throw(glui32 type, winid_t win, glui32 val1, glui32 val2)
35 {
36         GTimeVal timeout;
37         g_get_current_time(&timeout);
38         g_time_val_add(&timeout, 3000000); /* 3 Seconds */
39
40         /* Wait for room in the event queue */
41         g_mutex_lock(event_lock);
42         if( g_queue_get_length(event_queue) >= EVENT_QUEUE_MAX_LENGTH ) {
43                 if( !g_cond_timed_wait(event_queue_not_full, event_lock, &timeout) ) {
44                         /* Drop the event */
45                         g_mutex_unlock(event_lock);
46                         return;
47                 }
48         }
49
50         event_t *event = g_new0(event_t, 1);
51         event->type = type;
52         event->win = win;
53         event->val1 = val1;
54         event->val2 = val2;
55
56         g_queue_push_head(event_queue, event);
57
58         /* Signal that there is an event */
59         g_cond_signal(event_queue_not_empty);
60
61         g_mutex_unlock(event_lock);
62 }
63
64 void
65 glk_select(event_t *event)
66 {
67         event_t *retrieved_event;
68
69         g_return_if_fail(event != NULL);
70
71         g_mutex_lock(event_lock);
72
73         /* Wait for an event */
74         if( g_queue_is_empty(event_queue) ) {
75                 g_cond_wait(event_queue_not_empty, event_lock);
76         }
77
78         retrieved_event = g_queue_pop_tail(event_queue);
79         g_return_if_fail(retrieved_event != NULL);
80
81         event->type = retrieved_event->type;
82         event->win = retrieved_event->win;
83         event->val1 = retrieved_event->val1;
84         event->val2 = retrieved_event->val2;
85
86         g_free(retrieved_event);
87
88         /* Signal that the event queue is no longer full */
89         g_cond_signal(event_queue_not_full);
90
91         g_mutex_unlock(event_lock);
92
93         /* Implementation defined events */
94         switch(event->type) {
95                 case EVENT_TYPE_QUIT:
96                         g_thread_exit(NULL);
97         }
98 }