2
* Copyright (c) 2003 Benedikt Meurer <benedikt.meurer@unix-ag.uni-siegen.de>
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
#endif /* !HAVE_CONFIG_H */
43
#include <libxfce4util/i18n.h>
44
#include <libxfce4util/util.h>
45
#include <libxfcegui4/libxfcegui4.h>
47
#include <xfce4-session/splash-fallback.h>
48
#include <xfce4-session/splash-screen.h>
49
#include <xfce4-session/util.h>
51
/* max number of pictures for a splash theme */
52
#define MAX_PICTURES 25
55
#define SPLASH_DEFAULT_THEME "Default"
57
/* static prototypes */
58
static void xfsm_splash_screen_class_init(XfsmSplashScreenClass *);
59
static void xfsm_splash_screen_init(XfsmSplashScreen *);
60
static void xfsm_splash_screen_finalize(GObject *);
61
static gboolean xfsm_splash_screen_timeout(XfsmSplashScreen *);
62
static gboolean xfsm_splash_screen_load_theme(XfsmSplashScreen *,const gchar *);
63
static gboolean xfsm_splash_screen_load_theme_from_dir(XfsmSplashScreen *,
67
static GObjectClass *parent_class = NULL;
72
xfsm_splash_screen_get_type(void)
74
static GType splash_screen_type = 0;
76
if (!splash_screen_type) {
77
static const GTypeInfo splash_screen_info = {
78
sizeof(XfsmSplashScreenClass),
81
(GClassInitFunc)xfsm_splash_screen_class_init,
84
sizeof(XfsmSplashScreen),
86
(GInstanceInitFunc)xfsm_splash_screen_init
89
splash_screen_type = g_type_register_static(GTK_TYPE_WINDOW,
90
"XfsmSplashScreen", &splash_screen_info, 0);
93
return(splash_screen_type);
99
xfsm_splash_screen_class_init(XfsmSplashScreenClass *klass)
101
GObjectClass *gobject_class;
103
gobject_class = G_OBJECT_CLASS(klass);
104
gobject_class->finalize = xfsm_splash_screen_finalize;
105
parent_class = gtk_type_class(gtk_window_get_type());
111
xfsm_splash_screen_init(XfsmSplashScreen *splash)
116
splash->pictureCount = 0;
117
splash->pictureCurrent = 0;
118
splash->pictures = NULL;
121
splash->progressCount = 0;
122
splash->progressMax = 0;
124
/* set initial window options */
125
gtk_window_set_position(GTK_WINDOW(splash), GTK_WIN_POS_CENTER_ALWAYS);
126
gtk_window_set_decorated(GTK_WINDOW(splash), FALSE);
127
gtk_window_stick(GTK_WINDOW(splash));
129
/* set window manager type hint */
130
netk_gtk_window_set_type(GTK_WINDOW(splash), NETK_WINDOW_SPLASHSCREEN);
132
/* always use a "Watch cursor" on the splash window */
133
gtk_widget_realize(GTK_WIDGET(splash));
134
gdk_window_set_cursor(GTK_WIDGET(splash)->window,
135
gdk_cursor_new(GDK_WATCH));
138
#if GTK_CHECK_VERSION(2, 2, 0)
139
gdk_window_set_skip_pager_hint(GTK_WIDGET(splash)->window, TRUE);
140
gdk_window_set_skip_taskbar_hint(GTK_WIDGET(splash)->window, TRUE);
144
vbox = gtk_vbox_new(FALSE, 1);
145
gtk_container_add(GTK_CONTAINER(splash), vbox);
146
gtk_widget_show(vbox);
149
splash->logoImage = gtk_image_new();
150
gtk_box_pack_start(GTK_BOX(vbox), splash->logoImage, TRUE, TRUE, 0);
151
gtk_widget_show(splash->logoImage);
153
/* the progress bar */
154
splash->progressBar = gtk_progress_bar_new();
155
gtk_box_pack_start(GTK_BOX(vbox), splash->progressBar, FALSE, TRUE, 0);
156
gtk_widget_show(splash->progressBar);
162
xfsm_splash_screen_finalize(GObject *object)
164
XfsmSplashScreen *splash;
167
g_return_if_fail(XFSM_IS_SPLASH_SCREEN(object));
169
splash = XFSM_SPLASH_SCREEN(object);
171
if (splash->pictures != NULL) {
172
for (n = 0; n < splash->pictureCount; n++)
173
g_object_unref(splash->pictures[n]);
175
g_free(splash->pictures);
178
if (splash->pictureTimeoutId)
179
g_source_remove(splash->pictureTimeoutId);
181
G_OBJECT_CLASS(parent_class)->finalize(object);
187
xfsm_splash_screen_new(const gchar *splashTheme, guint progressMax,
188
const gchar *initialText)
190
XfsmSplashScreen *splash;
193
splash = XFSM_SPLASH_SCREEN(g_object_new(xfsm_splash_screen_get_type(),
196
/* prevent divide by null */
197
if ((splash->progressMax = progressMax) == 0)
198
splash->progressMax = 1;
200
/* NULL means use Default theme */
201
if (splashTheme == NULL)
202
splashTheme = SPLASH_DEFAULT_THEME;
205
if (!xfsm_splash_screen_load_theme(splash, splashTheme)) {
206
/* fallback to builtin logo */
207
splash->pictures = g_new(GdkPixbuf *, 1);
208
splash->pictures[0] = inline_icon_at_size(fallback_logo,
210
splash->pictureCurrent = 0;
211
splash->pictureCount = 1;
212
splash->pictureTimeout = 0;
215
/* init splash screen */
216
gtk_image_set_from_pixbuf(GTK_IMAGE(splash->logoImage),
217
splash->pictures[0]);
218
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(splash->progressBar),
220
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(splash->progressBar),
224
if (splash->pictureTimeout > 0) {
225
splash->pictureTimeoutId = g_timeout_add(
226
splash->pictureTimeout,
227
(GSourceFunc)xfsm_splash_screen_timeout,
231
return(GTK_WIDGET(splash));
237
xfsm_splash_screen_set_text(XfsmSplashScreen *splash, const gchar *text)
239
g_return_if_fail(text != NULL);
240
g_return_if_fail(XFSM_IS_SPLASH_SCREEN(splash));
242
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(splash->progressBar),
249
xfsm_splash_screen_launch(XfsmSplashScreen *splash, const gchar *program)
253
g_return_if_fail(program != NULL);
254
g_return_if_fail(XFSM_IS_SPLASH_SCREEN(splash));
257
if (splash->pictureTimeout == 0 && splash->pictureCount > 0) {
258
splash->pictureCurrent = (splash->pictureCurrent + 1) %
259
splash->pictureCount;
260
gtk_image_set_from_pixbuf(GTK_IMAGE(splash->logoImage),
261
splash->pictures[splash->pictureCurrent]);
265
if (splash->progressCount++ > splash->progressMax)
266
splash->progressCount = splash->progressMax;
267
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(splash->progressBar),
268
(double)splash->progressCount / (double)splash->progressMax);
271
buffer = g_strdup_printf(_("Starting %s..."), program);
272
xfsm_splash_screen_set_text(splash, buffer);
275
/* give splash screen time to update its visuals */
276
g_main_context_iteration(NULL, FALSE);
282
xfsm_splash_screen_timeout(XfsmSplashScreen *splash)
284
g_return_val_if_fail(XFSM_IS_SPLASH_SCREEN(splash), FALSE);
287
splash->pictureCurrent = (splash->pictureCurrent + 1) %
288
splash->pictureCount;
289
gtk_image_set_from_pixbuf(GTK_IMAGE(splash->logoImage),
290
splash->pictures[splash->pictureCurrent]);
292
/* give splash screen time to update its visuals */
293
g_main_context_iteration(NULL, FALSE);
295
/* keep the timeout running */
302
xfsm_splash_screen_load_theme(XfsmSplashScreen *splash, const gchar *theme)
307
dir = xfce_get_userfile("splash", theme, NULL);
308
if (xfsm_splash_screen_load_theme_from_dir(splash, dir)) {
315
dir = g_build_filename(SPLASH_THEMES_DIR, theme, NULL);
316
if (xfsm_splash_screen_load_theme_from_dir(splash, dir)) {
328
xfsm_splash_screen_load_theme_from_dir(XfsmSplashScreen *splash,
332
gchar buffer[LINE_MAX];
341
splash->pictures = NULL;
342
splash->pictureCount = 0;
343
splash->pictureTimeout = 0;
347
file = g_build_filename(dir, "splash.theme", NULL);
349
if ((fp = fopen(file, "r")) == NULL)
352
/* read first line */
353
if (fgets(buffer, LINE_MAX, fp) == NULL)
357
if (strncmp(buffer, "[Splash Theme]", 14) != 0) {
358
g_warning("No a splash theme file: %s", file);
363
while (fgets(buffer, LINE_MAX, fp) != NULL) {
364
/* strip leading and trailing whitespace */
365
p = g_strstrip(buffer);
367
/* ignore comments and empty lines */
368
if (*p == '#' || *p == '\0' || *p == '\n')
372
if (strncmp(p, "name=", 5) == 0) {
375
name = g_strdup(p + 5);
377
else if (strncmp(p, "timeout=", 8) == 0) {
378
splash->pictureTimeout = strtoul(p + 8, NULL, 10);
380
else if (strncmp(p, "imagelist=", 10) == 0) {
381
if (imagelist != NULL)
382
g_strfreev(imagelist);
383
imagelist = g_strsplit(p + 10, ",", MAX_PICTURES);
386
/* slightly ignore everything else */
389
/* close theme description file */
390
(void)fclose(fp); fp = NULL;
392
/* check for required settings */
394
g_warning("Splash theme file %s contains no name field", file);
397
else if (imagelist == NULL) {
398
g_warning("Splash theme file %s contains no imagelist field",
403
/* Ok, everything around, lets try to load the pixbufs */
404
splash->pictures = g_new0(GdkPixbuf *, MAX_PICTURES);
406
for (n = 0; imagelist[n] != NULL; n++) {
410
path = g_build_filename(dir, imagelist[n], NULL);
411
if ((pb = gdk_pixbuf_new_from_file(path, NULL)) != NULL)
412
splash->pictures[splash->pictureCount++] = pb;
416
/* Does any file got loaded? */
417
if (splash->pictureCount > 0)
420
g_free(splash->pictures);
426
if (imagelist != NULL)
427
g_strfreev(imagelist);