gio: Fix some typos in G*AppInfo documentation
[platform/upstream/glib.git] / gio / gappinfo.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 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  * Author: Alexander Larsson <alexl@redhat.com>
21  */
22
23 #include "config.h"
24 #include "gappinfo.h"
25 #include "glibintl.h"
26 #include <gioerror.h>
27 #include <gfile.h>
28
29 #include "gioalias.h"
30
31 /**
32  * SECTION:gappinfo
33  * @short_description: Application information and launch contexts
34  * @include: gio/gio.h
35  * 
36  * #GAppInfo and #GAppLaunchContext are used for describing and launching 
37  * applications installed on the system.
38  *
39  * As of GLib 2.20, URIs will always be converted to POSIX paths
40  * (using g_file_get_path()) when using g_app_info_launch() even if
41  * the application requested an URI and not a POSIX path. For example
42  * for an desktop-file based application with Exec key <literal>totem
43  * %%U</literal> and a single URI,
44  * <literal>sftp://foo/file.avi</literal>, then
45  * <literal>/home/user/.gvfs/sftp on foo/file.avi</literal> will be
46  * passed. This will only work if a set of suitable GIO extensions
47  * (such as gvfs 2.26 compiled with FUSE support), is available and
48  * operational; if this is not the case, the URI will be passed
49  * unmodified to the application. Some URIs, such as
50  * <literal>mailto:</literal>, of course cannot be mapped to a POSIX
51  * path (in gvfs there's no FUSE mount for it); such URIs will be
52  * passed unmodified to the application.
53  *
54  * Specifically for gvfs 2.26 and later, the POSIX URI will be mapped
55  * back to the GIO URI in the #GFile constructors (since gvfs
56  * implements the #GVfs extension point). As such, if the application
57  * needs to examine the URI, it needs to use g_file_get_uri() or
58  * similar on #GFile. In other words, an application cannot assume
59  * that the URI passed to e.g. g_file_new_for_commandline_arg() is
60  * equal to the result of g_file_get_uri(). The following snippet
61  * illustrates this:
62  *
63  * <programlisting>
64  * GFile *f;
65  * char *uri;
66  *
67  * file = g_file_new_for_commandline_arg (uri_from_commandline);
68  *
69  * uri = g_file_get_uri (file);
70  * strcmp (uri, uri_from_commandline) == 0; // FALSE
71  * g_free (uri);
72  *
73  * if (g_file_has_uri_scheme (file, "cdda"))
74  *   {
75  *     // do something special with uri
76  *   }
77  * g_object_unref (file);
78  * </programlisting>
79  *
80  * This code will work when both <literal>cdda://sr0/Track
81  * 1.wav</literal> and <literal>/home/user/.gvfs/cdda on sr0/Track
82  * 1.wav</literal> is passed to the application. It should be noted
83  * that it's generally not safe for applications to rely on the format
84  * of a particular URIs. Different launcher applications (e.g. file
85  * managers) may have different ideas of what a given URI means.
86  *
87  **/
88
89 static void g_app_info_base_init (gpointer g_class);
90 static void g_app_info_class_init (gpointer g_class,
91                                    gpointer class_data);
92
93
94 GType
95 g_app_info_get_type (void)
96 {
97   static volatile gsize g_define_type_id__volatile = 0;
98
99   if (g_once_init_enter (&g_define_type_id__volatile))
100     {
101      const GTypeInfo app_info_info =
102       {
103         sizeof (GAppInfoIface), /* class_size */
104         g_app_info_base_init,   /* base_init */
105         NULL,           /* base_finalize */
106         g_app_info_class_init,
107         NULL,           /* class_finalize */
108         NULL,           /* class_data */
109         0,
110         0,              /* n_preallocs */
111         NULL
112       };
113       GType g_define_type_id =
114         g_type_register_static (G_TYPE_INTERFACE, I_("GAppInfo"),
115                                 &app_info_info, 0);
116
117       g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_OBJECT);
118
119       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
120     }
121
122   return g_define_type_id__volatile;
123 }
124
125 static void
126 g_app_info_class_init (gpointer g_class,
127                        gpointer class_data)
128 {
129 }
130
131 static void
132 g_app_info_base_init (gpointer g_class)
133 {
134 }
135
136
137 /**
138  * g_app_info_dup:
139  * @appinfo: a #GAppInfo.
140  * 
141  * Creates a duplicate of a #GAppInfo.
142  *
143  * Returns: a duplicate of @appinfo.
144  **/
145 GAppInfo *
146 g_app_info_dup (GAppInfo *appinfo)
147 {
148   GAppInfoIface *iface;
149
150   g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
151
152   iface = G_APP_INFO_GET_IFACE (appinfo);
153
154   return (* iface->dup) (appinfo);
155 }
156
157 /**
158  * g_app_info_equal:
159  * @appinfo1: the first #GAppInfo.  
160  * @appinfo2: the second #GAppInfo.
161  * 
162  * Checks if two #GAppInfo<!-- -->s are equal.
163  *
164  * Returns: %TRUE if @appinfo1 is equal to @appinfo2. %FALSE otherwise.
165  **/
166 gboolean
167 g_app_info_equal (GAppInfo *appinfo1,
168                   GAppInfo *appinfo2)
169 {
170   GAppInfoIface *iface;
171
172   g_return_val_if_fail (G_IS_APP_INFO (appinfo1), FALSE);
173   g_return_val_if_fail (G_IS_APP_INFO (appinfo2), FALSE);
174
175   if (G_TYPE_FROM_INSTANCE (appinfo1) != G_TYPE_FROM_INSTANCE (appinfo2))
176     return FALSE;
177   
178   iface = G_APP_INFO_GET_IFACE (appinfo1);
179
180   return (* iface->equal) (appinfo1, appinfo2);
181 }
182
183 /**
184  * g_app_info_get_id:
185  * @appinfo: a #GAppInfo.
186  * 
187  * Gets the ID of an application. An id is a string that
188  * identifies the application. The exact format of the id is
189  * platform dependent. For instance, on Unix this is the
190  * desktop file id from the xdg menu specification.
191  *
192  * Note that the returned ID may be %NULL, depending on how
193  * the @appinfo has been constructed.
194  *
195  * Returns: a string containing the application's ID.
196  **/
197 const char *
198 g_app_info_get_id (GAppInfo *appinfo)
199 {
200   GAppInfoIface *iface;
201   
202   g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
203
204   iface = G_APP_INFO_GET_IFACE (appinfo);
205
206   return (* iface->get_id) (appinfo);
207 }
208
209 /**
210  * g_app_info_get_name:
211  * @appinfo: a #GAppInfo.
212  * 
213  * Gets the installed name of the application. 
214  *
215  * Returns: the name of the application for @appinfo.
216  **/
217 const char *
218 g_app_info_get_name (GAppInfo *appinfo)
219 {
220   GAppInfoIface *iface;
221   
222   g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
223
224   iface = G_APP_INFO_GET_IFACE (appinfo);
225
226   return (* iface->get_name) (appinfo);
227 }
228
229 /**
230  * g_app_info_get_description:
231  * @appinfo: a #GAppInfo.
232  * 
233  * Gets a human-readable description of an installed application.
234  *
235  * Returns: a string containing a description of the 
236  * application @appinfo, or %NULL if none. 
237  **/
238 const char *
239 g_app_info_get_description (GAppInfo *appinfo)
240 {
241   GAppInfoIface *iface;
242   
243   g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
244
245   iface = G_APP_INFO_GET_IFACE (appinfo);
246
247   return (* iface->get_description) (appinfo);
248 }
249
250 /**
251  * g_app_info_get_executable:
252  * @appinfo: a #GAppInfo
253  * 
254  * Gets the executable's name for the installed application.
255  *
256  * Returns: a string containing the @appinfo's application 
257  * binaries name
258  **/
259 const char *
260 g_app_info_get_executable (GAppInfo *appinfo)
261 {
262   GAppInfoIface *iface;
263   
264   g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
265
266   iface = G_APP_INFO_GET_IFACE (appinfo);
267
268   return (* iface->get_executable) (appinfo);
269 }
270
271
272 /**
273  * g_app_info_get_commandline:
274  * @appinfo: a #GAppInfo
275  * 
276  * Gets the commandline with which the application will be
277  * started.  
278  *
279  * Returns: a string containing the @appinfo's commandline, 
280  *     or %NULL if this information is not available
281  *
282  * Since: 2.20
283  **/
284 const char *
285 g_app_info_get_commandline (GAppInfo *appinfo)
286 {
287   GAppInfoIface *iface;
288   
289   g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
290
291   iface = G_APP_INFO_GET_IFACE (appinfo);
292
293   if (iface->get_commandline)
294     return (* iface->get_commandline) (appinfo);
295  
296   return NULL;
297 }
298
299 /**
300  * g_app_info_set_as_default_for_type:
301  * @appinfo: a #GAppInfo.
302  * @content_type: the content type.
303  * @error: a #GError.
304  * 
305  * Sets the application as the default handler for a given type.
306  *
307  * Returns: %TRUE on success, %FALSE on error.
308  **/
309 gboolean
310 g_app_info_set_as_default_for_type (GAppInfo    *appinfo,
311                                     const char  *content_type,
312                                     GError     **error)
313 {
314   GAppInfoIface *iface;
315   
316   g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
317   g_return_val_if_fail (content_type != NULL, FALSE);
318
319   iface = G_APP_INFO_GET_IFACE (appinfo);
320
321   return (* iface->set_as_default_for_type) (appinfo, content_type, error);
322 }
323
324
325 /**
326  * g_app_info_set_as_default_for_extension:
327  * @appinfo: a #GAppInfo.
328  * @extension: a string containing the file extension (without the dot).
329  * @error: a #GError.
330  * 
331  * Sets the application as the default handler for the given file extension.
332  *
333  * Returns: %TRUE on success, %FALSE on error.
334  **/
335 gboolean
336 g_app_info_set_as_default_for_extension (GAppInfo    *appinfo,
337                                          const char  *extension,
338                                          GError     **error)
339 {
340   GAppInfoIface *iface;
341   
342   g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
343   g_return_val_if_fail (extension != NULL, FALSE);
344
345   iface = G_APP_INFO_GET_IFACE (appinfo);
346
347   if (iface->set_as_default_for_extension)
348     return (* iface->set_as_default_for_extension) (appinfo, extension, error);
349
350   g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
351                        "g_app_info_set_as_default_for_extension not supported yet");
352   return FALSE;
353 }
354
355
356 /**
357  * g_app_info_add_supports_type:
358  * @appinfo: a #GAppInfo.
359  * @content_type: a string.
360  * @error: a #GError.
361  * 
362  * Adds a content type to the application information to indicate the 
363  * application is capable of opening files with the given content type.
364  *
365  * Returns: %TRUE on success, %FALSE on error.
366  **/
367 gboolean
368 g_app_info_add_supports_type (GAppInfo    *appinfo,
369                               const char  *content_type,
370                               GError     **error)
371 {
372   GAppInfoIface *iface;
373   
374   g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
375   g_return_val_if_fail (content_type != NULL, FALSE);
376
377   iface = G_APP_INFO_GET_IFACE (appinfo);
378
379   if (iface->add_supports_type)
380     return (* iface->add_supports_type) (appinfo, content_type, error);
381
382   g_set_error_literal (error, G_IO_ERROR, 
383                        G_IO_ERROR_NOT_SUPPORTED, 
384                        "g_app_info_add_supports_type not supported yet");
385
386   return FALSE;
387 }
388
389
390 /**
391  * g_app_info_can_remove_supports_type:
392  * @appinfo: a #GAppInfo.
393  * 
394  * Checks if a supported content type can be removed from an application.
395  *
396  * Returns: %TRUE if it is possible to remove supported 
397  *     content types from a given @appinfo, %FALSE if not.
398  **/
399 gboolean
400 g_app_info_can_remove_supports_type (GAppInfo *appinfo)
401 {
402   GAppInfoIface *iface;
403   
404   g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
405
406   iface = G_APP_INFO_GET_IFACE (appinfo);
407
408   if (iface->can_remove_supports_type)
409     return (* iface->can_remove_supports_type) (appinfo);
410
411   return FALSE;
412 }
413
414
415 /**
416  * g_app_info_remove_supports_type:
417  * @appinfo: a #GAppInfo.
418  * @content_type: a string.
419  * @error: a #GError.
420  *
421  * Removes a supported type from an application, if possible.
422  * 
423  * Returns: %TRUE on success, %FALSE on error.
424  **/
425 gboolean
426 g_app_info_remove_supports_type (GAppInfo    *appinfo,
427                                  const char  *content_type,
428                                  GError     **error)
429 {
430   GAppInfoIface *iface;
431   
432   g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
433   g_return_val_if_fail (content_type != NULL, FALSE);
434
435   iface = G_APP_INFO_GET_IFACE (appinfo);
436
437   if (iface->remove_supports_type)
438     return (* iface->remove_supports_type) (appinfo, content_type, error);
439
440   g_set_error_literal (error, G_IO_ERROR, 
441                        G_IO_ERROR_NOT_SUPPORTED, 
442                        "g_app_info_remove_supports_type not supported yet");
443
444   return FALSE;
445 }
446
447
448 /**
449  * g_app_info_get_icon:
450  * @appinfo: a #GAppInfo.
451  * 
452  * Gets the icon for the application.
453  *
454  * Returns: the default #GIcon for @appinfo.
455  **/
456 GIcon *
457 g_app_info_get_icon (GAppInfo *appinfo)
458 {
459   GAppInfoIface *iface;
460   
461   g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
462
463   iface = G_APP_INFO_GET_IFACE (appinfo);
464
465   return (* iface->get_icon) (appinfo);
466 }
467
468
469 /**
470  * g_app_info_launch:
471  * @appinfo: a #GAppInfo
472  * @files: a #GList of #GFile objects
473  * @launch_context: a #GAppLaunchContext or %NULL
474  * @error: a #GError
475  * 
476  * Launches the application. Passes @files to the launched application 
477  * as arguments, using the optional @launch_context to get information
478  * about the details of the launcher (like what screen it is on).
479  * On error, @error will be set accordingly.
480  *
481  * To lauch the application without arguments pass a %NULL @files list.
482  *
483  * Note that even if the launch is successful the application launched
484  * can fail to start if it runs into problems during startup. There is
485  * no way to detect this.
486  *
487  * Some URIs can be changed when passed through a GFile (for instance
488  * unsupported uris with strange formats like mailto:), so if you have
489  * a textual uri you want to pass in as argument, consider using
490  * g_app_info_launch_uris() instead.
491  * 
492  * Returns: %TRUE on successful launch, %FALSE otherwise. 
493  **/
494 gboolean
495 g_app_info_launch (GAppInfo           *appinfo,
496                    GList              *files,
497                    GAppLaunchContext  *launch_context,
498                    GError            **error)
499 {
500   GAppInfoIface *iface;
501   
502   g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
503
504   iface = G_APP_INFO_GET_IFACE (appinfo);
505
506   return (* iface->launch) (appinfo, files, launch_context, error);
507 }
508
509
510 /**
511  * g_app_info_supports_uris:
512  * @appinfo: a #GAppInfo.
513  * 
514  * Checks if the application supports reading files and directories from URIs.
515  *
516  * Returns: %TRUE if the @appinfo supports URIs.
517  **/
518 gboolean
519 g_app_info_supports_uris (GAppInfo *appinfo)
520 {
521   GAppInfoIface *iface;
522   
523   g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
524
525   iface = G_APP_INFO_GET_IFACE (appinfo);
526
527   return (* iface->supports_uris) (appinfo);
528 }
529
530
531 /**
532  * g_app_info_supports_files:
533  * @appinfo: a #GAppInfo.
534  * 
535  * Checks if the application accepts files as arguments.
536  *
537  * Returns: %TRUE if the @appinfo supports files.
538  **/
539 gboolean
540 g_app_info_supports_files (GAppInfo *appinfo)
541 {
542   GAppInfoIface *iface;
543   
544   g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
545
546   iface = G_APP_INFO_GET_IFACE (appinfo);
547
548   return (* iface->supports_files) (appinfo);
549 }
550
551
552 /**
553  * g_app_info_launch_uris:
554  * @appinfo: a #GAppInfo
555  * @uris: a #GList containing URIs to launch. 
556  * @launch_context: a #GAppLaunchContext or %NULL
557  * @error: a #GError
558  * 
559  * Launches the application. Passes @uris to the launched application 
560  * as arguments, using the optional @launch_context to get information
561  * about the details of the launcher (like what screen it is on).
562  * On error, @error will be set accordingly.
563  *
564  * To lauch the application without arguments pass a %NULL @uris list.
565  *
566  * Note that even if the launch is successful the application launched
567  * can fail to start if it runs into problems during startup. There is
568  * no way to detect this.
569  *
570  * Returns: %TRUE on successful launch, %FALSE otherwise. 
571  **/
572 gboolean
573 g_app_info_launch_uris (GAppInfo           *appinfo,
574                         GList              *uris,
575                         GAppLaunchContext  *launch_context,
576                         GError            **error)
577 {
578   GAppInfoIface *iface;
579   
580   g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
581
582   iface = G_APP_INFO_GET_IFACE (appinfo);
583
584   return (* iface->launch_uris) (appinfo, uris, launch_context, error);
585 }
586
587
588 /**
589  * g_app_info_should_show:
590  * @appinfo: a #GAppInfo.
591  *
592  * Checks if the application info should be shown in menus that 
593  * list available applications.
594  * 
595  * Returns: %TRUE if the @appinfo should be shown, %FALSE otherwise.
596  **/
597 gboolean
598 g_app_info_should_show (GAppInfo *appinfo)
599 {
600   GAppInfoIface *iface;
601   
602   g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
603
604   iface = G_APP_INFO_GET_IFACE (appinfo);
605
606   return (* iface->should_show) (appinfo);
607 }
608
609 /**
610  * g_app_info_launch_default_for_uri:
611  * @uri: the uri to show
612  * @launch_context: an optional #GAppLaunchContext.
613  * @error: a #GError.
614  *
615  * Utility function that launches the default application 
616  * registered to handle the specified uri. Synchronous I/O
617  * is done on the uri to detect the type of the file if
618  * required.
619  * 
620  * Returns: %TRUE on success, %FALSE on error.
621  **/
622 gboolean
623 g_app_info_launch_default_for_uri (const char         *uri,
624                                    GAppLaunchContext  *launch_context,
625                                    GError            **error)
626 {
627   GAppInfo *app_info;
628   GFile *file;
629   GList l;
630   gboolean res;
631
632   file = g_file_new_for_uri (uri);
633   app_info = g_file_query_default_handler (file, NULL, error);
634   g_object_unref (file);
635   if (app_info == NULL)
636     return FALSE;
637
638   /* Use the uri, not the GFile, as the GFile roundtrip may
639    * affect the uri which we don't want (for instance for a
640    * mailto: uri).
641    */
642   l.data = (char *)uri;
643   l.next = l.prev = NULL;
644   res = g_app_info_launch_uris (app_info, &l,
645                                 launch_context, error);
646
647   g_object_unref (app_info);
648   
649   return res;
650 }
651
652 /**
653  * g_app_info_can_delete:
654  * @appinfo: a #GAppInfo
655  *
656  * Obtains the information whether the #GAppInfo can be deleted.
657  * See g_app_info_delete().
658  *
659  * Returns: %TRUE if @appinfo can be deleted
660  *
661  * Since: 2.20
662  */
663 gboolean
664 g_app_info_can_delete (GAppInfo *appinfo)
665 {
666   GAppInfoIface *iface;
667   
668   g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
669
670   iface = G_APP_INFO_GET_IFACE (appinfo);
671
672   if (iface->can_delete)
673     return (* iface->can_delete) (appinfo);
674  
675   return FALSE; 
676 }
677
678
679 /**
680  * g_app_info_delete:
681  * @appinfo: a #GAppInfo
682  *
683  * Tries to delete a #GAppInfo.
684  *
685  * On some platforms, there may be a difference between user-defined
686  * #GAppInfo<!-- -->s which can be deleted, and system-wide ones which
687  * cannot. See g_app_info_can_delete().
688  * 
689  * Returns: %TRUE if @appinfo has been deleted
690  *
691  * Since: 2.20
692  */
693 gboolean
694 g_app_info_delete (GAppInfo *appinfo)
695 {
696   GAppInfoIface *iface;
697   
698   g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
699
700   iface = G_APP_INFO_GET_IFACE (appinfo);
701
702   if (iface->do_delete)
703     return (* iface->do_delete) (appinfo);
704  
705   return FALSE; 
706 }
707
708
709 G_DEFINE_TYPE (GAppLaunchContext, g_app_launch_context, G_TYPE_OBJECT);
710
711 /**
712  * g_app_launch_context_new:
713  * 
714  * Creates a new application launch context. This is not normally used,
715  * instead you instantiate a subclass of this, such as #GdkAppLaunchContext.
716  *
717  * Returns: a #GAppLaunchContext.
718  **/
719 GAppLaunchContext *
720 g_app_launch_context_new (void)
721 {
722   return g_object_new (G_TYPE_APP_LAUNCH_CONTEXT, NULL);
723 }
724
725 static void
726 g_app_launch_context_class_init (GAppLaunchContextClass *klass)
727 {
728 }
729
730 static void
731 g_app_launch_context_init (GAppLaunchContext *launch_context)
732 {
733 }
734
735 /**
736  * g_app_launch_context_get_display:
737  * @context: a #GAppLaunchContext
738  * @info: a #GAppInfo
739  * @files: a #GList of #GFile objects
740  *
741  * Gets the display string for the display. This is used to ensure new
742  * applications are started on the same display as the launching 
743  * application.
744  * 
745  * Returns: a display string for the display.
746  **/
747 char *
748 g_app_launch_context_get_display (GAppLaunchContext *context,
749                                   GAppInfo          *info,
750                                   GList             *files)
751 {
752   GAppLaunchContextClass *class;
753
754   g_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), NULL);
755   g_return_val_if_fail (G_IS_APP_INFO (info), NULL);
756
757   class = G_APP_LAUNCH_CONTEXT_GET_CLASS (context);
758
759   if (class->get_display == NULL)
760     return NULL;
761
762   return class->get_display (context, info, files);
763 }
764
765 /**
766  * g_app_launch_context_get_startup_notify_id:
767  * @context: a #GAppLaunchContext
768  * @info: a #GAppInfo
769  * @files: a #GList of of #GFile objects
770  * 
771  * Initiates startup notification for the application and returns the
772  * DESKTOP_STARTUP_ID for the launched operation, if supported.
773  *
774  * Startup notification IDs are defined in the <ulink
775  * url="http://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt">
776  * FreeDesktop.Org Startup Notifications standard</ulink>.
777  *
778  * Returns: a startup notification ID for the application, or %NULL if 
779  *     not supported.
780  **/
781 char *
782 g_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
783                                             GAppInfo          *info,
784                                             GList             *files)
785 {
786   GAppLaunchContextClass *class;
787
788   g_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), NULL);
789   g_return_val_if_fail (G_IS_APP_INFO (info), NULL);
790
791   class = G_APP_LAUNCH_CONTEXT_GET_CLASS (context);
792
793   if (class->get_startup_notify_id == NULL)
794     return NULL;
795
796   return class->get_startup_notify_id (context, info, files);
797 }
798
799
800 /**
801  * g_app_launch_context_launch_failed:
802  * @context: a #GAppLaunchContext.
803  * @startup_notify_id: the startup notification id that was returned by g_app_launch_context_get_startup_notify_id().
804  *
805  * Called when an application has failed to launch, so that it can cancel
806  * the application startup notification started in g_app_launch_context_get_startup_notify_id().
807  * 
808  **/
809 void
810 g_app_launch_context_launch_failed (GAppLaunchContext *context,
811                                     const char        *startup_notify_id)
812 {
813   GAppLaunchContextClass *class;
814
815   g_return_if_fail (G_IS_APP_LAUNCH_CONTEXT (context));
816   g_return_if_fail (startup_notify_id != NULL);
817
818   class = G_APP_LAUNCH_CONTEXT_GET_CLASS (context);
819
820   if (class->launch_failed != NULL)
821     class->launch_failed (context, startup_notify_id);
822 }
823
824
825 #define __G_APP_INFO_C__
826 #include "gioaliasdef.c"