Develop and Download Open Source Software

Browse Subversion Repository

Contents of /kazehakase/trunk/src/kz-app.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3843 - (show annotations) (download) (as text)
Fri Sep 11 03:37:20 2009 UTC (3 years, 8 months ago) by ikezoe
File MIME type: text/x-csrc
File size: 29934 byte(s)
	* src/kz-app.c: Free non-object variables in finalize.
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /*
4 * Copyright (C) 2004 Hiroyuki Ikezoe
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif /* HAVE_CONFIG_H */
24
25 #include "kz-app.h"
26 #include <stdlib.h>
27 #ifdef USE_SSL
28 #include <gcrypt.h>
29 #include <gnutls/gnutls.h>
30 #include <errno.h>
31 #include <pthread.h>
32 GCRY_THREAD_OPTION_PTHREAD_IMPL;
33 #endif
34 #ifdef HAVE_LIBSM
35 # include <X11/SM/SMlib.h>
36 # include <X11/ICE/ICElib.h>
37 # ifdef G_OS_UNIX
38 # include <sys/types.h>
39 # endif
40 # ifdef HAVE_UNISTD_H
41 # include <unistd.h>
42 # endif
43 # include <fcntl.h>
44 #endif /* HAVE_LIBSM */
45
46 #include <glib/gstdio.h>
47 #include <glib/gi18n.h>
48 #include "kazehakase.h"
49 #include "kz-actions-tab.h"
50 #include "kz-ext.h"
51 #include "kz-icons.h"
52 #include "kz-session.h"
53 #include "kz-tab-label.h"
54 #include "kz-window.h"
55 #include "kz-history-utils.h"
56 #include "kz-marshalers.h"
57 #include "glib-utils.h"
58 #include "utils.h"
59
60 #include "egg-pixbuf-thumbnail-type-builtins.h"
61
62 enum {
63 THUMBNAIL_CREATED_SIGNAL,
64 LAST_SIGNAL
65 };
66
67 enum {
68 PROP_0,
69 PROP_ARGC,
70 PROP_ARGV
71 };
72
73 typedef struct _KzAppPrivate KzAppPrivate;
74 struct _KzAppPrivate
75 {
76 gint argc;
77 gchar **argv;
78 GList *window_list;
79 KzFavicon *favicon;
80 KzSearch *search;
81 KzRootBookmark *bookmarks;
82 KzProfile *profile;
83 KzProfile *proxy;
84 #if USE_MIGEMO
85 KzMigemo *migemo;
86 #endif
87 #ifdef HAVE_LIBSM
88 gpointer smc_conn;
89 gchar *session_id;
90 #endif /* HAVE_LIBSM */
91
92 /* paths */
93 gchar *user_dir;
94 gchar *history_dir;
95 gchar *history_time_stamp;
96 gchar *popup_dir;
97 gchar *favicon_dir;
98 gchar *smartbookmark_history_dir;
99 gchar *form_data_dir;
100 gchar *clips_dir;
101 gchar *thumbnails_dir;
102
103 gchar *system_data_dir;
104 gchar *system_kz_data_dir;
105 gchar *system_lib_dir;
106 gchar *system_config_dir;
107
108 gchar *system_icons_dir;
109 gchar *system_pixmaps_dir;
110
111 gchar *system_embed_module_dir;
112 gchar *system_search_module_dir;
113
114 gchar *system_ext_dir;
115 gchar *system_ruby_ext_dir;
116 gchar *system_ruby_ext_data_dir;
117 };
118
119 #define KZ_APP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), KZ_TYPE_APP, KzAppPrivate))
120
121 static GObject *constructor (GType type,
122 guint n_props,
123 GObjectConstructParam *props);
124 static void dispose (GObject *object);
125 static void finalize (GObject *object);
126 static void set_property (GObject *object,
127 guint prop_id,
128 const GValue *value,
129 GParamSpec *pspec);
130 static void get_property (GObject *object,
131 guint prop_id,
132 GValue *value,
133 GParamSpec *pspec);
134
135 static void cb_destroy_window (GtkObject *object, gpointer data);
136
137 #ifdef HAVE_LIBSM
138 static void connect_sm (KzApp *app);
139 #endif /* HAVE_LIBSM */
140
141 static KzApp *the_kz_app = NULL;
142
143 KzApp *
144 kz_app_get (void)
145 {
146 return the_kz_app;
147 }
148
149 G_DEFINE_TYPE(KzApp, kz_app, G_TYPE_OBJECT)
150
151 static gint kz_app_signals[LAST_SIGNAL] = {0};
152
153 static void
154 kz_app_class_init (KzAppClass *klass)
155 {
156 GObjectClass *object_class;
157
158 object_class = G_OBJECT_CLASS(klass);
159
160 object_class->constructor = constructor;
161 object_class->dispose = dispose;
162 object_class->finalize = finalize;
163 object_class->set_property = set_property;
164 object_class->get_property = get_property;
165
166 klass->thumbnail_created = NULL;
167
168 kz_app_signals[THUMBNAIL_CREATED_SIGNAL]
169 = g_signal_new("thumbnail-created",
170 G_TYPE_FROM_CLASS (klass),
171 G_SIGNAL_RUN_FIRST,
172 G_STRUCT_OFFSET (KzAppClass, thumbnail_created),
173 NULL, NULL,
174 _kz_marshal_VOID__STRING_ENUM,
175 G_TYPE_NONE, 2,
176 G_TYPE_STRING, EGG_TYPE_PIXBUF_THUMBNAIL_SIZE);
177
178 g_object_class_install_property(
179 object_class,
180 PROP_ARGC,
181 g_param_spec_int(
182 "argc",
183 _("Argument number"),
184 _("The number of argument of program"),
185 0, G_MAXINT,
186 0,
187 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
188 g_object_class_install_property(
189 object_class,
190 PROP_ARGV,
191 g_param_spec_pointer ("argv",
192 _("Argument list"),
193 _("The argument list of program"),
194 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
195 g_type_class_add_private(object_class, sizeof(KzAppPrivate));
196 }
197
198 static GObject *
199 constructor (GType type,
200 guint n_props,
201 GObjectConstructParam *props)
202 {
203 GObject *object;
204
205 if (!the_kz_app)
206 {
207 GObjectClass *klass = G_OBJECT_CLASS(kz_app_parent_class);
208 object = klass->constructor(type, n_props, props);
209
210 #ifdef HAVE_LIBSM
211 /* session management */
212 connect_sm(KZ_APP(object));
213 #endif /* HAVE_LIBSM */
214
215 the_kz_app = KZ_APP(object);
216 }
217 else
218 {
219 object = g_object_ref(the_kz_app);
220 }
221 return object;
222 }
223
224 static void
225 set_property (GObject *object,
226 guint prop_id,
227 const GValue *value,
228 GParamSpec *pspec)
229 {
230 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(object);
231
232 switch (prop_id)
233 {
234 case PROP_ARGC:
235 priv->argc = g_value_get_int(value);
236 break;
237 case PROP_ARGV:
238 priv->argv = g_strdupv(g_value_get_pointer(value));
239 break;
240 default:
241 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
242 break;
243 }
244 }
245
246
247 static void
248 get_property (GObject *object,
249 guint prop_id,
250 GValue *value,
251 GParamSpec *pspec)
252 {
253 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(object);
254
255 switch (prop_id)
256 {
257 case PROP_ARGC:
258 g_value_set_int(value, priv->argc);
259 break;
260 case PROP_ARGV:
261 g_value_set_pointer(value, priv->argv);
262 break;
263 default:
264 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
265 break;
266 }
267 }
268
269
270 static void
271 ensure_directories (KzApp *app)
272 {
273 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(app);
274
275 g_mkdir_with_parents(priv->history_dir, 0700);
276 g_mkdir_with_parents(priv->favicon_dir, 0700);
277 g_mkdir_with_parents(priv->popup_dir, 0700);
278 g_mkdir_with_parents(priv->smartbookmark_history_dir, 0700);
279 g_mkdir_with_parents(priv->form_data_dir, 0700);
280 g_mkdir_with_parents(priv->clips_dir, 0700);
281 }
282
283 static void
284 kz_app_init_path (KzApp *app)
285 {
286 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(app);
287
288 #ifdef G_OS_WIN32
289 priv->user_dir = g_build_filename(g_get_user_config_dir(),
290 PACKAGE, NULL);
291 #else
292 priv->user_dir = g_build_filename(g_get_home_dir(), "."PACKAGE, NULL);
293 #endif
294 priv->history_dir = g_build_filename(priv->user_dir,
295 "history",
296 NULL);
297 priv->history_time_stamp = g_build_filename(priv->history_dir,
298 "time-stamp",
299 NULL);
300 priv->popup_dir = g_build_filename(priv->user_dir, "popup", NULL);
301 priv->favicon_dir = g_build_filename(priv->user_dir, "favicon", NULL);
302 priv->smartbookmark_history_dir =
303 g_build_filename(priv->user_dir, "smartbookmark_history", NULL);
304 priv->form_data_dir =
305 g_build_filename(priv->user_dir, "form_data", NULL);
306 priv->clips_dir = g_build_filename(priv->user_dir, "clips", NULL);
307 priv->thumbnails_dir = g_build_filename(g_get_home_dir(),
308 ".thumbnails",
309 NULL);
310
311 #ifdef G_OS_WIN32
312 priv->system_data_dir = g_build_filename(kz_win32_base_path(),
313 "share", NULL);
314 priv->system_kz_data_dir = g_build_filename(priv->system_data_dir,
315 PACKAGE, NULL);
316 priv->system_lib_dir = g_build_filename(kz_win32_base_path(),
317 "lib", PACKAGE, NULL);
318 priv->system_config_dir = g_build_filename(kz_win32_base_path(),
319 "etc", PACKAGE, NULL);
320
321 priv->system_embed_module_dir = g_build_filename(priv->system_lib_dir,
322 "web", NULL);
323 priv->system_search_module_dir = g_build_filename(priv->system_lib_dir,
324 "search", NULL);
325
326 priv->system_ext_dir = g_strdup(priv->system_lib_dir);
327 priv->system_ruby_ext_dir = g_build_filename(priv->system_ext_dir,
328 "ruby", NULL);
329 #else
330 priv->system_data_dir = g_strdup(SYSDATADIR);
331 priv->system_kz_data_dir = g_strdup(KZ_DATADIR);
332 priv->system_config_dir = g_strdup(KZ_SYSCONFDIR);
333 priv->system_lib_dir = g_strdup(KZ_LIBDIR);
334
335 priv->system_embed_module_dir = g_strdup(KZ_EMBED_MODULEDIR);
336 priv->system_search_module_dir = g_strdup(KZ_SEARCH_MODULEDIR);
337
338 priv->system_ext_dir = g_strdup(KZ_EXTDIR);
339 priv->system_ruby_ext_dir = g_strdup(KZ_RUBY_EXTDIR);
340 #endif
341
342 priv->system_icons_dir = g_build_filename(priv->system_kz_data_dir,
343 "icons", NULL);
344 priv->system_pixmaps_dir = g_build_filename(priv->system_data_dir,
345 "pixmaps", NULL);
346
347 priv->system_ruby_ext_data_dir =
348 g_build_filename(priv->system_kz_data_dir, "ext", "ruby", NULL);
349
350 ensure_directories(app);
351 }
352
353 static void
354 kz_app_dispose_path (GObject *app)
355 {
356 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(app);
357
358 g_free(priv->user_dir);
359 g_free(priv->history_dir);
360 g_free(priv->history_time_stamp);
361 g_free(priv->popup_dir);
362 g_free(priv->favicon_dir);
363 g_free(priv->smartbookmark_history_dir);
364 g_free(priv->form_data_dir);
365 g_free(priv->clips_dir);
366 g_free(priv->thumbnails_dir);
367
368 g_free(priv->system_data_dir);
369 g_free(priv->system_kz_data_dir);
370 g_free(priv->system_lib_dir);
371 g_free(priv->system_config_dir);
372
373 g_free(priv->system_icons_dir);
374 g_free(priv->system_pixmaps_dir);
375
376 g_free(priv->system_embed_module_dir);
377 g_free(priv->system_search_module_dir);
378
379 g_free(priv->system_ext_dir);
380 g_free(priv->system_ruby_ext_dir);
381 g_free(priv->system_ruby_ext_data_dir);
382 }
383
384 #define DEFINE_PATH_GETTER(name) \
385 const gchar * \
386 kz_app_get_ ## name (KzApp *app) \
387 { \
388 g_return_val_if_fail(KZ_IS_APP(app), NULL); \
389 \
390 return KZ_APP_GET_PRIVATE(app)->name; \
391 }
392
393 DEFINE_PATH_GETTER(user_dir)
394 DEFINE_PATH_GETTER(history_dir)
395 DEFINE_PATH_GETTER(history_time_stamp)
396 DEFINE_PATH_GETTER(popup_dir)
397 DEFINE_PATH_GETTER(favicon_dir)
398 DEFINE_PATH_GETTER(smartbookmark_history_dir)
399 DEFINE_PATH_GETTER(form_data_dir)
400 DEFINE_PATH_GETTER(clips_dir)
401 DEFINE_PATH_GETTER(thumbnails_dir)
402
403 DEFINE_PATH_GETTER(system_data_dir)
404 DEFINE_PATH_GETTER(system_kz_data_dir)
405 DEFINE_PATH_GETTER(system_lib_dir)
406 DEFINE_PATH_GETTER(system_config_dir)
407
408 DEFINE_PATH_GETTER(system_icons_dir)
409 DEFINE_PATH_GETTER(system_pixmaps_dir)
410
411 DEFINE_PATH_GETTER(system_embed_module_dir)
412 DEFINE_PATH_GETTER(system_search_module_dir)
413
414 DEFINE_PATH_GETTER(system_ext_dir)
415 DEFINE_PATH_GETTER(system_ruby_ext_dir)
416 DEFINE_PATH_GETTER(system_ruby_ext_data_dir)
417
418
419 static void
420 kz_app_init (KzApp *app)
421 {
422 gchar *sysconf_file, *conf_file;
423 gchar *bookmark_file, *sys_bookmark_file;
424 gchar *clip_file, *current_session_file;
425 gchar *bookmark_bar_file, *sys_bookmark_bar_file;
426 gchar *smartbookmark_file, *sys_smartbookmark_file;
427 gchar *accel_prefs_file;
428 gchar *proxy_file, *sysproxy_file;
429 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(app);
430
431 kz_app_init_path(app);
432
433 priv->window_list = NULL;
434 priv->favicon = kz_favicon_get_instance();
435
436 /* load prefs */
437 sysconf_file = g_build_filename(priv->system_config_dir, "kzrc", NULL);
438 conf_file = g_build_filename(priv->user_dir, "kzrc", NULL);
439
440 priv->profile = kz_profile_open(conf_file, sysconf_file);
441
442 /* load bookmarks */
443 bookmark_file = g_build_filename(priv->user_dir,
444 "bookmarks.xml",
445 NULL);
446 sys_bookmark_file = g_build_filename(priv->system_config_dir,
447 "bookmarks.xml",
448 NULL);
449
450 bookmark_bar_file = g_build_filename(priv->user_dir,
451 "bookmarkbar.xml",
452 NULL);
453 sys_bookmark_bar_file = g_build_filename(priv->system_config_dir,
454 "bookmarkbar.xml",
455 NULL);
456
457 clip_file = g_build_filename(priv->user_dir,
458 "clip.xml",
459 NULL);
460
461 smartbookmark_file = g_build_filename(priv->user_dir,
462 "smartbookmarks.xml",
463 NULL);
464 sys_smartbookmark_file= g_build_filename(priv->system_config_dir,
465 "smartbookmarks.xml",
466 NULL);
467
468 current_session_file = g_build_filename(priv->user_dir,
469 "current_session.xml",
470 NULL);
471
472 priv->bookmarks = kz_root_bookmark_new(bookmark_file, sys_bookmark_file,
473 clip_file, NULL);
474
475 kz_root_bookmark_add_smartbookmark_file(priv->bookmarks,
476 smartbookmark_file,
477 sys_smartbookmark_file);
478 kz_root_bookmark_add_bookmark_bar_file(priv->bookmarks,
479 bookmark_bar_file,
480 sys_bookmark_bar_file);
481 kz_root_bookmark_add_current_session_file(priv->bookmarks,
482 current_session_file);
483 kz_session_set_profile(KZ_SESSION(priv->bookmarks->current_session),
484 priv->profile);
485
486 /* Load other prefs... */
487 accel_prefs_file = g_build_filename(priv->user_dir, "keyaccelrc", NULL);
488 gtk_accel_map_load(accel_prefs_file);
489
490 sysproxy_file = g_build_filename(priv->system_config_dir,
491 "proxyrc", NULL);
492 proxy_file = g_build_filename(priv->user_dir, "proxyrc", NULL);
493 priv->proxy = kz_profile_open(proxy_file, sysproxy_file);
494
495 #ifdef USE_SSL
496 /* initialize gnutls. this function should be called once. */
497 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
498 gnutls_global_init();
499 #endif
500
501 #if USE_MIGEMO
502 priv->migemo = kz_migemo_new();
503 #endif
504
505 g_free(sysconf_file);
506 g_free(conf_file);
507 g_free(bookmark_file);
508 g_free(sys_bookmark_file);
509 g_free(clip_file);
510 g_free(bookmark_bar_file);
511 g_free(sys_bookmark_bar_file);
512 g_free(smartbookmark_file);
513 g_free(sys_smartbookmark_file);
514 g_free(current_session_file);
515 g_free(accel_prefs_file);
516 g_free(sysproxy_file);
517 g_free(proxy_file);
518 }
519
520
521 static void
522 clean_history_cache (void)
523 {
524 gboolean limit = FALSE;
525
526 KZ_CONF_GET("History", "limit_cache", limit, BOOL);
527 if (limit)
528 {
529 guint limit_days = 30;
530 time_t limit_seconds;
531
532 KZ_CONF_GET("History", "limit_days", limit_days, INT);
533 limit_seconds = limit_days * 86400;
534 if (!kz_history_time_stamp_exists())
535 kz_history_make_time_stamp();
536 kz_history_purge_by_time_stamp(limit_seconds);
537 kz_utils_purge_files(KZ_GET_POPUP_DIR, limit_seconds);
538 kz_utils_purge_files(KZ_GET_THUMBNAILS_DIR, limit_seconds);
539 }
540 }
541
542 static void
543 dispose (GObject *object)
544 {
545 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(object);
546
547 if (priv->bookmarks)
548 {
549 kz_root_bookmark_save_all(priv->bookmarks);
550 g_object_unref(priv->bookmarks);
551 priv->bookmarks = NULL;
552 }
553
554 if (priv->profile)
555 {
556 kz_profile_close(priv->profile);
557 priv->profile = NULL;
558 }
559
560 if (priv->proxy)
561 {
562 kz_profile_close(priv->proxy);
563 priv->proxy = NULL;
564 }
565
566 if (priv->favicon)
567 {
568 g_object_unref(priv->favicon);
569 priv->favicon = NULL;
570 }
571
572 if (G_OBJECT_CLASS (kz_app_parent_class)->dispose)
573 G_OBJECT_CLASS (kz_app_parent_class)->dispose(object);
574 }
575
576 static void
577 finalize (GObject *object)
578 {
579 gchar *accel_prefs_file;
580 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(object);
581
582 accel_prefs_file = g_build_filename(g_get_home_dir(),
583 "."PACKAGE,
584 "keyaccelrc",
585 NULL);
586
587 gtk_accel_map_save(accel_prefs_file);
588 g_free(accel_prefs_file);
589
590 #ifdef USE_SSL
591 gnutls_global_deinit();
592 #endif
593
594 #ifdef USE_MIGEMO
595 if (priv->migemo)
596 kz_migemo_free(priv->migemo);
597 #endif
598
599 #ifdef HAVE_LIBSM
600 if (priv->smc_conn)
601 SmcCloseConnection ((SmcConn) priv->smc_conn, 0, NULL);
602 #endif /* HAVE_LIBSM */
603
604 g_strfreev(priv->argv);
605 kz_app_dispose_path(object);
606
607 if (G_OBJECT_CLASS (kz_app_parent_class)->finalize)
608 G_OBJECT_CLASS (kz_app_parent_class)->finalize(object);
609 }
610
611 KzApp *
612 kz_app_new (gint argc, gchar **argv)
613 {
614 KzApp *kzapp = g_object_new(KZ_TYPE_APP,
615 "argc", argc,
616 "argv", argv,
617 NULL);
618
619 return kzapp;
620 }
621
622 void
623 kz_app_init_dependencies (KzApp *app, gpointer initial_address)
624 {
625 KzAppPrivate *priv;
626 gchar *search_engine;
627
628 g_return_if_fail(KZ_IS_APP(app));
629
630 kz_icons_init();
631
632 if (!kz_history_time_stamp_exists())
633 kz_history_make_time_stamp();
634
635 priv = KZ_APP_GET_PRIVATE(app);
636
637 search_engine = kz_profile_get_string(priv->profile,
638 "History", "search_engine");
639 if (search_engine)
640 {
641 kz_app_set_search(app, search_engine);
642 g_free(search_engine);
643 }
644
645 kz_ext_init(&initial_address);
646 }
647
648 void
649 kz_app_quit_dependencies (KzApp *app)
650 {
651 KzAppPrivate *priv;
652
653 g_return_if_fail(KZ_IS_APP(app));
654
655 priv = KZ_APP_GET_PRIVATE(app);
656
657 kz_ext_exit();
658 kz_embed_exit();
659
660 clean_history_cache();
661 if (priv->search)
662 g_object_unref(priv->search);
663 priv->search = NULL;
664 kz_search_exit();
665 }
666
667 void
668 kz_app_save_session (KzApp *app)
669 {
670 KzAppPrivate *priv;
671
672 g_return_if_fail(KZ_IS_APP(app));
673
674 priv = KZ_APP_GET_PRIVATE(app);
675 kz_bookmark_file_save(KZ_BOOKMARK_FILE(priv->bookmarks->current_session));
676 }
677
678 GtkWidget *
679 kz_app_restore_session (KzApp *app)
680 {
681 GList *list;
682 const GList *node, *window_node;
683 const gchar *location;
684 KzAppPrivate *priv;
685 KzBookmark *session;
686
687 g_return_val_if_fail(KZ_IS_APP(app), NULL);
688
689 priv = KZ_APP_GET_PRIVATE(app);
690
691 /* close all tabs before loading session file */
692 kz_app_freeze_session(app);
693 for (node = priv->window_list; node; node = g_list_next(node))
694 {
695 KzWindow *kz = KZ_WINDOW(node->data);
696 kz_bookmark_folder_remove(KZ_BOOKMARK_FOLDER(priv->bookmarks->current_session),
697 KZ_BOOKMARK(kz->tabs));
698 kz_window_close_all_tab(kz);
699 }
700
701 session = priv->bookmarks->current_session;
702 location = kz_bookmark_file_get_location(KZ_BOOKMARK_FILE(session));
703 if (g_file_test(location, G_FILE_TEST_EXISTS))
704 kz_bookmark_file_load(KZ_BOOKMARK_FILE(session));
705
706 list = kz_bookmark_folder_get_children(KZ_BOOKMARK_FOLDER(session));
707
708 window_node = priv->window_list;
709 /* windows */
710 for (node = list; node; node = g_list_next(node))
711 {
712 KzWindow *window;
713 KzBookmark *window_bookmark = KZ_BOOKMARK(node->data);
714
715 if (!window_node)
716 {
717 window = KZ_WINDOW(kz_app_create_new_window(app, NULL));
718 gtk_widget_show(GTK_WIDGET(window));
719 }
720 else
721 {
722 window = KZ_WINDOW(window_node->data);
723 window_node = g_list_next(window_node);
724 }
725
726 kz_window_restore_tabs(window, window_bookmark);
727 }
728 g_list_free(list);
729
730 /* close extra windows */
731 for (;window_node; window_node = g_list_next(window_node))
732 {
733 KzWindow *window = KZ_WINDOW(window_node->data);
734 gtk_widget_destroy(GTK_WIDGET(window));
735 }
736 kz_app_thaw_session(app);
737
738 /* if there is no window, create a window */
739 if (!priv->window_list)
740 kz_app_create_new_window(app, NULL);
741
742 return GTK_WIDGET(priv->window_list->data);
743 }
744
745 GtkWidget *
746 kz_app_create_new_window (KzApp *app, const gchar *uri)
747 {
748 GtkWidget *window;
749 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(app);
750
751 window = kz_window_new(uri);
752
753 if (!kz_session_is_frozen(KZ_SESSION(priv->bookmarks->current_session)))
754 {
755 kz_bookmark_folder_append(KZ_BOOKMARK_FOLDER(priv->bookmarks->current_session),
756 KZ_BOOKMARK(KZ_WINDOW(window)->tabs));
757 }
758
759 g_signal_connect(window, "destroy",
760 G_CALLBACK(cb_destroy_window), app);
761 priv->window_list = g_list_append(priv->window_list, window);
762
763 return window;
764 }
765
766 static KzUILevel
767 kz_ui_level_from_str (const gchar *level)
768 {
769 if (!level || !*level)
770 return KZ_UI_LEVEL_INVALID;
771
772 if (!strcmp(level, "custom"))
773 return KZ_UI_LEVEL_CUSTOM;
774 else if (!strcmp(level, "expert"))
775 return KZ_UI_LEVEL_EXPERT;
776 else if (!strcmp(level, "medium"))
777 return KZ_UI_LEVEL_MEDIUM;
778 else if (!strcmp(level, "beginner"))
779 return KZ_UI_LEVEL_BEGINNER;
780
781 return KZ_UI_LEVEL_INVALID;
782 }
783
784 #if 0
785 static const gchar *
786 kz_ui_level_to_str (KzUILevel level)
787 {
788 switch (level)
789 {
790 case KZ_UI_LEVEL_CUSTOM:
791 return "custom";
792 case KZ_UI_LEVEL_EXPERT:
793 return "expert";
794 case KZ_UI_LEVEL_MEDIUM:
795 return "medium";
796 case KZ_UI_LEVEL_BEGINNER:
797 return "beginner";
798 default:
799 break;
800 }
801
802 return NULL;
803 }
804 #endif
805
806 KzUILevel
807 kz_app_get_ui_level (KzApp *app)
808 {
809 KzUILevel val;
810 gchar level[16];
811 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(app);
812
813 g_return_val_if_fail(priv->profile, KZ_UI_LEVEL_BEGINNER);
814
815 level[0] = '\0';
816 kz_profile_get_value(priv->profile,
817 "Global", "ui_level",
818 level, sizeof(level),
819 KZ_PROFILE_VALUE_TYPE_STRING);
820
821 val = kz_ui_level_from_str(level);
822 if (!val)
823 return KZ_UI_LEVEL_BEGINNER;
824
825 return val;
826 }
827
828 KzFavicon *
829 kz_app_get_favicon (KzApp *app)
830 {
831 return KZ_APP_GET_PRIVATE(app)->favicon;
832 }
833
834 KzSearch *
835 kz_app_get_search (KzApp *app)
836 {
837 return KZ_APP_GET_PRIVATE(app)->search;
838 }
839
840 void
841 kz_app_set_search (KzApp *app, const gchar *engine_name)
842 {
843 KzAppPrivate *priv;
844
845 priv = KZ_APP_GET_PRIVATE(app);
846 if (priv->search)
847 g_object_unref(priv->search);
848
849 if (engine_name)
850 priv->search = kz_search_new(engine_name);
851 else
852 priv->search = NULL;
853
854 if (priv->search)
855 {
856 if (!kz_search_exist_index_dir(priv->search))
857 kz_search_make_index(priv->search);
858 }
859 }
860
861 KzRootBookmark *
862 kz_app_get_root_bookmark (KzApp *app)
863 {
864 return KZ_APP_GET_PRIVATE(app)->bookmarks;
865 }
866
867 KzProfile *
868 kz_app_get_profile (KzApp *app)
869 {
870 return KZ_APP_GET_PRIVATE(app)->profile;
871 }
872
873 KzProfile *
874 kz_app_get_proxy (KzApp *app)
875 {
876 return KZ_APP_GET_PRIVATE(app)->proxy;
877 }
878
879 const GList *
880 kz_app_get_window_list (KzApp *app)
881 {
882 return KZ_APP_GET_PRIVATE(app)->window_list;
883 }
884
885 GtkWidget *
886 kz_app_get_window_from_web (KzApp *app, KzWeb *web)
887 {
888 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(app);
889 GList *node;
890
891 for (node = (GList*)priv->window_list; node; node = g_list_next (node))
892 {
893 KzWindow *kz = node->data;
894 KzTabLabel *label;
895
896 if (!KZ_IS_WINDOW(kz)) continue;
897
898 label = kz_notebook_get_tab_label(KZ_NOTEBOOK(kz->notebook),
899 web);
900 if (label)
901 return GTK_WIDGET(kz);
902 }
903
904 return NULL;
905 }
906
907 void
908 kz_app_freeze_session (KzApp *app)
909 {
910 KzAppPrivate *priv;
911
912 g_return_if_fail (KZ_IS_APP(app));
913
914 priv = KZ_APP_GET_PRIVATE(app);
915 kz_session_freeze(KZ_SESSION(priv->bookmarks->current_session));
916 }
917
918 void
919 kz_app_thaw_session (KzApp *app)
920 {
921 KzAppPrivate *priv;
922
923 g_return_if_fail (KZ_IS_APP(app));
924
925 priv = KZ_APP_GET_PRIVATE(app);
926 kz_session_thaw(KZ_SESSION(priv->bookmarks->current_session));
927 }
928
929 static void
930 cb_destroy_window (GtkObject *object, gpointer data)
931 {
932 KzApp *app = KZ_APP(data);
933 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(app);
934 KzWindow *kz = KZ_WINDOW (object);
935
936 g_signal_handlers_disconnect_by_func(object,
937 G_CALLBACK(cb_destroy_window), data);
938 priv->window_list = g_list_remove(priv->window_list, object);
939
940 if (!priv->window_list)
941 {
942 static gboolean main_quited = FALSE;
943 if (!main_quited)
944 {
945 /* If the window is the last window, keep its tabs for saving the
946 * session. */
947 kz_app_freeze_session(app);
948 gtk_main_quit();
949 main_quited = TRUE;
950 }
951 }
952 else
953 {
954 if (kz->tabs)
955 kz_bookmark_folder_remove(KZ_BOOKMARK_FOLDER(priv->bookmarks->current_session),
956 KZ_BOOKMARK(kz->tabs));
957 }
958 }
959
960 #if USE_MIGEMO
961 KzMigemo *
962 kz_app_get_migemo (KzApp *app)
963 {
964 return KZ_APP_GET_PRIVATE(app)->migemo;
965 }
966 #endif
967
968 gboolean
969 kz_app_create_thumbnail (KzApp *app,
970 GdkPixbuf *pixbuf,
971 const gchar *uri,
972 time_t mtime,
973 EggPixbufThumbnailSize size)
974 {
975 GError *error = NULL;
976
977 if (!uri)
978 return FALSE;
979
980 if (uri[0] == '\0')
981 return FALSE;
982
983 egg_pixbuf_set_thumbnail_uri(pixbuf, uri);
984 egg_pixbuf_set_thumbnail_mtime(pixbuf, mtime);
985 egg_pixbuf_set_thumbnail_size(pixbuf, size);
986
987 if (!egg_pixbuf_save_thumbnail(pixbuf, &error, NULL))
988 {
989 g_warning("create_thumbnail: %s", error->message);
990 g_error_free(error);
991 return FALSE;
992 }
993
994 g_signal_emit(app, kz_app_signals[THUMBNAIL_CREATED_SIGNAL], 0,
995 uri, size);
996
997 return TRUE;
998 }
999
1000
1001 #ifdef HAVE_LIBSM
1002
1003 /* these codes are taken from libgnomeui.*/
1004
1005 static void ice_io_error_handler (IceConn connection);
1006
1007 static void new_ice_connection (IceConn connection, IcePointer client_data,
1008 Bool opening, IcePointer *watch_data);
1009
1010 /* This is called when data is available on an ICE connection. */
1011 static gboolean
1012 process_ice_messages (GIOChannel *source,
1013 GIOCondition condition,
1014 gpointer data)
1015 {
1016 IceConn connection = (IceConn) data;
1017 IceProcessMessagesStatus status;
1018
1019 status = IceProcessMessages (connection, NULL, NULL);
1020
1021 if (status == IceProcessMessagesIOError)
1022 {
1023 IcePointer context = IceGetConnectionContext (connection);
1024
1025 if (context && GTK_IS_OBJECT (context))
1026 {
1027 guint disconnect_id = g_signal_lookup ("disconnect", G_OBJECT_TYPE (context));
1028
1029 if (disconnect_id > 0)
1030 g_signal_emit (context, disconnect_id, 0);
1031 }
1032 else
1033 {
1034 IceSetShutdownNegotiation (connection, False);
1035 IceCloseConnection (connection);
1036 }
1037 }
1038
1039 return TRUE;
1040 }
1041
1042 /* This is called when a new ICE connection is made. It arranges for
1043 the ICE connection to be handled via the event loop. */
1044 static void
1045 new_ice_connection (IceConn connection, IcePointer client_data, Bool opening,
1046 IcePointer *watch_data)
1047 {
1048 guint input_id;
1049
1050 if (opening)
1051 {
1052 GIOChannel *channel;
1053 /* Make sure we don't pass on these file descriptors to any
1054 exec'ed children */
1055 fcntl(IceConnectionNumber(connection),F_SETFD,
1056 fcntl(IceConnectionNumber(connection),F_GETFD,0) | FD_CLOEXEC);
1057
1058 channel = g_io_channel_unix_new (IceConnectionNumber (connection));
1059 input_id = g_io_add_watch (channel,
1060 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI,
1061 process_ice_messages,
1062 connection);
1063 g_io_channel_unref (channel);
1064
1065 *watch_data = (IcePointer) GUINT_TO_POINTER (input_id);
1066 }
1067 else
1068 {
1069 input_id = GPOINTER_TO_UINT ((gpointer) *watch_data);
1070
1071 g_source_remove (input_id);
1072 }
1073 }
1074
1075 static IceIOErrorHandler ice_installed_handler;
1076
1077 /* We call any handler installed before (or after) gnome_ice_init but
1078 avoid calling the default libICE handler which does an exit() */
1079 static void
1080 ice_io_error_handler (IceConn connection)
1081 {
1082 if (ice_installed_handler)
1083 (*ice_installed_handler) (connection);
1084 }
1085
1086 static void
1087 ice_init (void)
1088 {
1089 static gboolean ice_init = FALSE;
1090
1091 if (! ice_init)
1092 {
1093 IceIOErrorHandler default_handler;
1094
1095 ice_installed_handler = IceSetIOErrorHandler (NULL);
1096 default_handler = IceSetIOErrorHandler (ice_io_error_handler);
1097
1098 if (ice_installed_handler == default_handler)
1099 ice_installed_handler = NULL;
1100
1101 IceAddConnectionWatch (new_ice_connection, NULL);
1102
1103 ice_init = TRUE;
1104 }
1105 }
1106
1107 static void
1108 save_yourself_callback (SmcConn smc_conn,
1109 SmPointer client_data,
1110 int save_style,
1111 gboolean shutdown,
1112 int interact_style,
1113 gboolean fast)
1114 {
1115 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(client_data);
1116
1117 SmcSaveYourselfDone((SmcConn) priv->smc_conn, TRUE);
1118 }
1119
1120 static void
1121 die_callback (SmcConn smc_conn, SmPointer client_data)
1122 {
1123 gtk_main_quit();
1124 }
1125
1126 static void
1127 save_complete_callback (SmcConn smc_conn, SmPointer client_data)
1128 {
1129 }
1130
1131 static void
1132 shutdown_cancelled_callback (SmcConn smc_conn, SmPointer client_data)
1133 {
1134 }
1135
1136 static void
1137 session_set_value (SmcConn smc_conn,
1138 gchar *name,
1139 char *type,
1140 int num_vals,
1141 SmPropValue *vals)
1142 {
1143 SmProp *proplist[1];
1144 SmProp prop;
1145
1146 prop.name = name;
1147 prop.type = type;
1148 prop.num_vals = num_vals;
1149 prop.vals = vals;
1150
1151 proplist[0]= &prop;
1152 SmcSetProperties ((SmcConn) smc_conn, 1, proplist);
1153 }
1154
1155 static void
1156 session_set_string (SmcConn smc_conn, gchar *name, gchar *value)
1157 {
1158 SmPropValue val;
1159
1160 g_return_if_fail (name);
1161
1162 val.length = strlen (value)+1;
1163 val.value = value;
1164
1165 session_set_value (smc_conn, name, SmARRAY8, 1, &val);
1166 }
1167
1168 static void
1169 session_set_gchar (SmcConn smc_conn, gchar *name, gchar value)
1170 {
1171 SmPropValue val;
1172
1173 g_return_if_fail (name);
1174
1175 val.length = 1;
1176 val.value = &value;
1177
1178 session_set_value (smc_conn, name, SmCARD8, 1, &val);
1179 }
1180
1181 static void
1182 session_set_clone_command (KzApp *app)
1183 {
1184 SmPropValue *vals;
1185 gint i;
1186 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(app);
1187
1188 vals = g_new(SmPropValue, priv->argc);
1189
1190 for (i = 0; i < priv->argc; i++)
1191 {
1192 vals[i].length = strlen(priv->argv[i]);
1193 vals[i].value = priv->argv[i];
1194 }
1195 session_set_value(priv->smc_conn, SmCloneCommand, SmLISTofARRAY8, i, vals);
1196 session_set_value(priv->smc_conn, SmRestartCommand, SmLISTofARRAY8, i, vals);
1197
1198 g_free(vals);
1199 }
1200
1201 static void
1202 connect_sm (KzApp *app)
1203 {
1204 SmcCallbacks callbacks;
1205 gchar *session_id;
1206 gchar error_string[256] = "";
1207 KzAppPrivate *priv = KZ_APP_GET_PRIVATE(app);
1208
1209 g_return_if_fail(app);
1210
1211 if (!g_getenv("SESSION_MANAGER"))
1212 return;
1213
1214 ice_init();
1215
1216 callbacks.save_yourself.callback = save_yourself_callback;
1217 callbacks.die.callback = die_callback;
1218 callbacks.save_complete.callback = save_complete_callback;
1219 callbacks.shutdown_cancelled.callback = shutdown_cancelled_callback;
1220
1221 callbacks.save_yourself.client_data =
1222 callbacks.die.client_data =
1223 callbacks.save_complete.client_data =
1224 callbacks.shutdown_cancelled.client_data = (SmPointer) app;
1225
1226 priv->session_id = NULL;
1227 priv->smc_conn= (gpointer)
1228 SmcOpenConnection(NULL, app,
1229 SmProtoMajor, SmProtoMinor,
1230 SmcSaveYourselfProcMask | SmcDieProcMask |
1231 SmcSaveCompleteProcMask |
1232 SmcShutdownCancelledProcMask,
1233 &callbacks,
1234 priv->session_id, &session_id,
1235 sizeof(error_string), error_string);
1236
1237 if (error_string[0])
1238 {
1239 g_warning("While connecting to session manager:\n%s.",
1240 error_string);
1241 }
1242 if (priv->smc_conn)
1243 {
1244 gchar *tmp;
1245
1246 gdk_set_sm_client_id(session_id);
1247
1248 tmp = g_get_current_dir();
1249 session_set_string(priv->smc_conn, SmCurrentDirectory, tmp);
1250 g_free(tmp);
1251
1252 tmp = g_strdup_printf("%d", (int) getpid());
1253 session_set_string(priv->smc_conn, SmProcessID, tmp);
1254 g_free(tmp);
1255
1256 session_set_string(priv->smc_conn, SmUserID, (gchar *)g_get_user_name());
1257
1258 session_set_gchar(priv->smc_conn, SmRestartStyleHint, (gchar) SmRestartIfRunning);
1259 session_set_string(priv->smc_conn, SmProgram, g_get_prgname());
1260
1261 session_set_clone_command(app);
1262 g_free(session_id);
1263 }
1264 }
1265 #endif /* HAVE_LIBSM */

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

SourceForge.JP is a Japanese version of SourceForge.net. For developments that are not related to Japan, we recommend you to use SourceForge.net.