1 /*
2  * Nautilus-Actions
3  * A Nautilus extension which offers configurable context menu actions.
4  *
5  * Copyright (C) 2005 The GNOME Foundation
6  * Copyright (C) 2006-2008 Frederic Ruaudel and others (see AUTHORS)
7  * Copyright (C) 2009-2014 Pierre Wieser and others (see AUTHORS)
8  *
9  * Nautilus-Actions is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * Nautilus-Actions is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with Nautilus-Actions; see the file COPYING. If not, see
21  * <http://www.gnu.org/licenses/>.
22  *
23  * Authors:
24  *   Frederic Ruaudel <grumz@grumz.net>
25  *   Rodrigo Moya <rodrigo@gnome-db.org>
26  *   Pierre Wieser <pwieser@trychlos.org>
27  *   ... and many others (see AUTHORS)
28  */
29 
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33 
34 #include <glib/gi18n.h>
35 #include <string.h>
36 
37 #include "base-application.h"
38 #include "base-isession.h"
39 #include "base-iunique.h"
40 
41 /* private class data
42  */
43 struct _BaseApplicationClassPrivate {
44 	void *empty;						/* so that gcc -pedantic is happy */
45 };
46 
47 /* private instance data
48  */
49 struct _BaseApplicationPrivate {
50 	gboolean      dispose_has_run;
51 
52 	/* properties
53 	 */
54 	int           argc;
55 	GStrv         argv;
56 	GOptionEntry *options;
57 	gchar        *application_name;
58 	gchar        *description;
59 	gchar        *icon_name;
60 	gchar        *unique_app_name;
61 	int           code;
62 };
63 
64 /* instance properties
65  */
66 enum {
67 	BASE_PROP_0,
68 
69 	BASE_PROP_ARGC_ID,
70 	BASE_PROP_ARGV_ID,
71 	BASE_PROP_OPTIONS_ID,
72 	BASE_PROP_APPLICATION_NAME_ID,
73 	BASE_PROP_DESCRIPTION_ID,
74 	BASE_PROP_ICON_NAME_ID,
75 	BASE_PROP_UNIQUE_NAME_ID,
76 	BASE_PROP_CODE_ID,
77 
78 	BASE_PROP_N_PROPERTIES
79 };
80 
81 static GObjectClass *st_parent_class = NULL;
82 
83 static GType        register_type( void );
84 static void         class_init( BaseApplicationClass *klass );
85 static void         isession_iface_init( BaseISessionInterface *iface, void *user_data );
86 static void         iunique_iface_init( BaseIUniqueInterface *iface, void *user_data );
87 static const gchar *iunique_get_application_name( const BaseIUnique *instance );
88 static void         instance_init( GTypeInstance *instance, gpointer klass );
89 static void         instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
90 static void         instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
91 static void         instance_dispose( GObject *application );
92 static void         instance_finalize( GObject *application );
93 
94 static gboolean     init_i18n( BaseApplication *application );
95 static gboolean     init_application_name( BaseApplication *application );
96 static gboolean     init_gtk( BaseApplication *application );
97 static gboolean     v_manage_options( BaseApplication *application );
98 static gboolean     init_unique_manager( BaseApplication *application );
99 static gboolean     init_session_manager( BaseApplication *application );
100 static gboolean     init_icon_name( BaseApplication *application );
101 static gboolean     v_init_application( BaseApplication *application );
102 static gboolean     v_create_windows( BaseApplication *application );
103 
104 /*
105  * the BaseISessionInterface interface is registered here because
106  * the interface requires its implementation to be of BaseApplication
107  * type. So we have to first register the type class before trying to
108  * register the type interface.
109  */
110 GType
base_application_get_type(void)111 base_application_get_type( void )
112 {
113 	static GType application_type = 0;
114 
115 	if( !application_type ){
116 		application_type = register_type();
117 	}
118 
119 	return( application_type );
120 }
121 
122 static GType
register_type(void)123 register_type( void )
124 {
125 	static const gchar *thisfn = "base_application_register_type";
126 	GType type;
127 
128 	static GTypeInfo info = {
129 		sizeof( BaseApplicationClass ),
130 		( GBaseInitFunc ) NULL,
131 		( GBaseFinalizeFunc ) NULL,
132 		( GClassInitFunc ) class_init,
133 		NULL,
134 		NULL,
135 		sizeof( BaseApplication ),
136 		0,
137 		( GInstanceInitFunc ) instance_init
138 	};
139 
140 	static const GInterfaceInfo isession_iface_info = {
141 		( GInterfaceInitFunc ) isession_iface_init,
142 		NULL,
143 		NULL
144 	};
145 
146 	static const GInterfaceInfo iunique_iface_info = {
147 		( GInterfaceInitFunc ) iunique_iface_init,
148 		NULL,
149 		NULL
150 	};
151 
152 	g_debug( "%s", thisfn );
153 
154 #if !GLIB_CHECK_VERSION( 2,36, 0 )
155 	g_type_init();
156 #endif
157 
158 	type = g_type_register_static( G_TYPE_OBJECT, "BaseApplication", &info, 0 );
159 
160 	g_type_add_interface_static( type, BASE_TYPE_ISESSION, &isession_iface_info );
161 
162 	g_type_add_interface_static( type, BASE_TYPE_IUNIQUE, &iunique_iface_info );
163 
164 	return( type );
165 }
166 
167 static void
class_init(BaseApplicationClass * klass)168 class_init( BaseApplicationClass *klass )
169 {
170 	static const gchar *thisfn = "base_application_class_init";
171 	GObjectClass *object_class;
172 
173 	g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
174 
175 	st_parent_class = g_type_class_peek_parent( klass );
176 
177 	object_class = G_OBJECT_CLASS( klass );
178 	object_class->dispose = instance_dispose;
179 	object_class->finalize = instance_finalize;
180 	object_class->get_property = instance_get_property;
181 	object_class->set_property = instance_set_property;
182 
183 	g_object_class_install_property( object_class, BASE_PROP_ARGC_ID,
184 			g_param_spec_int(
185 					BASE_PROP_ARGC,
186 					_( "Arguments count" ),
187 					_( "The count of command-line arguments" ),
188 					0, 65535, 0,
189 					G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
190 
191 	g_object_class_install_property( object_class, BASE_PROP_ARGV_ID,
192 			g_param_spec_boxed(
193 					BASE_PROP_ARGV,
194 					_( "Arguments" ),
195 					_( "The array of command-line arguments" ),
196 					G_TYPE_STRV,
197 					G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
198 
199 	g_object_class_install_property( object_class, BASE_PROP_OPTIONS_ID,
200 			g_param_spec_pointer(
201 					BASE_PROP_OPTIONS,
202 					_( "Option entries" ),
203 					_( "The array of command-line option definitions" ),
204 					G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
205 
206 	g_object_class_install_property( object_class, BASE_PROP_APPLICATION_NAME_ID,
207 			g_param_spec_string(
208 					BASE_PROP_APPLICATION_NAME,
209 					_( "Application name" ),
210 					_( "The name of the application" ),
211 					"",
212 					G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
213 
214 	g_object_class_install_property( object_class, BASE_PROP_DESCRIPTION_ID,
215 			g_param_spec_string(
216 					BASE_PROP_DESCRIPTION,
217 					_( "Description" ),
218 					_( "A short description to be displayed in the first line of --help output" ),
219 					"",
220 					G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
221 
222 	g_object_class_install_property( object_class, BASE_PROP_ICON_NAME_ID,
223 			g_param_spec_string(
224 					BASE_PROP_ICON_NAME,
225 					_( "Icon name" ),
226 					_( "The name of the icon of the application" ),
227 					"",
228 					G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
229 
230 	g_object_class_install_property( object_class, BASE_PROP_UNIQUE_NAME_ID,
231 			g_param_spec_string(
232 					BASE_PROP_UNIQUE_NAME,
233 					_( "UniqueApp name" ),
234 					_( "The Unique name of the application" ),
235 					"",
236 					G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
237 
238 	g_object_class_install_property( object_class, BASE_PROP_CODE_ID,
239 			g_param_spec_int(
240 					BASE_PROP_CODE,
241 					_( "Return code" ),
242 					_( "The return code of the application" ),
243 					-127, 127, 0,
244 					G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
245 
246 	klass->private = g_new0( BaseApplicationClassPrivate, 1 );
247 
248 	klass->manage_options = NULL;
249 	klass->init_application = NULL;
250 	klass->create_windows = NULL;
251 }
252 
253 static void
isession_iface_init(BaseISessionInterface * iface,void * user_data)254 isession_iface_init( BaseISessionInterface *iface, void *user_data )
255 {
256 	static const gchar *thisfn = "base_application_isession_iface_init";
257 
258 	g_debug( "%s: iface=%p, user_data=%p", thisfn, ( void * ) iface, ( void * ) user_data );
259 }
260 
261 static void
iunique_iface_init(BaseIUniqueInterface * iface,void * user_data)262 iunique_iface_init( BaseIUniqueInterface *iface, void *user_data )
263 {
264 	static const gchar *thisfn = "base_application_iunique_iface_init";
265 
266 	g_debug( "%s: iface=%p, user_data=%p", thisfn, ( void * ) iface, ( void * ) user_data );
267 
268 	iface->get_application_name = iunique_get_application_name;
269 }
270 
271 static const gchar *
iunique_get_application_name(const BaseIUnique * instance)272 iunique_get_application_name( const BaseIUnique *instance )
273 {
274 	g_return_val_if_fail( BASE_IS_IUNIQUE( instance ), NULL );
275 	g_return_val_if_fail( BASE_IS_APPLICATION( instance ), NULL );
276 
277 	return( BASE_APPLICATION( instance )->private->application_name );
278 }
279 
280 static void
instance_init(GTypeInstance * application,gpointer klass)281 instance_init( GTypeInstance *application, gpointer klass )
282 {
283 	static const gchar *thisfn = "base_application_instance_init";
284 	BaseApplication *self;
285 
286 	g_return_if_fail( BASE_IS_APPLICATION( application ));
287 
288 	g_debug( "%s: application=%p (%s), klass=%p",
289 			thisfn, ( void * ) application, G_OBJECT_TYPE_NAME( application ), ( void * ) klass );
290 
291 	self = BASE_APPLICATION( application );
292 
293 	self->private = g_new0( BaseApplicationPrivate, 1 );
294 
295 	self->private->dispose_has_run = FALSE;
296 }
297 
298 static void
instance_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * spec)299 instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
300 {
301 	BaseApplication *self;
302 
303 	g_return_if_fail( BASE_IS_APPLICATION( object ));
304 	self = BASE_APPLICATION( object );
305 
306 	if( !self->private->dispose_has_run ){
307 
308 		switch( property_id ){
309 			case BASE_PROP_ARGC_ID:
310 				g_value_set_int( value, self->private->argc );
311 				break;
312 
313 			case BASE_PROP_ARGV_ID:
314 				g_value_set_boxed( value, self->private->argv );
315 				break;
316 
317 			case BASE_PROP_OPTIONS_ID:
318 				g_value_set_pointer( value, self->private->options );
319 				break;
320 
321 			case BASE_PROP_APPLICATION_NAME_ID:
322 				g_value_set_string( value, self->private->application_name );
323 				break;
324 
325 			case BASE_PROP_DESCRIPTION_ID:
326 				g_value_set_string( value, self->private->description );
327 				break;
328 
329 			case BASE_PROP_ICON_NAME_ID:
330 				g_value_set_string( value, self->private->icon_name );
331 				break;
332 
333 			case BASE_PROP_UNIQUE_NAME_ID:
334 				g_value_set_string( value, self->private->unique_app_name );
335 				break;
336 
337 			case BASE_PROP_CODE_ID:
338 				g_value_set_int( value, self->private->code );
339 				break;
340 
341 			default:
342 				G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
343 				break;
344 		}
345 	}
346 }
347 
348 static void
instance_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * spec)349 instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
350 {
351 	BaseApplication *self;
352 
353 	g_return_if_fail( BASE_IS_APPLICATION( object ));
354 	self = BASE_APPLICATION( object );
355 
356 	if( !self->private->dispose_has_run ){
357 
358 		switch( property_id ){
359 			case BASE_PROP_ARGC_ID:
360 				self->private->argc = g_value_get_int( value );
361 				break;
362 
363 			case BASE_PROP_ARGV_ID:
364 				if( self->private->argv ){
365 					g_boxed_free( G_TYPE_STRV, self->private->argv );
366 				}
367 				self->private->argv = g_value_dup_boxed( value );
368 				break;
369 
370 			case BASE_PROP_OPTIONS_ID:
371 				self->private->options = g_value_get_pointer( value );
372 				break;
373 
374 			case BASE_PROP_APPLICATION_NAME_ID:
375 				g_free( self->private->application_name );
376 				self->private->application_name = g_value_dup_string( value );
377 				break;
378 
379 			case BASE_PROP_DESCRIPTION_ID:
380 				g_free( self->private->description );
381 				self->private->description = g_value_dup_string( value );
382 				break;
383 
384 			case BASE_PROP_ICON_NAME_ID:
385 				g_free( self->private->icon_name );
386 				self->private->icon_name = g_value_dup_string( value );
387 				break;
388 
389 			case BASE_PROP_UNIQUE_NAME_ID:
390 				g_free( self->private->unique_app_name );
391 				self->private->unique_app_name = g_value_dup_string( value );
392 				break;
393 
394 			case BASE_PROP_CODE_ID:
395 				self->private->code = g_value_get_int( value );
396 				break;
397 
398 			default:
399 				G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
400 				break;
401 		}
402 	}
403 }
404 
405 static void
instance_dispose(GObject * application)406 instance_dispose( GObject *application )
407 {
408 	static const gchar *thisfn = "base_application_instance_dispose";
409 	BaseApplication *self;
410 
411 	g_return_if_fail( BASE_IS_APPLICATION( application ));
412 
413 	self = BASE_APPLICATION( application );
414 
415 	if( !self->private->dispose_has_run ){
416 
417 		g_debug( "%s: application=%p (%s)", thisfn, ( void * ) application, G_OBJECT_TYPE_NAME( application ));
418 
419 		self->private->dispose_has_run = TRUE;
420 
421 		/* chain up to the parent class */
422 		if( G_OBJECT_CLASS( st_parent_class )->dispose ){
423 			G_OBJECT_CLASS( st_parent_class )->dispose( application );
424 		}
425 	}
426 }
427 
428 static void
instance_finalize(GObject * application)429 instance_finalize( GObject *application )
430 {
431 	static const gchar *thisfn = "base_application_instance_finalize";
432 	BaseApplication *self;
433 
434 	g_return_if_fail( BASE_IS_APPLICATION( application ));
435 
436 	g_debug( "%s: application=%p (%s)", thisfn, ( void * ) application, G_OBJECT_TYPE_NAME( application ));
437 
438 	self = BASE_APPLICATION( application );
439 
440 	g_free( self->private->application_name );
441 	g_free( self->private->description );
442 	g_free( self->private->icon_name );
443 	g_free( self->private->unique_app_name );
444 	g_strfreev( self->private->argv );
445 
446 	g_free( self->private );
447 
448 	/* chain call to parent class */
449 	if( G_OBJECT_CLASS( st_parent_class )->finalize ){
450 		G_OBJECT_CLASS( st_parent_class )->finalize( application );
451 	}
452 }
453 
454 /**
455  * base_application_run_with_args:
456  * @application: this #BaseApplication -derived instance.
457  *
458  * Starts and runs the application.
459  * Takes care of creating, initializing, and running the main window.
460  *
461  * All steps are implemented as virtual functions which provide some
462  * suitable defaults, and may be overriden by a derived class.
463  *
464  * Returns: an %int code suitable as an exit code for the program.
465  *
466  * Though it is defined as a virtual function itself, it should be very
467  * seldomly needed to override this in a derived class.
468  */
469 int
base_application_run_with_args(BaseApplication * application,int argc,GStrv argv)470 base_application_run_with_args( BaseApplication *application, int argc, GStrv argv )
471 {
472 	static const gchar *thisfn = "base_application_run_with_args";
473 	BaseApplicationPrivate *priv;
474 
475 	g_return_val_if_fail( BASE_IS_APPLICATION( application ), BASE_EXIT_CODE_PROGRAM );
476 
477 	priv = application->private;
478 
479 	if( !priv->dispose_has_run ){
480 
481 		g_debug( "%s: application=%p (%s), argc=%d",
482 				thisfn,
483 				( void * ) application, G_OBJECT_TYPE_NAME( application ),
484 				argc );
485 
486 		priv->argc = argc;
487 		priv->argv = g_strdupv( argv );
488 		priv->code = BASE_EXIT_CODE_OK;
489 
490 		if( init_i18n( application ) &&
491 			init_application_name( application ) &&
492 			init_gtk( application ) &&
493 			v_manage_options( application ) &&
494 			init_unique_manager( application ) &&
495 			init_session_manager( application ) &&
496 			init_icon_name( application ) &&
497 			v_init_application( application ) &&
498 			v_create_windows( application )){
499 
500 			g_debug( "%s: entering gtk_main", thisfn );
501 			gtk_main();
502 		}
503 	}
504 
505 	return( priv->code );
506 }
507 
508 /*
509  * i18n initialization
510  *
511  * Returns: %TRUE to continue the execution, %FALSE to terminate the program.
512  * The program exit code will be taken from @code.
513  */
514 static gboolean
init_i18n(BaseApplication * application)515 init_i18n( BaseApplication *application )
516 {
517 	static const gchar *thisfn = "base_application_init_i18n";
518 
519 	g_debug( "%s: application=%p", thisfn, ( void * ) application );
520 
521 #ifdef ENABLE_NLS
522 	bindtextdomain( GETTEXT_PACKAGE, GNOMELOCALEDIR );
523 # ifdef HAVE_BIND_TEXTDOMAIN_CODESET
524 	bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
525 # endif
526 	textdomain( GETTEXT_PACKAGE );
527 #endif
528 
529 	return( TRUE );
530 }
531 
532 /*
533  * From GLib Reference Manual:
534  * Sets a human-readable name for the application.
535  * This name should be localized if possible, and is intended for display to the user.
536  *
537  * This application name is supposed to have been set as a property when
538  * the BaseApplication-derived has been instanciated.
539  */
540 static gboolean
init_application_name(BaseApplication * application)541 init_application_name( BaseApplication *application )
542 {
543 	static const gchar *thisfn = "base_application_init_application_name";
544 	gchar *name;
545 	gboolean ret;
546 
547 	g_debug( "%s: application=%p", thisfn, ( void * ) application );
548 
549 	ret = TRUE;
550 
551 	/* setup default Gtk+ application name
552 	 * must have been set at instanciation time by the derived class
553 	 */
554 	name = base_application_get_application_name( application );
555 	if( name && g_utf8_strlen( name, -1 )){
556 		g_set_application_name( name );
557 
558 	} else {
559 		application->private->code = BASE_EXIT_CODE_APPLICATION_NAME;
560 		ret = FALSE;
561 	}
562 	g_free( name );
563 
564 	return( ret );
565 }
566 
567 /*
568  * pre-gtk initialization
569  */
570 static gboolean
init_gtk(BaseApplication * application)571 init_gtk( BaseApplication *application )
572 {
573 	static const gchar *thisfn = "base_application_init_gtk";
574 	gboolean ret;
575 	char *parameter_string;
576 	GError *error;
577 
578 	g_debug( "%s: application=%p", thisfn, ( void * ) application );
579 
580 	/* manage command-line arguments
581 	 */
582 	if( application->private->options ){
583 		parameter_string = g_strdup( g_get_application_name());
584 		error = NULL;
585 		ret = gtk_init_with_args(
586 				&application->private->argc,
587 				( char *** ) &application->private->argv,
588 				parameter_string,
589 				application->private->options,
590 				GETTEXT_PACKAGE,
591 				&error );
592 		if( error ){
593 			g_warning( "%s: %s", thisfn, error->message );
594 			g_error_free( error );
595 			ret = FALSE;
596 			application->private->code = BASE_EXIT_CODE_ARGS;
597 		}
598 		g_free( parameter_string );
599 
600 	} else {
601 		ret = gtk_init_check(
602 				&application->private->argc,
603 				( char *** ) &application->private->argv );
604 		if( !ret ){
605 			g_warning( "%s", _( "Unable to interpret command-line arguments" ));
606 			application->private->code = BASE_EXIT_CODE_ARGS;
607 		}
608 	}
609 
610 	return( ret );
611 }
612 
613 static gboolean
v_manage_options(BaseApplication * application)614 v_manage_options( BaseApplication *application )
615 {
616 	static const gchar *thisfn = "base_application_v_manage_options";
617 	gboolean ret;
618 
619 	g_debug( "%s: application=%p", thisfn, ( void * ) application );
620 
621 	ret = TRUE;
622 
623 	if( BASE_APPLICATION_GET_CLASS( application )->manage_options ){
624 		ret = BASE_APPLICATION_GET_CLASS( application )->manage_options( application );
625 	}
626 
627 	return( ret );
628 }
629 
630 /*
631  * Initialize BaseIUnique interface for the instance
632  */
633 static gboolean
init_unique_manager(BaseApplication * application)634 init_unique_manager( BaseApplication *application )
635 {
636 	static const gchar *thisfn = "base_application_init_unique_manager";
637 	gboolean ret;
638 
639 	g_debug( "%s: application=%p", thisfn, ( void * ) application );
640 
641 	ret = base_iunique_init_with_name(
642 			BASE_IUNIQUE( application ),
643 			application->private->unique_app_name );
644 
645 	if( !ret ){
646 		application->private->code = BASE_EXIT_CODE_UNIQUE_APP;
647 	}
648 
649 	return( ret );
650 }
651 
652 /*
653  * Relying on session manager to have a chance to save the modifications
654  * before exiting a session
655  */
656 static gboolean
init_session_manager(BaseApplication * application)657 init_session_manager( BaseApplication *application )
658 {
659 	static const gchar *thisfn = "base_application_init_session_manager";
660 
661 	g_debug( "%s: application=%p", thisfn, ( void * ) application );
662 
663 	base_isession_init( BASE_ISESSION( application ));
664 
665 	return( TRUE );
666 }
667 
668 /*
669  * From GTK+ Reference Manual:
670  * Sets an icon to be used as fallback for windows that haven't had
671  * gtk_window_set_icon_list() called on them from a named themed icon.
672  *
673  * This icon name is supposed to have been set as a property when
674  * the BaseApplication-derived has been instanciated.
675  */
676 static gboolean
init_icon_name(BaseApplication * application)677 init_icon_name( BaseApplication *application )
678 {
679 	static const gchar *thisfn = "base_application_init_icon_name";
680 
681 	g_debug( "%s: application=%p", thisfn, ( void * ) application );
682 
683 	/* setup default application icon
684 	 */
685 	if( application->private->icon_name && g_utf8_strlen( application->private->icon_name, -1 )){
686 			gtk_window_set_default_icon_name( application->private->icon_name );
687 
688 	} else {
689 		g_warning( "%s: no default icon name", thisfn );
690 	}
691 
692 	return( TRUE );
693 }
694 
695 static gboolean
v_init_application(BaseApplication * application)696 v_init_application( BaseApplication *application )
697 {
698 	static const gchar *thisfn = "base_application_v_init_application";
699 	gboolean ret;
700 
701 	g_debug( "%s: application=%p", thisfn, ( void * ) application );
702 
703 	ret = TRUE;
704 
705 	if( BASE_APPLICATION_GET_CLASS( application )->init_application ){
706 		ret = BASE_APPLICATION_GET_CLASS( application )->init_application( application );
707 	}
708 
709 	return( ret );
710 }
711 
712 static gboolean
v_create_windows(BaseApplication * application)713 v_create_windows( BaseApplication *application )
714 {
715 	static const gchar *thisfn = "base_application_v_create_windows";
716 	gboolean ret;
717 
718 	g_debug( "%s: application=%p", thisfn, ( void * ) application );
719 
720 	ret = TRUE;
721 
722 	if( BASE_APPLICATION_GET_CLASS( application )->create_windows ){
723 		ret = BASE_APPLICATION_GET_CLASS( application )->create_windows( application );
724 	}
725 
726 	return( ret );
727 }
728 
729 /**
730  * base_application_get_application_name:
731  * @application: this #BaseApplication instance.
732  *
733  * Returns: the application name as a newly allocated string which should
734  * be be g_free() by the caller.
735  */
736 gchar *
base_application_get_application_name(const BaseApplication * application)737 base_application_get_application_name( const BaseApplication *application )
738 {
739 	gchar *name = NULL;
740 
741 	g_return_val_if_fail( BASE_IS_APPLICATION( application ), NULL );
742 
743 	if( !application->private->dispose_has_run ){
744 
745 		name = g_strdup( application->private->application_name );
746 	}
747 
748 	return( name );
749 }
750 
751 /**
752  * base_application_is_willing_to_quit:
753  * @application: this #BaseApplication instance.
754  *
755  * Returns: %TRUE if the application is willing to quit, %FALSE else.
756  *
757  * This function is typically called from the derived application, when
758  * the user has required the termination, in order to let it handle
759  * unsaved modifications.
760  */
761 gboolean
base_application_is_willing_to_quit(const BaseApplication * application)762 base_application_is_willing_to_quit( const BaseApplication *application )
763 {
764 	g_return_val_if_fail( BASE_IS_APPLICATION( application ), TRUE );
765 	g_return_val_if_fail( BASE_IS_ISESSION( application ), TRUE );
766 
767 	return( base_isession_is_willing_to_quit( BASE_ISESSION( application )));
768 }
769