1 /* GSequencer - Advanced GTK Sequencer
2 * Copyright (C) 2005-2021 Joël Krähemann
3 *
4 * This file is part of GSequencer.
5 *
6 * GSequencer is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GSequencer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GSequencer. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <ags/object/ags_application_context.h>
21
22 #include <ags/lib/ags_log.h>
23
24 #include <ags/file/ags_file.h>
25
26 #include <ags/object/ags_connectable.h>
27
28 #include <gio/gio.h>
29
30 #include <sys/types.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34
35 #include <ags/i18n.h>
36
37 void ags_application_context_class_init(AgsApplicationContextClass *application_context);
38 void ags_application_context_connectable_interface_init(AgsConnectableInterface *connectable);
39 void ags_application_context_init(AgsApplicationContext *application_context);
40 void ags_application_context_set_property(GObject *gobject,
41 guint prop_id,
42 const GValue *value,
43 GParamSpec *param_spec);
44 void ags_application_context_get_property(GObject *gobject,
45 guint prop_id,
46 GValue *value,
47 GParamSpec *param_spec);
48 void ags_application_context_dispose(GObject *gobject);
49 void ags_application_context_finalize(GObject *gobject);
50
51 AgsUUID* ags_application_context_get_uuid(AgsConnectable *connectable);
52 gboolean ags_application_context_has_resource(AgsConnectable *connectable);
53 gboolean ags_application_context_is_ready(AgsConnectable *connectable);
54 void ags_application_context_add_to_registry(AgsConnectable *connectable);
55 void ags_application_context_remove_from_registry(AgsConnectable *connectable);
56 xmlNode* ags_application_context_list_resource(AgsConnectable *connectable);
57 xmlNode* ags_application_context_xml_compose(AgsConnectable *connectable);
58 void ags_application_context_xml_parse(AgsConnectable *connectable,
59 xmlNode *node);
60 gboolean ags_application_context_is_connected(AgsConnectable *connectable);
61 void ags_application_context_connect(AgsConnectable *connectable);
62 void ags_application_context_disconnect(AgsConnectable *connectable);
63
64 void ags_application_context_real_load_config(AgsApplicationContext *application_context);
65
66 void ags_application_context_real_prepare(AgsApplicationContext *application_context);
67 void ags_application_context_real_setup(AgsApplicationContext *application_context);
68
69 void ags_application_context_real_register_types(AgsApplicationContext *application_context);
70
71 void ags_application_context_real_quit(AgsApplicationContext *application_context);
72
73 /**
74 * SECTION:ags_application_context
75 * @short_description: The application context
76 * @title: AgsApplicationContext
77 * @section_id:
78 * @include: ags/object/ags_application_context.h
79 *
80 * #AgsApplicationContext is a context provider is your and libraries entry
81 * point to the application. You might subtype it to implement your own contices.
82 * Thus you should consider to create a provider interface for reusability.
83 */
84
85 enum{
86 LOAD_CONFIG,
87 PREPARE,
88 SETUP,
89 REGISTER_TYPES,
90 QUIT,
91 LAST_SIGNAL,
92 };
93
94 enum{
95 PROP_0,
96 PROP_MAIN_LOOP,
97 PROP_TASK_LAUNCHER,
98 PROP_CONFIG,
99 PROP_FILE,
100 };
101
102 static gpointer ags_application_context_parent_class = NULL;
103 static guint application_context_signals[LAST_SIGNAL];
104
105 AgsApplicationContext *ags_application_context = NULL;
106
107 GType
ags_application_context_get_type()108 ags_application_context_get_type()
109 {
110 static volatile gsize g_define_type_id__volatile = 0;
111
112 if(g_once_init_enter (&g_define_type_id__volatile)){
113 GType ags_type_application_context = 0;
114
115 static const GTypeInfo ags_application_context_info = {
116 sizeof (AgsApplicationContextClass),
117 NULL, /* base_init */
118 NULL, /* base_finalize */
119 (GClassInitFunc) ags_application_context_class_init,
120 NULL, /* class_finalize */
121 NULL, /* class_data */
122 sizeof (AgsApplicationContext),
123 0, /* n_preallocs */
124 (GInstanceInitFunc) ags_application_context_init,
125 };
126
127 static const GInterfaceInfo ags_connectable_interface_info = {
128 (GInterfaceInitFunc) ags_application_context_connectable_interface_init,
129 NULL, /* interface_finalize */
130 NULL, /* interface_data */
131 };
132
133 ags_type_application_context = g_type_register_static(G_TYPE_OBJECT,
134 "AgsApplicationContext",
135 &ags_application_context_info,
136 0);
137
138 g_type_add_interface_static(ags_type_application_context,
139 AGS_TYPE_CONNECTABLE,
140 &ags_connectable_interface_info);
141
142 g_once_init_leave(&g_define_type_id__volatile, ags_type_application_context);
143 }
144
145 return g_define_type_id__volatile;
146 }
147
148 GType
ags_application_context_flags_get_type()149 ags_application_context_flags_get_type()
150 {
151 static volatile gsize g_flags_type_id__volatile;
152
153 if(g_once_init_enter (&g_flags_type_id__volatile)){
154 static const GFlagsValue values[] = {
155 { AGS_APPLICATION_CONTEXT_ADDED_TO_REGISTRY, "AGS_APPLICATION_CONTEXT_ADDED_TO_REGISTRY", "application-context-added-to-registry" },
156 { AGS_APPLICATION_CONTEXT_CONNECTED, "AGS_APPLICATION_CONTEXT_CONNECTED", "application-context-connected" },
157 { AGS_APPLICATION_CONTEXT_TYPES_REGISTERED, "AGS_APPLICATION_CONTEXT_TYPES_REGISTERED", "application-context-types-registered" },
158 { 0, NULL, NULL }
159 };
160
161 GType g_flags_type_id = g_flags_register_static(g_intern_static_string("AgsApplicationContextFlags"), values);
162
163 g_once_init_leave (&g_flags_type_id__volatile, g_flags_type_id);
164 }
165
166 return g_flags_type_id__volatile;
167 }
168
169 void
ags_application_context_class_init(AgsApplicationContextClass * application_context)170 ags_application_context_class_init(AgsApplicationContextClass *application_context)
171 {
172 GObjectClass *gobject;
173
174 GParamSpec *param_spec;
175
176 ags_application_context_parent_class = g_type_class_peek_parent(application_context);
177
178 /* GObjectClass */
179 gobject = (GObjectClass *) application_context;
180
181 gobject->set_property = ags_application_context_set_property;
182 gobject->get_property = ags_application_context_get_property;
183
184 gobject->dispose = ags_application_context_dispose;
185 gobject->finalize = ags_application_context_finalize;
186
187 /* properties */
188 /**
189 * AgsApplicationContext:main-loop:
190 *
191 * The assigned main-loop.
192 *
193 * Since: 3.0.0
194 */
195 param_spec = g_param_spec_object("main-loop",
196 i18n_pspec("main loop of application context"),
197 i18n_pspec("The main loop of application context running"),
198 G_TYPE_OBJECT,
199 G_PARAM_READABLE | G_PARAM_WRITABLE);
200 g_object_class_install_property(gobject,
201 PROP_MAIN_LOOP,
202 param_spec);
203
204 /**
205 * AgsApplicationContext:task-launcher:
206 *
207 * The assigned task launcher.
208 *
209 * Since: 3.0.0
210 */
211 param_spec = g_param_spec_object("task-launcher",
212 i18n_pspec("task launcher"),
213 i18n_pspec("The task launcher"),
214 G_TYPE_OBJECT,
215 G_PARAM_READABLE | G_PARAM_WRITABLE);
216 g_object_class_install_property(gobject,
217 PROP_TASK_LAUNCHER,
218 param_spec);
219
220 /**
221 * AgsApplicationContext:config:
222 *
223 * The assigned config.
224 *
225 * Since: 3.0.0
226 */
227 param_spec = g_param_spec_object("config",
228 i18n_pspec("config of application context"),
229 i18n_pspec("The config what application context is running in"),
230 G_TYPE_OBJECT,
231 G_PARAM_READABLE | G_PARAM_WRITABLE);
232 g_object_class_install_property(gobject,
233 PROP_CONFIG,
234 param_spec);
235
236 /**
237 * AgsApplicationContext:file:
238 *
239 * The assigned file.
240 *
241 * Since: 3.0.0
242 */
243 param_spec = g_param_spec_object("file",
244 i18n_pspec("file of application context"),
245 i18n_pspec("The file what application context does persist"),
246 G_TYPE_OBJECT,
247 G_PARAM_READABLE | G_PARAM_WRITABLE);
248 g_object_class_install_property(gobject,
249 PROP_FILE,
250 param_spec);
251
252 /* AgsApplicationContextClass */
253 application_context->load_config = ags_application_context_real_load_config;
254
255 application_context->prepare = ags_application_context_real_prepare;
256 application_context->setup = ags_application_context_real_setup;
257
258 application_context->register_types = ags_application_context_real_register_types;
259
260 application_context->read = NULL;
261 application_context->write = NULL;
262
263 application_context->quit = ags_application_context_real_quit;
264
265 /* signals */
266 /**
267 * AgsApplicationContext::load-config:
268 * @application_context: the #AgsApplicationContext
269 *
270 * The ::load-config notifies to load configuration.
271 *
272 * Since: 3.0.0
273 */
274 application_context_signals[LOAD_CONFIG] =
275 g_signal_new("load-config",
276 G_TYPE_FROM_CLASS (application_context),
277 G_SIGNAL_RUN_LAST,
278 G_STRUCT_OFFSET (AgsApplicationContextClass, load_config),
279 NULL, NULL,
280 g_cclosure_marshal_VOID__VOID,
281 G_TYPE_NONE, 0);
282
283 /**
284 * AgsApplicationContext::prepare:
285 * @application_context: the #AgsApplicationContext
286 *
287 * The ::prepare signal should be implemented to prepare
288 * your application context.
289 *
290 * Since: 3.0.0
291 */
292 application_context_signals[PREPARE] =
293 g_signal_new("prepare",
294 G_TYPE_FROM_CLASS (application_context),
295 G_SIGNAL_RUN_LAST,
296 G_STRUCT_OFFSET (AgsApplicationContextClass, prepare),
297 NULL, NULL,
298 g_cclosure_marshal_VOID__VOID,
299 G_TYPE_NONE, 0);
300
301 /**
302 * AgsApplicationContext::setup:
303 * @application_context: the #AgsApplicationContext
304 *
305 * The ::setup signal should be implemented to setup
306 * your application context.
307 *
308 * Since: 3.0.0
309 */
310 application_context_signals[SETUP] =
311 g_signal_new("setup",
312 G_TYPE_FROM_CLASS (application_context),
313 G_SIGNAL_RUN_LAST,
314 G_STRUCT_OFFSET (AgsApplicationContextClass, setup),
315 NULL, NULL,
316 g_cclosure_marshal_VOID__VOID,
317 G_TYPE_NONE, 0);
318
319 /**
320 * AgsApplicationContext::register-types:
321 * @application_context: the #AgsApplicationContext
322 *
323 * The ::register-types signal should be implemented to load
324 * your types.
325 *
326 * Since: 3.0.0
327 */
328 application_context_signals[REGISTER_TYPES] =
329 g_signal_new("register-types",
330 G_TYPE_FROM_CLASS (application_context),
331 G_SIGNAL_RUN_LAST,
332 G_STRUCT_OFFSET (AgsApplicationContextClass, register_types),
333 NULL, NULL,
334 g_cclosure_marshal_VOID__VOID,
335 G_TYPE_NONE, 0);
336
337 /**
338 * AgsApplicationContext::quit:
339 * @application_context: the #AgsApplicationContext
340 *
341 * The ::quit notifies to load configuration.
342 *
343 * Since: 3.0.0
344 */
345 application_context_signals[QUIT] =
346 g_signal_new("quit",
347 G_TYPE_FROM_CLASS (application_context),
348 G_SIGNAL_RUN_LAST,
349 G_STRUCT_OFFSET (AgsApplicationContextClass, quit),
350 NULL, NULL,
351 g_cclosure_marshal_VOID__VOID,
352 G_TYPE_NONE, 0);
353 }
354
355 void
ags_application_context_connectable_interface_init(AgsConnectableInterface * connectable)356 ags_application_context_connectable_interface_init(AgsConnectableInterface *connectable)
357 {
358 connectable->get_uuid = ags_application_context_get_uuid;
359 connectable->has_resource = ags_application_context_has_resource;
360
361 connectable->is_ready = ags_application_context_is_ready;
362 connectable->add_to_registry = ags_application_context_add_to_registry;
363 connectable->remove_from_registry = ags_application_context_remove_from_registry;
364
365 connectable->list_resource = ags_application_context_list_resource;
366 connectable->xml_compose = ags_application_context_xml_compose;
367 connectable->xml_parse = ags_application_context_xml_parse;
368
369 connectable->is_connected = ags_application_context_is_connected;
370 connectable->connect = ags_application_context_connect;
371 connectable->disconnect = ags_application_context_disconnect;
372
373 connectable->connect_connection = NULL;
374 connectable->disconnect_connection = NULL;
375 }
376
377 void
ags_application_context_init(AgsApplicationContext * application_context)378 ags_application_context_init(AgsApplicationContext *application_context)
379 {
380 GFile *file;
381
382 application_context->flags = 0;
383
384 g_rec_mutex_init(&(application_context->obj_mutex));
385
386 /* uuid */
387 application_context->uuid = ags_uuid_alloc();
388 ags_uuid_generate(application_context->uuid);
389
390 application_context->argc = 0;
391 application_context->argv = NULL;
392
393 application_context->version = g_strdup(AGS_VERSION);
394 application_context->build_id = g_strdup(AGS_BUILD_ID);
395
396 application_context->log = NULL;
397
398 application_context->domain = NULL;
399
400 application_context->config = NULL;
401
402 application_context->main_loop = NULL;
403 application_context->task_launcher = NULL;
404
405 application_context->file = NULL;
406 application_context->history = NULL;
407 }
408
409 void
ags_application_context_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)410 ags_application_context_set_property(GObject *gobject,
411 guint prop_id,
412 const GValue *value,
413 GParamSpec *param_spec)
414 {
415 AgsApplicationContext *application_context;
416
417 GRecMutex *application_context_mutex;
418
419 application_context = AGS_APPLICATION_CONTEXT(gobject);
420
421 /* get application context mutex */
422 application_context_mutex = AGS_APPLICATION_CONTEXT_GET_OBJ_MUTEX(application_context);
423
424 switch(prop_id){
425 case PROP_MAIN_LOOP:
426 {
427 GObject *main_loop;
428
429 main_loop = (GObject *) g_value_get_object(value);
430
431 g_rec_mutex_lock(application_context_mutex);
432
433 if(main_loop == application_context->main_loop){
434 g_rec_mutex_unlock(application_context_mutex);
435
436 return;
437 }
438
439 if(application_context->main_loop != NULL){
440 g_object_unref(application_context->main_loop);
441 }
442
443 if(main_loop != NULL){
444 g_object_ref(G_OBJECT(main_loop));
445 }
446
447 application_context->main_loop = main_loop;
448
449 g_rec_mutex_unlock(application_context_mutex);
450 }
451 break;
452 case PROP_TASK_LAUNCHER:
453 {
454 GObject *task_launcher;
455
456 task_launcher = (GObject *) g_value_get_object(value);
457
458 g_rec_mutex_lock(application_context_mutex);
459
460 if(task_launcher == application_context->task_launcher){
461 g_rec_mutex_unlock(application_context_mutex);
462
463 return;
464 }
465
466 if(application_context->task_launcher != NULL){
467 g_object_unref(application_context->task_launcher);
468 }
469
470 if(task_launcher != NULL){
471 g_object_ref(G_OBJECT(task_launcher));
472 }
473
474 application_context->task_launcher = task_launcher;
475
476 g_rec_mutex_unlock(application_context_mutex);
477 }
478 break;
479 case PROP_CONFIG:
480 {
481 AgsConfig *config;
482
483 config = (AgsConfig *) g_value_get_object(value);
484
485 g_rec_mutex_lock(application_context_mutex);
486
487 if(config == application_context->config){
488 g_rec_mutex_unlock(application_context_mutex);
489
490 return;
491 }
492
493 if(application_context->config != NULL){
494 g_object_unref(application_context->config);
495 }
496
497 if(config != NULL){
498 g_object_ref(G_OBJECT(config));
499 }
500
501 application_context->config = config;
502
503 g_rec_mutex_unlock(application_context_mutex);
504 }
505 break;
506 case PROP_FILE:
507 {
508 AgsFile *file;
509
510 file = (AgsFile *) g_value_get_object(value);
511
512 g_rec_mutex_lock(application_context_mutex);
513
514 if(file == application_context->file){
515 g_rec_mutex_unlock(application_context_mutex);
516
517 return;
518 }
519
520 if(application_context->file != NULL){
521 g_object_unref(application_context->file);
522 }
523
524 if(file != NULL){
525 g_object_ref(G_OBJECT(file));
526 }
527
528 application_context->file = (AgsFile *) file;
529
530 g_rec_mutex_unlock(application_context_mutex);
531 }
532 break;
533 default:
534 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
535 break;
536 }
537
538 }
539
540 void
ags_application_context_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)541 ags_application_context_get_property(GObject *gobject,
542 guint prop_id,
543 GValue *value,
544 GParamSpec *param_spec)
545 {
546 AgsApplicationContext *application_context;
547
548 GRecMutex *application_context_mutex;
549
550 application_context = AGS_APPLICATION_CONTEXT(gobject);
551
552 /* get application context mutex */
553 application_context_mutex = AGS_APPLICATION_CONTEXT_GET_OBJ_MUTEX(application_context);
554
555 switch(prop_id){
556 case PROP_MAIN_LOOP:
557 {
558 g_rec_mutex_lock(application_context_mutex);
559
560 g_value_set_object(value, application_context->main_loop);
561
562 g_rec_mutex_unlock(application_context_mutex);
563 }
564 break;
565 case PROP_TASK_LAUNCHER:
566 {
567 g_rec_mutex_lock(application_context_mutex);
568
569 g_value_set_object(value, application_context->task_launcher);
570
571 g_rec_mutex_unlock(application_context_mutex);
572 }
573 break;
574 case PROP_CONFIG:
575 {
576 g_rec_mutex_lock(application_context_mutex);
577
578 g_value_set_object(value, application_context->config);
579
580 g_rec_mutex_unlock(application_context_mutex);
581 }
582 break;
583 case PROP_FILE:
584 {
585 g_rec_mutex_lock(application_context_mutex);
586
587 g_value_set_object(value, application_context->file);
588
589 g_rec_mutex_unlock(application_context_mutex);
590 }
591 break;
592 default:
593 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
594 break;
595 }
596 }
597
598 void
ags_application_context_dispose(GObject * gobject)599 ags_application_context_dispose(GObject *gobject)
600 {
601 AgsApplicationContext *application_context;
602
603 application_context = AGS_APPLICATION_CONTEXT(gobject);
604
605 /* log */
606 if(application_context->log != NULL){
607 g_object_unref(application_context->log);
608
609 application_context->log = NULL;
610 }
611
612 /* config */
613 if(application_context->config != NULL){
614 g_object_unref(application_context->config);
615
616 application_context->config = NULL;
617 }
618
619 /* main loop */
620 if(application_context->main_loop != NULL){
621 g_object_unref(application_context->main_loop);
622
623 application_context->main_loop = NULL;
624 }
625
626 /* task launcher */
627 if(application_context->task_launcher != NULL){
628 g_object_unref(application_context->task_launcher);
629
630 application_context->task_launcher = NULL;
631 }
632
633 /* file */
634 if(application_context->file != NULL){
635 g_object_unref(application_context->file);
636
637 application_context->file = NULL;
638 }
639
640 /* call parent */
641 G_OBJECT_CLASS(ags_application_context_parent_class)->dispose(gobject);
642 }
643
644 void
ags_application_context_finalize(GObject * gobject)645 ags_application_context_finalize(GObject *gobject)
646 {
647 AgsApplicationContext *application_context;
648
649 application_context = AGS_APPLICATION_CONTEXT(gobject);
650
651 g_free(application_context->version);
652 g_free(application_context->build_id);
653
654 /* log */
655 if(application_context->log != NULL){
656 g_object_unref(application_context->log);
657 }
658
659 /* config */
660 if(application_context->config != NULL){
661 g_object_unref(application_context->config);
662 }
663
664 /* main loop */
665 if(application_context->main_loop != NULL){
666 g_object_unref(application_context->main_loop);
667 }
668
669 /* task launcher */
670 if(application_context->task_launcher != NULL){
671 g_object_unref(application_context->task_launcher);
672 }
673
674 /* file */
675 if(application_context->file != NULL){
676 g_object_unref(application_context->file);
677 }
678
679 if(application_context == ags_application_context){
680 ags_application_context = NULL;
681 }
682
683 /* call parent */
684 G_OBJECT_CLASS(ags_application_context_parent_class)->finalize(gobject);
685 }
686
687 AgsUUID*
ags_application_context_get_uuid(AgsConnectable * connectable)688 ags_application_context_get_uuid(AgsConnectable *connectable)
689 {
690 AgsApplicationContext *application_context;
691
692 AgsUUID *ptr;
693
694 GRecMutex *application_context_mutex;
695
696 application_context = AGS_APPLICATION_CONTEXT(connectable);
697
698 /* get application_context mutex */
699 application_context_mutex = AGS_APPLICATION_CONTEXT_GET_OBJ_MUTEX(application_context);
700
701 /* get UUID */
702 g_rec_mutex_lock(application_context_mutex);
703
704 ptr = application_context->uuid;
705
706 g_rec_mutex_unlock(application_context_mutex);
707
708 return(ptr);
709 }
710
711 gboolean
ags_application_context_has_resource(AgsConnectable * connectable)712 ags_application_context_has_resource(AgsConnectable *connectable)
713 {
714 return(TRUE);
715 }
716
717 gboolean
ags_application_context_is_ready(AgsConnectable * connectable)718 ags_application_context_is_ready(AgsConnectable *connectable)
719 {
720 AgsApplicationContext *application_context;
721
722 gboolean is_ready;
723
724 GRecMutex *application_context_mutex;
725
726 application_context = AGS_APPLICATION_CONTEXT(connectable);
727
728 /* get application_context mutex */
729 application_context_mutex = AGS_APPLICATION_CONTEXT_GET_OBJ_MUTEX(application_context);
730
731 /* check is added */
732 g_rec_mutex_lock(application_context_mutex);
733
734 is_ready = (((AGS_APPLICATION_CONTEXT_ADDED_TO_REGISTRY & (application_context->flags)) != 0) ? TRUE: FALSE);
735
736 g_rec_mutex_unlock(application_context_mutex);
737
738 return(is_ready);
739 }
740
741 void
ags_application_context_add_to_registry(AgsConnectable * connectable)742 ags_application_context_add_to_registry(AgsConnectable *connectable)
743 {
744 AgsApplicationContext *application_context;
745
746 if(ags_connectable_is_ready(connectable)){
747 return;
748 }
749
750 application_context = AGS_APPLICATION_CONTEXT(connectable);
751
752 ags_application_context_set_flags(application_context, AGS_APPLICATION_CONTEXT_ADDED_TO_REGISTRY);
753 }
754
755 void
ags_application_context_remove_from_registry(AgsConnectable * connectable)756 ags_application_context_remove_from_registry(AgsConnectable *connectable)
757 {
758 AgsApplicationContext *application_context;
759
760 if(!ags_connectable_is_ready(connectable)){
761 return;
762 }
763
764 application_context = AGS_APPLICATION_CONTEXT(connectable);
765
766 ags_application_context_unset_flags(application_context, AGS_APPLICATION_CONTEXT_ADDED_TO_REGISTRY);
767 }
768
769 xmlNode*
ags_application_context_list_resource(AgsConnectable * connectable)770 ags_application_context_list_resource(AgsConnectable *connectable)
771 {
772 xmlNode *node;
773
774 node = NULL;
775
776 //TODO:JK: implement me
777
778 return(node);
779 }
780
781 xmlNode*
ags_application_context_xml_compose(AgsConnectable * connectable)782 ags_application_context_xml_compose(AgsConnectable *connectable)
783 {
784 xmlNode *node;
785
786 node = NULL;
787
788 //TODO:JK: implement me
789
790 return(node);
791 }
792
793 void
ags_application_context_xml_parse(AgsConnectable * connectable,xmlNode * node)794 ags_application_context_xml_parse(AgsConnectable *connectable,
795 xmlNode *node)
796 {
797 //TODO:JK: implement me
798 }
799
800 gboolean
ags_application_context_is_connected(AgsConnectable * connectable)801 ags_application_context_is_connected(AgsConnectable *connectable)
802 {
803 AgsApplicationContext *application_context;
804
805 gboolean is_connected;
806
807 GRecMutex *application_context_mutex;
808
809 application_context = AGS_APPLICATION_CONTEXT(connectable);
810
811 /* get application_context mutex */
812 application_context_mutex = AGS_APPLICATION_CONTEXT_GET_OBJ_MUTEX(application_context);
813
814 /* check is connected */
815 g_rec_mutex_lock(application_context_mutex);
816
817 is_connected = (((AGS_APPLICATION_CONTEXT_CONNECTED & (application_context->flags)) != 0) ? TRUE: FALSE);
818
819 g_rec_mutex_unlock(application_context_mutex);
820
821 return(is_connected);
822 }
823
824 void
ags_application_context_connect(AgsConnectable * connectable)825 ags_application_context_connect(AgsConnectable *connectable)
826 {
827 AgsApplicationContext *application_context;
828
829 if(ags_connectable_is_connected(connectable)){
830 return;
831 }
832
833 application_context = AGS_APPLICATION_CONTEXT(connectable);
834
835 ags_application_context_set_flags(application_context, AGS_APPLICATION_CONTEXT_CONNECTED);
836 }
837
838 void
ags_application_context_disconnect(AgsConnectable * connectable)839 ags_application_context_disconnect(AgsConnectable *connectable)
840 {
841 AgsApplicationContext *application_context;
842
843 if(!ags_connectable_is_connected(connectable)){
844 return;
845 }
846
847 application_context = AGS_APPLICATION_CONTEXT(connectable);
848
849 ags_application_context_unset_flags(application_context, AGS_APPLICATION_CONTEXT_CONNECTED);
850 }
851
852 /**
853 * ags_application_context_test_flags:
854 * @application_context: the #AgsApplicationContext
855 * @flags: the flags
856 *
857 * Test @flags to be set on @application_context.
858 *
859 * Returns: %TRUE if flags are set, else %FALSE
860 *
861 * Since: 3.0.0
862 */
863 gboolean
ags_application_context_test_flags(AgsApplicationContext * application_context,guint flags)864 ags_application_context_test_flags(AgsApplicationContext *application_context, guint flags)
865 {
866 gboolean retval;
867
868 GRecMutex *application_context_mutex;
869
870 if(!AGS_IS_APPLICATION_CONTEXT(application_context)){
871 return(FALSE);
872 }
873
874 /* get application_context mutex */
875 application_context_mutex = AGS_APPLICATION_CONTEXT_GET_OBJ_MUTEX(application_context);
876
877 /* test */
878 g_rec_mutex_lock(application_context_mutex);
879
880 retval = (flags & (application_context->flags)) ? TRUE: FALSE;
881
882 g_rec_mutex_unlock(application_context_mutex);
883
884 return(retval);
885 }
886
887 /**
888 * ags_application_context_set_flags:
889 * @application_context: the #AgsApplicationContext
890 * @flags: see enum AgsApplicationContextFlags
891 *
892 * Enable a feature of #AgsApplicationContext.
893 *
894 * Since: 3.0.0
895 */
896 void
ags_application_context_set_flags(AgsApplicationContext * application_context,guint flags)897 ags_application_context_set_flags(AgsApplicationContext *application_context, guint flags)
898 {
899 guint application_context_flags;
900
901 GRecMutex *application_context_mutex;
902
903 if(!AGS_IS_APPLICATION_CONTEXT(application_context)){
904 return;
905 }
906
907 /* get application_context mutex */
908 application_context_mutex = AGS_APPLICATION_CONTEXT_GET_OBJ_MUTEX(application_context);
909
910 /* set flags */
911 g_rec_mutex_lock(application_context_mutex);
912
913 application_context->flags |= flags;
914
915 g_rec_mutex_unlock(application_context_mutex);
916 }
917
918 /**
919 * ags_application_context_unset_flags:
920 * @application_context: the #AgsApplicationContext
921 * @flags: see enum AgsApplicationContextFlags
922 *
923 * Disable a feature of AgsApplicationContext.
924 *
925 * Since: 3.0.0
926 */
927 void
ags_application_context_unset_flags(AgsApplicationContext * application_context,guint flags)928 ags_application_context_unset_flags(AgsApplicationContext *application_context, guint flags)
929 {
930 guint application_context_flags;
931
932 GRecMutex *application_context_mutex;
933
934 if(!AGS_IS_APPLICATION_CONTEXT(application_context)){
935 return;
936 }
937
938 /* get application_context mutex */
939 application_context_mutex = AGS_APPLICATION_CONTEXT_GET_OBJ_MUTEX(application_context);
940
941 /* unset flags */
942 g_rec_mutex_lock(application_context_mutex);
943
944 application_context->flags &= (~flags);
945
946 g_rec_mutex_unlock(application_context_mutex);
947 }
948
949 void
ags_application_context_real_load_config(AgsApplicationContext * application_context)950 ags_application_context_real_load_config(AgsApplicationContext *application_context)
951 {
952 //TODO:JK: implement me
953 }
954
955 /**
956 * ags_application_context_load_config:
957 * @application_context: the #AgsApplicationContext
958 *
959 * Signal to load and parse configuration.
960 *
961 * Since: 3.0.0
962 */
963 void
ags_application_context_load_config(AgsApplicationContext * application_context)964 ags_application_context_load_config(AgsApplicationContext *application_context)
965 {
966 g_return_if_fail(AGS_IS_APPLICATION_CONTEXT(application_context));
967
968 g_object_ref(G_OBJECT(application_context));
969 g_signal_emit(G_OBJECT(application_context),
970 application_context_signals[LOAD_CONFIG], 0);
971 g_object_unref(G_OBJECT(application_context));
972 }
973
974 void
ags_application_context_real_prepare(AgsApplicationContext * application_context)975 ags_application_context_real_prepare(AgsApplicationContext *application_context)
976 {
977 ags_log_add_message(ags_log_get_instance(), "prepare Advanced Gtk+ Sequencer");
978 }
979
980 /**
981 * ags_application_context_prepare:
982 * @application_context: the #AgsApplicationContext
983 *
984 * Prepare @application_context.
985 *
986 * Since: 3.0.0
987 */
988 void
ags_application_context_prepare(AgsApplicationContext * application_context)989 ags_application_context_prepare(AgsApplicationContext *application_context)
990 {
991 g_return_if_fail(AGS_IS_APPLICATION_CONTEXT(application_context));
992
993 g_object_ref(G_OBJECT(application_context));
994 g_signal_emit(G_OBJECT(application_context),
995 application_context_signals[PREPARE], 0);
996 g_object_unref(G_OBJECT(application_context));
997 }
998
999 void
ags_application_context_real_setup(AgsApplicationContext * application_context)1000 ags_application_context_real_setup(AgsApplicationContext *application_context)
1001 {
1002 ags_log_add_message(ags_log_get_instance(), "setup Advanced Gtk+ Sequencer");
1003 }
1004
1005 /**
1006 * ags_application_context_setup:
1007 * @application_context: the #AgsApplicationContext
1008 *
1009 * Setup @application_context.
1010 *
1011 * Since: 3.0.0
1012 */
1013 void
ags_application_context_setup(AgsApplicationContext * application_context)1014 ags_application_context_setup(AgsApplicationContext *application_context)
1015 {
1016 g_return_if_fail(AGS_IS_APPLICATION_CONTEXT(application_context));
1017
1018 g_object_ref(G_OBJECT(application_context));
1019 g_signal_emit(G_OBJECT(application_context),
1020 application_context_signals[SETUP], 0);
1021 g_object_unref(G_OBJECT(application_context));
1022 }
1023
1024 void
ags_application_context_real_register_types(AgsApplicationContext * application_context)1025 ags_application_context_real_register_types(AgsApplicationContext *application_context)
1026 {
1027 //TODO:JK: implement me
1028 }
1029
1030 /**
1031 * ags_application_context_register_types:
1032 * @application_context: the #AgsApplicationContext
1033 *
1034 * Notification to register your types.
1035 *
1036 * Since: 3.0.0
1037 */
1038 void
ags_application_context_register_types(AgsApplicationContext * application_context)1039 ags_application_context_register_types(AgsApplicationContext *application_context)
1040 {
1041 g_return_if_fail(AGS_IS_APPLICATION_CONTEXT(application_context));
1042
1043 g_object_ref(G_OBJECT(application_context));
1044 g_signal_emit(G_OBJECT(application_context),
1045 application_context_signals[REGISTER_TYPES], 0);
1046 g_object_unref(G_OBJECT(application_context));
1047 }
1048
1049 void
ags_application_context_real_quit(AgsApplicationContext * application_context)1050 ags_application_context_real_quit(AgsApplicationContext *application_context)
1051 {
1052 //TODO:JK: enhance me
1053 exit(0);
1054 }
1055
1056 /**
1057 * ags_application_context_quit:
1058 * @application_context: the #AgsApplicationContext
1059 *
1060 * Calls exit()
1061 *
1062 * Since: 3.0.0
1063 */
1064 void
ags_application_context_quit(AgsApplicationContext * application_context)1065 ags_application_context_quit(AgsApplicationContext *application_context)
1066 {
1067 g_return_if_fail(AGS_IS_APPLICATION_CONTEXT(application_context));
1068
1069 g_object_ref(G_OBJECT(application_context));
1070 g_signal_emit(G_OBJECT(application_context),
1071 application_context_signals[QUIT], 0);
1072 g_object_unref(G_OBJECT(application_context));
1073 }
1074
1075 /**
1076 * ags_application_context_get_instance:
1077 *
1078 * Get your application context instance.
1079 *
1080 * Returns: (transfer none): the #AgsApplicationContext instance
1081 *
1082 * Since: 3.0.0
1083 */
1084 AgsApplicationContext*
ags_application_context_get_instance()1085 ags_application_context_get_instance()
1086 {
1087 static GMutex mutex;
1088
1089 g_mutex_lock(&mutex);
1090
1091 if(ags_application_context == NULL){
1092 ags_application_context = ags_application_context_new(NULL,
1093 NULL);
1094 }
1095
1096 g_mutex_unlock(&mutex);
1097
1098 return(ags_application_context);
1099 }
1100
1101 /**
1102 * ags_application_context_new:
1103 * @main_loop: (nullable): the #AgsMainLoop
1104 * @config: (nullable): the #AgsConfig
1105 *
1106 * Create a new instance of #AgsApplicationContext
1107 *
1108 * Returns: the #AgsApplicationContext instance
1109 *
1110 * Since: 3.0.0
1111 */
1112 AgsApplicationContext*
ags_application_context_new(GObject * main_loop,AgsConfig * config)1113 ags_application_context_new(GObject *main_loop,
1114 AgsConfig *config)
1115 {
1116 AgsApplicationContext *application_context;
1117
1118 application_context = (AgsApplicationContext *) g_object_new(AGS_TYPE_APPLICATION_CONTEXT,
1119 "main-loop", main_loop,
1120 "config", config,
1121 NULL);
1122
1123 return(application_context);
1124 }
1125