File: | cdk/broadway/cdkbroadway-server.c |
Warning: | line 567, column 2 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | #include "config.h" | |||
2 | ||||
3 | #ifdef HAVE_SYS_MMAN_H1 | |||
4 | #include <sys/mman.h> | |||
5 | #endif | |||
6 | #include <sys/stat.h> | |||
7 | #include <fcntl.h> | |||
8 | ||||
9 | #include "cdkbroadway-server.h" | |||
10 | ||||
11 | #include "cdkprivate-broadway.h" | |||
12 | ||||
13 | #include <glib.h> | |||
14 | #include <glib/gprintf.h> | |||
15 | #ifdef G_OS_UNIX | |||
16 | #include <gio/gunixsocketaddress.h> | |||
17 | #endif | |||
18 | #include <stdlib.h> | |||
19 | #include <string.h> | |||
20 | #include <errno(*__errno_location ()).h> | |||
21 | #ifdef HAVE_UNISTD_H1 | |||
22 | #include <unistd.h> | |||
23 | #elif defined (G_OS_WIN32) | |||
24 | #include <io.h> | |||
25 | #define ftruncate _chsize_s | |||
26 | #endif | |||
27 | #include <sys/types.h> | |||
28 | #ifdef G_OS_WIN32 | |||
29 | #include <windows.h> | |||
30 | #endif | |||
31 | #include "cdkintl.h" | |||
32 | ||||
33 | typedef struct BroadwayInput BroadwayInput; | |||
34 | ||||
35 | struct _CdkBroadwayServer { | |||
36 | GObject parent_instance; | |||
37 | ||||
38 | guint32 next_serial; | |||
39 | GSocketConnection *connection; | |||
40 | ||||
41 | guint32 recv_buffer_size; | |||
42 | guint8 recv_buffer[1024]; | |||
43 | ||||
44 | guint process_input_idle; | |||
45 | GList *incomming; | |||
46 | ||||
47 | }; | |||
48 | ||||
49 | struct _CdkBroadwayServerClass | |||
50 | { | |||
51 | GObjectClass parent_class; | |||
52 | }; | |||
53 | ||||
54 | static gboolean input_available_cb (gpointer stream, gpointer user_data); | |||
55 | ||||
56 | static GType cdk_broadway_server_get_type (void); | |||
57 | ||||
58 | G_DEFINE_TYPE (CdkBroadwayServer, cdk_broadway_server, G_TYPE_OBJECT)static void cdk_broadway_server_init (CdkBroadwayServer *self ); static void cdk_broadway_server_class_init (CdkBroadwayServerClass *klass); static GType cdk_broadway_server_get_type_once (void ); static gpointer cdk_broadway_server_parent_class = ((void* )0); static gint CdkBroadwayServer_private_offset; static void cdk_broadway_server_class_intern_init (gpointer klass) { cdk_broadway_server_parent_class = g_type_class_peek_parent (klass); if (CdkBroadwayServer_private_offset != 0) g_type_class_adjust_private_offset (klass, &CdkBroadwayServer_private_offset ); cdk_broadway_server_class_init ((CdkBroadwayServerClass*) klass ); } __attribute__ ((__unused__)) static inline gpointer cdk_broadway_server_get_instance_private (CdkBroadwayServer *self) { return (((gpointer) ((guint8*) ( self) + (glong) (CdkBroadwayServer_private_offset)))); } GType cdk_broadway_server_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); (void ) (0 ? (gpointer) * (&static_g_define_type_id) : ((void*) 0)); (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = cdk_broadway_server_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType cdk_broadway_server_get_type_once (void) { GType g_define_type_id = g_type_register_static_simple (((GType) ((20) << (2))), g_intern_static_string ("CdkBroadwayServer" ), sizeof (CdkBroadwayServerClass), (GClassInitFunc)(void (*) (void)) cdk_broadway_server_class_intern_init, sizeof (CdkBroadwayServer ), (GInstanceInitFunc)(void (*)(void)) cdk_broadway_server_init , (GTypeFlags) 0); { {{};} } return g_define_type_id; } | |||
59 | ||||
60 | static void | |||
61 | cdk_broadway_server_init (CdkBroadwayServer *server) | |||
62 | { | |||
63 | server->next_serial = 1; | |||
64 | } | |||
65 | ||||
66 | static void | |||
67 | cdk_broadway_server_finalize (GObject *object) | |||
68 | { | |||
69 | G_OBJECT_CLASS (cdk_broadway_server_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((cdk_broadway_server_parent_class)), (((GType) ((20) << (2))))))))->finalize (object); | |||
70 | } | |||
71 | ||||
72 | static void | |||
73 | cdk_broadway_server_class_init (CdkBroadwayServerClass * class) | |||
74 | { | |||
75 | GObjectClass *object_class = G_OBJECT_CLASS (class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((class)), (((GType) ((20) << (2)))))))); | |||
76 | ||||
77 | object_class->finalize = cdk_broadway_server_finalize; | |||
78 | } | |||
79 | ||||
80 | gboolean | |||
81 | _cdk_broadway_server_lookahead_event (CdkBroadwayServer *server G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
82 | const char *types G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
83 | { | |||
84 | ||||
85 | return FALSE(0); | |||
86 | } | |||
87 | ||||
88 | gulong | |||
89 | _cdk_broadway_server_get_next_serial (CdkBroadwayServer *server) | |||
90 | { | |||
91 | return (gulong)server->next_serial; | |||
92 | } | |||
93 | ||||
94 | CdkBroadwayServer * | |||
95 | _cdk_broadway_server_new (const char *display, GError **error) | |||
96 | { | |||
97 | CdkBroadwayServer *server; | |||
98 | GSocketClient *client; | |||
99 | GSocketConnection *connection; | |||
100 | GInetAddress *inet; | |||
101 | GSocketAddress *address; | |||
102 | GPollableInputStream *pollable; | |||
103 | GInputStream *in; | |||
104 | GSource *source; | |||
105 | char *local_socket_type = NULL((void*)0); | |||
106 | int port; | |||
107 | ||||
108 | if (display == NULL((void*)0)) | |||
109 | { | |||
110 | #ifdef G_OS_UNIX | |||
111 | if (g_unix_socket_address_abstract_names_supported ()) | |||
112 | display = ":0"; | |||
113 | else | |||
114 | #endif | |||
115 | display = ":tcp"; | |||
116 | } | |||
117 | ||||
118 | if (g_str_has_prefix (display, ":tcp")(__builtin_constant_p (":tcp")? __extension__ ({ const char * const __str = (display); const char * const __prefix = (":tcp" ); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void*)0)) __result = (g_str_has_prefix) (__str, __prefix ); else { const size_t __str_len = strlen (((__str) + !(__str ))); const size_t __prefix_len = strlen (((__prefix) + !(__prefix ))); if (__str_len >= __prefix_len) __result = memcmp (((__str ) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len) == 0 ; } __result; }) : (g_str_has_prefix) (display, ":tcp") )) | |||
119 | { | |||
120 | port = 9090 + strtol (display + strlen (":tcp"), NULL((void*)0), 10); | |||
121 | ||||
122 | inet = g_inet_address_new_from_string ("127.0.0.1"); | |||
123 | address = g_inet_socket_address_new (inet, port); | |||
124 | g_object_unref (inet); | |||
125 | } | |||
126 | #ifdef G_OS_UNIX | |||
127 | else if (display[0] == ':' && g_ascii_isdigit(display[1])((g_ascii_table[(guchar) (display[1])] & G_ASCII_DIGIT) != 0)) | |||
128 | { | |||
129 | char *path, *basename; | |||
130 | ||||
131 | port = strtol (display + strlen (":"), NULL((void*)0), 10); | |||
132 | basename = g_strdup_printf ("broadway%d.socket", port + 1); | |||
133 | path = g_build_filename (g_get_user_runtime_dir (), basename, NULL((void*)0)); | |||
134 | g_free (basename); | |||
135 | ||||
136 | address = g_unix_socket_address_new_with_type (path, -1, | |||
137 | G_UNIX_SOCKET_ADDRESS_ABSTRACT); | |||
138 | g_free (path); | |||
139 | } | |||
140 | #endif | |||
141 | else | |||
142 | { | |||
143 | g_set_error (error, G_IO_ERRORg_io_error_quark(), G_IO_ERROR_NOT_SUPPORTED, | |||
144 | _("Broadway display type not supported: %s")((char *) g_dgettext ("ctk30", "Broadway display type not supported: %s" )), display); | |||
145 | return NULL((void*)0); | |||
146 | } | |||
147 | ||||
148 | g_free (local_socket_type); | |||
149 | ||||
150 | client = g_socket_client_new (); | |||
151 | ||||
152 | connection = g_socket_client_connect (client, G_SOCKET_CONNECTABLE (address)((((GSocketConnectable*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((address)), ((g_socket_connectable_get_type ())))))), NULL((void*)0), error); | |||
153 | ||||
154 | g_object_unref (address); | |||
155 | g_object_unref (client); | |||
156 | ||||
157 | if (connection == NULL((void*)0)) | |||
158 | return NULL((void*)0); | |||
159 | ||||
160 | server = g_object_new (CDK_TYPE_BROADWAY_SERVER(cdk_broadway_server_get_type()), NULL((void*)0)); | |||
161 | server->connection = connection; | |||
162 | ||||
163 | in = g_io_stream_get_input_stream (G_IO_STREAM (server->connection)((((GIOStream*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((server->connection)), ((g_io_stream_get_type ()))))))); | |||
164 | pollable = G_POLLABLE_INPUT_STREAM (in)((((GPollableInputStream*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((in)), ((g_pollable_input_stream_get_type ())))))); | |||
165 | ||||
166 | source = g_pollable_input_stream_create_source (pollable, NULL((void*)0)); | |||
167 | g_source_attach (source, NULL((void*)0)); | |||
168 | g_source_set_callback (source, (GSourceFunc)input_available_cb, server, NULL((void*)0)); | |||
169 | ||||
170 | return server; | |||
171 | } | |||
172 | ||||
173 | guint32 | |||
174 | _cdk_broadway_server_get_last_seen_time (CdkBroadwayServer *server G_GNUC_UNUSED__attribute__ ((__unused__))) | |||
175 | { | |||
176 | return 0; | |||
177 | } | |||
178 | ||||
179 | static guint32 | |||
180 | cdk_broadway_server_send_message_with_size (CdkBroadwayServer *server, BroadwayRequestBase *base, | |||
181 | gsize size, guint32 type) | |||
182 | { | |||
183 | GOutputStream *out; | |||
184 | gsize written; | |||
185 | ||||
186 | base->size = size; | |||
187 | base->type = type; | |||
188 | base->serial = server->next_serial++; | |||
189 | ||||
190 | out = g_io_stream_get_output_stream (G_IO_STREAM (server->connection)((((GIOStream*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((server->connection)), ((g_io_stream_get_type ()))))))); | |||
191 | ||||
192 | if (!g_output_stream_write_all (out, base, size, &written, NULL((void*)0), NULL((void*)0))) | |||
193 | { | |||
194 | g_printerr ("Unable to write to server\n"); | |||
195 | exit (1); | |||
196 | } | |||
197 | ||||
198 | g_assert (written == size)do { if (written == size) ; else g_assertion_message_expr ("Cdk" , "cdkbroadway-server.c", 198, ((const char*) (__func__)), "written == size" ); } while (0); | |||
199 | ||||
200 | return base->serial; | |||
201 | } | |||
202 | ||||
203 | #define cdk_broadway_server_send_message(_server, _msg, _type)cdk_broadway_server_send_message_with_size(_server, (BroadwayRequestBase *)&_msg, sizeof (_msg), _type) \ | |||
204 | cdk_broadway_server_send_message_with_size(_server, (BroadwayRequestBase *)&_msg, sizeof (_msg), _type) | |||
205 | ||||
206 | static void | |||
207 | parse_all_input (CdkBroadwayServer *server) | |||
208 | { | |||
209 | guint8 *p, *end; | |||
210 | guint32 size; | |||
211 | BroadwayReply *reply; | |||
212 | ||||
213 | p = server->recv_buffer; | |||
214 | end = p + server->recv_buffer_size; | |||
215 | ||||
216 | while (p + sizeof (guint32) <= end) | |||
217 | { | |||
218 | memcpy (&size, p, sizeof (guint32)); | |||
219 | if (p + size > end) | |||
220 | break; | |||
221 | ||||
222 | reply = g_memdup2 (p, size); | |||
223 | p += size; | |||
224 | ||||
225 | server->incomming = g_list_append (server->incomming, reply); | |||
226 | } | |||
227 | ||||
228 | if (p < end) | |||
229 | memmove (server->recv_buffer, p, end - p); | |||
230 | server->recv_buffer_size = end - p; | |||
231 | } | |||
232 | ||||
233 | static void | |||
234 | read_some_input_blocking (CdkBroadwayServer *server) | |||
235 | { | |||
236 | GInputStream *in; | |||
237 | gssize res; | |||
238 | ||||
239 | in = g_io_stream_get_input_stream (G_IO_STREAM (server->connection)((((GIOStream*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((server->connection)), ((g_io_stream_get_type ()))))))); | |||
240 | ||||
241 | g_assert (server->recv_buffer_size < sizeof (server->recv_buffer))do { if (server->recv_buffer_size < sizeof (server-> recv_buffer)) ; else g_assertion_message_expr ("Cdk", "cdkbroadway-server.c" , 241, ((const char*) (__func__)), "server->recv_buffer_size < sizeof (server->recv_buffer)" ); } while (0); | |||
242 | res = g_input_stream_read (in, &server->recv_buffer[server->recv_buffer_size], | |||
243 | sizeof (server->recv_buffer) - server->recv_buffer_size, | |||
244 | NULL((void*)0), NULL((void*)0)); | |||
245 | ||||
246 | if (res <= 0) | |||
247 | { | |||
248 | g_printerr ("Unable to read from broadway server\n"); | |||
249 | exit (1); | |||
250 | } | |||
251 | ||||
252 | server->recv_buffer_size += res; | |||
253 | } | |||
254 | ||||
255 | static void | |||
256 | read_some_input_nonblocking (CdkBroadwayServer *server) | |||
257 | { | |||
258 | GInputStream *in; | |||
259 | GPollableInputStream *pollable; | |||
260 | gssize res; | |||
261 | GError *error; | |||
262 | ||||
263 | in = g_io_stream_get_input_stream (G_IO_STREAM (server->connection)((((GIOStream*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((server->connection)), ((g_io_stream_get_type ()))))))); | |||
264 | pollable = G_POLLABLE_INPUT_STREAM (in)((((GPollableInputStream*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((in)), ((g_pollable_input_stream_get_type ())))))); | |||
265 | ||||
266 | g_assert (server->recv_buffer_size < sizeof (server->recv_buffer))do { if (server->recv_buffer_size < sizeof (server-> recv_buffer)) ; else g_assertion_message_expr ("Cdk", "cdkbroadway-server.c" , 266, ((const char*) (__func__)), "server->recv_buffer_size < sizeof (server->recv_buffer)" ); } while (0); | |||
267 | error = NULL((void*)0); | |||
268 | res = g_pollable_input_stream_read_nonblocking (pollable, &server->recv_buffer[server->recv_buffer_size], | |||
269 | sizeof (server->recv_buffer) - server->recv_buffer_size, | |||
270 | NULL((void*)0), &error); | |||
271 | ||||
272 | if (res < 0 && g_error_matches (error, G_IO_ERRORg_io_error_quark(), G_IO_ERROR_WOULD_BLOCK)) | |||
273 | { | |||
274 | g_error_free (error); | |||
275 | res = 0; | |||
276 | } | |||
277 | else if (res <= 0) | |||
278 | { | |||
279 | g_printerr ("Unable to read from broadway server: %s\n", error ? error->message : "eof"); | |||
280 | exit (1); | |||
281 | } | |||
282 | ||||
283 | server->recv_buffer_size += res; | |||
284 | } | |||
285 | ||||
286 | static BroadwayReply * | |||
287 | find_response_by_serial (CdkBroadwayServer *server, guint32 serial) | |||
288 | { | |||
289 | GList *l; | |||
290 | ||||
291 | for (l = server->incomming; l != NULL((void*)0); l = l->next) | |||
292 | { | |||
293 | BroadwayReply *reply = l->data; | |||
294 | ||||
295 | if (reply->base.in_reply_to == serial) | |||
296 | return reply; | |||
297 | } | |||
298 | ||||
299 | return NULL((void*)0); | |||
300 | } | |||
301 | ||||
302 | static void | |||
303 | process_input_messages (CdkBroadwayServer *server) | |||
304 | { | |||
305 | BroadwayReply *reply; | |||
306 | ||||
307 | if (server->process_input_idle != 0) | |||
308 | { | |||
309 | g_source_remove (server->process_input_idle); | |||
310 | server->process_input_idle = 0; | |||
311 | } | |||
312 | ||||
313 | while (server->incomming) | |||
314 | { | |||
315 | reply = server->incomming->data; | |||
316 | server->incomming = | |||
317 | g_list_delete_link (server->incomming, | |||
318 | server->incomming); | |||
319 | ||||
320 | if (reply->base.type == BROADWAY_REPLY_EVENT) | |||
321 | _cdk_broadway_events_got_input (&reply->event.msg); | |||
322 | else | |||
323 | g_warning ("Unhandled reply type %d", reply->base.type); | |||
324 | g_free (reply); | |||
325 | } | |||
326 | } | |||
327 | ||||
328 | static gboolean | |||
329 | process_input_idle_cb (CdkBroadwayServer *server) | |||
330 | { | |||
331 | server->process_input_idle = 0; | |||
332 | process_input_messages (server); | |||
333 | return G_SOURCE_REMOVE(0); | |||
334 | } | |||
335 | ||||
336 | static void | |||
337 | queue_process_input_at_idle (CdkBroadwayServer *server) | |||
338 | { | |||
339 | if (server->process_input_idle == 0) | |||
340 | server->process_input_idle = | |||
341 | g_idle_add_full (G_PRIORITY_DEFAULT0, (GSourceFunc)process_input_idle_cb, server, NULL((void*)0)); | |||
342 | } | |||
343 | ||||
344 | static gboolean | |||
345 | input_available_cb (gpointer stream G_GNUC_UNUSED__attribute__ ((__unused__)), | |||
346 | gpointer user_data) | |||
347 | { | |||
348 | CdkBroadwayServer *server = user_data; | |||
349 | ||||
350 | read_some_input_nonblocking (server); | |||
351 | parse_all_input (server); | |||
352 | ||||
353 | process_input_messages (server); | |||
354 | ||||
355 | return G_SOURCE_CONTINUE(!(0)); | |||
356 | } | |||
357 | ||||
358 | static BroadwayReply * | |||
359 | cdk_broadway_server_wait_for_reply (CdkBroadwayServer *server, | |||
360 | guint32 serial) | |||
361 | { | |||
362 | BroadwayReply *reply; | |||
363 | ||||
364 | while (TRUE(!(0))) | |||
365 | { | |||
366 | reply = find_response_by_serial (server, serial); | |||
367 | if (reply) | |||
368 | { | |||
369 | server->incomming = g_list_remove (server->incomming, reply); | |||
370 | break; | |||
371 | } | |||
372 | ||||
373 | read_some_input_blocking (server); | |||
374 | parse_all_input (server); | |||
375 | } | |||
376 | ||||
377 | queue_process_input_at_idle (server); | |||
378 | return reply; | |||
379 | } | |||
380 | ||||
381 | void | |||
382 | _cdk_broadway_server_flush (CdkBroadwayServer *server) | |||
383 | { | |||
384 | BroadwayRequestFlush msg; | |||
385 | ||||
386 | cdk_broadway_server_send_message(server, msg, BROADWAY_REQUEST_FLUSH)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_FLUSH); | |||
387 | } | |||
388 | ||||
389 | void | |||
390 | _cdk_broadway_server_sync (CdkBroadwayServer *server) | |||
391 | { | |||
392 | BroadwayRequestSync msg; | |||
393 | guint32 serial; | |||
394 | BroadwayReply *reply; | |||
395 | ||||
396 | serial = cdk_broadway_server_send_message (server, msg,cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_SYNC) | |||
397 | BROADWAY_REQUEST_SYNC)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_SYNC); | |||
398 | reply = cdk_broadway_server_wait_for_reply (server, serial); | |||
399 | ||||
400 | g_assert (reply->base.type == BROADWAY_REPLY_SYNC)do { if (reply->base.type == BROADWAY_REPLY_SYNC) ; else g_assertion_message_expr ("Cdk", "cdkbroadway-server.c", 400, ((const char*) (__func__ )), "reply->base.type == BROADWAY_REPLY_SYNC"); } while (0 ); | |||
401 | ||||
402 | g_free (reply); | |||
403 | ||||
404 | return; | |||
405 | } | |||
406 | ||||
407 | void | |||
408 | _cdk_broadway_server_query_mouse (CdkBroadwayServer *server, | |||
409 | guint32 *toplevel, | |||
410 | gint32 *root_x, | |||
411 | gint32 *root_y, | |||
412 | guint32 *mask) | |||
413 | { | |||
414 | BroadwayRequestQueryMouse msg; | |||
415 | guint32 serial; | |||
416 | BroadwayReply *reply; | |||
417 | ||||
418 | serial = cdk_broadway_server_send_message (server, msg,cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_QUERY_MOUSE) | |||
419 | BROADWAY_REQUEST_QUERY_MOUSE)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_QUERY_MOUSE); | |||
420 | reply = cdk_broadway_server_wait_for_reply (server, serial); | |||
421 | ||||
422 | g_assert (reply->base.type == BROADWAY_REPLY_QUERY_MOUSE)do { if (reply->base.type == BROADWAY_REPLY_QUERY_MOUSE) ; else g_assertion_message_expr ("Cdk", "cdkbroadway-server.c" , 422, ((const char*) (__func__)), "reply->base.type == BROADWAY_REPLY_QUERY_MOUSE" ); } while (0); | |||
423 | ||||
424 | if (toplevel) | |||
425 | *toplevel = reply->query_mouse.toplevel; | |||
426 | if (root_x) | |||
427 | *root_x = reply->query_mouse.root_x; | |||
428 | if (root_y) | |||
429 | *root_y = reply->query_mouse.root_y; | |||
430 | if (mask) | |||
431 | *mask = reply->query_mouse.mask; | |||
432 | ||||
433 | g_free (reply); | |||
434 | } | |||
435 | ||||
436 | guint32 | |||
437 | _cdk_broadway_server_new_window (CdkBroadwayServer *server, | |||
438 | int x, | |||
439 | int y, | |||
440 | int width, | |||
441 | int height, | |||
442 | gboolean is_temp) | |||
443 | { | |||
444 | BroadwayRequestNewWindow msg; | |||
445 | guint32 serial, id; | |||
446 | BroadwayReply *reply; | |||
447 | ||||
448 | msg.x = x; | |||
449 | msg.y = y; | |||
450 | msg.width = width; | |||
451 | msg.height = height; | |||
452 | msg.is_temp = is_temp; | |||
453 | ||||
454 | serial = cdk_broadway_server_send_message (server, msg,cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_NEW_WINDOW) | |||
455 | BROADWAY_REQUEST_NEW_WINDOW)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_NEW_WINDOW); | |||
456 | reply = cdk_broadway_server_wait_for_reply (server, serial); | |||
457 | ||||
458 | g_assert (reply->base.type == BROADWAY_REPLY_NEW_WINDOW)do { if (reply->base.type == BROADWAY_REPLY_NEW_WINDOW) ; else g_assertion_message_expr ("Cdk", "cdkbroadway-server.c", 458 , ((const char*) (__func__)), "reply->base.type == BROADWAY_REPLY_NEW_WINDOW" ); } while (0); | |||
459 | ||||
460 | id = reply->new_window.id; | |||
461 | ||||
462 | g_free (reply); | |||
463 | ||||
464 | return id; | |||
465 | } | |||
466 | ||||
467 | void | |||
468 | _cdk_broadway_server_destroy_window (CdkBroadwayServer *server, | |||
469 | gint id) | |||
470 | { | |||
471 | BroadwayRequestDestroyWindow msg; | |||
472 | ||||
473 | msg.id = id; | |||
474 | cdk_broadway_server_send_message (server, msg,cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_DESTROY_WINDOW) | |||
475 | BROADWAY_REQUEST_DESTROY_WINDOW)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_DESTROY_WINDOW); | |||
476 | } | |||
477 | ||||
478 | gboolean | |||
479 | _cdk_broadway_server_window_show (CdkBroadwayServer *server, | |||
480 | gint id) | |||
481 | { | |||
482 | BroadwayRequestShowWindow msg; | |||
483 | ||||
484 | msg.id = id; | |||
485 | cdk_broadway_server_send_message (server, msg,cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_SHOW_WINDOW) | |||
486 | BROADWAY_REQUEST_SHOW_WINDOW)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_SHOW_WINDOW); | |||
487 | ||||
488 | return TRUE(!(0)); | |||
489 | } | |||
490 | ||||
491 | gboolean | |||
492 | _cdk_broadway_server_window_hide (CdkBroadwayServer *server, | |||
493 | gint id) | |||
494 | { | |||
495 | BroadwayRequestHideWindow msg; | |||
496 | ||||
497 | msg.id = id; | |||
498 | cdk_broadway_server_send_message (server, msg,cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_HIDE_WINDOW) | |||
499 | BROADWAY_REQUEST_HIDE_WINDOW)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_HIDE_WINDOW); | |||
500 | ||||
501 | return TRUE(!(0)); | |||
502 | } | |||
503 | ||||
504 | void | |||
505 | _cdk_broadway_server_window_focus (CdkBroadwayServer *server, | |||
506 | gint id) | |||
507 | { | |||
508 | BroadwayRequestFocusWindow msg; | |||
509 | ||||
510 | msg.id = id; | |||
511 | cdk_broadway_server_send_message (server, msg,cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_FOCUS_WINDOW) | |||
512 | BROADWAY_REQUEST_FOCUS_WINDOW)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_FOCUS_WINDOW); | |||
513 | } | |||
514 | ||||
515 | void | |||
516 | _cdk_broadway_server_window_set_transient_for (CdkBroadwayServer *server, | |||
517 | gint id, gint parent) | |||
518 | { | |||
519 | BroadwayRequestSetTransientFor msg; | |||
520 | ||||
521 | msg.id = id; | |||
522 | msg.parent = parent; | |||
523 | cdk_broadway_server_send_message (server, msg,cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_SET_TRANSIENT_FOR ) | |||
524 | BROADWAY_REQUEST_SET_TRANSIENT_FOR)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_SET_TRANSIENT_FOR ); | |||
525 | } | |||
526 | ||||
527 | static void * | |||
528 | map_named_shm (char *name, gsize size, gboolean *is_shm) | |||
529 | { | |||
530 | #ifdef G_OS_UNIX | |||
531 | ||||
532 | char *filename = NULL((void*)0); | |||
533 | int fd; | |||
534 | void *ptr; | |||
535 | int res; | |||
536 | ||||
537 | fd = shm_open(name, O_RDWR02|O_CREAT0100|O_EXCL0200, 0600); | |||
538 | if (fd == -1) | |||
| ||||
539 | { | |||
540 | if (errno(*__errno_location ()) == EEXIST17) | |||
541 | return NULL((void*)0); | |||
542 | ||||
543 | filename = g_build_filename (g_get_tmp_dir (), name, NULL((void*)0)); | |||
544 | ||||
545 | fd = open (filename, O_RDWR02 | O_CREAT0100 | O_EXCL0200, 0600); | |||
546 | g_free (filename); | |||
547 | if (fd == -1) | |||
548 | { | |||
549 | if (errno(*__errno_location ()) != EEXIST17) | |||
550 | g_error ("Unable to allocate shared mem for window"); | |||
551 | return NULL((void*)0); | |||
552 | } | |||
553 | else | |||
554 | *is_shm = FALSE(0); | |||
555 | } | |||
556 | else | |||
557 | *is_shm = TRUE(!(0)); | |||
558 | ||||
559 | res = ftruncate (fd, size); | |||
560 | g_assert (res != -1)do { if (res != -1) ; else g_assertion_message_expr ("Cdk", "cdkbroadway-server.c" , 560, ((const char*) (__func__)), "res != -1"); } while (0); | |||
561 | ||||
562 | #ifdef HAVE_POSIX_FALLOCATE1 | |||
563 | res = posix_fallocate (fd, 0, size); | |||
564 | if (res != 0 && errno(*__errno_location ()) == ENOSPC28) | |||
565 | { | |||
566 | if (filename
| |||
567 | unlink (filename); | |||
| ||||
568 | else | |||
569 | shm_unlink (name); | |||
570 | g_error ("Not enough shared memory for window surface"); | |||
571 | } | |||
572 | #endif | |||
573 | ||||
574 | ptr = mmap(0, size, PROT_READ0x1|PROT_WRITE0x2, MAP_SHARED0x01, fd, 0); | |||
575 | ||||
576 | (void) close(fd); | |||
577 | ||||
578 | return ptr; | |||
579 | ||||
580 | #elif defined(G_OS_WIN32) | |||
581 | ||||
582 | int fd; | |||
583 | void *ptr; | |||
584 | char *shmpath; | |||
585 | void *map = ((void *)-1); | |||
586 | int res; | |||
587 | ||||
588 | if (*name == '/') | |||
589 | ++name; | |||
590 | shmpath = g_build_filename (g_get_tmp_dir (), name, NULL((void*)0)); | |||
591 | ||||
592 | fd = open(shmpath, O_RDWR02|O_CREAT0100|O_EXCL0200, 0600); | |||
593 | g_free (shmpath); | |||
594 | if (fd == -1) | |||
595 | { | |||
596 | if (errno(*__errno_location ()) != EEXIST17) | |||
597 | g_error ("Unable to allocate shared mem for window"); | |||
598 | return NULL((void*)0); | |||
599 | } | |||
600 | ||||
601 | *is_shm = TRUE(!(0)); | |||
602 | res = ftruncate (fd, size); | |||
603 | g_assert (res != -1)do { if (res != -1) ; else g_assertion_message_expr ("Cdk", "cdkbroadway-server.c" , 603, ((const char*) (__func__)), "res != -1"); } while (0); | |||
604 | ||||
605 | if (size == 0) | |||
606 | ptr = map; | |||
607 | else | |||
608 | { | |||
609 | HANDLE h, fm; | |||
610 | h = (HANDLE)_get_osfhandle (fd); | |||
611 | fm = CreateFileMapping (h, NULL((void*)0), PAGE_READWRITE, 0, (DWORD)size, NULL((void*)0)); | |||
612 | ptr = MapViewOfFile (fm, FILE_MAP_WRITE, 0, 0, (size_t)size); | |||
613 | CloseHandle (fm); | |||
614 | } | |||
615 | ||||
616 | (void) close(fd); | |||
617 | ||||
618 | return ptr; | |||
619 | ||||
620 | #else | |||
621 | #error "No shm mapping supported" | |||
622 | ||||
623 | return NULL((void*)0); | |||
624 | #endif | |||
625 | } | |||
626 | ||||
627 | static char | |||
628 | make_valid_fs_char (char c) | |||
629 | { | |||
630 | char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890"; | |||
631 | ||||
632 | return chars[c % (sizeof (chars) - 1)]; | |||
633 | } | |||
634 | ||||
635 | /* name must have at least space for 34 bytes */ | |||
636 | static gpointer | |||
637 | create_random_shm (char *name, gsize size, gboolean *is_shm) | |||
638 | { | |||
639 | guint32 r; | |||
640 | int i, o; | |||
641 | gpointer ptr; | |||
642 | ||||
643 | while (TRUE(!(0))) | |||
644 | { | |||
645 | o = 0; | |||
646 | name[o++] = '/'; | |||
647 | name[o++] = 'b'; | |||
648 | name[o++] = 'd'; | |||
649 | name[o++] = 'w'; | |||
650 | name[o++] = '-'; | |||
651 | for (i = 0; i < 32/4 - 1; i++) | |||
652 | { | |||
653 | r = g_random_int (); | |||
654 | name[o++] = make_valid_fs_char ((r >> 0) & 0xff); | |||
655 | name[o++] = make_valid_fs_char ((r >> 8) & 0xff); | |||
656 | name[o++] = make_valid_fs_char ((r >> 16) & 0xff); | |||
657 | name[o++] = make_valid_fs_char ((r >> 24) & 0xff); | |||
658 | } | |||
659 | name[o++] = 0; | |||
660 | ||||
661 | ptr = map_named_shm (name, size, is_shm); | |||
662 | if (ptr) | |||
663 | return ptr; | |||
664 | } | |||
665 | } | |||
666 | ||||
667 | static const cairo_user_data_key_t cdk_broadway_shm_cairo_key; | |||
668 | ||||
669 | typedef struct { | |||
670 | char name[36]; | |||
671 | void *data; | |||
672 | gsize data_size; | |||
673 | gboolean is_shm; | |||
674 | } BroadwayShmSurfaceData; | |||
675 | ||||
676 | static void | |||
677 | shm_data_destroy (void *_data) | |||
678 | { | |||
679 | BroadwayShmSurfaceData *data = _data; | |||
680 | ||||
681 | #ifdef G_OS_UNIX | |||
682 | ||||
683 | munmap (data->data, data->data_size); | |||
684 | if (data->is_shm) | |||
685 | shm_unlink (data->name); | |||
686 | else | |||
687 | { | |||
688 | char *filename = g_build_filename (g_get_tmp_dir (), data->name, NULL((void*)0)); | |||
689 | unlink (filename); | |||
690 | g_free (filename); | |||
691 | } | |||
692 | ||||
693 | #elif defined(G_OS_WIN32) | |||
694 | ||||
695 | char *name = data->name; | |||
696 | char *shmpath; | |||
697 | ||||
698 | if (*name == '/') | |||
699 | ++name; | |||
700 | ||||
701 | shmpath = g_build_filename (g_get_tmp_dir (), name, NULL((void*)0)); | |||
702 | UnmapViewOfFile (data->data); | |||
703 | remove (shmpath); | |||
704 | g_free (shmpath); | |||
705 | ||||
706 | #endif | |||
707 | ||||
708 | g_free (data); | |||
709 | } | |||
710 | ||||
711 | cairo_surface_t * | |||
712 | _cdk_broadway_server_create_surface (int width, | |||
713 | int height) | |||
714 | { | |||
715 | BroadwayShmSurfaceData *data; | |||
716 | cairo_surface_t *surface; | |||
717 | ||||
718 | data = g_new (BroadwayShmSurfaceData, 1)((BroadwayShmSurfaceData *) g_malloc_n ((1), sizeof (BroadwayShmSurfaceData ))); | |||
719 | data->data_size = width * height * sizeof (guint32); | |||
720 | data->data = create_random_shm (data->name, data->data_size, &data->is_shm); | |||
721 | ||||
722 | surface = cairo_image_surface_create_for_data ((guchar *)data->data, | |||
723 | CAIRO_FORMAT_ARGB32, width, height, width * sizeof (guint32)); | |||
724 | g_assert (surface != NULL)do { if (surface != ((void*)0)) ; else g_assertion_message_expr ("Cdk", "cdkbroadway-server.c", 724, ((const char*) (__func__ )), "surface != NULL"); } while (0); | |||
725 | ||||
726 | cairo_surface_set_user_data (surface, &cdk_broadway_shm_cairo_key, | |||
727 | data, shm_data_destroy); | |||
728 | ||||
729 | return surface; | |||
730 | } | |||
731 | ||||
732 | void | |||
733 | _cdk_broadway_server_window_update (CdkBroadwayServer *server, | |||
734 | gint id, | |||
735 | cairo_surface_t *surface) | |||
736 | { | |||
737 | BroadwayRequestUpdate msg; | |||
738 | BroadwayShmSurfaceData *data; | |||
739 | ||||
740 | if (surface == NULL((void*)0)) | |||
741 | return; | |||
742 | ||||
743 | data = cairo_surface_get_user_data (surface, &cdk_broadway_shm_cairo_key); | |||
744 | g_assert (data != NULL)do { if (data != ((void*)0)) ; else g_assertion_message_expr ( "Cdk", "cdkbroadway-server.c", 744, ((const char*) (__func__) ), "data != NULL"); } while (0); | |||
745 | ||||
746 | msg.id = id; | |||
747 | memcpy (msg.name, data->name, 36); | |||
748 | msg.width = cairo_image_surface_get_width (surface); | |||
749 | msg.height = cairo_image_surface_get_height (surface); | |||
750 | ||||
751 | cdk_broadway_server_send_message (server, msg,cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_UPDATE) | |||
752 | BROADWAY_REQUEST_UPDATE)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_UPDATE); | |||
753 | } | |||
754 | ||||
755 | gboolean | |||
756 | _cdk_broadway_server_window_move_resize (CdkBroadwayServer *server, | |||
757 | gint id, | |||
758 | gboolean with_move, | |||
759 | int x, | |||
760 | int y, | |||
761 | int width, | |||
762 | int height) | |||
763 | { | |||
764 | BroadwayRequestMoveResize msg; | |||
765 | ||||
766 | msg.id = id; | |||
767 | msg.with_move = with_move; | |||
768 | msg.x = x; | |||
769 | msg.y = y; | |||
770 | msg.width = width; | |||
771 | msg.height = height; | |||
772 | ||||
773 | cdk_broadway_server_send_message (server, msg,cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_MOVE_RESIZE) | |||
774 | BROADWAY_REQUEST_MOVE_RESIZE)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_MOVE_RESIZE); | |||
775 | ||||
776 | return TRUE(!(0)); | |||
777 | } | |||
778 | ||||
779 | CdkGrabStatus | |||
780 | _cdk_broadway_server_grab_pointer (CdkBroadwayServer *server, | |||
781 | gint id, | |||
782 | gboolean owner_events, | |||
783 | guint32 event_mask, | |||
784 | guint32 time_) | |||
785 | { | |||
786 | BroadwayRequestGrabPointer msg; | |||
787 | guint32 serial, status; | |||
788 | BroadwayReply *reply; | |||
789 | ||||
790 | msg.id = id; | |||
791 | msg.owner_events = owner_events; | |||
792 | msg.event_mask = event_mask; | |||
793 | msg.time_ = time_; | |||
794 | ||||
795 | serial = cdk_broadway_server_send_message (server, msg,cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_GRAB_POINTER) | |||
796 | BROADWAY_REQUEST_GRAB_POINTER)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_GRAB_POINTER); | |||
797 | reply = cdk_broadway_server_wait_for_reply (server, serial); | |||
798 | ||||
799 | g_assert (reply->base.type == BROADWAY_REPLY_GRAB_POINTER)do { if (reply->base.type == BROADWAY_REPLY_GRAB_POINTER) ; else g_assertion_message_expr ("Cdk", "cdkbroadway-server.c" , 799, ((const char*) (__func__)), "reply->base.type == BROADWAY_REPLY_GRAB_POINTER" ); } while (0); | |||
800 | ||||
801 | status = reply->grab_pointer.status; | |||
802 | ||||
803 | g_free (reply); | |||
804 | ||||
805 | return status; | |||
806 | } | |||
807 | ||||
808 | guint32 | |||
809 | _cdk_broadway_server_ungrab_pointer (CdkBroadwayServer *server, | |||
810 | guint32 time_) | |||
811 | { | |||
812 | BroadwayRequestUngrabPointer msg; | |||
813 | guint32 serial, status; | |||
814 | BroadwayReply *reply; | |||
815 | ||||
816 | msg.time_ = time_; | |||
817 | ||||
818 | serial = cdk_broadway_server_send_message (server, msg,cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_UNGRAB_POINTER) | |||
819 | BROADWAY_REQUEST_UNGRAB_POINTER)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_UNGRAB_POINTER); | |||
820 | reply = cdk_broadway_server_wait_for_reply (server, serial); | |||
821 | ||||
822 | g_assert (reply->base.type == BROADWAY_REPLY_UNGRAB_POINTER)do { if (reply->base.type == BROADWAY_REPLY_UNGRAB_POINTER ) ; else g_assertion_message_expr ("Cdk", "cdkbroadway-server.c" , 822, ((const char*) (__func__)), "reply->base.type == BROADWAY_REPLY_UNGRAB_POINTER" ); } while (0); | |||
823 | ||||
824 | status = reply->ungrab_pointer.status; | |||
825 | ||||
826 | g_free (reply); | |||
827 | ||||
828 | return status; | |||
829 | } | |||
830 | ||||
831 | void | |||
832 | _cdk_broadway_server_set_show_keyboard (CdkBroadwayServer *server, | |||
833 | gboolean show) | |||
834 | { | |||
835 | BroadwayRequestSetShowKeyboard msg; | |||
836 | ||||
837 | msg.show_keyboard = show; | |||
838 | cdk_broadway_server_send_message (server, msg,cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_SET_SHOW_KEYBOARD ) | |||
839 | BROADWAY_REQUEST_SET_SHOW_KEYBOARD)cdk_broadway_server_send_message_with_size(server, (BroadwayRequestBase *)&msg, sizeof (msg), BROADWAY_REQUEST_SET_SHOW_KEYBOARD ); | |||
840 | } |