~ubuntu-branches/ubuntu/karmic/xfce4-session/karmic

« back to all changes in this revision

Viewing changes to xfce4-session/splash-screen.c

  • Committer: Bazaar Package Importer
  • Author(s): Yves-Alexis Perez
  • Date: 2005-11-06 22:01:12 UTC
  • mto: (4.1.1 lenny) (1.3.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20051106220112-5rusox237ymjghsp
Tags: upstream-4.2.3
ImportĀ upstreamĀ versionĀ 4.2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (c) 2003 Benedikt Meurer <benedikt.meurer@unix-ag.uni-siegen.de>
3
 
 * All rights reserved.
4
 
 *
5
 
 * Redistribution and use in source and binary forms, with or without
6
 
 * modification, are permitted provided that the following conditions
7
 
 * are met:
8
 
 *
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.
14
 
 *
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.
25
 
 */
26
 
 
27
 
#ifdef HAVE_CONFIG_H
28
 
#include <config.h>
29
 
#endif /* !HAVE_CONFIG_H */
30
 
 
31
 
#ifdef HAVE_LIMITS_H
32
 
#include <limits.h>
33
 
#endif
34
 
#include <stdio.h>
35
 
#ifdef HAVE_STDLIB_H
36
 
#include <stdlib.h>
37
 
#endif
38
 
#ifdef HAVE_STRING_H
39
 
#include <string.h>
40
 
#endif
41
 
 
42
 
#include <gtk/gtk.h>
43
 
#include <libxfce4util/i18n.h>
44
 
#include <libxfce4util/util.h>
45
 
#include <libxfcegui4/libxfcegui4.h>
46
 
 
47
 
#include <xfce4-session/splash-fallback.h>
48
 
#include <xfce4-session/splash-screen.h>
49
 
#include <xfce4-session/util.h>
50
 
 
51
 
/* max number of pictures for a splash theme */
52
 
#define MAX_PICTURES    25
53
 
 
54
 
/* default theme */
55
 
#define SPLASH_DEFAULT_THEME    "Default"
56
 
 
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 *,
64
 
                        const gchar *);
65
 
 
66
 
/* */
67
 
static GObjectClass     *parent_class = NULL;
68
 
 
69
 
/*
70
 
 */
71
 
GType
72
 
xfsm_splash_screen_get_type(void)
73
 
{
74
 
        static GType splash_screen_type = 0;
75
 
 
76
 
        if (!splash_screen_type) {
77
 
                static const GTypeInfo splash_screen_info = {
78
 
                        sizeof(XfsmSplashScreenClass),
79
 
                        NULL,
80
 
                        NULL,
81
 
                        (GClassInitFunc)xfsm_splash_screen_class_init,
82
 
                        NULL,
83
 
                        NULL,
84
 
                        sizeof(XfsmSplashScreen),
85
 
                        0,
86
 
                        (GInstanceInitFunc)xfsm_splash_screen_init
87
 
                };
88
 
 
89
 
                splash_screen_type = g_type_register_static(GTK_TYPE_WINDOW,
90
 
                                "XfsmSplashScreen", &splash_screen_info, 0);
91
 
        }
92
 
 
93
 
        return(splash_screen_type);
94
 
}
95
 
 
96
 
/*
97
 
 */
98
 
static void
99
 
xfsm_splash_screen_class_init(XfsmSplashScreenClass *klass)
100
 
{
101
 
        GObjectClass *gobject_class;
102
 
 
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());
106
 
}
107
 
 
108
 
/*
109
 
 */
110
 
static void
111
 
xfsm_splash_screen_init(XfsmSplashScreen *splash)
112
 
{
113
 
        GtkWidget *vbox;
114
 
 
115
 
        /* */
116
 
        splash->pictureCount = 0;
117
 
        splash->pictureCurrent = 0;
118
 
        splash->pictures = NULL;
119
 
 
120
 
        /* */
121
 
        splash->progressCount = 0;
122
 
        splash->progressMax = 0;
123
 
 
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));
128
 
 
129
 
        /* set window manager type hint */
130
 
        netk_gtk_window_set_type(GTK_WINDOW(splash), NETK_WINDOW_SPLASHSCREEN);
131
 
 
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));
136
 
 
137
 
        /* */
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);
141
 
#endif
142
 
 
143
 
        /* */
144
 
        vbox = gtk_vbox_new(FALSE, 1);
145
 
        gtk_container_add(GTK_CONTAINER(splash), vbox);
146
 
        gtk_widget_show(vbox);
147
 
 
148
 
        /* the logo image */
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);
152
 
 
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);
157
 
}
158
 
 
159
 
/*
160
 
 */
161
 
static void
162
 
xfsm_splash_screen_finalize(GObject *object)
163
 
