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