GApplication: use g_signal_accumulator_first_wins
[platform/upstream/glib.git] / gio / gapplication.c
1 /*
2  * Copyright © 2010 Codethink Limited
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published
6  * by the Free Software Foundation; either version 2 of the licence or (at
7  * your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Authors: Ryan Lortie <desrt@desrt.ca>
20  */
21
22 /* Prologue {{{1 */
23 #include "gapplication.h"
24
25 #include "gapplicationcommandline.h"
26 #include "gapplicationimpl.h"
27 #include "gactiongroup.h"
28
29 #include "gioenumtypes.h"
30 #include "gio-marshal.h"
31 #include "gioenums.h"
32 #include "gfile.h"
33
34 #include <string.h>
35
36 struct _GApplicationPrivate
37 {
38   GApplicationFlags  flags;
39   gchar             *id;
40
41   GActionGroup      *actions;
42   GMainLoop         *mainloop;
43
44   guint              inactivity_timeout_id;
45   guint              inactivity_timeout;
46   guint              use_count;
47
48   guint              is_registered : 1;
49   guint              is_remote : 1;
50
51   GApplicationImpl  *impl;
52 };
53
54 enum
55 {
56   PROP_NONE,
57   PROP_APPLICATION_ID,
58   PROP_FLAGS,
59   PROP_IS_REGISTERED,
60   PROP_IS_REMOTE,
61   PROP_INACTIVITY_TIMEOUT,
62   PROP_ACTION_GROUP
63 };
64
65 enum
66 {
67   SIGNAL_STARTUP,
68   SIGNAL_ACTIVATE,
69   SIGNAL_OPEN,
70   SIGNAL_ACTION,
71   SIGNAL_COMMAND_LINE,
72   NR_SIGNALS
73 };
74
75 static guint g_application_signals[NR_SIGNALS];
76
77 static void g_application_action_group_iface_init (GActionGroupInterface *);
78 G_DEFINE_TYPE_WITH_CODE (GApplication, g_application, G_TYPE_OBJECT,
79  G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP,
80    g_application_action_group_iface_init))
81
82 /* vfunc defaults {{{1 */
83 static void
84 g_application_real_before_emit (GApplication *application,
85                                 GVariant     *platform_data)
86 {
87 }
88
89 static void
90 g_application_real_after_emit (GApplication *application,
91                                GVariant     *platform_data)
92 {
93 }
94
95 static void
96 g_application_real_startup (GApplication *application)
97 {
98 }
99
100 static void
101 g_application_real_activate (GApplication *application)
102 {
103   if (!g_signal_has_handler_pending (application,
104                                      g_application_signals[SIGNAL_ACTIVATE],
105                                      0, TRUE))
106     {
107       static gboolean warned;
108
109       if (warned)
110         return;
111
112       g_warning ("Your application does not implement "
113                  "g_application_activate() and has no handlers connected "
114                  "to the 'activate' signal.  It should do one of these.");
115       warned = TRUE;
116     }
117 }
118
119 static void
120 g_application_real_open (GApplication  *application,
121                          GFile        **files,
122                          gint           n_files,
123                          const gchar   *hint)
124 {
125   if (!g_signal_has_handler_pending (application,
126                                      g_application_signals[SIGNAL_OPEN],
127                                      0, TRUE))
128     {
129       static gboolean warned;
130
131       if (warned)
132         return;
133
134       g_warning ("Your application claims to support opening files "
135                  "but does not implement g_application_open() and has no "
136                  "handlers connected to the 'open' signal.");
137       warned = TRUE;
138     }
139 }
140
141 static int
142 g_application_real_command_line (GApplication            *application,
143                                  GApplicationCommandLine *cmdline)
144 {
145   static gboolean warned;
146
147   if (warned) 
148     return 1;
149
150   g_warning ("Your application claims to support custom command line "
151              "handling but does not implement g_application_command_line() "
152              "and has no handlers connected to the 'command-line' signal.");
153
154   warned = TRUE;
155
156   return 1;
157 }
158
159 static gboolean
160 g_application_real_local_command_line (GApplication  *application,
161                                        GVariant     **arguments,
162                                        int           *exit_status)
163 {
164   if (application->priv->flags & G_APPLICATION_HANDLES_COMMAND_LINE)
165     return FALSE;
166
167   else
168     {
169       GError *error = NULL;
170       gint n_args;
171
172       if (!g_application_register (application, NULL, &error))
173         {
174           g_critical ("%s", error->message);
175           g_error_free (error);
176           *exit_status = 1;
177           return TRUE;
178         }
179
180       n_args = g_variant_n_children (*arguments);
181
182       if (application->priv->flags & G_APPLICATION_IS_SERVICE)
183         {
184           if (n_args > 1)
185             {
186               g_printerr ("GApplication service mode takes no arguments.\n");
187               application->priv->flags &= ~G_APPLICATION_IS_SERVICE;
188             }
189
190           return TRUE;
191         }
192
193       if (n_args <= 1)
194         {
195           g_application_activate (application);
196           *exit_status = 0;
197         }
198
199       else
200         {
201           if (~application->priv->flags & G_APPLICATION_HANDLES_OPEN)
202             {
203               g_critical ("This application can not open files.");
204               *exit_status = 1;
205             }
206           else
207             {
208               GFile **files;
209               gint n_files;
210               gint i;
211
212               n_files = n_args - 1;
213               files = g_new (GFile *, n_files);
214
215               for (i = 0; i < n_files; i++)
216                 {
217                   const gchar *arg;
218
219                   g_variant_get_child (*arguments, i + 1, "^&ay", &arg);
220                   files[i] = g_file_new_for_commandline_arg (arg);
221                 }
222
223               g_application_open (application, files, n_files, "");
224
225               for (i = 0; i < n_files; i++)
226                 g_object_unref (files[i]);
227               g_free (files);
228
229               *exit_status = 0;
230             }
231         }
232
233       return TRUE;
234     }
235 }
236
237 static void
238 g_application_real_add_platform_data (GApplication    *application,
239                                       GVariantBuilder *builder)
240 {
241 }
242
243 static void
244 g_application_real_quit_mainloop (GApplication *application)
245 {
246   if (application->priv->mainloop != NULL)
247     g_main_loop_quit (application->priv->mainloop);
248 }
249
250 static void
251 g_application_real_run_mainloop (GApplication *application)
252 {
253   if (application->priv->mainloop == NULL)
254     application->priv->mainloop = g_main_loop_new (NULL, FALSE);
255
256   g_main_loop_run (application->priv->mainloop);
257 }
258
259 /* GObject implementation stuff {{{1 */
260 static void
261 g_application_set_property (GObject *object, guint prop_id,
262                             const GValue *value, GParamSpec *pspec)
263 {
264   GApplication *application = G_APPLICATION (object);
265
266   switch (prop_id)
267     {
268     case PROP_APPLICATION_ID:
269       g_application_set_application_id (application,
270                                         g_value_get_string (value));
271       break;
272
273     case PROP_FLAGS:
274       g_application_set_flags (application, g_value_get_flags (value));
275       break;
276
277     case PROP_INACTIVITY_TIMEOUT:
278       g_application_set_inactivity_timeout (application,
279                                             g_value_get_uint (value));
280       break;
281
282     case PROP_ACTION_GROUP:
283       g_application_set_action_group (application,
284                                       g_value_get_object (value));
285       break;
286
287     default:
288       g_assert_not_reached ();
289     }
290 }
291
292 /**
293  * g_application_set_action_group:
294  * @application: a #GApplication
295  * @action_group: a #GActionGroup, or %NULL
296  *
297  * Sets or unsets the group of actions associated with the application.
298  *
299  * These actions are the actions that can be remotely invoked.
300  *
301  * It is an error to call this function after the application has been
302  * registered.
303  *
304  * Since: 2.28
305  **/
306 void
307 g_application_set_action_group (GApplication *application,
308                                 GActionGroup *action_group)
309 {
310   g_return_if_fail (G_IS_APPLICATION (application));
311   g_return_if_fail (application->priv->is_registered);
312
313   if (application->priv->actions != NULL)
314     g_object_unref (application->priv->actions);
315
316   application->priv->actions = action_group;
317
318   if (application->priv->actions != NULL)
319     g_object_ref (application->priv->actions);
320 }
321
322 static void
323 g_application_get_property (GObject *object, guint prop_id,
324                             GValue *value, GParamSpec *pspec)
325 {
326   GApplication *application = G_APPLICATION (object);
327
328   switch (prop_id)
329     {
330     case PROP_APPLICATION_ID:
331       g_value_set_string (value,
332                           g_application_get_application_id (application));
333       break;
334
335     case PROP_FLAGS:
336       g_value_set_flags (value,
337                          g_application_get_flags (application));
338       break;
339
340     case PROP_IS_REGISTERED:
341       g_value_set_boolean (value,
342                            g_application_get_is_registered (application));
343       break;
344
345     case PROP_IS_REMOTE:
346       g_value_set_boolean (value,
347                            g_application_get_is_remote (application));
348       break;
349
350     case PROP_INACTIVITY_TIMEOUT:
351       g_value_set_uint (value,
352                         g_application_get_inactivity_timeout (application));
353       break;
354
355     default:
356       g_assert_not_reached ();
357     }
358 }
359
360 static void
361 g_application_constructed (GObject *object)
362 {
363   GApplication *application = G_APPLICATION (object);
364
365   g_assert (application->priv->id != NULL);
366 }
367
368 static void
369 g_application_finalize (GObject *object)
370 {
371   GApplication *application = G_APPLICATION (object);
372
373   if (application->priv->impl)
374     g_application_impl_destroy (application->priv->impl);
375   g_free (application->priv->id);
376
377   if (application->priv->mainloop)
378     g_main_loop_unref (application->priv->mainloop);
379
380   G_OBJECT_CLASS (g_application_parent_class)
381     ->finalize (object);
382 }
383
384 static void
385 g_application_init (GApplication *application)
386 {
387   application->priv = G_TYPE_INSTANCE_GET_PRIVATE (application,
388                                                    G_TYPE_APPLICATION,
389                                                    GApplicationPrivate);
390 }
391
392 static void
393 g_application_class_init (GApplicationClass *class)
394 {
395   GObjectClass *object_class = G_OBJECT_CLASS (class);
396
397   object_class->constructed = g_application_constructed;
398   object_class->finalize = g_application_finalize;
399   object_class->get_property = g_application_get_property;
400   object_class->set_property = g_application_set_property;
401
402   class->before_emit = g_application_real_before_emit;
403   class->after_emit = g_application_real_after_emit;
404   class->startup = g_application_real_startup;
405   class->activate = g_application_real_activate;
406   class->open = g_application_real_open;
407   class->command_line = g_application_real_command_line;
408   class->local_command_line = g_application_real_local_command_line;
409   class->add_platform_data = g_application_real_add_platform_data;
410   class->quit_mainloop = g_application_real_quit_mainloop;
411   class->run_mainloop = g_application_real_run_mainloop;
412
413   g_object_class_install_property (object_class, PROP_APPLICATION_ID,
414     g_param_spec_string ("application-id", "application identifier",
415                          "Unique identifier for the application",
416                          NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
417                          G_PARAM_STATIC_STRINGS));
418
419   g_object_class_install_property (object_class, PROP_FLAGS,
420     g_param_spec_flags ("flags", "application flags",
421                         "Flags specifying the behaviour of the application",
422                          G_TYPE_APPLICATION_FLAGS, G_APPLICATION_FLAGS_NONE,
423                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
424
425   g_object_class_install_property (object_class, PROP_IS_REGISTERED,
426     g_param_spec_boolean ("is-registered", "is registered",
427                           "If g_application_register() has been called",
428                           FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
429
430   g_object_class_install_property (object_class, PROP_IS_REMOTE,
431     g_param_spec_boolean ("is-remote", "is remote",
432                           "If this application instance is remote",
433                           FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
434
435   g_object_class_install_property (object_class, PROP_INACTIVITY_TIMEOUT,
436     g_param_spec_boolean ("inactivity-timeout", "inactivity timeout",
437                           "time (ms) to stay alive after becoming idle",
438                           FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
439
440   g_object_class_install_property (object_class, PROP_ACTION_GROUP,
441     g_param_spec_object ("action-group", "action group",
442                          "the group of actions that the application exports",
443                          G_TYPE_ACTION_GROUP, 
444                          G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
445
446   g_application_signals[SIGNAL_STARTUP] =
447     g_signal_new ("startup", G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
448                   G_STRUCT_OFFSET (GApplicationClass, startup),
449                   NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
450
451   g_application_signals[SIGNAL_ACTIVATE] =
452     g_signal_new ("activate", G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
453                   G_STRUCT_OFFSET (GApplicationClass, activate),
454                   NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
455
456   g_application_signals[SIGNAL_OPEN] =
457     g_signal_new ("open", G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
458                   G_STRUCT_OFFSET (GApplicationClass, open),
459                   NULL, NULL, _gio_marshal_VOID__POINTER_INT_STRING,
460                   G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_INT, G_TYPE_STRING);
461
462   g_application_signals[SIGNAL_COMMAND_LINE] =
463     g_signal_new ("command-line", G_TYPE_APPLICATION, G_SIGNAL_RUN_LAST,
464                   G_STRUCT_OFFSET (GApplicationClass, command_line),
465                   g_signal_accumulator_first_wins, NULL,
466                   _gio_marshal_INT__OBJECT,
467                   G_TYPE_INT, 1, G_TYPE_APPLICATION_COMMAND_LINE);
468
469   g_type_class_add_private (class, sizeof (GApplicationPrivate));
470 }
471
472 static GVariant *
473 get_platform_data (GApplication *application)
474 {
475   GVariantBuilder *builder;
476   GVariant *result;
477
478   builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
479
480   {
481     gchar *cwd = g_get_current_dir ();
482     g_variant_builder_add (builder, "{sv}", "cwd",
483                            g_variant_new_bytestring (cwd));
484     g_free (cwd);
485   }
486
487   G_APPLICATION_GET_CLASS (application)->
488     add_platform_data (application, builder);
489
490   result = g_variant_builder_end (builder);
491   g_variant_builder_unref (builder);
492
493   return result;
494 }
495
496 /* Application ID validity {{{1 */
497
498 /**
499  * g_application_id_is_valid:
500  * @application_id: a potential application identifier
501  * @returns: %TRUE if @application_id is valid
502  *
503  * Checks if @application_id is a valid application ID.  A valid ID is
504  * required for calls to g_application_new() and
505  * g_application_set_application_id().
506  **/
507 gboolean
508 g_application_id_is_valid (const gchar *application_id)
509 {
510   gboolean allow_dot;
511
512   if (strlen (application_id) > 255)
513     return FALSE;
514
515   if (!g_ascii_isalpha (*application_id))
516     return FALSE;
517
518   application_id++;
519   allow_dot = FALSE;
520   for (; *application_id; application_id++)
521     {
522       if (g_ascii_isalnum (*application_id) ||
523           (*application_id == '-') ||
524           (*application_id == '_'))
525         allow_dot = TRUE;
526       else if (allow_dot && *application_id == '.')
527         allow_dot = FALSE;
528       else
529         return FALSE;
530     }
531
532   return TRUE;
533 }
534
535 /* Public Constructor {{{1 */
536 /**
537  * g_application_new:
538  * @application_id: the application id
539  * @flags: the application flags
540  * @returns: a new #GApplication instance
541  *
542  * Creates a new #GApplication instance.
543  *
544  * This function calls g_type_init() for you.
545  *
546  * The application id must be valid.  See g_application_id_is_valid().
547  **/
548 GApplication *
549 g_application_new (const gchar       *application_id,
550                    GApplicationFlags  flags)
551 {
552   g_return_val_if_fail (g_application_id_is_valid (application_id), NULL);
553
554   g_type_init ();
555
556   return g_object_new (G_TYPE_APPLICATION,
557                        "application-id", application_id,
558                        "flags", flags,
559                        NULL);
560 }
561
562 /* Simple get/set: application id, flags, inactivity timeout {{{1 */
563 /**
564  * g_application_get_application_id:
565  * @application: a #GApplication
566  * @returns: the identifier for @application, owned by @application
567  *
568  * Gets the unique identifier for @application.
569  *
570  * Since: 2.28
571  **/
572 const gchar *
573 g_application_get_application_id (GApplication *application)
574 {
575   g_return_val_if_fail (G_IS_APPLICATION (application), NULL);
576
577   return application->priv->id;
578 }
579
580 /**
581  * g_application_set_application_id:
582  * @application: a #GApplication
583  * @application_id: the identifier for @application
584  *
585  * Sets the unique identifier for @application.
586  *
587  * The application id can only be modified if @application has not yet
588  * been registered.
589  *
590  * The application id must be valid.  See g_application_id_is_valid().
591  *
592  * Since: 2.28
593  **/
594 void
595 g_application_set_application_id (GApplication *application,
596                                   const gchar  *application_id)
597 {
598   g_return_if_fail (G_IS_APPLICATION (application));
599
600   if (g_strcmp0 (application->priv->id, application_id) != 0)
601     {
602       g_return_if_fail (g_application_id_is_valid (application_id));
603       g_return_if_fail (!application->priv->is_registered);
604
605       g_free (application->priv->id);
606       application->priv->id = g_strdup (application_id);
607
608       g_object_notify (G_OBJECT (application), "application-id");
609     }
610 }
611
612 /**
613  * g_application_get_flags:
614  * @application: a #GApplication
615  * @returns: the flags for @application
616  *
617  * Gets the flags for @application.
618  *
619  * See #GApplicationFlags.
620  *
621  * Since: 2.28
622  **/
623 GApplicationFlags
624 g_application_get_flags (GApplication *application)
625 {
626   g_return_val_if_fail (G_IS_APPLICATION (application), 0);
627
628   return application->priv->flags;
629 }
630
631 /**
632  * g_application_set_flags:
633  * @application: a #GApplication
634  * @flags: the flags for @application
635  *
636  * Sets the flags for @application.
637  *
638  * The flags can only be modified if @application has not yet been
639  * registered.
640  *
641  * See #GApplicationFlags.
642  *
643  * Since: 2.28
644  **/
645 void
646 g_application_set_flags (GApplication      *application,
647                          GApplicationFlags  flags)
648 {
649   g_return_if_fail (G_IS_APPLICATION (application));
650
651   if (application->priv->flags != flags)
652     {
653       g_return_if_fail (!application->priv->is_registered);
654
655       application->priv->flags = flags;
656
657       g_object_notify (G_OBJECT (application), "flags");
658     }
659 }
660
661 /**
662  * g_application_get_inactivity_timeout:
663  * @application: a #GApplication
664  *
665  * Gets the current inactivity timeout for the application.
666  *
667  * This is the amount of time (in milliseconds) after the last call to
668  * g_application_release() before the application stops running.
669  *
670  * Returns: the timeout, in milliseconds
671  *
672  * Since: 2.28
673  **/
674 guint
675 g_application_get_inactivity_timeout (GApplication *application)
676 {
677   g_return_val_if_fail (G_IS_APPLICATION (application), 0);
678
679   return application->priv->inactivity_timeout;
680 }
681
682 /**
683  * g_application_set_inactivity_timeout:
684  * @application: a #GApplication
685  * @inactivity_timeout: the timeout, in milliseconds
686  *
687  * Sets the current inactivity timeout for the application.
688  *
689  * This is the amount of time (in milliseconds) after the last call to
690  * g_application_release() before the application stops running.
691  *
692  * This call has no side effects of its own.  The value set here is only
693  * used for next time g_application_release() drops the use count to
694  * zero.  Any timeouts currently in progress are not impacted.
695  *
696  * Returns: the timeout, in milliseconds
697  *
698  * Since: 2.28
699  **/
700 void
701 g_application_set_inactivity_timeout (GApplication *application,
702                                       guint         inactivity_timeout)
703 {
704   g_return_if_fail (G_IS_APPLICATION (application));
705
706   if (application->priv->inactivity_timeout != inactivity_timeout)
707     {
708       application->priv->inactivity_timeout = inactivity_timeout;
709
710       g_object_notify (G_OBJECT (application), "inactivity-timeout");
711     }
712 }
713 /* Read-only property getters (is registered, is remote) {{{1 */
714 /**
715  * g_application_get_is_registered:
716  * @application: a #GApplication
717  * @returns: %TRUE if @application is registered
718  *
719  * Checks if @application is registered.
720  *
721  * An application is registered if g_application_register() has been
722  * successfully called.
723  *
724  * Since: 2.28
725  **/
726 gboolean
727 g_application_get_is_registered (GApplication *application)
728 {
729   g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
730
731   return application->priv->is_registered;
732 }
733
734 /**
735  * g_application_get_is_remote:
736  * @application: a #GApplication
737  * @returns: %TRUE if @application is remote
738  *
739  * Checks if @application is remote.
740  *
741  * If @application is remote then it means that another instance of
742  * application already exists (the 'primary' instance).  Calls to
743  * perform actions on @application will result in the actions being
744  * performed by the primary instance.
745  *
746  * The value of this property can not be accessed before
747  * g_application_register() has been called.  See
748  * g_application_get_is_registered().
749  *
750  * Since: 2.28
751  **/
752 gboolean
753 g_application_get_is_remote (GApplication *application)
754 {
755   g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
756   g_return_val_if_fail (application->priv->is_registered, FALSE);
757
758   return application->priv->is_remote;
759 }
760
761 /* Register {{{1 */
762 /**
763  * g_application_register:
764  * @application: a #GApplication
765  * @cancellable: a #GCancellable, or %NULL
766  * @error: a pointer to a NULL #GError, or %NULL
767  * @returns: %TRUE if registration succeeded
768  *
769  * Attempts registration of the application.
770  *
771  * This is the point at which the application discovers if it is the
772  * primary instance or merely acting as a remote for an already-existing
773  * primary instance.
774  *
775  * If the application has already been registered then %TRUE is
776  * returned with no work performed.
777  *
778  * The startup() virtual function is invoked if registration succeeds
779  * and @application is the primary instance.
780  *
781  * In the event of an error (such as @cancellable being cancelled, or a
782  * failure to connect to the session bus), %FALSE is returned and @error
783  * is set appropriately.
784  *
785  * Note: the return value of this function is not an indicator that this
786  * instance is or is not the primary instance of the application.  See
787  * g_application_get_is_remote() for that.
788  *
789  * Since: 2.28
790  **/
791 gboolean
792 g_application_register (GApplication  *application,
793                         GCancellable  *cancellable,
794                         GError       **error)
795 {
796   g_return_val_if_fail (G_IS_APPLICATION (application), FALSE);
797
798   if (!application->priv->is_registered)
799     {
800       gboolean is_remote;
801       gboolean try;
802
803       /* don't try to be the primary instance if
804        * G_APPLICATION_IS_LAUNCHER was specified.
805        */
806       try = !(application->priv->flags & G_APPLICATION_IS_LAUNCHER);
807
808       application->priv->impl =
809         g_application_impl_register (application, application->priv->id,
810                                      application->priv->flags,
811                                      &is_remote, cancellable, error);
812
813       if (application->priv->impl == NULL)
814         return FALSE;
815
816       application->priv->is_remote = is_remote;
817       application->priv->is_registered = TRUE;
818
819       g_object_notify (G_OBJECT (application), "is-registered");
820
821       if (!is_remote)
822         g_signal_emit (application, g_application_signals[SIGNAL_STARTUP], 0);
823     }
824
825   return TRUE;
826 }
827
828 /* Hold/release {{{1 */
829 /**
830  * g_application_hold:
831  * @application: a #GApplication
832  *
833  * Increases the use count of @application.
834  *
835  * Use this function to indicate that the application has a reason to
836  * continue to run.  For example, g_application_hold() is called by Gtk
837  * when a toplevel window is on the screen.
838  *
839  * To cancel the hold, call g_application_release().
840  **/
841 void
842 g_application_hold (GApplication *application)
843 {
844   if (application->priv->inactivity_timeout_id)
845     {
846       g_source_remove (application->priv->inactivity_timeout_id);
847       application->priv->inactivity_timeout_id = 0;
848     }
849
850   application->priv->use_count++;
851 }
852
853 static gboolean
854 inactivity_timeout_expired (gpointer data)
855 {
856   GApplication *application = G_APPLICATION (data);
857
858   G_APPLICATION_GET_CLASS (application)
859     ->quit_mainloop (application);
860
861   return FALSE;
862 }
863
864
865 /**
866  * g_application_release:
867  * @application: a #GApplication
868  *
869  * Decrease the use count of @application.
870  *
871  * When the use count reaches zero, the application will stop running.
872  *
873  * Never call this function except to cancel the effect of a previous
874  * call to g_application_hold().
875  **/
876 void
877 g_application_release (GApplication *application)
878 {
879   application->priv->use_count--;
880
881   if (application->priv->use_count == 0)
882     {
883       if (application->priv->inactivity_timeout)
884         application->priv->inactivity_timeout_id =
885           g_timeout_add (application->priv->inactivity_timeout,
886                          inactivity_timeout_expired, application);
887
888       else
889         G_APPLICATION_GET_CLASS (application)
890           ->quit_mainloop (application);
891     }
892 }
893
894 /* Activate, Open {{{1 */
895 /**
896  * g_application_activate:
897  * @application: a #GApplication
898  *
899  * Activates the application.
900  *
901  * In essence, this results in the activate() virtual function being
902  * invoked in the primary instance.
903  *
904  * The application must be registered before calling this function.
905  *
906  * Since: 2.28
907  **/
908 void
909 g_application_activate (GApplication *application)
910 {
911   g_return_if_fail (G_IS_APPLICATION (application));
912   g_return_if_fail (application->priv->is_registered);
913
914   if (application->priv->is_remote)
915     g_application_impl_activate (application->priv->impl,
916                                  get_platform_data (application));
917
918   else
919     g_signal_emit (application, g_application_signals[SIGNAL_ACTIVATE], 0);
920 }
921
922 /**
923  * g_application_open:
924  * @application: a #GApplication
925  * @files: an array of #GFile<!-- -->s to open
926  * @n_files: the length of the @files array
927  * @hint: a hint (or ""), but never %NULL
928  *
929  * Opens the given files.
930  *
931  * In essence, this results in the open() virtual function being invoked
932  * in the primary instance.
933  *
934  * @n_files must be greater than zero.
935  *
936  * @hint is simply passed through to the open() virtual function.  It is
937  * intended to be used by applications that have multiple modes for
938  * opening files (eg: "view" vs "edit", etc).  Unless you have a need
939  * for this functionality, you should use "".
940  *
941  * The application must be registered before calling this function and
942  * it must have the %G_APPLICATION_CAN_OPEN flag set.  The open()
943  * virtual function should also be implemented in order for anything
944  * meaningful to happen.
945  *
946  * Since: 2.28
947  **/
948 void
949 g_application_open (GApplication  *application,
950                     GFile        **files,
951                     gint           n_files,
952                     const gchar   *hint)
953 {
954   g_return_if_fail (G_IS_APPLICATION (application));
955   g_return_if_fail (application->priv->flags &
956                     G_APPLICATION_HANDLES_OPEN);
957   g_return_if_fail (application->priv->is_registered);
958
959   if (application->priv->is_remote)
960     g_application_impl_open (application->priv->impl,
961                              files, n_files, hint,
962                              get_platform_data (application));
963
964   else
965     g_signal_emit (application, g_application_signals[SIGNAL_OPEN],
966                    0, files, n_files, hint);
967 }
968
969 /* Run {{{1 */
970 /**
971  * g_application_run:
972  * @application: a #GApplication
973  * @argc: the argc from main()
974  * @argv: the argv from main()
975  * @returns: the exit status
976  *
977  * Runs the application.
978  *
979  * This function is intended to be run from main() and its return value
980  * is intended to be returned by main().
981  *
982  * First, the handle_command_line() virtual function is invoked.  This
983  * function always runs on the local instance.  If that function returns
984  * %FALSE then the application is registered and the command_line()
985  * virtual function is invoked in the primary instance (which may or may
986  * not be this instance).
987  *
988  * If the application has the %G_APPLICATION_REMOTE_COMMAND_LINE
989  * flag set then the default implementation of handle_command_line()
990  * always returns %FALSE immediately, resulting in the commandline
991  * always being handled in the primary instance.
992  *
993  * Otherwise, the default implementation of handle_command_line() tries
994  * to do a couple of things that are probably reasoanble for most
995  * applications.  First, g_application_register() is called to attempt
996  * to register the application.  If that works, then the command line
997  * arguments are inspected.  If no commandline arguments are given, then
998  * g_application_activate() is called.  If commandline arguments are
999  * given and the %G_APPLICATION_CAN_OPEN flags is set then they
1000  * are assumed to be filenames and g_application_open() is called.
1001  *
1002  * If you are interested in doing more complicated local handling of the
1003  * commandline then you should override handle_command_line().
1004  *
1005  * If, after the above is done, the use count of the application is zero
1006  * then the exit status is returned immediately.  If the use count is
1007  * non-zero then the mainloop is run until the use count falls to zero,
1008  * at which point 0 is returned.
1009  *
1010  * Since: 2.28
1011  **/
1012 int
1013 g_application_run (GApplication  *application,
1014                    int            argc,
1015                    char         **argv)
1016 {
1017   g_return_val_if_fail (G_IS_APPLICATION (application), 1);
1018   g_return_val_if_fail (argc == 0 || argv != NULL, 1);
1019
1020   return g_application_run_with_arguments (application,
1021     g_variant_new_bytestring_array ((const gchar **) argv, argc));
1022 }
1023
1024 /**
1025  * g_application_run_with_arguments:
1026  * @application: a #GApplication
1027  * @arguments: a bytestring array #GVariant
1028  * @returns: the exit status
1029  *
1030  * This is a bindings-friendly version of g_application_run().
1031  *
1032  * This function will consume @arguments if it is floating.
1033  **/
1034 int
1035 g_application_run_with_arguments (GApplication *application,
1036                                   GVariant     *arguments)
1037 {
1038   int status;
1039
1040   g_return_val_if_fail (G_IS_APPLICATION (application), 1);
1041   g_return_val_if_fail (G_IS_APPLICATION (application), 1);
1042
1043   g_variant_ref_sink (arguments);
1044
1045   if (g_get_prgname () == NULL && g_variant_n_children (arguments))
1046     {
1047       const gchar *argv0;
1048       gchar *prgname;
1049
1050       g_variant_get_child (arguments, 0, "^&ay", &argv0);
1051       prgname = g_path_get_basename (argv0);
1052       g_set_prgname (prgname);
1053       g_free (prgname);
1054     }
1055
1056   if (!G_APPLICATION_GET_CLASS (application)
1057         ->local_command_line (application, &arguments, &status))
1058     {
1059       GError *error = NULL;
1060
1061       if (!g_application_register (application, NULL, &error))
1062         {
1063           g_printerr ("%s", error->message);
1064           g_error_free (error);
1065           return 1;
1066         }
1067
1068       if (application->priv->is_remote)
1069         {
1070           GVariant *platform_data;
1071
1072           platform_data = get_platform_data (application);
1073           status = g_application_impl_command_line (application->priv->impl,
1074                                                     arguments, platform_data);
1075         }
1076       else
1077         {
1078           GApplicationCommandLine *cmdline;
1079
1080           cmdline = g_object_new (G_TYPE_APPLICATION_COMMAND_LINE,
1081                                   "arguments", arguments, NULL);
1082           g_signal_emit (application,
1083                          g_application_signals[SIGNAL_COMMAND_LINE],
1084                          0, cmdline, &status);
1085           g_object_unref (cmdline);
1086         }
1087     }
1088
1089   g_variant_unref (arguments);
1090
1091   if (application->priv->flags & G_APPLICATION_IS_SERVICE &&
1092       !application->priv->use_count &&
1093       !application->priv->inactivity_timeout_id)
1094     {
1095       application->priv->inactivity_timeout_id =
1096         g_timeout_add (10000, inactivity_timeout_expired, application);
1097     }
1098
1099   if (application->priv->use_count ||
1100       application->priv->inactivity_timeout_id)
1101     {
1102       G_APPLICATION_GET_CLASS (application)
1103         ->run_mainloop (application);
1104       status = 0;
1105     }
1106
1107   if (application->priv->impl)
1108     g_application_impl_flush (application->priv->impl);
1109
1110   return status;
1111 }
1112
1113 static gboolean
1114 g_application_has_action (GActionGroup *action_group,
1115                           const gchar  *action_name)
1116 {
1117   GApplication *application = G_APPLICATION (action_group);
1118
1119   g_return_val_if_fail (application->priv->is_registered, FALSE);
1120
1121   return application->priv->actions &&
1122          g_action_group_has_action (application->priv->actions, action_name);
1123 }
1124
1125 static gchar **
1126 g_application_list_actions (GActionGroup *action_group)
1127 {
1128   GApplication *application = G_APPLICATION (action_group);
1129
1130   g_return_val_if_fail (application->priv->is_registered, NULL);
1131
1132   if (application->priv->actions != NULL)
1133     return g_action_group_list_actions (application->priv->actions);
1134
1135   else
1136     /* empty string array */
1137     return g_new0 (gchar *, 1);
1138 }
1139
1140 static gboolean
1141 g_application_get_action_enabled (GActionGroup *action_group,
1142                                   const gchar  *action_name)
1143 {
1144   GApplication *application = G_APPLICATION (action_group);
1145
1146   g_return_val_if_fail (application->priv->actions != NULL, FALSE);
1147   g_return_val_if_fail (application->priv->is_registered, FALSE);
1148
1149   return g_action_group_get_action_enabled (application->priv->actions,
1150                                             action_name);
1151 }
1152
1153 static const GVariantType *
1154 g_application_get_action_parameter_type (GActionGroup *action_group,
1155                                          const gchar  *action_name)
1156 {
1157   GApplication *application = G_APPLICATION (action_group);
1158
1159   g_return_val_if_fail (application->priv->actions != NULL, NULL);
1160   g_return_val_if_fail (application->priv->is_registered, NULL);
1161
1162   return g_action_group_get_action_parameter_type (application->priv->actions,
1163                                                    action_name);
1164 }
1165
1166 static const GVariantType *
1167 g_application_get_action_state_type (GActionGroup *action_group,
1168                                      const gchar  *action_name)
1169 {
1170   GApplication *application = G_APPLICATION (action_group);
1171
1172   g_return_val_if_fail (application->priv->actions != NULL, NULL);
1173   g_return_val_if_fail (application->priv->is_registered, NULL);
1174
1175   return g_action_group_get_action_state_type (application->priv->actions,
1176                                                action_name);
1177 }
1178
1179 static GVariant *
1180 g_application_get_action_state_hint (GActionGroup *action_group,
1181                                      const gchar  *action_name)
1182 {
1183   GApplication *application = G_APPLICATION (action_group);
1184
1185   g_return_val_if_fail (application->priv->actions != NULL, NULL);
1186   g_return_val_if_fail (application->priv->is_registered, NULL);
1187
1188   return g_action_group_get_action_state_hint (application->priv->actions,
1189                                                action_name);
1190 }
1191
1192 static GVariant *
1193 g_application_get_action_state (GActionGroup *action_group,
1194                                 const gchar  *action_name)
1195 {
1196   GApplication *application = G_APPLICATION (action_group);
1197
1198   g_return_val_if_fail (application->priv->actions != NULL, NULL);
1199   g_return_val_if_fail (application->priv->is_registered, NULL);
1200
1201   return g_action_group_get_action_state (application->priv->actions,
1202                                           action_name);
1203 }
1204
1205 static void
1206 g_application_change_action_state (GActionGroup *action_group,
1207                                    const gchar  *action_name,
1208                                    GVariant     *value)
1209 {
1210   GApplication *application = G_APPLICATION (action_group);
1211
1212   g_return_if_fail (application->priv->actions != NULL);
1213   g_return_if_fail (application->priv->is_registered);
1214
1215   g_action_group_change_action_state (application->priv->actions,
1216                                       action_name, value);
1217 }
1218
1219 static void
1220 g_application_activate_action (GActionGroup *action_group,
1221                                const gchar  *action_name,
1222                                GVariant     *parameter)
1223 {
1224   GApplication *application = G_APPLICATION (action_group);
1225
1226   g_return_if_fail (application->priv->actions != NULL);
1227   g_return_if_fail (application->priv->is_registered);
1228
1229   g_action_group_activate_action (application->priv->actions,
1230                                   action_name, parameter);
1231 }
1232
1233 static void
1234 g_application_action_group_iface_init (GActionGroupInterface *iface)
1235 {
1236   iface->has_action = g_application_has_action;
1237   iface->list_actions = g_application_list_actions;
1238
1239   iface->get_action_enabled = g_application_get_action_enabled;
1240   iface->get_action_parameter_type = g_application_get_action_parameter_type;
1241   iface->get_action_state_type = g_application_get_action_state_type;
1242   iface->get_action_state_hint = g_application_get_action_state_hint;
1243   iface->get_action_state = g_application_get_action_state;
1244   iface->change_action_state = g_application_change_action_state;
1245   iface->activate_action = g_application_activate_action;
1246 }
1247
1248 /* Epilogue {{{1 */
1249 /* vim:set foldmethod=marker: */