{
164
 
        XfsmSplashScreen *splash;
165
 
        guint n;
166
 
 
167
 
        g_return_if_fail(XFSM_IS_SPLASH_SCREEN(object));
168
 
 
169
 
        splash = XFSM_SPLASH_SCREEN(object);
170
 
 
171
 
        if (splash->pictures != NULL) {
172
 
                for (n = 0; n < splash->pictureCount; n++)
173
 
                        g_object_unref(splash->pictures[n]);
174
 
 
175
 
                g_free(splash->pictures);
176
 
        }
177
 
 
178
 
        if (splash->pictureTimeoutId)
179
 
                g_source_remove(splash->pictureTimeoutId);
180
 
 
181
 
        G_OBJECT_CLASS(parent_class)->finalize(object);
182
 
}
183
 
 
184
 
/*
185
 
 */
186
 
GtkWidget *
187
 
xfsm_splash_screen_new(const gchar *splashTheme, guint progressMax,
188
 
                const gchar *initialText)
189
 
{
190
 
        XfsmSplashScreen *splash;
191
 
 
192
 
        /* XXX */
193
 
        splash = XFSM_SPLASH_SCREEN(g_object_new(xfsm_splash_screen_get_type(),
194
 
                                NULL));
195
 
 
196
 
        /* prevent divide by null */
197
 
        if ((splash->progressMax = progressMax) == 0)
198
 
                splash->progressMax = 1;
199
 
 
200
 
        /* NULL means use Default theme */
201
 
        if (splashTheme == NULL)
202
 
                splashTheme = SPLASH_DEFAULT_THEME;
203
 
 
204
 
        /* */
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,
209
 
                                350, 350);
210
 
                splash->pictureCurrent = 0;
211
 
                splash->pictureCount = 1;
212
 
                splash->pictureTimeout = 0;
213
 
        }
214
 
 
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),
219
 
                        0.0);
220
 
        gtk_progress_bar_set_text(GTK_PROGRESS_BAR(splash->progressBar),
221
 
                        initialText);
222
 
 
223
 
        /* */
224
 
        if (splash->pictureTimeout > 0) {
225
 
                splash->pictureTimeoutId = g_timeout_add(
226
 
                                splash->pictureTimeout,
227
 
                                (GSourceFunc)xfsm_splash_screen_timeout,
228
 
                                splash);
229
 
        }
230
 
 
231
 
        return(GTK_WIDGET(splash));
232
 
}
233
 
 
234
 
/*
235
 
 */
236
 
void
237
 
xfsm_splash_screen_set_text(XfsmSplashScreen *splash, const gchar *text)
238
 
{
239
 
        g_return_if_fail(text != NULL);
240
 
        g_return_if_fail(XFSM_IS_SPLASH_SCREEN(splash));
241
 
 
242
 
        gtk_progress_bar_set_text(GTK_PROGRESS_BAR(splash->progressBar),
243
 
                        text);
244
 
}
245
 
 
246
 
/*
247
 
 */
248
 
void
249
 
xfsm_splash_screen_launch(XfsmSplashScreen *splash, const gchar *program)
250
 
{
251
 
        gchar *buffer;
252
 
 
253
 
        g_return_if_fail(program != NULL);
254
 
        g_return_if_fail(XFSM_IS_SPLASH_SCREEN(splash));
255
 
 
256
 
        /* */
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]);
262
 
        }
263
 
 
264
 
        /* */
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);
269
 
 
270
 
        /* */
271
 
        buffer = g_strdup_printf(_("Starting %s..."), program);
272
 
        xfsm_splash_screen_set_text(splash, buffer);
273
 
        g_free(buffer);
274
 
 
275
 
        /* give splash screen time to update its visuals */
276
 
        g_main_context_iteration(NULL, FALSE);
277
 
}
278
 
 
279
 
/*
280
 
 */
281
 
static gboolean
282
 
xfsm_splash_screen_timeout(XfsmSplashScreen *splash)
283
 
{
284
 
        g_return_val_if_fail(XFSM_IS_SPLASH_SCREEN(splash), FALSE);
285
 
 
286
 
        /* */
287
 
        splash->pictureCurrent = (splash->pictureCurrent + 1) %
288
 
                splash->pictureCount;
289
 
        gtk_image_set_from_pixbuf(GTK_IMAGE(splash->logoImage),
290
 
                        splash->pictures[splash->pictureCurrent]);
291
 
 
292
 
        /* give splash screen time to update its visuals */
293
 
        g_main_context_iteration(NULL, FALSE);
294
 
 
295
 
        /* keep the timeout running */
296
 
        return(TRUE);
297
 
}
298
 
 
299
 
/*
300
 
 */
301
 
static gboolean
302
 
xfsm_splash_screen_load_theme(XfsmSplashScreen *splash, const gchar *theme)
303
 
