[GApplication] Tweak docs a bit
[platform/upstream/glib.git] / gio / gapplication.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright © 2010 Red Hat, Inc
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Authors: Colin Walters <walters@verbum.org>
21  *          Emmanuele Bassi <ebassi@linux.intel.com>
22  */
23
24 #include "config.h"
25
26 #include <string.h>
27 #include <stdlib.h>
28
29 #include <gobject/gvaluecollector.h>
30
31 #include "gapplication.h"
32 #include "gio-marshal.h"
33 #include "glibintl.h"
34
35 #include "gioerror.h"
36
37 #include "gdbusconnection.h"
38 #include "gdbusintrospection.h"
39 #include "gdbusmethodinvocation.h"
40
41 #include "gioalias.h"
42
43 /**
44  * SECTION: gapplication
45  * @title: GApplication
46  * @short_description: Core application class
47  *
48  * A #GApplication is the foundation of an application, unique for a
49  * given application identifier.  The #GApplication wraps some
50  * low-level platform-specific services and is intended to act as the
51  * foundation for higher-level application classes such as
52  * #GtkApplication or #MxApplication.  In general, you should not use
53  * this class outside of a higher level framework.  By default,
54  * g_application_register_with_data() will invoke g_error() if it is
55  * run in a context where it cannot support its core features.  Note
56  * that g_error() is by default fatal.
57  *
58  * One of the core features that #GApplication provides is process
59  * uniqueness, in the context of a "session".  The session concept is
60  * platform-dependent, but corresponds roughly to a graphical desktop
61  * login.  When your application is launched again, its arguments
62  * are passed through platform communication to the already running
63  * program.
64  *
65  * In addition, #GApplication provides support for 'actions', which
66  * can be presented to the user in a platform-specific way
67  * (e.g. Windows 7 jump lists). Note that these are just simple
68  * actions without parameters. For more flexible scriptability,
69  * implementing a a separate D-Bus interface is recommended, see e.g.
70  * <xref linkend="gdbus-convenience"/>.
71  * 
72  * Finally, #GApplication acts as a basic lifecycle root; see the
73  * g_application_run() and g_application_quit_with_data() methods.
74  *
75  * Before using #GApplication, you must choose an "application identifier".
76  * The expected form of an application identifier is very close to that of
77  * of a <ulink url="http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-interface">DBus bus name</ulink>.
78  * Examples include: "com.example.MyApp" "org.example.internal-apps.Calculator"
79  * For convenience, the restrictions on application identifiers are reproduced
80  * here:
81  * <itemizedlist>
82  *   <listitem>Application identifiers must contain only the ASCII characters "[A-Z][a-z][0-9]_-" and must not begin with a digit.</listitem>
83  *   <listitem>Application identifiers must contain at least one '.' (period) character (and thus at least two elements).</listitem>
84  *   <listitem>Application identifiers must not begin with a '.' (period) character.</listitem>
85  *   <listitem>Application identifiers must not exceed 255 characters.</listitem>
86  * </itemizedlist>
87  *
88  * <refsect2><title>D-Bus implementation</title>
89  * <para>
90  * On UNIX systems using D-Bus, #GApplication is implemented by claiming the
91  * application identifier as a bus name on the session bus. The implementation
92  * exports an object at the object path that is created by replacing '.' with
93  * '/' in the application identifier (e.g. the object path for the
94  * application id 'org.gtk.TestApp' is '/org/gtk/TestApp'). The object
95  * implements the org.gtk.Application interface.
96  * </para>
97  * <classsynopsis class="interface">
98  *   <ooclass><interfacename>org.gtk.Application</interfacename></ooclass>
99  *   <methodsynopsis>
100  *     <void/>
101  *     <methodname>Activate</methodname>
102  *     <methodparam><modifier>in</modifier><type>aay</type><parameter>arguments</parameter></methodparam>
103  *     <methodparam><modifier>in</modifier><type>a{sv}</type><parameter>data</parameter></methodparam>
104  *   </methodsynopsis>
105  *   <methodsynopsis>
106  *     <void/>
107  *     <methodname>InvokeAction</methodname>
108  *     <methodparam><modifier>in</modifier><type>s</type><parameter>action</parameter></methodparam>
109  *     <methodparam><modifier>in</modifier><type>u</type><parameter>timestamp</parameter></methodparam>
110  *   </methodsynopsis>
111  *   <methodsynopsis>
112  *     <type>a{s(sb)}</type>
113  *     <methodname>ListActions</methodname>
114  *     <void/>
115  *   </methodsynopsis>
116  *   <methodsynopsis>
117  *     <void/>
118  *     <methodname>Quit</methodname>
119  *     <methodparam><modifier>in</modifier><type>u</type><parameter>timestamp</parameter></methodparam>
120  *   </methodsynopsis>
121  *   <methodsynopsis>
122  *     <modifier>Signal</modifier>
123  *     <void/>
124  *     <methodname>ActionsChanged</methodname>
125  *     <void/>
126  *   </methodsynopsis>
127  * </classsynopsis>
128  * <para>
129  * The <methodname>Activate</methodname> function is called on the existing
130  * application instance when a second instance fails to take the bus name.
131  * @arguments contains the commandline arguments given to the second instance
132  * and @data contains platform-specific additional data, see
133  * g_application_format_activation_data().
134  * </para>
135  * <para>
136  * The <methodname>InvokeAction</methodname> function can be called to invoke
137  * one of the actions exported by the application. The @timestamp parameter
138  * should be taken from the user event that triggered the method call (e.g.
139  * a button press event).
140  * </para>
141  * <para>
142  * The <methodname>ListActions</methodname> function returns a dictionary
143  * with the exported actions of the application. The keys of the dictionary
144  * are the action names, and the values are structs containing the description
145  * for the action and a boolean that represents if the action is enabled or not.
146  * </para>
147  * <para>
148  * The <methodname>Quit</methodname> function can be called to terminate
149  * the application. The @timestamp parameter should be taken from the user
150  * event that triggered the method call (e.g. a button press event).
151  * </para>
152  * <para>
153  * The <methodname>ActionsChanged</methodname> signal is emitted when the
154  * exported actions change (i.e. an action is added, removed, enabled,
155  * disabled, or otherwise changed).
156  * </para>
157  * <para>
158  * #GApplication is supported since Gio 2.26.
159  * </para>
160  * </refsect2>
161  */
162
163 G_DEFINE_TYPE (GApplication, g_application, G_TYPE_OBJECT);
164
165 enum
166 {
167   PROP_0,
168
169   PROP_APPLICATION_ID,
170   PROP_DEFAULT_QUIT,
171   PROP_IS_REMOTE
172 };
173
174 enum
175 {
176   QUIT,
177   ACTION,
178   PREPARE_ACTIVATION,
179
180   LAST_SIGNAL
181 };
182
183 static guint application_signals[LAST_SIGNAL] = { 0 };
184
185 typedef struct {
186   gchar *name;
187   gchar *description;
188   guint enabled : 1;
189 } GApplicationAction;
190
191 struct _GApplicationPrivate
192 {
193   gchar *appid;
194   GHashTable *actions; /* name -> GApplicationAction */
195   GMainLoop *mainloop;
196
197   guint default_quit : 1;
198   guint is_remote    : 1;
199
200   guint actions_changed_id;
201
202 #ifdef G_OS_UNIX
203   gchar *dbus_path;
204   GDBusConnection *session_bus;
205 #endif
206 };
207
208 static GApplication *primary_application = NULL;
209 static GHashTable *instances_for_appid = NULL;
210
211 static void     _g_application_platform_init                    (GApplication  *app); 
212 static gboolean _g_application_platform_acquire_single_instance (GApplication  *app,
213                                                                  GError       **error);
214 static void     _g_application_platform_remote_invoke_action    (GApplication  *app,
215                                                                  const gchar   *action,
216                                                                  guint          timestamp);
217 static void     _g_application_platform_remote_quit             (GApplication  *app,
218                                                                  guint          timestamp);
219 static void     _g_application_platform_activate                (GApplication  *app,
220                                                                  GVariant      *data) G_GNUC_NORETURN;
221 static void     _g_application_platform_on_actions_changed      (GApplication  *app);
222
223 #ifdef G_OS_UNIX
224 #include "gdbusapplication.c"
225 #else
226 #include "gnullapplication.c"
227 #endif
228
229 static gboolean
230 _g_application_validate_id (const char *id)
231 {
232   gboolean allow_dot;
233
234   if (strlen (id) > 255)
235     return FALSE;
236
237   if (!g_ascii_isalpha (*id))
238     return FALSE;
239
240   id++;
241   allow_dot = FALSE;
242   for (; *id; id++)
243     {
244       if (g_ascii_isalnum (*id) || (*id == '-') || (*id == '_'))
245         allow_dot = TRUE;
246       else if (allow_dot && *id == '.')
247         allow_dot = FALSE;
248       else
249         return FALSE;
250     }
251   return TRUE;
252 }
253
254 static gpointer
255 init_appid_statics (gpointer data)
256 {
257   instances_for_appid = g_hash_table_new (g_str_hash, g_str_equal);
258   return NULL;
259 }
260
261 static GApplication *
262 application_for_appid (const char *appid)
263 {
264   static GOnce appid_once = G_ONCE_INIT;
265
266   g_once (&appid_once, init_appid_statics, NULL);
267
268   return g_hash_table_lookup (instances_for_appid, appid);
269 }
270
271 static gboolean
272 g_application_default_quit (GApplication *application,
273                             guint         timestamp)
274 {
275   g_return_val_if_fail (application->priv->mainloop != NULL, FALSE);
276   g_main_loop_quit (application->priv->mainloop);
277
278   return TRUE;
279 }
280
281 static void
282 g_application_default_run (GApplication *application)
283 {
284   if (application->priv->mainloop == NULL)
285     application->priv->mainloop = g_main_loop_new (NULL, TRUE);
286
287   g_main_loop_run (application->priv->mainloop);
288 }
289
290 static void
291 _g_application_handle_activation (GApplication  *app,
292                                   int            argc,
293                                   char         **argv,
294                                   GVariant      *platform_data)
295 {
296   GVariantBuilder builder;
297   GVariant *message;
298   int i;
299
300   g_variant_builder_init (&builder, G_VARIANT_TYPE ("(aaya{sv})"));
301   g_variant_builder_open (&builder, G_VARIANT_TYPE ("aay"));
302
303   for (i = 1; i < argc; i++)
304     {
305       int j;
306       guint8 *argv_bytes;
307
308       g_variant_builder_open (&builder, G_VARIANT_TYPE ("ay"));
309
310       argv_bytes = (guint8*) argv[i];
311       for (j = 0; argv_bytes[j]; j++)
312         g_variant_builder_add_value (&builder,
313                                      g_variant_new_byte (argv_bytes[j]));
314       g_variant_builder_close (&builder);
315     }
316   g_variant_builder_close (&builder);
317
318   if (platform_data)
319     g_variant_builder_add (&builder, "@a{sv}", platform_data);
320   else
321     {
322       g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}"));
323       g_variant_builder_close (&builder);
324     }
325
326   message = g_variant_builder_end (&builder);
327   _g_application_platform_activate (app, message);
328   g_variant_unref (message);
329 }
330
331 static gboolean
332 timeout_handle_actions_changed (gpointer user_data)
333 {
334   GApplication *application = user_data;
335
336   application->priv->actions_changed_id = 0;
337
338   _g_application_platform_on_actions_changed (application);
339
340   return FALSE;
341 }
342
343 static inline void
344 queue_actions_change_notification (GApplication *application)
345 {
346   GApplicationPrivate *priv = application->priv;
347
348   if (priv->actions_changed_id == 0)
349     priv->actions_changed_id = g_timeout_add (0, timeout_handle_actions_changed, application);
350 }
351
352 static void
353 g_application_action_free (gpointer data)
354 {
355   if (G_LIKELY (data != NULL))
356     {
357       GApplicationAction *action = data;
358
359       g_free (action->name);
360       g_free (action->description);
361
362       g_slice_free (GApplicationAction, action);
363     }
364 }
365
366
367 /**
368  * g_application_new:
369  * @appid: System-dependent application identifier
370  *
371  * Create a new #GApplication.  The application is initially in
372  * "remote" mode.  Almost certainly, you want to call
373  * g_application_register() immediately after this function, which
374  * will finish initialization.
375  *
376  * As a convenience, this function is defined to call g_type_init() as
377  * its very first action.
378  *
379  * Returns: (transfer full): An application instance
380  *
381  * Since: 2.26
382  */
383 GApplication *
384 g_application_new (const gchar *appid)
385 {
386   g_type_init ();
387
388   return G_APPLICATION (g_object_new (G_TYPE_APPLICATION, "application-id", appid, NULL));
389 }
390
391 /**
392  * g_application_register_with_data:
393  * @application: A #GApplication
394  * @argc: System argument count
395  * @argv: (array length=argc): System argument vector
396  * @platform_data: (allow-none): Arbitrary platform-specific data, must have signature "a{sv}"
397  *
398  * Ensure the current process is the unique owner of the application.
399  * If successful, the #GApplication:is-remote property will be changed
400  * to %FALSE, and it is safe to continue creating other resources
401  * such as graphics windows.
402  *
403  * If the given @appid is already running in another process, the
404  * #GApplication:default-exit property will be evaluated.  If it's
405  * %TRUE, then a platform-specific action such as bringing any
406  * graphics windows associated with the application to the foreground
407  * may be initiated.  After that, the current process will terminate.
408  * If %FALSE, then the application remains in the #GApplication:is-remote
409  * state, and you can e.g. call g_application_invoke_action().
410  *
411  * This function may do synchronous I/O to obtain unique ownership
412  * of the application id, and will block the calling thread in this
413  * case.
414  */
415 void
416 g_application_register_with_data (GApplication  *application,
417                                   gint           argc,
418                                   gchar        **argv,
419                                   GVariant      *platform_data)
420 {
421   g_return_if_fail (application->priv->appid != NULL);
422   g_return_if_fail (application->priv->is_remote);
423   g_return_if_fail (platform_data == NULL
424                     || g_variant_is_of_type (platform_data, G_VARIANT_TYPE ("a{sv}")));
425
426   if (!_g_application_platform_acquire_single_instance (application, NULL))
427     {
428       if (application->priv->default_quit)
429         _g_application_handle_activation (application, argc, argv, platform_data);
430       else
431         return;
432     }
433
434   application->priv->is_remote = FALSE;
435
436   _g_application_platform_init (application);
437 }
438
439 /**
440  * g_application_new_and_register:
441  * @appid: An application identifier
442  * @argc: System argument count
443  * @argv: (array length=argc): System argument vector
444  *
445  * This is a convenience function which combines g_application_new()
446  * with g_application_register_with_data(). Therefore, it may block
447  * the calling thread just like g_application_register_with_data().
448  */
449 GApplication *
450 g_application_new_and_register (const gchar  *appid,
451                                 gint          argc,
452                                 gchar       **argv)
453 {
454   GApplication *app = g_application_new (appid);
455   g_application_register_with_data (app, argc, argv, NULL);
456   return app;
457 }
458
459 /**
460  * g_application_add_action:
461  * @application: a #GApplication
462  * @name: the action name
463  * @description: the action description; can be a translatable
464  *   string
465  *
466  * Adds an action @name to the list of exported actions of @application.
467  *
468  * It is an error to call this function if @application is a proxy for
469  * a remote application.
470  *
471  * You can invoke an action using g_application_invoke_action().
472  *
473  * The newly added action is enabled by default; you can call
474  * g_application_set_action_enabled() to disable it.
475  *
476  * Since: 2.26
477  */
478 void
479 g_application_add_action (GApplication *application,
480                           const gchar  *name,
481                           const gchar  *description)
482 {
483   GApplicationPrivate *priv;
484   GApplicationAction *action;
485
486   g_return_if_fail (G_IS_APPLICATION (application));
487   g_return_if_fail (name != NULL && *name != '\0');
488   g_return_if_fail (!application->priv->is_remote);
489
490   priv = application->priv;
491
492   g_return_if_fail (g_hash_table_lookup (priv->actions, name) == NULL);
493
494   action = g_slice_new (GApplicationAction);
495   action->name = g_strdup (name);
496   action->description = g_strdup (description);
497   action->enabled = TRUE;
498
499   g_hash_table_insert (priv->actions, action->name, action);
500   queue_actions_change_notification (application);
501 }
502
503 /**
504  * g_application_remove_action:
505  * @application: a #GApplication
506  * @name: the name of the action to remove
507  *
508  * Removes the action @name from the list of exported actions of @application.
509  *
510  * It is an error to call this function if @application is a proxy for
511  * a remote application.
512  *
513  * Since: 2.26
514  */
515 void
516 g_application_remove_action (GApplication *application,
517                              const gchar  *name)
518 {
519   GApplicationPrivate *priv;
520
521   g_return_if_fail (G_IS_APPLICATION (application));
522   g_return_if_fail (name != NULL && *name != '\0');
523   g_return_if_fail (!application->priv->is_remote);
524
525   priv = application->priv;
526
527   g_return_if_fail (g_hash_table_lookup (priv->actions, name) != NULL);
528
529   g_hash_table_remove (priv->actions, name);
530   queue_actions_change_notification (application);
531 }
532
533 /**
534  * g_application_invoke_action:
535  * @application: a #GApplication
536  * @name: the name of the action to invoke
537  * @timestamp: the timestamp that is going to be passed to
538  *   the #GApplication::action signal
539  *
540  * Invokes the action @name of the passed #GApplication.
541  *
542  * This function has different behavior depending on whether @application
543  * is acting as a proxy for another process.  In the normal case where
544  * the current process is hosting the application, and the specified
545  * action exists and is enabled, the #GApplication::action signal will
546  * be emitted.
547  *
548  * If @application is a proxy, then the specified action will be invoked
549  * in the remote process. It is not necessary to call
550  * g_application_add_action() in the current process in order to invoke
551  * one remotely.
552  *
553  * Since: 2.26
554  */
555 void
556 g_application_invoke_action (GApplication *application,
557                              const gchar  *name,
558                              guint         timestamp)
559 {
560   GApplicationPrivate *priv;
561   GApplicationAction *action;
562
563   g_return_if_fail (G_IS_APPLICATION (application));
564   g_return_if_fail (name != NULL);
565
566   priv = application->priv;
567
568   if (priv->is_remote)
569     {
570       _g_application_platform_remote_invoke_action (application, name, timestamp);
571       return;
572     }
573
574   action = g_hash_table_lookup (priv->actions, name);
575   g_return_if_fail (action != NULL);
576   if (!action->enabled)
577     return;
578
579   g_signal_emit (application, application_signals[ACTION],
580                  g_quark_from_string (name),
581                  name,
582                  timestamp);
583 }
584
585 /**
586  * g_application_list_actions:
587  * @application: a #GApplication
588  *
589  * Retrieves the list of action names currently exported by @application.
590  *
591  * It is an error to call this function if @application is a proxy for
592  * a remote application.
593  *
594  * Return value: (transfer full): a newly allocation, %NULL-terminated array
595  *   of strings containing action names; use g_strfreev() to free the
596  *   resources used by the returned array
597  *
598  * Since: 2.26
599  */
600 gchar **
601 g_application_list_actions (GApplication *application)
602 {
603   GApplicationPrivate *priv;
604   GHashTableIter iter;
605   gpointer key;
606   gchar **retval;
607   gint i;
608
609   g_return_val_if_fail (G_IS_APPLICATION (application), NULL);
610   g_return_val_if_fail (!application->priv->is_remote, NULL);
611
612   priv = application->priv;
613
614   retval = g_new (gchar*, g_hash_table_size (priv->actions));
615
616   i = 0;
617   g_hash_table_iter_init (&iter, priv->actions);
618   while (g_hash_table_iter_next (&iter, &key, NULL))
619     retval[i++] = g_strdup (key);
620
621   retval[i] = NULL;
622
623   return retval;
624 }
625
626 /**
627  * g_application_set_action_enabled:
628  * @application: a #GApplication
629  * @name: the name of the application
630  * @enabled: whether to enable or disable the action @name
631  *
632  * Sets whether the action @name inside @application should be enabled
633  * or disabled.
634  *
635  * It is an error to call this function if @application is a proxy for
636  * a remote application.
637  *
638  * Invoking a disabled action will not result in the #GApplication::action
639  * signal being emitted.
640  *
641  * Since: 2.26
642  */
643 void
644 g_application_set_action_enabled (GApplication *application,
645                                   const gchar  *name,
646                                   gboolean      enabled)
647 {
648   GApplicationAction *action;
649
650   g_return_if_fail (G_IS_APPLICATION (application));
651   g_return_if_fail (name != NULL);
652   g_return_if_fail (!application->priv->is_remote);
653
654   enabled = !!enabled;
655
656   action = g_hash_table_lookup (application->priv->actions, name);
657   g_return_if_fail (action != NULL);
658   if (action->enabled == enabled)
659     return;
660
661   action->enabled = enabled;
662
663   queue_actions_change_notification (application);
664 }
665
666
667 /**
668  * g_application_get_action_description:
669  * @application: a #GApplication
670  * @name: Action name
671  *
672  * Gets the description of the action @name.
673  *
674  * It is an error to call this function if @application is a proxy for
675  * a remote application.
676  *
677  * Returns: Description for the given action named @name
678  *
679  * Since: 2.26
680  */
681 G_CONST_RETURN gchar *
682 g_application_get_action_description (GApplication *application,
683                                       const gchar  *name)
684 {
685   GApplicationAction *action;
686   
687   g_return_val_if_fail (G_IS_APPLICATION (application), NULL);
688   g_return_val_if_fail (name != NULL, NULL);
689   g_return_val_if_fail (!application->priv->is_remote, NULL);
690
691   action = g_hash_table_lookup (application->priv->actions, name);
692   g_return_val_if_fail (action != NULL, NULL);
693
694   return action->description;
695 }
696
697
698 /**
699  * g_application_get_action_enabled:
700  * @application: a #GApplication
701  * @name: the name of the action
702  *
703  * Retrieves whether the action @name is enabled or not.
704  *
705  * See g_application_set_action_enabled().
706  *
707  * It is an error to call this function if @application is a proxy for
708  * a remote application.
709  *
710  * Return value: %TRUE if the action was enabled, and %FALSE otherwise
711  *
712  * Since: 2.26
713  */
714 gboolean
715 g_application_get_action_enabled (GApplication *application,
716                                   const gchar  *name)
717 {
718   GApplicationAction *action;
719
720   g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
721   g_return_val_if_fail (name != NULL, FALSE);
722   g_return_val_if_fail (!application->priv->is_remote, FALSE);
723
724   action = g_hash_table_lookup (application->priv->actions, name);
725   g_return_val_if_fail (action != NULL, FALSE);
726
727   return action->enabled;
728 }
729
730 /**
731  * g_application_run:
732  * @application: a #GApplication
733  *
734  * Starts the application.
735  *
736  * The default implementation of this virtual function will simply run
737  * a main loop.
738  *
739  * It is an error to call this function if @application is a proxy for
740  * a remote application.
741  *
742  * Since: 2.26
743  */
744 void
745 g_application_run (GApplication *application)
746 {
747   g_return_if_fail (G_IS_APPLICATION (application));
748   g_return_if_fail (!application->priv->is_remote);
749
750   G_APPLICATION_GET_CLASS (application)->run (application);
751 }
752
753 /**
754  * g_application_quit:
755  * @application: a #GApplication
756  * @timestamp: Platform-specific event timestamp, may be 0 for default
757  *
758  * Request that the application quits.
759  *
760  * This function has different behavior depending on whether @application
761  * is acting as a proxy for another process.  In the normal case where
762  * the current process is hosting the application, the default
763  * implementation will quit the main loop created by g_application_run().
764  *
765  * If @application is a proxy, then the remote process will be asked
766  * to quit.
767  *
768  * Returns: %TRUE if the application accepted the request, %FALSE otherwise
769  *
770  * Since: 2.26
771  */
772 gboolean
773 g_application_quit (GApplication *application,
774                     guint         timestamp)
775 {
776   gboolean retval = FALSE;
777
778   g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
779
780   if (application->priv->is_remote)
781     {
782        _g_application_platform_remote_quit (application, timestamp);
783        retval = TRUE;
784     }
785   else
786     g_signal_emit (application, application_signals[QUIT], 0, timestamp, &retval);
787
788   return retval;
789 }
790
791 /**
792  * g_application_get_instance:
793  *
794  * In the normal case where there is exactly one #GApplication instance
795  * in this process, return that instance.  If there are multiple, the
796  * first one created will be returned.  Otherwise, return %NULL.
797  *
798  * Returns: (transfer none): The primary instance of #GApplication,
799  *   or %NULL if none is set
800  *
801  * Since: 2.26
802  */
803 GApplication *
804 g_application_get_instance (void)
805 {
806   return primary_application;
807 }
808
809 /**
810  * g_application_get_id:
811  * @application: a #GApplication
812  *
813  * Retrieves the platform-specific identifier for the #GApplication.
814  *
815  * Return value: The platform-specific identifier. The returned string
816  *   is owned by the #GApplication instance and it should never be
817  *   modified or freed
818  *
819  * Since: 2.26
820  */
821 G_CONST_RETURN gchar *
822 g_application_get_id (GApplication *application)
823 {
824   g_return_val_if_fail (G_IS_APPLICATION (application), NULL);
825
826   return application->priv->appid;
827 }
828
829 /**
830  * g_application_is_remote:
831  * @application: a #GApplication
832  *
833  * Returns: %TRUE if this object represents a proxy for a remote application.
834  */
835 gboolean
836 g_application_is_remote (GApplication *application)
837 {
838   g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
839
840   return application->priv->is_remote;
841 }
842
843 static void
844 g_application_init (GApplication *app)
845 {
846   app->priv = G_TYPE_INSTANCE_GET_PRIVATE (app,
847                                            G_TYPE_APPLICATION,
848                                            GApplicationPrivate);
849
850   app->priv->actions = g_hash_table_new_full (g_str_hash, g_str_equal,
851                                               NULL,
852                                               g_application_action_free);
853   app->priv->default_quit = TRUE;
854   app->priv->is_remote = TRUE;
855 }
856
857 static void
858 g_application_get_property (GObject    *object,
859                             guint       prop_id,
860                             GValue     *value,
861                             GParamSpec *pspec)
862 {
863   GApplication *app = G_APPLICATION (object);
864
865   switch (prop_id)
866     {
867     case PROP_APPLICATION_ID:
868       g_value_set_string (value, g_application_get_id (app));
869       break;
870
871     case PROP_DEFAULT_QUIT:
872       g_value_set_boolean (value, app->priv->default_quit);
873       break;
874
875     case PROP_IS_REMOTE:
876       g_value_set_boolean (value, g_application_is_remote (app));
877       break;
878
879     default:
880       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
881     }
882 }
883
884 static void
885 g_application_set_property (GObject      *object,
886                             guint         prop_id,
887                             const GValue *value,
888                             GParamSpec   *pspec)
889 {
890   GApplication *app = G_APPLICATION (object);
891
892   switch (prop_id)
893     {
894     case PROP_APPLICATION_ID:
895       g_return_if_fail (_g_application_validate_id (g_value_get_string (value)));
896       app->priv->appid = g_value_dup_string (value);
897       break;
898
899     case PROP_DEFAULT_QUIT:
900       app->priv->default_quit = g_value_get_boolean (value);
901       break;
902
903     default:
904       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
905     }
906 }
907
908 static GObject*
909 g_application_constructor (GType                  type,
910                            guint                  n_construct_properties,
911                            GObjectConstructParam *construct_params)
912 {
913   GApplication *app;
914   GObject *object;
915   const char *appid = NULL;
916   guint i;
917
918   for (i = 0; i < n_construct_properties; i++)
919     {
920       GObjectConstructParam *param = &construct_params[i];
921       if (strcmp (param->pspec->name, "application-id") == 0)
922         appid = g_value_get_string (param->value);
923     }
924
925   g_return_val_if_fail (appid != NULL, NULL);
926
927   app = application_for_appid (appid);
928   if (app != NULL)
929     return g_object_ref (app);
930
931   object = (* G_OBJECT_CLASS (g_application_parent_class)->constructor) (type,
932                                                                          n_construct_properties,
933                                                                          construct_params);
934   app = G_APPLICATION (object);
935
936   if (primary_application == NULL)
937     primary_application = app;
938   g_hash_table_insert (instances_for_appid, g_strdup (appid), app);
939
940   return object;
941 }
942
943 static void
944 g_application_finalize (GObject *object)
945 {
946   GApplication *app = G_APPLICATION (object);
947
948   g_free (app->priv->appid);
949   if (app->priv->actions)
950     g_hash_table_unref (app->priv->actions);
951   if (app->priv->actions_changed_id)
952     g_source_remove (app->priv->actions_changed_id);
953   if (app->priv->mainloop)
954     g_main_loop_unref (app->priv->mainloop);
955
956 #ifdef G_OS_UNIX
957   g_free (app->priv->dbus_path);
958   if (app->priv->session_bus)
959     g_object_unref (app->priv->session_bus);
960 #endif
961
962   G_OBJECT_CLASS (g_application_parent_class)->finalize (object);
963 }
964
965 static void
966 g_application_class_init (GApplicationClass *klass)
967 {
968   GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
969
970   g_type_class_add_private (klass, sizeof (GApplicationPrivate));
971
972   gobject_class->constructor = g_application_constructor;
973   gobject_class->set_property = g_application_set_property;
974   gobject_class->get_property = g_application_get_property;
975
976   gobject_class->finalize = g_application_finalize;
977
978   klass->run = g_application_default_run;
979   klass->quit = g_application_default_quit;
980
981   /**
982    * GApplication::quit:
983    * @application: the object on which the signal is emitted
984    * @timestamp: Platform-specific event timestamp, may be 0 for default
985    *
986    * This signal is emitted when the Quit action is invoked on the
987    * application.
988    *
989    * The default handler for this signal exits the mainloop of the
990    * application.
991    *
992    * Returns: %TRUE if the signal has been handled, %FALSE to continue
993    *   signal emission
994    */
995   application_signals[QUIT] =
996     g_signal_new (g_intern_static_string ("quit"),
997                   G_OBJECT_CLASS_TYPE (klass),
998                   G_SIGNAL_RUN_LAST,
999                   G_STRUCT_OFFSET (GApplicationClass, quit),
1000                   g_signal_accumulator_true_handled, NULL,
1001                   _gio_marshal_BOOLEAN__UINT,
1002                   G_TYPE_BOOLEAN, 1,
1003                   G_TYPE_UINT);
1004
1005   /**
1006    * GApplication::action:
1007    * @application: the object on which the signal is emitted
1008    * @name: The name of the activated action
1009    * @timestamp: Platform-specific event timestamp, may be 0 for default
1010    *
1011    * This signal is emitted when an action is activated. The action name
1012    * is passed as the first argument, but also as signal detail, so it
1013    * is possible to connect to this signal for individual actions.
1014    *
1015    * The signal is never emitted for disabled actions.
1016    */
1017   application_signals[ACTION] =
1018     g_signal_new (g_intern_static_string ("action"),
1019                   G_OBJECT_CLASS_TYPE (klass),
1020                   G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED,
1021                   G_STRUCT_OFFSET (GApplicationClass, action),
1022                   NULL, NULL,
1023                   _gio_marshal_VOID__STRING_UINT,
1024                   G_TYPE_NONE, 2,
1025                   G_TYPE_STRING,
1026                   G_TYPE_UINT);
1027
1028    /**
1029    * GApplication::prepare-activation:
1030    * @application: the object on which the signal is emitted
1031    * @arguments: A #GVariant with the signature "aay"
1032    * @platform_data: A #GVariant with the signature "a{sv}"
1033    *
1034    * This signal is emitted when a non-primary process for a given
1035    * application is invoked while your application is running; for
1036    * example, when a file browser launches your program to open a
1037    * file.  The raw operating system arguments are passed in the
1038    * @arguments variant.  Additional platform-dependent data is
1039    * stored in @platform_data.
1040    */
1041   application_signals[PREPARE_ACTIVATION] =
1042     g_signal_new (g_intern_static_string ("prepare-activation"),
1043                   G_OBJECT_CLASS_TYPE (klass),
1044                   G_SIGNAL_RUN_LAST,
1045                   G_STRUCT_OFFSET (GApplicationClass, prepare_activation),
1046                   NULL, NULL,
1047                   _gio_marshal_VOID__BOXED_BOXED,
1048                   G_TYPE_NONE, 2,
1049                   G_TYPE_VARIANT,
1050                   G_TYPE_VARIANT);
1051
1052    /**
1053    * GApplication:application-id:
1054    *
1055    * The unique identifier for this application.  See the documentation for
1056    * #GApplication for more information about this property.
1057    *
1058    */
1059   g_object_class_install_property (gobject_class,
1060                                    PROP_APPLICATION_ID,
1061                                    g_param_spec_string ("application-id",
1062                                                         P_("Application ID"),
1063                                                         P_("Identifier for this application"),
1064                                                         NULL,
1065                                                         G_PARAM_READWRITE |
1066                                                         G_PARAM_CONSTRUCT_ONLY |
1067                                                         G_PARAM_STATIC_STRINGS));
1068
1069   /**
1070    * GApplication:default-quit:
1071    *
1072    * By default, if a different process is running this application, the
1073    * process will be exited.  Set this property to %FALSE to allow custom
1074    * interaction with the remote process.
1075    *
1076    */
1077   g_object_class_install_property (gobject_class,
1078                                    PROP_DEFAULT_QUIT,
1079                                    g_param_spec_boolean ("default-quit",
1080                                                          P_("Default Quit"),
1081                                                          P_("Exit the process by default"),
1082                                                          TRUE,
1083                                                          G_PARAM_READWRITE |
1084                                                          G_PARAM_CONSTRUCT_ONLY |
1085                                                          G_PARAM_STATIC_STRINGS));
1086
1087
1088   /**
1089    * GApplication:is-remote:
1090    *
1091    * This property is %TRUE if this application instance represents a proxy
1092    * to the instance of this application in another process.
1093    *
1094    */
1095   g_object_class_install_property (gobject_class,
1096                                    PROP_IS_REMOTE,
1097                                    g_param_spec_boolean ("is-remote",
1098                                                          P_("Is Remote"),
1099                                                          P_("Whether this application is a proxy for another process"),
1100                                                          TRUE,
1101                                                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
1102 }
1103
1104 #define __G_APPLICATION_C__
1105 #include "gioaliasdef.c"