Bug Summary

File:cdk/broadway/cdkbroadway-server.c
Warning:line 567, column 2
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cdkbroadway-server.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/cdk/broadway -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../.. -D G_LOG_DOMAIN="Cdk" -D G_LOG_USE_STRUCTURED=1 -D CDK_COMPILATION -D CDK_DISABLE_DEPRECATION_WARNINGS -I ../.. -I ../../cdk -I ../../cdk -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/cdk/broadway -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-09-19-171502-43637-1 -x c cdkbroadway-server.c
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
33typedef struct BroadwayInput BroadwayInput;
34
35struct _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
49struct _CdkBroadwayServerClass
50{
51 GObjectClass parent_class;
52};
53
54static gboolean input_available_cb (gpointer stream, gpointer user_data);
55
56static GType cdk_broadway_server_get_type (void);
57
58G_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
60static void
61cdk_broadway_server_init (CdkBroadwayServer *server)
62{
63 server->next_serial = 1;
64}
65
66static void
67cdk_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
72static void
73cdk_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
80gboolean
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
88gulong
89_cdk_broadway_server_get_next_serial (CdkBroadwayServer *server)
90{
91 return (gulong)server->next_serial;
92}
93
94CdkBroadwayServer *
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
173guint32
174_cdk_broadway_server_get_last_seen_time (CdkBroadwayServer *server G_GNUC_UNUSED__attribute__ ((__unused__)))
175{
176 return 0;
177}
178
179static guint32
180cdk_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
206static void
207parse_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
233static void
234read_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
255static void
256read_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
286static BroadwayReply *
287find_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
302static void
303process_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
328static gboolean
329process_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
336static void
337queue_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
344static gboolean
345input_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
358static BroadwayReply *
359cdk_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
381void
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
389void
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
407void
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
436guint32
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
467void
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
478gboolean
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
491gboolean
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
504void
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
515void
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
527static void *
528map_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)
1
Assuming the condition is true
2
Taking true branch
539 {
540 if (errno(*__errno_location ()) == EEXIST17)
3
Assuming the condition is false
4
Taking false branch
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);
5
Memory is released
547 if (fd == -1)
6
Assuming the condition is false
7
Taking false branch
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)
;
8
Assuming the condition is true
9
Taking true branch
10
Loop condition is false. Exiting loop
561
562#ifdef HAVE_POSIX_FALLOCATE1
563 res = posix_fallocate (fd, 0, size);
564 if (res != 0 && errno(*__errno_location ()) == ENOSPC28)
11
Assuming 'res' is not equal to 0
12
Assuming the condition is true
13
Taking true branch
565 {
566 if (filename
13.1
'filename' is non-null
)
14
Taking true branch
567 unlink (filename);
15
Use of memory after it is freed
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
627static char
628make_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 */
636static gpointer
637create_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
667static const cairo_user_data_key_t cdk_broadway_shm_cairo_key;
668
669typedef struct {
670 char name[36];
671 void *data;
672 gsize data_size;
673 gboolean is_shm;
674} BroadwayShmSurfaceData;
675
676static void
677shm_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
711cairo_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
732void
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
755gboolean
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
779CdkGrabStatus
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
808guint32
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
831void
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}