{
304
 
        gchar *dir;
305
 
 
306
 
        /* */
307
 
        dir = xfce_get_userfile("splash", theme, NULL);
308
 
        if (xfsm_splash_screen_load_theme_from_dir(splash, dir)) {
309
 
                g_free(dir);
310
 
                return(TRUE);
311
 
        }
312
 
        g_free(dir);
313
 
 
314
 
        /* */
315
 
        dir = g_build_filename(SPLASH_THEMES_DIR, theme, NULL);
316
 
        if (xfsm_splash_screen_load_theme_from_dir(splash, dir)) {
317
 
                g_free(dir);
318
 
                return(TRUE);
319
 
        }
320
 
        g_free(dir);
321
 
 
322
 
        return(FALSE);
323
 
}
324
 
 
325
 
/*
326
 
 */
327
 
static gboolean 
328
 
xfsm_splash_screen_load_theme_from_dir(XfsmSplashScreen *splash,
329
 
                                       const gchar *dir)
330
 
{
331
 
        gboolean succeed;
332
 
        gchar buffer[LINE_MAX];
333
 
        gchar *p;
334
 
        gchar *file;
335
 
        gchar *name;
336
 
        gchar **imagelist;
337
 
        FILE *fp;
338
 
        guint n;
339
 
 
340
 
        succeed = FALSE;
341
 
        splash->pictures = NULL;
342
 
        splash->pictureCount = 0;
343
 
        splash->pictureTimeout = 0;
344
 
        name = NULL;
345
 
        imagelist = NULL;
346
 
 
347
 
        file = g_build_filename(dir, "splash.theme", NULL);
348
 
        
349
 
        if ((fp = fopen(file, "r")) == NULL)
350
 
                goto end;
351
 
 
352
 
        /* read first line */
353
 
        if (fgets(buffer, LINE_MAX, fp) == NULL)
354
 
                goto end;
355
 
 
356
 
        /* */
357
 
        if (strncmp(buffer, "[Splash Theme]", 14) != 0) {
358
 
                g_warning("No a splash theme file: %s", file);
359
 
                goto end;
360
 
        }
361
 
 
362
 
        /* */
363
 
        while (fgets(buffer, LINE_MAX, fp) != NULL) {
364
 
                /* strip leading and trailing whitespace */
365
 
                p = g_strstrip(buffer);
366
 
 
367
 
                /* ignore comments and empty lines */
368
 
                if (*p == '#' || *p == '\0' || *p == '\n')
369
 
                        continue;
370
 
 
371
 
                /* */
372
 
                if (strncmp(p, "name=", 5) == 0) {
373
 
                        if (name != NULL)
374
 
                                g_free(name);
375
 
                        name = g_strdup(p + 5);
376
 
                }
377
 
                else if (strncmp(p, "timeout=", 8) == 0) {
378
 
                        splash->pictureTimeout = strtoul(p + 8, NULL, 10);
379
 
                }
380
 
                else if (strncmp(p, "imagelist=", 10) == 0) {
381
 
                        if (imagelist != NULL)
382
 
                                g_strfreev(imagelist);
383
 
                        imagelist = g_strsplit(p + 10, ",", MAX_PICTURES);
384
 
                }
385
 
 
386
 
                /* slightly ignore everything else */
387
 
        }
388
 
 
389
 
        /* close theme description file */
390
 
        (void)fclose(fp); fp = NULL;
391
 
 
392
 
        /* check for required settings */
393
 
        if (name == NULL) {
394
 
                g_warning("Splash theme file %s contains no name field", file);
395
 
                goto end;
396
 
        }
397
 
        else if (imagelist == NULL) {
398
 
                g_warning("Splash theme file %s contains no imagelist field",
399
 
                                file);
400
 
                goto end;
401
 
        }
402
 
 
403
 
        /* Ok, everything around, lets try to load the pixbufs */
404
 
        splash->pictures = g_new0(GdkPixbuf *, MAX_PICTURES);
405
 
 
406
 
        for (n = 0; imagelist[n] != NULL; n++) {
407
 
                GdkPixbuf *pb;
408
 
                gchar *path;
409
 
 
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;
413
 
                g_free(path);
414
 
        }
415
 
 
416
 
        /* Does any file got loaded? */
417
 
        if (splash->pictureCount > 0)
418
 
                succeed = TRUE;
419
 
        else
420
 
                g_free(splash->pictures);
421
 
                
422
 
 
423
 
end:
424
 
        if (name != NULL)
425
 
                g_free(name);
426
 
        if (imagelist != NULL)
427
 
                g_strfreev(imagelist);
428
 
        if (fp != NULL)
429
 
                (void)fclose(fp);
430
 
        g_free(file);
431
 
        return(succeed);
432
 
}
433