Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / server / X11 / xf_event.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * X11 Server Event Handling
4  *
5  * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #include <errno.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <X11/Xlib.h>
26 #include <freerdp/utils/memory.h>
27
28 #include "xf_event.h"
29
30 int xf_is_event_set(xfEventQueue* event_queue)
31 {
32         fd_set rfds;
33         int num_set;
34         struct timeval time;
35
36         FD_ZERO(&rfds);
37         FD_SET(event_queue->pipe_fd[0], &rfds);
38         memset(&time, 0, sizeof(time));
39         num_set = select(event_queue->pipe_fd[0] + 1, &rfds, 0, 0, &time);
40
41         return (num_set == 1);
42 }
43
44 void xf_signal_event(xfEventQueue* event_queue)
45 {
46         int length;
47
48         length = write(event_queue->pipe_fd[1], "sig", 4);
49
50         if (length != 4)
51                 printf("xf_signal_event: error\n");
52 }
53
54 void xf_set_event(xfEventQueue* event_queue)
55 {
56         int length;
57
58         length = write(event_queue->pipe_fd[1], "sig", 4);
59
60         if (length != 4)
61                 printf("xf_set_event: error\n");
62 }
63
64 void xf_clear_event(xfEventQueue* event_queue)
65 {
66         int length;
67
68         while (xf_is_event_set(event_queue))
69         {
70                 length = read(event_queue->pipe_fd[0], &length, 4);
71
72                 if (length != 4)
73                         printf("xf_clear_event: error\n");
74         }
75 }
76
77 void xf_event_push(xfEventQueue* event_queue, xfEvent* event)
78 {
79         pthread_mutex_lock(&(event_queue->mutex));
80
81         if (event_queue->count >= event_queue->size)
82         {
83                 event_queue->size *= 2;
84                 event_queue->events = (xfEvent**) xrealloc((void*) event_queue->events, sizeof(xfEvent*) * event_queue->size);
85         }
86
87         event_queue->events[(event_queue->count)++] = event;
88
89         xf_set_event(event_queue);
90
91         pthread_mutex_unlock(&(event_queue->mutex));
92 }
93
94 xfEvent* xf_event_peek(xfEventQueue* event_queue)
95 {
96         xfEvent* event;
97
98         pthread_mutex_lock(&(event_queue->mutex));
99
100         if (event_queue->count < 1)
101                 event = NULL;
102         else
103                 event = event_queue->events[0];
104
105         pthread_mutex_unlock(&(event_queue->mutex));
106
107         return event;
108 }
109
110 xfEvent* xf_event_pop(xfEventQueue* event_queue)
111 {
112         xfEvent* event;
113
114         pthread_mutex_lock(&(event_queue->mutex));
115
116         if (event_queue->count < 1)
117                 return NULL;
118
119         event = event_queue->events[0];
120         (event_queue->count)--;
121
122         memmove(&event_queue->events[0], &event_queue->events[1], event_queue->count * sizeof(void*));
123
124         pthread_mutex_unlock(&(event_queue->mutex));
125
126         return event;
127 }
128
129 xfEventRegion* xf_event_region_new(int x, int y, int width, int height)
130 {
131         xfEventRegion* event_region = xnew(xfEventRegion);
132
133         if (event_region != NULL)
134         {
135                 event_region->x = x;
136                 event_region->y = y;
137                 event_region->width = width;
138                 event_region->height = height;
139         }
140
141         return event_region;
142 }
143
144 void xf_event_region_free(xfEventRegion* event_region)
145 {
146         xfree(event_region);
147 }
148
149 xfEvent* xf_event_new(int type)
150 {
151         xfEvent* event = xnew(xfEvent);
152         event->type = type;
153         return event;
154 }
155
156 void xf_event_free(xfEvent* event)
157 {
158         xfree(event);
159 }
160
161 xfEventQueue* xf_event_queue_new()
162 {
163         xfEventQueue* event_queue = xnew(xfEventQueue);
164
165         if (event_queue != NULL)
166         {
167                 event_queue->pipe_fd[0] = -1;
168                 event_queue->pipe_fd[1] = -1;
169
170                 event_queue->size = 16;
171                 event_queue->count = 0;
172                 event_queue->events = (xfEvent**) xzalloc(sizeof(xfEvent*) * event_queue->size);
173
174                 if (pipe(event_queue->pipe_fd) < 0)
175                         printf("xf_event_queue_new: pipe failed\n");
176
177                 pthread_mutex_init(&(event_queue->mutex), NULL);
178         }
179
180         return event_queue;
181 }
182
183 void xf_event_queue_free(xfEventQueue* event_queue)
184 {
185         if (event_queue->pipe_fd[0] != -1)
186         {
187                 close(event_queue->pipe_fd[0]);
188                 event_queue->pipe_fd[0] = -1;
189         }
190
191         if (event_queue->pipe_fd[1] != -1)
192         {
193                 close(event_queue->pipe_fd[1]);
194                 event_queue->pipe_fd[1] = -1;
195         }
196
197         pthread_mutex_destroy(&(event_queue->mutex));
198 }