Rename the hash table to thumbs_hash_table.
[gliv.git] / src / main.c
blob17121ff854a546e3fa3ca1d0f4351dd3de77fc8b
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * See the COPYING file for license information.
18 * Guillaume Chazarain <guichaz@yahoo.fr>
21 /********************
22 * Main source file *
23 ********************/
25 #include <unistd.h> /* close(), dup(), dup2(), STDERR_FILENO */
26 #include <stdlib.h> /* exit() */
27 #include <gtk/gtkgl.h>
29 #include "gliv.h"
30 #include "main.h"
31 #include "cmdline.h"
32 #include "options.h"
33 #include "gliv_image.h"
34 #include "rcfile.h"
35 #include "files_list.h"
36 #include "messages.h"
37 #include "windows.h"
39 rt_struct *rt;
40 options_struct *options;
41 gliv_image *current_image = NULL;
42 GtkWidget *gl_widget;
43 GtkMenuBar *menu_bar;
46 * This is borrowed from gtk+-2, without the gtk_grab_notify() calls.
47 * They slow down things a lot when the images menus are built with many files.
49 GtkWindowGroup *_gtk_window_get_group(GtkWindow * window)
51 if (window && window->group)
52 return window->group;
53 else {
54 static GtkWindowGroup *default_group = NULL;
56 if (!default_group)
57 default_group = gtk_window_group_new();
59 return default_group;
63 static GtkWindowGroup *gtk_main_get_window_group(GtkWidget * widget)
65 GtkWidget *toplevel = NULL;
67 if (widget)
68 toplevel = gtk_widget_get_toplevel(widget);
70 if (toplevel && GTK_IS_WINDOW(toplevel))
71 return _gtk_window_get_group(GTK_WINDOW(toplevel));
72 else
73 return _gtk_window_get_group(NULL);
76 void gtk_grab_add(GtkWidget * widget)
78 GtkWindowGroup *group;
80 g_return_if_fail(widget != NULL);
82 if (!GTK_WIDGET_HAS_GRAB(widget) && GTK_WIDGET_IS_SENSITIVE(widget)) {
83 GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_GRAB);
85 group = gtk_main_get_window_group(widget);
87 g_object_ref(widget);
88 group->grabs = g_slist_prepend(group->grabs, widget);
90 /* gtk_grab_notify (group, widget, FALSE); */
94 void gtk_grab_remove(GtkWidget * widget)
96 GtkWindowGroup *group;
98 g_return_if_fail(widget != NULL);
100 if (GTK_WIDGET_HAS_GRAB(widget)) {
101 GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_GRAB);
103 group = gtk_main_get_window_group(widget);
104 group->grabs = g_slist_remove(group->grabs, widget);
106 g_object_unref(widget);
108 /* gtk_grab_notify (group, widget, TRUE); */
112 typedef struct {
113 gboolean given;
114 gint *flag;
115 gint value;
116 gint minimum;
117 } ggo_arg;
119 static void fill_options(struct gengetopt_args_info *ggo)
121 ggo_arg args[] = {
122 /* *INDENT-OFF* */
123 { ggo->full_screen_given, &options->fullscreen, ggo->full_screen_flag, 0 },
124 { ggo->scale_down_given, &options->scaledown, ggo->scale_down_flag, 0 },
125 { ggo->maximize_given, &options->maximize, ggo->maximize_flag, 0 },
126 { ggo->zoom_pointer_given, &options->zoom_pointer, ggo->zoom_pointer_flag, 0 },
127 { ggo->dither_given, &options->dither, ggo->dither_flag, 0 },
128 { ggo->force_load_given, &options->force, ggo->force_load_flag, 0 },
129 { ggo->mipmap_given, &options->mipmap, ggo->mipmap_flag, 0 },
130 { ggo->build_menus_given, &options->build_menus, ggo->build_menus_flag, 0 },
131 { ggo->mnemonics_given, &options->mnemonics, ggo->mnemonics_flag, 0 },
132 { ggo->menu_given, &options->menu_bar, ggo->menu_flag, 0 },
133 { ggo->info_given, &options->status_bar, ggo->info_flag, 0 },
134 { ggo->scrollbars_given, &options->scrollbars, ggo->scrollbars_flag, 0 },
135 { ggo->alpha_checks_given, &options->alpha_checks, ggo->alpha_checks_flag, 0 },
136 { ggo->loop_given, &options->loop, ggo->loop_flag , 0 },
137 { ggo->one_image_given, &options->one_image, ggo->one_image_flag, 0 },
138 { ggo->thumbnails_given, &options->thumbnails, ggo->thumbnails_flag, 0 },
139 { ggo->slide_show_given, &options->start_show, ggo->slide_show_flag, 0 },
140 { ggo->resize_win_given, &options->resize_win, ggo->resize_win_flag, 0 },
141 { ggo->make_fit_given, &options->maximize, ggo->make_fit_flag, 0 },
142 { ggo->make_fit_given, &options->scaledown, ggo->make_fit_flag, 0 },
143 { ggo->delay_given, &options->delay, ggo->delay_arg, 0 },
144 { ggo->history_given, &options->history_size, ggo->history_arg, -1 },
145 { ggo->duration_given, &options->duration, ggo->duration_arg, 0 },
146 { ggo->fps_given, &options->fps, ggo->fps_arg, -1 },
147 { FALSE, NULL, FALSE, 0 }
148 /* *INDENT-ON* */
151 ggo_arg *arg;
153 for (arg = args; arg->flag != NULL; arg++)
154 if (arg->given && arg->value >= arg->minimum)
155 *arg->flag = arg->value;
158 static void init_args(gint argc, gchar ** argv)
160 struct gengetopt_args_info ggo;
161 options_struct *rc_file;
163 /* Command line (only the glivrc flag). */
164 if (cmdline_parser(argc, argv, &ggo) != 0)
165 quit(1);
167 /* Configuration file. */
168 rc_file = load_rc(ggo.glivrc_flag);
169 options = g_memdup(rc_file, sizeof(options_struct));
171 /* Command line (remaining options). */
172 fill_options(&ggo);
174 rt = g_new(rt_struct, 1);
176 rt->cursor_hidden = FALSE;
177 rt->help = FALSE;
178 rt->alpha_checks_changed = TRUE;
179 rt->scr_width = gdk_screen_width();
180 rt->scr_height = gdk_screen_height();
182 if (ggo.inputs_num > 0)
183 /* There are filenames on the command line. */
184 init_list(ggo.inputs, ggo.inputs_num,
185 ggo.recursive_flag, ggo.shuffle_given, ggo.sort_given);
187 g_free(ggo.inputs);
191 * We call cmdline_parser() a first time to quickly exit if --help or --version
192 * was given. We do the real work after the next call in init_args(), after
193 * gtk_init() removed the gtk arguments.
195 * We temporarily close stderr because unknown and gtk arguments are handled
196 * afterwards.
198 static void check_quick_exit(gint argc, gchar ** argv)
200 struct gengetopt_args_info ggo;
201 gint fd;
203 /* Silence stderr. */
204 fd = dup(STDERR_FILENO);
205 close(STDERR_FILENO);
207 cmdline_parser(argc, argv, &ggo);
209 /* Restore stderr. */
210 dup2(fd, STDERR_FILENO);
211 close(fd);
214 G_GNUC_NORETURN void quit(gint code)
216 exit(code);
219 void gui_quit(void)
221 GtkMessageDialog *dialog;
222 gchar *msg;
224 msg = _("Do you really want to quit GLiv?");
226 dialog = GTK_MESSAGE_DIALOG(gtk_message_dialog_new(get_current_window(),
227 GTK_DIALOG_MODAL,
228 GTK_MESSAGE_QUESTION,
229 GTK_BUTTONS_YES_NO,
230 "%s", msg));
232 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_YES);
234 set_hide_cursor_enabled(FALSE);
235 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES)
236 quit(0);
238 gtk_widget_destroy(GTK_WIDGET(dialog));
239 set_hide_cursor_enabled(TRUE);
242 gint main(gint argc, gchar ** argv)
244 check_quick_exit(argc, argv);
246 /* i18n */
247 #ifdef ENABLE_NLS
248 gtk_set_locale();
249 #ifdef LOCALEDIR
250 bindtextdomain(PACKAGE, LOCALEDIR);
251 #endif
252 textdomain(PACKAGE);
253 bind_textdomain_codeset(PACKAGE, "UTF-8");
254 #endif
256 g_thread_init(NULL);
257 gtk_init(&argc, &argv);
258 gtk_gl_init(&argc, &argv);
260 init_args(argc, argv);
262 create_windows();
264 gtk_main();
266 return 0;