Bug Summary

File:demos/ctk-demo/main.c
Warning:line 430, column 15
Out of bound memory access (access exceeds upper limit of memory block)

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 main.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 -pic-is-pie -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/demos/ctk-demo -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../.. -I ../.. -I ../../cdk -D CDK_DISABLE_DEPRECATED -D CTK_DISABLE_DEPRECATED -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/atk-1.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gio-unix-2.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -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/pango-1.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -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/demos/ctk-demo -ferror-limit 19 -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-171836-43636-1 -x c main.c
1#include <errno(*__errno_location ()).h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5
6#include "config.h"
7
8#include <ctk/ctk.h>
9#include <glib/gstdio.h>
10
11#include "demos.h"
12
13static CtkWidget *info_view;
14static CtkWidget *source_view;
15
16static gchar *current_file = NULL((void*)0);
17
18static CtkWidget *notebook;
19static CtkWidget *treeview;
20static CtkWidget *headerbar;
21
22enum {
23 NAME_COLUMN,
24 TITLE_COLUMN,
25 FILENAME_COLUMN,
26 FUNC_COLUMN,
27 STYLE_COLUMN,
28 NUM_COLUMNS
29};
30
31typedef struct _CallbackData CallbackData;
32struct _CallbackData
33{
34 CtkTreeModel *model;
35 CtkTreePath *path;
36};
37
38static void
39activate_about (GSimpleAction *action,
40 GVariant *parameter,
41 gpointer user_data)
42{
43 CtkApplication *app = user_data;
44 const gchar *authors[] = {
45 "The CTK+ Team",
46 NULL((void*)0)
47 };
48
49 ctk_show_about_dialog (CTK_WINDOW (ctk_application_get_active_window (app))((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_application_get_active_window (app))), ((ctk_window_get_type
()))))))
,
50 "program-name", "CTK+ Demo",
51 "version", g_strdup_printf ("%s,\nRunning against CTK+ %d.%d.%d",
52 PACKAGE_VERSION"3.25.5",
53 ctk_get_major_version (),
54 ctk_get_minor_version (),
55 ctk_get_micro_version ()),
56 "copyright", "(C) 1997-2013 The CTK+ Team",
57 "license-type", CTK_LICENSE_LGPL_2_1,
58 "website", "http://github.com/cafe-desktop/ctk",
59 "comments", "Program to demonstrate CTK+ widgets",
60 "authors", authors,
61 "logo-icon-name", "ctk3-demo",
62 "title", "About CTK+ Demo",
63 NULL((void*)0));
64}
65
66static void
67activate_quit (GSimpleAction *action,
68 GVariant *parameter,
69 gpointer user_data)
70{
71 CtkApplication *app = user_data;
72 GList *list, *next;
73
74 list = ctk_application_get_windows (app);
75 while (list)
76 {
77 CtkWidget *win;
78
79 win = list->data;
80 next = list->next;
81
82 ctk_widget_destroy (CTK_WIDGET (win)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((win)), ((ctk_widget_get_type ()))))))
);
83
84 list = next;
85 }
86}
87
88static void
89window_closed_cb (CtkWidget *window, gpointer data)
90{
91 CallbackData *cbdata = data;
92 CtkTreeIter iter;
93 PangoStyle style;
94
95 ctk_tree_model_get_iter (cbdata->model, &iter, cbdata->path);
96 ctk_tree_model_get (CTK_TREE_MODEL (cbdata->model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cbdata->model)), ((ctk_tree_model_get_type ()))))))
, &iter,
97 STYLE_COLUMN, &style,
98 -1);
99 if (style == PANGO_STYLE_ITALIC)
100 ctk_tree_store_set (CTK_TREE_STORE (cbdata->model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((cbdata->model)), ((ctk_tree_store_get_type ()))))))
, &iter,
101 STYLE_COLUMN, PANGO_STYLE_NORMAL,
102 -1);
103
104 ctk_tree_path_free (cbdata->path);
105 g_free (cbdata);
106}
107
108static void
109run_example_for_row (CtkWidget *window,
110 CtkTreeModel *model,
111 CtkTreeIter *iter)
112{
113 PangoStyle style;
114 GDoDemoFunc func;
115
116 ctk_tree_model_get (CTK_TREE_MODEL (model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((model)), ((ctk_tree_model_get_type ()))))))
,
117 iter,
118 FUNC_COLUMN, &func,
119 STYLE_COLUMN, &style,
120 -1);
121
122 if (func)
123 {
124 CtkWidget *demo;
125
126 ctk_tree_store_set (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((model)), ((ctk_tree_store_get_type ()))))))
,
127 iter,
128 STYLE_COLUMN, (style == PANGO_STYLE_ITALIC ? PANGO_STYLE_NORMAL : PANGO_STYLE_ITALIC),
129 -1);
130 demo = (func) (window);
131
132 if (demo != NULL((void*)0))
133 {
134 CallbackData *cbdata;
135
136 cbdata = g_new (CallbackData, 1)((CallbackData *) g_malloc_n ((1), sizeof (CallbackData)));
137 cbdata->model = model;
138 cbdata->path = ctk_tree_model_get_path (model, iter);
139
140 if (ctk_widget_is_toplevel (demo))
141 {
142 ctk_window_set_transient_for (CTK_WINDOW (demo)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((demo)), ((ctk_window_get_type ()))))))
, CTK_WINDOW (window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_window_get_type ()))))))
);
143 ctk_window_set_modal (CTK_WINDOW (demo)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((demo)), ((ctk_window_get_type ()))))))
, TRUE(!(0)));
144 }
145
146 g_signal_connect (demo, "destroy",g_signal_connect_data ((demo), ("destroy"), (((GCallback) (window_closed_cb
))), (cbdata), ((void*)0), (GConnectFlags) 0)
147 G_CALLBACK (window_closed_cb), cbdata)g_signal_connect_data ((demo), ("destroy"), (((GCallback) (window_closed_cb
))), (cbdata), ((void*)0), (GConnectFlags) 0)
;
148 }
149 }
150}
151
152static void
153activate_run (GSimpleAction *action,
154 GVariant *parameter,
155 gpointer user_data)
156{
157 CtkTreeSelection *selection;
158 CtkTreeModel *model;
159 CtkTreeIter iter;
160
161 selection = ctk_tree_view_get_selection (CTK_TREE_VIEW (treeview)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((treeview)), ((ctk_tree_view_get_type ()))))))
);
162
163 if (ctk_tree_selection_get_selected (selection, &model, &iter)) {
164 CtkWidget *window = user_data;
165 run_example_for_row (window, model, &iter);
166 }
167}
168
169/* Stupid syntax highlighting.
170 *
171 * No regex was used in the making of this highlighting.
172 * It should only work for simple cases. This is good, as
173 * that's all we should have in the demos.
174 */
175/* This code should not be used elsewhere, except perhaps as an example of how
176 * to iterate through a text buffer.
177 */
178enum {
179 STATE_NORMAL,
180 STATE_IN_COMMENT
181};
182
183static gchar *tokens[] =
184{
185 "/*",
186 "\"",
187 NULL((void*)0)
188};
189
190static gchar *types[] =
191{
192 "static",
193 "const ",
194 "void",
195 "gint",
196 " int ",
197 " char ",
198 "gchar ",
199 "gfloat",
200 "float",
201 "double",
202 "gint8",
203 "gint16",
204 "gint32",
205 "guint",
206 "guint8",
207 "guint16",
208 "guint32",
209 "guchar",
210 "glong",
211 "gboolean" ,
212 "gshort",
213 "gushort",
214 "gulong",
215 "gdouble",
216 "gldouble",
217 "gpointer",
218 "NULL",
219 "GList",
220 "GSList",
221 "FALSE",
222 "TRUE",
223 "FILE ",
224 "CtkColorSelection ",
225 "CtkWidget ",
226 "CtkButton ",
227 "CdkColor ",
228 "CdkRectangle ",
229 "CdkEventExpose ",
230 "CdkGC ",
231 "GdkPixbufLoader ",
232 "GdkPixbuf ",
233 "GError",
234 "size_t",
235 "CtkAboutDialog ",
236 "CtkAction ",
237 "CtkActionEntry ",
238 "CtkRadioActionEntry ",
239 "CtkIconFactory ",
240 "CtkIconSet ",
241 "CtkTextBuffer ",
242 "CtkStatusbar ",
243 "CtkTextIter ",
244 "CtkTextMark ",
245 "CdkEventWindowState ",
246 "CtkActionGroup ",
247 "CtkUIManager ",
248 "CtkRadioAction ",
249 "CtkActionClass ",
250 "CtkToggleActionEntry ",
251 "CtkAssistant ",
252 "CtkBuilder ",
253 "CtkSizeGroup ",
254 "CtkTreeModel ",
255 "CtkTreeSelection ",
256 "CdkDisplay ",
257 "CdkScreen ",
258 "CdkWindow ",
259 "CdkEventButton ",
260 "CdkCursor ",
261 "CtkTreeIter ",
262 "CtkTreeViewColumn ",
263 "CdkDisplayManager ",
264 "CtkClipboard ",
265 "CtkIconSize ",
266 "CtkImage ",
267 "CdkDragContext ",
268 "CtkSelectionData ",
269 "CtkDialog ",
270 "CtkMenuItem ",
271 "CtkListStore ",
272 "CtkCellLayout ",
273 "CtkCellRenderer ",
274 "CtkTreePath ",
275 "CtkTreeStore ",
276 "CtkEntry ",
277 "CtkEditable ",
278 "CtkEditableInterface ",
279 "CdkPixmap ",
280 "CdkEventConfigure ",
281 "CdkEventMotion ",
282 "CdkModifierType ",
283 "CtkEntryCompletion ",
284 "CtkToolItem ",
285 "GDir ",
286 "CtkIconView ",
287 "CtkCellRendererText ",
288 "CtkContainer ",
289 "CtkAccelGroup ",
290 "CtkPaned ",
291 "CtkPrintOperation ",
292 "CtkPrintContext ",
293 "cairo_t ",
294 "PangoLayout "
295 "PangoFontDescription ",
296 "PangoRenderer ",
297 "PangoMatrix ",
298 "PangoContext ",
299 "PangoLayout ",
300 "CtkTable ",
301 "CtkToggleButton ",
302 "GString ",
303 "CtkIconSize ",
304 "CtkTreeView ",
305 "CtkTextTag ",
306 "CdkEvent ",
307 "CdkEventKey ",
308 "CtkTextView ",
309 "CdkEventVisibility ",
310 "CdkBitmap ",
311 "CtkTextChildAnchor ",
312 "GArray ",
313 "CtkCellEditable ",
314 "CtkCellRendererToggle ",
315 NULL((void*)0)
316};
317
318static gchar *control[] =
319{
320 " if ",
321 " while ",
322 " else",
323 " do ",
324 " for ",
325 "?",
326 ":",
327 "return ",
328 "goto ",
329 NULL((void*)0)
330};
331void
332parse_chars (gchar *text,
333 gchar **end_ptr,
334 gint *state,
335 gchar **tag,
336 gboolean start)
337{
338 gint i;
339 gchar *next_token;
340
341 /* Handle comments first */
342 if (*state == STATE_IN_COMMENT)
14
Taking false branch
343 {
344 *end_ptr = strstr (text, "*/");
345 if (*end_ptr)
346 {
347 *end_ptr += 2;
348 *state = STATE_NORMAL;
349 *tag = "comment";
350 }
351 return;
352 }
353
354 *tag = NULL((void*)0);
355 *end_ptr = NULL((void*)0);
356
357 /* check for comment */
358 if (!strncmp (text, "/*", 2))
15
Assuming the condition is false
359 {
360 *end_ptr = strstr (text, "*/");
361 if (*end_ptr)
362 *end_ptr += 2;
363 else
364 *state = STATE_IN_COMMENT;
365 *tag = "comment";
366 return;
367 }
368
369 /* check for preprocessor defines */
370 if (*text == '#' && start)
16
Assuming the condition is false
371 {
372 *end_ptr = NULL((void*)0);
373 *tag = "preprocessor";
374 return;
375 }
376
377 /* functions */
378 if (start
16.1
'start' is 1
&& * text != '\t' && *text != ' ' && *text != '{' && *text != '}')
17
Assuming the condition is false
379 {
380 if (strstr (text, "("))
381 {
382 *end_ptr = strstr (text, "(");
383 *tag = "function";
384 return;
385 }
386 }
387 /* check for types */
388 for (i = 0; types[i] != NULL((void*)0); i++)
18
Assuming the condition is false
19
Loop condition is false. Execution continues on line 398
389 if (!strncmp (text, types[i], strlen (types[i])) ||
390 (start && types[i][0] == ' ' && !strncmp (text, types[i] + 1, strlen (types[i]) - 1)))
391 {
392 *end_ptr = text + strlen (types[i]);
393 *tag = "type";
394 return;
395 }
396
397 /* check for control */
398 for (i = 0; control[i] != NULL((void*)0); i++)
20
Assuming the condition is false
21
Loop condition is false. Execution continues on line 407
399 if (!strncmp (text, control[i], strlen (control[i])))
400 {
401 *end_ptr = text + strlen (control[i]);
402 *tag = "control";
403 return;
404 }
405
406 /* check for string */
407 if (text[0] == '"')
22
Taking false branch
408 {
409 gint maybe_escape = FALSE(0);
410
411 *end_ptr = text + 1;
412 *tag = "string";
413 while (**end_ptr != '\000')
414 {
415 if (**end_ptr == '\"' && !maybe_escape)
416 {
417 *end_ptr += 1;
418 return;
419 }
420 if (**end_ptr == '\\')
421 maybe_escape = TRUE(!(0));
422 else
423 maybe_escape = FALSE(0);
424 *end_ptr += 1;
425 }
426 return;
427 }
428
429 /* not at the start of a tag. Find the next one. */
430 for (i = 0; tokens[i] != NULL((void*)0); i++)
23
Assuming the condition is true
24
Loop condition is true. Entering loop body
27
Assuming the condition is true
28
Loop condition is true. Entering loop body
31
Assuming the condition is true
32
Loop condition is true. Entering loop body
35
Out of bound memory access (access exceeds upper limit of memory block)
431 {
432 next_token = strstr (text, tokens[i]);
433 if (next_token)
25
Assuming 'next_token' is null
26
Taking false branch
29
Assuming 'next_token' is null
30
Taking false branch
33
Assuming 'next_token' is null
34
Taking false branch
434 {
435 if (*end_ptr)
436 *end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;
437 else
438 *end_ptr = next_token;
439 }
440 }
441
442 for (i = 0; types[i] != NULL((void*)0); i++)
443 {
444 next_token = strstr (text, types[i]);
445 if (next_token)
446 {
447 if (*end_ptr)
448 *end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;
449 else
450 *end_ptr = next_token;
451 }
452 }
453
454 for (i = 0; control[i] != NULL((void*)0); i++)
455 {
456 next_token = strstr (text, control[i]);
457 if (next_token)
458 {
459 if (*end_ptr)
460 *end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;
461 else
462 *end_ptr = next_token;
463 }
464 }
465}
466
467/* While not as cool as c-mode, this will do as a quick attempt at highlighting */
468static void
469fontify (CtkTextBuffer *source_buffer)
470{
471 CtkTextIter start_iter, next_iter, tmp_iter;
472 gint state;
473 gchar *text;
474 gchar *tag;
475
476 ctk_text_buffer_create_tag (source_buffer, "source",
477 "font", "monospace",
478 NULL((void*)0));
479 ctk_text_buffer_create_tag (source_buffer, "comment",
480 "foreground", "DodgerBlue",
481 NULL((void*)0));
482 ctk_text_buffer_create_tag (source_buffer, "type",
483 "foreground", "ForestGreen",
484 NULL((void*)0));
485 ctk_text_buffer_create_tag (source_buffer, "string",
486 "foreground", "RosyBrown",
487 "weight", PANGO_WEIGHT_BOLD,
488 NULL((void*)0));
489 ctk_text_buffer_create_tag (source_buffer, "control",
490 "foreground", "purple",
491 NULL((void*)0));
492 ctk_text_buffer_create_tag (source_buffer, "preprocessor",
493 "style", PANGO_STYLE_OBLIQUE,
494 "foreground", "burlywood4",
495 NULL((void*)0));
496 ctk_text_buffer_create_tag (source_buffer, "function",
497 "weight", PANGO_WEIGHT_BOLD,
498 "foreground", "DarkGoldenrod4",
499 NULL((void*)0));
500
501 ctk_text_buffer_get_bounds (source_buffer, &start_iter, &tmp_iter);
502 ctk_text_buffer_apply_tag_by_name (source_buffer, "source", &start_iter, &tmp_iter);
503
504 state = STATE_NORMAL;
505
506 ctk_text_buffer_get_iter_at_offset (source_buffer, &start_iter, 0);
507
508 next_iter = start_iter;
509 while (ctk_text_iter_forward_line (&next_iter))
12
Loop condition is true. Entering loop body
510 {
511 gchar *start_ptr, *end_ptr;
512 gboolean start = TRUE(!(0));
513
514 start_ptr = text = ctk_text_iter_get_text (&start_iter, &next_iter);
515
516 do
517 {
518 parse_chars (start_ptr, &end_ptr, &state, &tag, start);
13
Calling 'parse_chars'
519
520 start = FALSE(0);
521 if (end_ptr)
522 {
523 tmp_iter = start_iter;
524 ctk_text_iter_forward_chars (&tmp_iter, end_ptr - start_ptr);
525 }
526 else
527 {
528 tmp_iter = next_iter;
529 }
530 if (tag)
531 ctk_text_buffer_apply_tag_by_name (source_buffer, tag, &start_iter, &tmp_iter);
532
533 start_iter = tmp_iter;
534 start_ptr = end_ptr;
535 }
536 while (end_ptr);
537
538 g_free (text);
539 start_iter = next_iter;
540 }
541}
542
543static CtkWidget *create_text (CtkWidget **text_view, gboolean is_source);
544
545static void
546add_data_tab (const gchar *demoname)
547{
548 gchar *resource_dir;
549 gchar **resources;
550 guint i;
551
552 resource_dir = g_strconcat ("/", demoname, NULL((void*)0));
553 resources = g_resources_enumerate_children (resource_dir, 0, NULL((void*)0));
554 if (resources == NULL((void*)0))
555 {
556 g_free (resource_dir);
557 return;
558 }
559
560 for (i = 0; resources[i]; i++)
561 {
562 gchar *resource_name;
563 CtkWidget *widget, *label;
564
565 resource_name = g_strconcat (resource_dir, "/", resources[i], NULL((void*)0));
566
567 widget = ctk_image_new_from_resource (resource_name);
568 if (ctk_image_get_pixbuf (CTK_IMAGE (widget)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_image_get_type ()))))))
) == NULL((void*)0) &&
569 ctk_image_get_animation (CTK_IMAGE (widget)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_image_get_type ()))))))
) == NULL((void*)0))
570 {
571 GBytes *bytes;
572
573 /* So we've used the best API available to figure out it's
574 * not an image. Let's try something else then.
575 */
576 g_object_ref_sink (widget)((__typeof__ (widget)) (g_object_ref_sink) (widget));
577 g_object_unref (widget);
578
579 bytes = g_resources_lookup_data (resource_name, 0, NULL((void*)0));
580 g_assert (bytes)do { if (bytes) ; else g_assertion_message_expr (((gchar*) 0)
, "main.c", 580, ((const char*) (__func__)), "bytes"); } while
(0)
;
581
582 if (g_utf8_validate (g_bytes_get_data (bytes, NULL((void*)0)), g_bytes_get_size (bytes), NULL((void*)0)))
583 {
584 /* Looks like it parses as text. Dump it into a textview then! */
585 CtkTextBuffer *buffer;
586 CtkWidget *textview;
587
588 widget = create_text (&textview, FALSE(0));
589 buffer = ctk_text_buffer_new (NULL((void*)0));
590 ctk_text_buffer_set_text (buffer, g_bytes_get_data (bytes, NULL((void*)0)), g_bytes_get_size (bytes));
591 if (g_str_has_suffix (resource_name, ".c")(__builtin_constant_p (".c")? __extension__ ({ const char * const
__str = (resource_name); const char * const __suffix = (".c"
); gboolean __result = (0); if (__str == ((void*)0) || __suffix
== ((void*)0)) __result = (g_str_has_suffix) (__str, __suffix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix
))); if (__str_len >= __suffix_len) __result = memcmp (__str
+ __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len
) == 0; } __result; }) : (g_str_has_suffix) (resource_name, ".c"
) )
)
592 fontify (buffer);
593 ctk_text_view_set_buffer (CTK_TEXT_VIEW (textview)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((textview)), ((ctk_text_view_get_type ()))))))
, buffer);
594 }
595 else
596 {
597 g_warning ("Don't know how to display resource '%s'", resource_name);
598 widget = NULL((void*)0);
599 }
600
601 g_bytes_unref (bytes);
602 }
603
604 ctk_widget_show_all (widget);
605 label = ctk_label_new (resources[i]);
606 ctk_widget_show (label);
607 ctk_notebook_append_page (CTK_NOTEBOOK (notebook)((((CtkNotebook*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((notebook)), ((ctk_notebook_get_type ()))))))
, widget, label);
608 ctk_container_child_set (CTK_CONTAINER (notebook)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((notebook)), ((ctk_container_get_type ()))))))
,
609 CTK_WIDGET (widget)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((widget)), ((ctk_widget_get_type ()))))))
,
610 "tab-expand", TRUE(!(0)),
611 NULL((void*)0));
612
613 g_free (resource_name);
614 }
615
616 g_strfreev (resources);
617 g_free (resource_dir);
618}
619
620static void
621remove_data_tabs (void)
622{
623 gint i;
624
625 for (i = ctk_notebook_get_n_pages (CTK_NOTEBOOK (notebook)((((CtkNotebook*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((notebook)), ((ctk_notebook_get_type ()))))))
) - 1; i > 1; i--)
626 ctk_notebook_remove_page (CTK_NOTEBOOK (notebook)((((CtkNotebook*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((notebook)), ((ctk_notebook_get_type ()))))))
, i);
627}
628
629void
630load_file (const gchar *demoname,
631 const gchar *filename)
632{
633 CtkTextBuffer *info_buffer, *source_buffer;
634 CtkTextIter start, end;
635 char *resource_filename;
636 GError *err = NULL((void*)0);
637 int state = 0;
638 gboolean in_para = 0;
639 gchar **lines;
640 GBytes *bytes;
641 gint i;
642
643 if (!g_strcmp0 (current_file, filename))
5
Assuming the condition is false
6
Taking false branch
644 return;
645
646 remove_data_tabs ();
647
648 add_data_tab (demoname);
649
650 g_free (current_file);
651 current_file = g_strdup (filename)g_strdup_inline (filename);
652
653 info_buffer = ctk_text_buffer_new (NULL((void*)0));
654 ctk_text_buffer_create_tag (info_buffer, "title",
655 "font", "Sans 18",
656 "pixels-below-lines", 10,
657 NULL((void*)0));
658
659 source_buffer = ctk_text_buffer_new (NULL((void*)0));
660
661 resource_filename = g_strconcat ("/sources/", filename, NULL((void*)0));
662 bytes = g_resources_lookup_data (resource_filename, 0, &err);
663 g_free (resource_filename);
664
665 if (bytes == NULL((void*)0))
7
Assuming 'bytes' is not equal to NULL
8
Taking false branch
666 {
667 g_warning ("Cannot open source for %s: %s", filename, err->message);
668 g_error_free (err);
669 return;
670 }
671
672 lines = g_strsplit (g_bytes_get_data (bytes, NULL((void*)0)), "\n", -1);
673 g_bytes_unref (bytes);
674
675 ctk_text_buffer_get_iter_at_offset (info_buffer, &start, 0);
676 for (i = 0; lines[i] != NULL((void*)0); i++)
9
Assuming the condition is false
10
Loop condition is false. Execution continues on line 789
677 {
678 gchar *p;
679 gchar *q;
680 gchar *r;
681
682 /* Make sure \r is stripped at the end for the poor windows people */
683 lines[i] = g_strchomp (lines[i]);
684
685 p = lines[i];
686 switch (state)
687 {
688 case 0:
689 /* Reading title */
690 while (*p == '/' || *p == '*' || g_ascii_isspace (*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_SPACE) != 0))
691 p++;
692 r = p;
693 while (*r != '\0')
694 {
695 while (*r != '/' && *r != ':' && *r != '\0')
696 r++;
697 if (*r == '/')
698 {
699 r++;
700 p = r;
701 }
702 if (r[0] == ':' && r[1] == ':')
703 *r = '\0';
704 }
705 q = p + strlen (p);
706 while (q > p && g_ascii_isspace (*(q - 1))((g_ascii_table[(guchar) (*(q - 1))] & G_ASCII_SPACE) != 0
)
)
707 q--;
708
709
710 if (q > p)
711 {
712 int len_chars = g_utf8_pointer_to_offset (p, q);
713
714 end = start;
715
716 g_assert (strlen (p) >= q - p)do { if (strlen (p) >= q - p) ; else g_assertion_message_expr
(((gchar*) 0), "main.c", 716, ((const char*) (__func__)), "strlen (p) >= q - p"
); } while (0)
;
717 ctk_text_buffer_insert (info_buffer, &end, p, q - p);
718 start = end;
719
720 ctk_text_iter_backward_chars (&start, len_chars);
721 ctk_text_buffer_apply_tag_by_name (info_buffer, "title", &start, &end);
722
723 start = end;
724
725 while (*p && *p != '\n') p++;
726
727 state++;
728 }
729 break;
730
731 case 1:
732 /* Reading body of info section */
733 while (g_ascii_isspace (*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_SPACE) != 0))
734 p++;
735 if (*p == '*' && *(p + 1) == '/')
736 {
737 ctk_text_buffer_get_iter_at_offset (source_buffer, &start, 0);
738 state++;
739 }
740 else
741 {
742 int len;
743
744 while (*p == '*' || g_ascii_isspace (*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_SPACE) != 0))
745 p++;
746
747 len = strlen (p);
748 while (g_ascii_isspace (*(p + len - 1))((g_ascii_table[(guchar) (*(p + len - 1))] & G_ASCII_SPACE
) != 0)
)
749 len--;
750
751 if (len > 0)
752 {
753 if (in_para)
754 ctk_text_buffer_insert (info_buffer, &start, " ", 1);
755
756 g_assert (strlen (p) >= len)do { if (strlen (p) >= len) ; else g_assertion_message_expr
(((gchar*) 0), "main.c", 756, ((const char*) (__func__)), "strlen (p) >= len"
); } while (0)
;
757 ctk_text_buffer_insert (info_buffer, &start, p, len);
758 in_para = 1;
759 }
760 else
761 {
762 ctk_text_buffer_insert (info_buffer, &start, "\n", 1);
763 in_para = 0;
764 }
765 }
766 break;
767
768 case 2:
769 /* Skipping blank lines */
770 while (g_ascii_isspace (*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_SPACE) != 0))
771 p++;
772
773 if (!*p)
774 break;
775
776 p = lines[i];
777 state++;
778 /* Fall through */
779
780 case 3:
781 /* Reading program body */
782 ctk_text_buffer_insert (source_buffer, &start, p, -1);
783 if (lines[i+1] != NULL((void*)0))
784 ctk_text_buffer_insert (source_buffer, &start, "\n", 1);
785 break;
786 }
787 }
788
789 g_strfreev (lines);
790
791 fontify (source_buffer);
11
Calling 'fontify'
792
793 ctk_text_view_set_buffer (CTK_TEXT_VIEW (source_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((source_view)), ((ctk_text_view_get_type ()))))))
, source_buffer);
794 g_object_unref (source_buffer);
795
796 ctk_text_view_set_buffer (CTK_TEXT_VIEW (info_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((info_view)), ((ctk_text_view_get_type ()))))))
, info_buffer);
797 g_object_unref (info_buffer);
798}
799
800static void
801selection_cb (CtkTreeSelection *selection,
802 CtkTreeModel *model)
803{
804 CtkTreeIter iter;
805 char *name;
806 char *filename;
807 char *title;
808
809 if (! ctk_tree_selection_get_selected (selection, NULL((void*)0), &iter))
810 return;
811
812 ctk_tree_model_get (model, &iter,
813 NAME_COLUMN, &name,
814 TITLE_COLUMN, &title,
815 FILENAME_COLUMN, &filename,
816 -1);
817
818 if (filename)
819 load_file (name, filename);
820
821 ctk_header_bar_set_title (CTK_HEADER_BAR (headerbar)((((CtkHeaderBar*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((headerbar)), ((ctk_header_bar_get_type ()))))))
, title);
822
823 g_free (name);
824 g_free (title);
825 g_free (filename);
826}
827
828static CtkWidget *
829create_text (CtkWidget **view,
830 gboolean is_source)
831{
832 CtkWidget *scrolled_window;
833 CtkWidget *text_view;
834
835 scrolled_window = ctk_scrolled_window_new (NULL((void*)0), NULL((void*)0));
836 ctk_scrolled_window_set_policy (CTK_SCROLLED_WINDOW (scrolled_window)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((scrolled_window)), ((ctk_scrolled_window_get_type
()))))))
,
837 CTK_POLICY_AUTOMATIC,
838 CTK_POLICY_AUTOMATIC);
839 ctk_scrolled_window_set_shadow_type (CTK_SCROLLED_WINDOW (scrolled_window)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((scrolled_window)), ((ctk_scrolled_window_get_type
()))))))
,
840 CTK_SHADOW_NONE);
841
842 *view = text_view = ctk_text_view_new ();
843 g_object_set (text_view,
844 "left-margin", 20,
845 "right-margin", 20,
846 "top-margin", 20,
847 "bottom-margin", 20,
848 NULL((void*)0));
849
850 ctk_text_view_set_editable (CTK_TEXT_VIEW (text_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text_view)), ((ctk_text_view_get_type ()))))))
, FALSE(0));
851 ctk_text_view_set_cursor_visible (CTK_TEXT_VIEW (text_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text_view)), ((ctk_text_view_get_type ()))))))
, FALSE(0));
852
853 ctk_container_add (CTK_CONTAINER (scrolled_window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((scrolled_window)), ((ctk_container_get_type ()))))))
, text_view);
854
855 if (is_source)
856 {
857 ctk_text_view_set_monospace (CTK_TEXT_VIEW (text_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text_view)), ((ctk_text_view_get_type ()))))))
, TRUE(!(0)));
858 ctk_text_view_set_wrap_mode (CTK_TEXT_VIEW (text_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text_view)), ((ctk_text_view_get_type ()))))))
, CTK_WRAP_NONE);
859 }
860 else
861 {
862 /* Make it a bit nicer for text. */
863 ctk_text_view_set_wrap_mode (CTK_TEXT_VIEW (text_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text_view)), ((ctk_text_view_get_type ()))))))
, CTK_WRAP_WORD);
864 ctk_text_view_set_pixels_above_lines (CTK_TEXT_VIEW (text_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text_view)), ((ctk_text_view_get_type ()))))))
, 2);
865 ctk_text_view_set_pixels_below_lines (CTK_TEXT_VIEW (text_view)((((CtkTextView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((text_view)), ((ctk_text_view_get_type ()))))))
, 2);
866 }
867
868 return scrolled_window;
869}
870
871static void
872populate_model (CtkTreeModel *model)
873{
874 Demo *d = ctk_demos;
875
876 /* this code only supports 1 level of children. If we
877 * want more we probably have to use a recursing function.
878 */
879 while (d->title)
880 {
881 Demo *children = d->children;
882 CtkTreeIter iter;
883
884 ctk_tree_store_append (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((model)), ((ctk_tree_store_get_type ()))))))
, &iter, NULL((void*)0));
885
886 ctk_tree_store_set (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((model)), ((ctk_tree_store_get_type ()))))))
,
887 &iter,
888 NAME_COLUMN, d->name,
889 TITLE_COLUMN, d->title,
890 FILENAME_COLUMN, d->filename,
891 FUNC_COLUMN, d->func,
892 STYLE_COLUMN, PANGO_STYLE_NORMAL,
893 -1);
894
895 d++;
896
897 if (!children)
898 continue;
899
900 while (children->title)
901 {
902 CtkTreeIter child_iter;
903
904 ctk_tree_store_append (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((model)), ((ctk_tree_store_get_type ()))))))
, &child_iter, &iter);
905
906 ctk_tree_store_set (CTK_TREE_STORE (model)((((CtkTreeStore*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((model)), ((ctk_tree_store_get_type ()))))))
,
907 &child_iter,
908 NAME_COLUMN, children->name,
909 TITLE_COLUMN, children->title,
910 FILENAME_COLUMN, children->filename,
911 FUNC_COLUMN, children->func,
912 STYLE_COLUMN, PANGO_STYLE_NORMAL,
913 -1);
914
915 children++;
916 }
917 }
918
919}
920
921static void
922startup (GApplication *app)
923{
924 CtkBuilder *builder;
925 GMenuModel *appmenu;
926 gchar *ids[] = { "appmenu", NULL((void*)0) };
927
928 builder = ctk_builder_new ();
929 ctk_builder_add_objects_from_resource (builder, "/ui/appmenu.ui", ids, NULL((void*)0));
930
931 appmenu = (GMenuModel *)ctk_builder_get_object (builder, "appmenu");
932
933 ctk_application_set_app_menu (CTK_APPLICATION (app)((((CtkApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((app)), ((ctk_application_get_type ()))))))
, appmenu);
934
935 g_object_unref (builder);
936}
937
938static void
939row_activated_cb (CtkWidget *tree_view,
940 CtkTreePath *path,
941 CtkTreeViewColumn *column)
942{
943 CtkTreeIter iter;
944 CtkWidget *window;
945 CtkTreeModel *model;
946
947 window = ctk_widget_get_toplevel (tree_view);
948 model = ctk_tree_view_get_model (CTK_TREE_VIEW (tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((tree_view)), ((ctk_tree_view_get_type ()))))))
);
949 ctk_tree_model_get_iter (model, &iter, path);
950
951 run_example_for_row (window, model, &iter);
952}
953
954static void
955start_cb (CtkMenuItem *item, CtkWidget *scrollbar)
956{
957 CtkAdjustment *adj;
958
959 adj = ctk_range_get_adjustment (CTK_RANGE (scrollbar)((((CtkRange*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((scrollbar)), ((ctk_range_get_type ()))))))
);
960 ctk_adjustment_set_value (adj, ctk_adjustment_get_lower (adj));
961}
962
963static void
964end_cb (CtkMenuItem *item, CtkWidget *scrollbar)
965{
966 CtkAdjustment *adj;
967
968 adj = ctk_range_get_adjustment (CTK_RANGE (scrollbar)((((CtkRange*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((scrollbar)), ((ctk_range_get_type ()))))))
);
969 ctk_adjustment_set_value (adj, ctk_adjustment_get_upper (adj) - ctk_adjustment_get_page_size (adj));
970}
971
972static gboolean
973scrollbar_popup (CtkWidget *scrollbar, CtkWidget *menu)
974{
975 ctk_menu_popup_at_pointer (CTK_MENU (menu)((((CtkMenu*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_get_type ()))))))
, NULL((void*)0));
976
977 return TRUE(!(0));
978}
979
980static void
981activate (GApplication *app)
982{
983 CtkBuilder *builder;
984 CtkWindow *window;
985 CtkWidget *widget;
986 CtkTreeModel *model;
987 CtkTreeIter iter;
988 GError *error = NULL((void*)0);
989 CtkWidget *sw;
990 CtkWidget *scrollbar;
991 CtkWidget *menu;
992 CtkWidget *item;
993
994 static GActionEntry win_entries[] = {
995 { .name = "run", .activate = activate_run }
996 };
997
998 builder = ctk_builder_new ();
999 ctk_builder_add_from_resource (builder, "/ui/main.ui", &error);
1000 if (error != NULL((void*)0))
2
Assuming 'error' is equal to NULL
3
Taking false branch
1001 {
1002 g_critical ("%s", error->message);
1003 exit (1);
1004 }
1005
1006 window = (CtkWindow *)ctk_builder_get_object (builder, "window");
1007 ctk_application_add_window (CTK_APPLICATION (app)((((CtkApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((app)), ((ctk_application_get_type ()))))))
, window);
1008 g_action_map_add_action_entries (G_ACTION_MAP (window)((((GActionMap*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((g_action_map_get_type ()))))))
,
1009 win_entries, G_N_ELEMENTS (win_entries)(sizeof (win_entries) / sizeof ((win_entries)[0])),
1010 window);
1011
1012 notebook = (CtkWidget *)ctk_builder_get_object (builder, "notebook");
1013
1014 info_view = (CtkWidget *)ctk_builder_get_object (builder, "info-textview");
1015 source_view = (CtkWidget *)ctk_builder_get_object (builder, "source-textview");
1016 headerbar = (CtkWidget *)ctk_builder_get_object (builder, "headerbar");
1017 treeview = (CtkWidget *)ctk_builder_get_object (builder, "treeview");
1018 model = ctk_tree_view_get_model (CTK_TREE_VIEW (treeview)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((treeview)), ((ctk_tree_view_get_type ()))))))
);
1019
1020 sw = (CtkWidget *)ctk_builder_get_object (builder, "source-scrolledwindow");
1021 scrollbar = ctk_scrolled_window_get_vscrollbar (CTK_SCROLLED_WINDOW (sw)((((CtkScrolledWindow*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((sw)), ((ctk_scrolled_window_get_type ())))
)))
);
1022
1023 menu = ctk_menu_new ();
1024
1025 item = ctk_menu_item_new_with_label ("Start");
1026 g_signal_connect (item, "activate", G_CALLBACK (start_cb), scrollbar)g_signal_connect_data ((item), ("activate"), (((GCallback) (start_cb
))), (scrollbar), ((void*)0), (GConnectFlags) 0)
;
1027 ctk_menu_shell_append (CTK_MENU_SHELL (menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_shell_get_type ()))))))
, item);
1028
1029 item = ctk_menu_item_new_with_label ("End");
1030 g_signal_connect (item, "activate", G_CALLBACK (end_cb), scrollbar)g_signal_connect_data ((item), ("activate"), (((GCallback) (end_cb
))), (scrollbar), ((void*)0), (GConnectFlags) 0)
;
1031 ctk_menu_shell_append (CTK_MENU_SHELL (menu)((((CtkMenuShell*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((menu)), ((ctk_menu_shell_get_type ()))))))
, item);
1032
1033 ctk_widget_show_all (menu);
1034
1035 g_signal_connect (scrollbar, "popup-menu", G_CALLBACK (scrollbar_popup), menu)g_signal_connect_data ((scrollbar), ("popup-menu"), (((GCallback
) (scrollbar_popup))), (menu), ((void*)0), (GConnectFlags) 0)
;
1036
1037 load_file (ctk_demos[0].name, ctk_demos[0].filename);
4
Calling 'load_file'
1038
1039 populate_model (model);
1040
1041 g_signal_connect (treeview, "row-activated", G_CALLBACK (row_activated_cb), model)g_signal_connect_data ((treeview), ("row-activated"), (((GCallback
) (row_activated_cb))), (model), ((void*)0), (GConnectFlags) 0
)
;
1042
1043 widget = (CtkWidget *)ctk_builder_get_object (builder, "treeview-selection");
1044 g_signal_connect (widget, "changed", G_CALLBACK (selection_cb), model)g_signal_connect_data ((widget), ("changed"), (((GCallback) (
selection_cb))), (model), ((void*)0), (GConnectFlags) 0)
;
1045
1046 ctk_tree_model_get_iter_first (ctk_tree_view_get_model (CTK_TREE_VIEW (treeview)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((treeview)), ((ctk_tree_view_get_type ()))))))
), &iter);
1047 ctk_tree_selection_select_iter (CTK_TREE_SELECTION (widget)((((CtkTreeSelection*) (void *) g_type_check_instance_cast ((
GTypeInstance*) ((widget)), ((ctk_tree_selection_get_type ())
)))))
, &iter);
1048
1049 ctk_tree_view_collapse_all (CTK_TREE_VIEW (treeview)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((treeview)), ((ctk_tree_view_get_type ()))))))
);
1050
1051 ctk_widget_show_all (CTK_WIDGET (window)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_widget_get_type ()))))))
);
1052
1053 g_object_unref (builder);
1054}
1055
1056static gboolean
1057auto_quit (gpointer data)
1058{
1059 g_application_quit (G_APPLICATION (data)((((GApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((data)), ((g_application_get_type ()))))))
);
1060 return G_SOURCE_REMOVE(0);
1061}
1062
1063static void
1064list_demos (void)
1065{
1066 Demo *d;
1067
1068 d = ctk_demos;
1069
1070 while (d->title)
1071 {
1072 Demo *c;
1073
1074 c = d->children;
1075 if (d->name)
1076 g_print ("%s\n", d->name);
1077 d++;
1078 while (c && c->title)
1079 {
1080 if (c->name)
1081 g_print ("%s\n", c->name);
1082 c++;
1083 }
1084 }
1085}
1086
1087static gint
1088command_line (GApplication *app,
1089 GApplicationCommandLine *cmdline)
1090{
1091 GVariantDict *options;
1092 const gchar *name = NULL((void*)0);
1093 gboolean autoquit = FALSE(0);
1094 gboolean list = FALSE(0);
1095 Demo *d, *c;
1096 GDoDemoFunc func = 0;
1097 CtkWidget *window, *demo;
1098
1099 activate (app);
1
Calling 'activate'
1100
1101 options = g_application_command_line_get_options_dict (cmdline);
1102 g_variant_dict_lookup (options, "run", "&s", &name);
1103 g_variant_dict_lookup (options, "autoquit", "b", &autoquit);
1104 g_variant_dict_lookup (options, "list", "b", &list);
1105
1106 if (list)
1107 {
1108 list_demos ();
1109 g_application_quit (app);
1110 return 0;
1111 }
1112
1113 if (name == NULL((void*)0))
1114 goto out;
1115
1116 window = ctk_application_get_windows (CTK_APPLICATION (app)((((CtkApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((app)), ((ctk_application_get_type ()))))))
)->data;
1117
1118 d = ctk_demos;
1119
1120 while (d->title)
1121 {
1122 c = d->children;
1123 if (g_strcmp0 (d->name, name) == 0)
1124 {
1125 func = d->func;
1126 goto out;
1127 }
1128 d++;
1129 while (c && c->title)
1130 {
1131 if (g_strcmp0 (c->name, name) == 0)
1132 {
1133 func = c->func;
1134 goto out;
1135 }
1136 c++;
1137 }
1138 }
1139
1140out:
1141 if (func)
1142 {
1143 demo = (func) (window);
1144
1145 ctk_window_set_transient_for (CTK_WINDOW (demo)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((demo)), ((ctk_window_get_type ()))))))
, CTK_WINDOW (window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((window)), ((ctk_window_get_type ()))))))
);
1146 ctk_window_set_modal (CTK_WINDOW (demo)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((demo)), ((ctk_window_get_type ()))))))
, TRUE(!(0)));
1147 }
1148
1149 if (autoquit)
1150 g_timeout_add_seconds (1, auto_quit, app);
1151
1152 return 0;
1153}
1154
1155static void
1156print_version (void)
1157{
1158 g_print ("ctk3-demo %d.%d.%d\n",
1159 ctk_get_major_version (),
1160 ctk_get_minor_version (),
1161 ctk_get_micro_version ());
1162}
1163
1164static int
1165local_options (GApplication *app,
1166 GVariantDict *options,
1167 gpointer data)
1168{
1169 gboolean version = FALSE(0);
1170
1171 g_variant_dict_lookup (options, "version", "b", &version);
1172
1173 if (version)
1174 {
1175 print_version ();
1176 return 0;
1177 }
1178
1179 return -1;
1180}
1181
1182int
1183main (int argc, char **argv)
1184{
1185 CtkApplication *app;
1186 static GActionEntry app_entries[] = {
1187 { .name = "about", .activate = activate_about },
1188 { .name = "quit", .activate = activate_quit },
1189 };
1190
1191 /* Most code in ctk-demo is intended to be exemplary, but not
1192 * these few lines, which are just a hack so ctk-demo will work
1193 * in the CTK tree without installing it.
1194 */
1195 if (g_file_test ("../../modules/input/immodules.cache", G_FILE_TEST_EXISTS))
1196 {
1197 g_setenv ("CTK_IM_MODULE_FILE", "../../modules/input/immodules.cache", TRUE(!(0)));
1198 }
1199 /* -- End of hack -- */
1200
1201 app = ctk_application_new ("org.ctk.Demo", G_APPLICATION_NON_UNIQUE|G_APPLICATION_HANDLES_COMMAND_LINE);
1202
1203 g_action_map_add_action_entries (G_ACTION_MAP (app)((((GActionMap*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((app)), ((g_action_map_get_type ()))))))
,
1204 app_entries, G_N_ELEMENTS (app_entries)(sizeof (app_entries) / sizeof ((app_entries)[0])),
1205 app);
1206
1207 g_application_add_main_option (G_APPLICATION (app)((((GApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((app)), ((g_application_get_type ()))))))
, "version", 0, 0, G_OPTION_ARG_NONE, "Show program version", NULL((void*)0));
1208 g_application_add_main_option (G_APPLICATION (app)((((GApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((app)), ((g_application_get_type ()))))))
, "run", 0, 0, G_OPTION_ARG_STRING, "Run an example", "EXAMPLE");
1209 g_application_add_main_option (G_APPLICATION (app)((((GApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((app)), ((g_application_get_type ()))))))
, "list", 0, 0, G_OPTION_ARG_NONE, "List examples", NULL((void*)0));
1210 g_application_add_main_option (G_APPLICATION (app)((((GApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((app)), ((g_application_get_type ()))))))
, "autoquit", 0, 0, G_OPTION_ARG_NONE, "Quit after a delay", NULL((void*)0));
1211
1212 g_signal_connect (app, "startup", G_CALLBACK (startup), NULL)g_signal_connect_data ((app), ("startup"), (((GCallback) (startup
))), (((void*)0)), ((void*)0), (GConnectFlags) 0)
;
1213 g_signal_connect (app, "activate", G_CALLBACK (activate), NULL)g_signal_connect_data ((app), ("activate"), (((GCallback) (activate
))), (((void*)0)), ((void*)0), (GConnectFlags) 0)
;
1214 g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL)g_signal_connect_data ((app), ("command-line"), (((GCallback)
(command_line))), (((void*)0)), ((void*)0), (GConnectFlags) 0
)
;
1215 g_signal_connect (app, "handle-local-options", G_CALLBACK (local_options), NULL)g_signal_connect_data ((app), ("handle-local-options"), (((GCallback
) (local_options))), (((void*)0)), ((void*)0), (GConnectFlags
) 0)
;
1216
1217 g_application_run (G_APPLICATION (app)((((GApplication*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((app)), ((g_application_get_type ()))))))
, argc, argv);
1218
1219 return 0;
1220}