1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2 
3 /*
4  * GImageView
5  * Copyright (C) 2001 Takuro Ashie
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  *
21  * $Id: gimv_image_win.c,v 1.19 2004/12/20 15:57:07 makeinu Exp $
22  */
23 
24 #include <stdlib.h>
25 #include <gdk/gdkkeysyms.h>
26 
27 #include "gimageview.h"
28 
29 #include "charset.h"
30 #include "cursors.h"
31 #include "gtk2-compat.h"
32 #include "gtkutils.h"
33 #include "gimv_comment_view.h"
34 #include "gimv_icon_stock.h"
35 #include "gimv_image_view.h"
36 #include "gimv_image_win.h"
37 #include "gimv_prefs_win.h"
38 #include "gimv_thumb_win.h"
39 #include "help.h"
40 #include "menu.h"
41 #include "prefs.h"
42 
43 #ifdef ENABLE_EXIF
44 #   include "exif_view.h"
45 #endif /* ENABLE_EXIF */
46 
47 
48 #define IMGWIN_FULLSCREEN_HIDE_CURSOR_DELAY 1000
49 
50 enum {
51    SHOW_FULLSCREEN_SIGNAL,
52    HIDE_FULLSCREEN_SIGNAL,
53    LAST_SIGNAL
54 };
55 
56 enum {
57    IMG_FIRST,
58    IMG_PREV,
59    IMG_NEXT,
60    IMG_LAST
61 };
62 
63 typedef enum {
64    MOUSE_PRESS_NONE,
65    MOUSE_PRESS_NEXT,
66    MOUSE_PRESS_PREV,
67    MOUSE_PRESS_POPUP,
68    MOUSE_PRESS_ZOOM_IN,
69    MOUSE_PRESS_ZOOM_OUT,
70    MOUSE_PRESS_FIT,
71    MOUSE_PRESS_ROTATE_CCW,
72    MOUSE_PRESS_ROTATE_CW,
73    MOUSE_PRESS_NAVWIN,
74    MOUSE_PRESS_UP,
75    MOUSE_PRESS_DOWN,
76    MOUSE_PRESS_LEFT,
77    MOUSE_PRESS_RIGHT
78 } ImageViewPressType;
79 
80 
81 struct GimvImageWinPriv_Tag
82 {
83    /* flags */
84    GimvImageWinFlags flags;
85    GimvImageViewPlayerVisibleType player_visible;
86 
87    /* window geometory */
88    gint             win_x;
89    gint             win_y;
90    gint             win_width;
91    gint             win_height;
92 
93    GdkColor        *fs_bg_color;
94 
95    guint            hide_cursor_timer_id;
96 
97    guint            slideshow_interval;  /* [msec] */
98    gint             slideshow_timer_id;
99 };
100 
101 
102 static void     gimv_image_win_class_init           (GimvImageWinClass *klass);
103 static void     gimv_image_win_init                 (GimvImageWin *iw);
104 static void     gimv_image_win_destroy              (GtkObject *object);
105 static void     gimv_image_win_realize              (GtkWidget *widget);
106 static void     gimv_image_win_real_show_fullscreen (GimvImageWin *iw);
107 static void     gimv_image_win_real_hide_fullscreen (GimvImageWin *iw);
108 
109 static void       create_imageview_menus            (GimvImageWin  *iw);
110 static GtkWidget *create_toolbar                    (GimvImageWin  *iw,
111                                                      GtkWidget     *container);
112 static GtkWidget *create_player_toolbar             (GimvImageWin  *iw,
113                                                      GtkWidget     *container);
114 
115 static void     gimv_image_win_set_win_size         (GimvImageWin  *iw);
116 static void     gimv_image_win_set_window_title     (GimvImageWin  *iw);
117 static void     gimv_image_win_set_statusbar_info   (GimvImageWin  *iw);
118 
119 static void     gimv_image_win_fullscreen_show      (GimvImageWin *iw);
120 static void     gimv_image_win_fullscreen_hide      (GimvImageWin *iw);
121 
122 /* callback functions for menubar */
123 static void     cb_file_select          (gpointer      data,
124                                          guint         action,
125                                          GtkWidget    *widget);
126 static void     cb_open_imagewin        (gpointer      data,
127                                          guint         action,
128                                          GtkWidget    *widget);
129 static void     cb_open_thumbwin        (gpointer      data,
130                                          guint         action,
131                                          GtkWidget    *widget);
132 static void     cb_toggle_buffer        (GimvImageWin *iw,
133                                          guint         action,
134                                          GtkWidget    *widget);
135 static void     cb_window_close         (GimvImageWin *iw,
136                                          guint         action,
137                                          GtkWidget    *widget);
138 static void     cb_ignore_alpha         (GimvImageWin *iv,
139                                          guint         action,
140                                          GtkWidget    *widget);
141 static void     cb_toggle_menubar       (GimvImageWin *iw,
142                                          guint         action,
143                                          GtkWidget    *widget);
144 static void     cb_toggle_player        (GimvImageWin *iw,
145                                          guint         action,
146                                          GtkWidget    *widget);
147 static void     cb_toggle_toolbar       (GimvImageWin *iw,
148                                          guint         action,
149                                          GtkWidget    *widget);
150 static void     cb_toggle_statusbar     (GimvImageWin *iw,
151                                          guint         action,
152                                          GtkWidget    *widget);
153 static void     cb_toggle_scrollbar     (GimvImageWin *iw,
154                                          guint         action,
155                                          GtkWidget    *widget);
156 static void     cb_switch_player        (GimvImageWin *iw,
157                                          GimvImageViewPlayerVisibleType visible,
158                                          GtkWidget    *widget);
159 static void     cb_toggle_maximize      (GimvImageWin *iw,
160                                          guint         action,
161                                          GtkWidget    *widget);
162 static void     cb_toggle_fullscreen    (GimvImageWin *iw,
163                                          guint         action,
164                                          GtkWidget    *widget);
165 static void     cb_fit_to_image         (GimvImageWin *iw,
166                                          guint         action,
167                                          GtkWidget    *widget);
168 static void     cb_edit_comment         (GimvImageWin *iw,
169                                          guint         action,
170                                          GtkWidget    *widget);
171 #ifdef ENABLE_EXIF
172 static void     cb_exif                 (GimvImageWin *iw,
173                                          guint         action,
174                                          GtkWidget    *menuitem);
175 #endif /* ENABLE_EXIF */
176 static void     cb_create_thumb         (GimvImageWin *iw,
177                                          guint         action,
178                                          GtkWidget    *widget);
179 static void     cb_options              (GimvImageWin *iw);
180 static void     cb_move_menu            (GimvImageWin *iw,
181                                          guint         action,
182                                          GtkWidget    *widget);
183 
184 /* callback functions for toolbar */
185 static void     cb_toolbar_open_button      (GtkWidget    *widget);
186 static void     cb_toolbar_prefs_button     (GtkWidget    *widget,
187                                              GimvImageWin *iw);
188 static void     cb_toolbar_prev_button      (GtkWidget    *widget,
189                                              GimvImageWin *iw);
190 static void     cb_toolbar_next_button      (GtkWidget    *widget,
191                                              GimvImageWin *iw);
192 static void     cb_toolbar_no_zoom          (GtkWidget    *widget,
193                                              GimvImageWin *iw);
194 static void     cb_toolbar_zoom_in          (GtkWidget    *widget,
195                                              GimvImageWin *iw);
196 static void     cb_toolbar_zoom_out         (GtkWidget    *widget,
197                                              GimvImageWin *iw);
198 static void     cb_toolbar_zoom_fit         (GtkWidget    *widget,
199                                              GimvImageWin *iw);
200 static void     cb_toolbar_zoom             (GtkWidget    *widget,
201                                              GimvImageWin *iw);
202 static void     cb_toolbar_keep_aspect      (GtkWidget    *widget,
203                                              GimvImageWin *iw);
204 static void     cb_toolbar_fit_window       (GtkWidget    *widget,
205                                              GimvImageWin *iw);
206 static void     cb_toolbar_fullscreen       (GtkWidget    *widget,
207                                              GimvImageWin *iw);
208 static gboolean cb_scale_spinner_key_press  (GtkWidget      *widget,
209                                              GdkEventKey    *event,
210                                              GimvImageWin   *iw);
211 static void     cb_rotate_menu              (GtkWidget      *widget,
212                                              GimvImageWin   *iw);
213 static gboolean cb_rotate_menu_button_press (GtkWidget      *widget,
214                                              GdkEventButton *event,
215                                              GimvImageWin   *iw);
216 
217 /* callback functions for slideshow toolbar */
218 static void     cb_play_clicked     (GtkWidget      *button,
219                                      GimvImageWin   *iw);
220 static void     cb_stop_clicked     (GtkWidget      *button,
221                                      GimvImageWin   *iw);
222 static void     cb_prev_clicked     (GtkWidget      *button,
223                                      GimvImageWin   *iw);
224 static void     cb_next_clicked     (GtkWidget      *button,
225                                      GimvImageWin   *iw);
226 static void     cb_first_clicked    (GtkWidget      *button,
227                                      GimvImageWin   *iw);
228 static void     cb_last_clicked     (GtkWidget      *button,
229                                      GimvImageWin   *iw);
230 static gboolean cb_seekbar_pressed  (GtkWidget      *widget,
231                                      GdkEventButton *event,
232                                      GimvImageWin   *iw);
233 static gboolean cb_seekbar_released (GtkWidget      *widget,
234                                      GdkEventButton *event,
235                                      GimvImageWin   *iw);
236 
237 /* other callback functions */
238 static void     cb_image_changed       (GimvImageView *iv,
239                                         GimvImageWin *iw);
240 static void     cb_load_start          (GimvImageView *iv,
241                                         GimvImageInfo *info,
242                                         GimvImageWin *iw);
243 static void     cb_load_end            (GimvImageView *iv,
244                                         GimvImageInfo *info,
245                                         gboolean cancel,
246                                         GimvImageWin *iw);
247 static void     cb_set_list            (GimvImageView  *iv,
248                                         GimvImageWin   *iw);
249 static void     cb_unset_list          (GimvImageView  *iv,
250                                         GimvImageWin   *iw);
251 static void     cb_rendered            (GimvImageView  *iv,
252                                         GimvImageWin   *iw);
253 static void     cb_toggle_aspect       (GimvImageView  *iv,
254                                         gboolean        keep_aspect,
255                                         GimvImageWin   *iw);
256 static gboolean cb_draw_area_key_press (GtkWidget      *widget,
257                                         GdkEventKey    *event,
258                                         GimvImageWin   *iw);
259 static gint     cb_imageview_pressed   (GimvImageView  *iv,
260                                         GdkEventButton *event,
261                                         GimvImageWin   *iw);
262 static gint     cb_imageview_clicked   (GimvImageView  *iv,
263                                         GdkEventButton *event,
264                                         GimvImageWin   *iw);
265 
266 static gint     gimv_image_view_button_action (GimvImageView  *iv,
267                                                GdkEventButton *event,
268                                                gint            num);
269 
270 /* for main menu */
271 GtkItemFactoryEntry gimv_image_win_menu_items[] =
272 {
273    {N_("/_File"),                        NULL,         NULL,              0,  "<Branch>"},
274    {N_("/_File/_Open..."),               "<control>F", cb_file_select,    0,  NULL},
275    {N_("/_File/Open _Image Window"),     "<control>I", cb_open_imagewin,  0,  NULL},
276    {N_("/_File/Open _Thumbnail Window"), "<control>W", cb_open_thumbwin,  0,  NULL},
277    {N_("/_File/---"),                    NULL,         NULL,              0,  "<Separator>"},
278    {N_("/_File/Memory _Buffer"),         "<control>B", cb_toggle_buffer,  0,  "<ToggleItem>"},
279    {N_("/_File/---"),                    NULL,         NULL,              0,  "<Separator>"},
280    {N_("/_File/_Close"),                 "Q",          cb_window_close,   0,  NULL},
281    {N_("/_File/_Quit"),                  "<control>C", gimv_quit,         0,  NULL},
282 
283    {N_("/_Edit"),                        NULL,         NULL,              0,  "<Branch>"},
284    {N_("/_Edit/Edit _Comment..."),       NULL,         cb_edit_comment,   0,  NULL},
285    {N_("/_Edit/Scan E_XIF Data..."),       NULL,       cb_exif,           0,  NULL},
286    {N_("/_Edit/Create _Thumbnail"),      "<shift>T",   cb_create_thumb,   0,  NULL},
287    {N_("/_Edit/---"),                    NULL,         NULL,              0,  "<Separator>"},
288    {N_("/_Edit/_Options..."),            "<control>O", cb_options,        0,  NULL},
289 
290    {N_("/_View"),                        NULL,         NULL,              0,  "<Branch>"},
291 
292    {N_("/_Move"),                        NULL,         NULL,              0,  "<Branch>"},
293 
294    {N_("/M_ovie"),                       NULL,         NULL,              0,  "<Branch>"},
295 
296    {N_("/_Help"),                        NULL,         NULL,              0,  "<LastBranch>"},
297    {NULL, NULL, NULL, 0, NULL},
298 };
299 
300 
301 /* for "View" sub menu */
302 GtkItemFactoryEntry gimv_image_win_view_items [] =
303 {
304    {N_("/tear"),          NULL,        NULL,                 0,  "<Tearoff>"},
305    {N_("/_Zoom"),         NULL,        NULL,                 0,  "<Branch>"},
306    {N_("/_Rotate"),       NULL,        NULL,                 0,  "<Branch>"},
307    {N_("/Ignore _Alpha Channel"), NULL,cb_ignore_alpha,      0,  "<ToggleItem>"},
308    {N_("/---"),           NULL,        NULL,                 0,  "<Separator>"},
309    {N_("/_Menu Bar"),     "M",         cb_toggle_menubar,    0,  "<ToggleItem>"},
310    {N_("/_Tool Bar"),     "N",         cb_toggle_toolbar,    0,  "<ToggleItem>"},
311    {N_("/Slide Show _Player"), "<shift>N", cb_toggle_player,     0,  "<ToggleItem>"},
312    {N_("/St_atus Bar"),   "V",         cb_toggle_statusbar,  0,  "<ToggleItem>"},
313    {N_("/_Scroll Bar"),   "<shift>S",  cb_toggle_scrollbar,  0,  "<ToggleItem>"},
314    {N_("/_Player"),       NULL,        NULL,                 0,              "<Branch>"},
315    {N_("/_Player/_Show"), NULL,        cb_switch_player,     GimvImageViewPlayerVisibleShow, "<RadioItem>"},
316    {N_("/_Player/_Hide"), NULL,        cb_switch_player,     GimvImageViewPlayerVisibleHide, "/Player/Show"},
317    {N_("/_Player/_Auto"), NULL,        cb_switch_player,     GimvImageViewPlayerVisibleAuto, "/Player/Hide"},
318    {N_("/---"),           NULL,        NULL,                 0,  "<Separator>"},
319    {N_("/_View modes"),   NULL,        NULL,                 0, "<Branch>"},
320    {N_("/---"),           NULL,        NULL,                 0,  "<Separator>"},
321    {N_("/_Fit to Image"), "I",         cb_fit_to_image,      0,  NULL},
322    {N_("/Ma_ximize"),     "F",         cb_toggle_maximize,   0,  "<ToggleItem>"},
323    {N_("/F_ull Screen"),  "<shift>F",  cb_toggle_fullscreen, 0,  "<ToggleItem>"},
324    {NULL, NULL, NULL, 0, NULL},
325 };
326 
327 
328 GtkItemFactoryEntry gimv_image_win_move_items [] =
329 {
330    {N_("/_Next"),        "L",  cb_move_menu,  IMG_NEXT,  NULL},
331    {N_("/_Previous"),    "H",  cb_move_menu,  IMG_PREV,  NULL},
332    {N_("/_First"),       "K",  cb_move_menu,  IMG_FIRST, NULL},
333    {N_("/_Last"),        "J",  cb_move_menu,  IMG_LAST,  NULL},
334    {NULL, NULL, NULL, 0, NULL},
335 };
336 
337 
338 static GtkWindowClass *parent_class = NULL;
339 static gint            gimv_image_win_signals[LAST_SIGNAL] = {0};
340 
341 
342 static GList         *ImageWinList   = NULL;
343 static GimvImageWin  *shared_img_win = NULL;
344 
345 
346 GtkType
gimv_image_win_get_type(void)347 gimv_image_win_get_type (void)
348 {
349    static GtkType gimv_image_win_type = 0;
350 
351    if (!gimv_image_win_type) {
352       static const GtkTypeInfo gimv_image_win_info = {
353          "GimvImageWin",
354          sizeof (GimvImageWin),
355          sizeof (GimvImageWinClass),
356          (GtkClassInitFunc) gimv_image_win_class_init,
357          (GtkObjectInitFunc) gimv_image_win_init,
358          NULL,
359          NULL,
360          (GtkClassInitFunc) NULL,
361       };
362 
363       gimv_image_win_type = gtk_type_unique (GTK_TYPE_WINDOW,
364                                              &gimv_image_win_info);
365    }
366 
367    return gimv_image_win_type;
368 }
369 
370 
371 static void
gimv_image_win_class_init(GimvImageWinClass * klass)372 gimv_image_win_class_init (GimvImageWinClass *klass)
373 {
374    GtkObjectClass *object_class;
375    GtkWidgetClass *widget_class;
376 
377    object_class = (GtkObjectClass *) klass;
378    widget_class = (GtkWidgetClass *) klass;
379    parent_class = gtk_type_class (GTK_TYPE_WINDOW);
380 
381    gimv_image_win_signals[SHOW_FULLSCREEN_SIGNAL]
382       = gtk_signal_new ("show_fullscreen",
383                         GTK_RUN_FIRST,
384                         GTK_CLASS_TYPE(object_class),
385                         GTK_SIGNAL_OFFSET (GimvImageWinClass, show_fullscreen),
386                         gtk_signal_default_marshaller,
387                         GTK_TYPE_NONE, 0);
388    gimv_image_win_signals[HIDE_FULLSCREEN_SIGNAL]
389       = gtk_signal_new ("hide_fullscreen",
390                         GTK_RUN_FIRST,
391                         GTK_CLASS_TYPE(object_class),
392                         GTK_SIGNAL_OFFSET (GimvImageWinClass, hide_fullscreen),
393                         gtk_signal_default_marshaller,
394                         GTK_TYPE_NONE, 0);
395 
396    gtk_object_class_add_signals (object_class, gimv_image_win_signals, LAST_SIGNAL);
397 
398    object_class->destroy  = gimv_image_win_destroy;
399 
400    widget_class->realize  = gimv_image_win_realize;
401 
402    klass->show_fullscreen = gimv_image_win_real_show_fullscreen;
403    klass->hide_fullscreen = gimv_image_win_real_hide_fullscreen;;
404 }
405 
406 
407 static void
gimv_image_win_init(GimvImageWin * iw)408 gimv_image_win_init (GimvImageWin *iw)
409 {
410    GtkWidget *vbox, *hbox;
411    GtkObject *adj;
412 
413    iw->priv = g_new0 (GimvImageWinPriv, 1);
414 
415    iw->iv = GIMV_IMAGE_VIEW (gimv_image_view_new (NULL));
416 
417    iw->priv->flags = 0;
418    iw->priv->flags |= GimvImageWinCreatingFlag;
419    if (conf.imgwin_show_menubar)
420       iw->priv->flags |= GimvImageWinShowMenuBarFlag;
421    if (conf.imgwin_show_toolbar)
422       iw->priv->flags |= GimvImageWinShowToolBarFlag;
423    if (conf.imgwin_show_player)
424       iw->priv->flags |= GimvImageWinShowPlayerFlag;
425    if (conf.imgwin_show_statusbar)
426       iw->priv->flags |= GimvImageWinShowStatusBarFlag;
427    /*
428    iw->flags              &= ~GimvImageWinMaximizeFlag;
429    iw->hide_frame         &= ~GimvImageWinHideFrameFlag;
430    iw->seekbar_dragging   &= ~GimvImageWinSeekBarDraggingFlag;
431    iw->is_movie           &= ~GimvImageWinMovieFlag;
432    */
433    iw->priv->player_visible = conf.imgview_player_visible;
434    gimv_image_view_set_player_visible (iw->iv, iw->priv->player_visible);
435 
436    iw->fullscreen                 = NULL;
437    iw->priv->hide_cursor_timer_id = 0;
438    iw->priv->slideshow_interval   = conf.slideshow_interval * 1000;
439    iw->priv->slideshow_timer_id   = 0;
440    if (conf.slideshow_repeat)
441       iw->priv->flags |= GimvImageWinSlideShowRepeatFlag;
442 
443    /* set bg color */
444    if (conf.imgwin_set_bg) {
445       gimv_image_view_set_bg_color (iw->iv,
446                                     conf.imgwin_bg_color[0],
447                                     conf.imgwin_bg_color[1],
448                                     conf.imgwin_bg_color[2]);
449    }
450 
451    if (conf.imgwin_fullscreen_set_bg) {
452       iw->priv->fs_bg_color = g_new0 (GdkColor, 1);
453       iw->priv->fs_bg_color->red   = conf.imgwin_fullscreen_bg_color[0];
454       iw->priv->fs_bg_color->green = conf.imgwin_fullscreen_bg_color[1];
455       iw->priv->fs_bg_color->blue  = conf.imgwin_fullscreen_bg_color[2];
456    } else {
457       iw->priv->fs_bg_color = NULL;
458    }
459 
460    /* set window properties */
461    gtk_window_set_wmclass(GTK_WINDOW(iw), "imagewin", "GImageView");
462    gtk_window_set_policy(GTK_WINDOW(iw), TRUE, TRUE, FALSE);
463    gtk_window_set_default_size (GTK_WINDOW(iw),
464                                 conf.imgwin_width, conf.imgwin_height);
465    gimv_image_win_set_window_title (iw);
466 
467    /* Main vbox */
468    vbox = gtk_vbox_new (FALSE, 0);
469    iw->main_vbox = vbox;
470    if (iw == shared_img_win)
471       gtk_widget_set_name (iw->main_vbox, "SharedImageWin");
472    else
473       gtk_widget_set_name (iw->main_vbox, "ImageWin");
474    gtk_container_add (GTK_CONTAINER (iw), vbox);
475    gtk_widget_show (vbox);
476 
477    /* Menu Bar */
478    iw->menubar_handle = gtk_handle_box_new();
479    gtk_widget_set_name (iw->menubar_handle, "MenuBarContainer");
480    gtk_container_set_border_width (GTK_CONTAINER(iw->menubar_handle), 2);
481    gtk_box_pack_start(GTK_BOX(vbox), iw->menubar_handle, FALSE, FALSE, 0);
482 
483    if (!(iw->priv->flags & GimvImageWinShowMenuBarFlag))
484       gtk_widget_hide (iw->menubar_handle);
485    else
486       gtk_widget_show (iw->menubar_handle);
487 
488    /* toolbar */
489    iw->toolbar_handle = gtk_handle_box_new();
490    gtk_widget_set_name (iw->toolbar_handle, "ToolBarContainer");
491    gtk_container_set_border_width (GTK_CONTAINER(iw->toolbar_handle), 2);
492    gtk_box_pack_start (GTK_BOX(vbox), iw->toolbar_handle, FALSE, FALSE, 0);
493    iw->toolbar = create_toolbar (iw, iw->toolbar_handle);
494    gtk_container_add(GTK_CONTAINER(iw->toolbar_handle), iw->toolbar);
495    gtk_widget_show_all (iw->toolbar);
496 
497    gtk_toolbar_set_style (GTK_TOOLBAR(iw->toolbar), conf.imgwin_toolbar_style);
498 
499    if (!(iw->priv->flags & GimvImageWinShowToolBarFlag))
500       gtk_widget_hide (iw->toolbar_handle);
501    else
502       gtk_widget_show (iw->toolbar_handle);
503 
504    /* player toolbar */
505    iw->player_handle = gtk_handle_box_new ();
506    gtk_widget_set_name (iw->player_handle, "PlayerToolBarContainer");
507    gtk_container_set_border_width (GTK_CONTAINER(iw->player_handle), 2);
508    gtk_box_pack_start(GTK_BOX(vbox), iw->player_handle, FALSE, FALSE, 0);
509 
510    hbox = gtk_hbox_new (FALSE, 0);
511    gtk_container_add (GTK_CONTAINER (iw->player_handle), hbox);
512    gtk_widget_show (hbox);
513 
514    iw->player_bar = create_player_toolbar(iw, iw->player_handle);
515    gtk_box_pack_start (GTK_BOX (hbox), iw->player_bar, FALSE, FALSE, 0);
516    gtk_widget_show_all (iw->player_bar);
517 
518    adj = gtk_adjustment_new (0.0, 0.0, 100.0, 0.1, 1.0, 1.0);
519 
520    /* draw area */
521    gtk_box_pack_start (GTK_BOX (iw->main_vbox), GTK_WIDGET (iw->iv),
522                        TRUE, TRUE, 0);
523    gtk_widget_show (GTK_WIDGET (iw->iv));
524 
525    gtk_signal_connect (GTK_OBJECT (iw->iv), "image_changed",
526                        GTK_SIGNAL_FUNC (cb_image_changed), iw);
527    gtk_signal_connect (GTK_OBJECT (iw->iv), "load_start",
528                        GTK_SIGNAL_FUNC (cb_load_start), iw);
529    gtk_signal_connect (GTK_OBJECT (iw->iv), "load_end",
530                        GTK_SIGNAL_FUNC (cb_load_end), iw);
531    gtk_signal_connect (GTK_OBJECT (iw->iv), "set_list",
532                        GTK_SIGNAL_FUNC (cb_set_list), iw);
533    gtk_signal_connect (GTK_OBJECT (iw->iv), "unset_list",
534                        GTK_SIGNAL_FUNC (cb_unset_list), iw);
535    gtk_signal_connect (GTK_OBJECT (iw->iv), "rendered",
536                        GTK_SIGNAL_FUNC (cb_rendered), iw);
537    gtk_signal_connect (GTK_OBJECT (iw->iv), "toggle_aspect",
538                        GTK_SIGNAL_FUNC (cb_toggle_aspect), iw);
539    gtk_signal_connect (GTK_OBJECT (iw->iv), "image_pressed",
540                        GTK_SIGNAL_FUNC (cb_imageview_pressed), iw);
541    gtk_signal_connect (GTK_OBJECT (iw->iv), "image_clicked",
542                        GTK_SIGNAL_FUNC (cb_imageview_clicked), iw);
543    gtk_signal_connect (GTK_OBJECT (iw->iv->draw_area), "key_press_event",
544                        GTK_SIGNAL_FUNC (cb_draw_area_key_press), iw);
545 
546    iw->player.seekbar = gtk_hscale_new (GTK_ADJUSTMENT (adj));
547    gtk_scale_set_draw_value (GTK_SCALE (iw->player.seekbar), FALSE);
548    gtk_box_pack_start (GTK_BOX (hbox), iw->player.seekbar, TRUE, TRUE, 0);
549    gtk_widget_show (iw->player.seekbar);
550 
551    gtk_signal_connect (GTK_OBJECT (iw->player.seekbar),
552                        "button_press_event",
553                        GTK_SIGNAL_FUNC (cb_seekbar_pressed), iw);
554    gtk_signal_connect (GTK_OBJECT (iw->player.seekbar),
555                        "button_release_event",
556                        GTK_SIGNAL_FUNC (cb_seekbar_released), iw);
557 
558    gtk_toolbar_set_style (GTK_TOOLBAR(iw->player_bar),
559                           conf.imgwin_toolbar_style);
560 
561    if (!(iw->priv->flags & GimvImageWinShowPlayerFlag))
562       gtk_widget_hide (iw->player_handle);
563    else
564       gtk_widget_show (iw->player_handle);
565 
566    /* status bar */
567    hbox = gtk_hbox_new (FALSE, 0);
568    iw->status_bar_container = hbox;
569    gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
570    gtk_widget_show (hbox);
571 
572    iw->status_bar1 = gtk_statusbar_new ();
573    gtk_widget_set_name (iw->status_bar1, "StatuBar1");
574    gtk_container_border_width (GTK_CONTAINER (iw->status_bar1), 1);
575    gtk_widget_set_usize(iw->status_bar1, 200, -1);
576    gtk_box_pack_start (GTK_BOX (hbox), iw->status_bar1, TRUE, TRUE, 0);
577    gtk_statusbar_push(GTK_STATUSBAR (iw->status_bar1), 1, _("New Window"));
578    gtk_widget_show (iw->status_bar1);
579 
580    iw->status_bar2 = gtk_statusbar_new ();
581    gtk_widget_set_name (iw->status_bar1, "StatuBar2");
582    gtk_container_border_width (GTK_CONTAINER (iw->status_bar2), 1);
583    gtk_widget_set_usize(iw->status_bar2, 50, -1);
584    gtk_box_pack_start (GTK_BOX (hbox), iw->status_bar2, TRUE, TRUE, 0);
585    gtk_widget_show (iw->status_bar2);
586 
587    iw->progressbar = gtk_progress_bar_new ();
588    gtk_widget_set_name (iw->progressbar, "ProgressBar");
589    gtk_box_pack_end (GTK_BOX (hbox), iw->progressbar, FALSE, FALSE, 0);
590    gtk_widget_show (iw->progressbar);
591 
592    gimv_image_view_set_progressbar (iw->iv, iw->progressbar);
593 
594    gimv_image_win_player_set_sensitive_all (iw, FALSE);
595 
596    if (!(iw->priv->flags & GimvImageWinShowStatusBarFlag))
597       gtk_widget_hide (iw->status_bar_container);
598    else
599       gtk_widget_show (iw->status_bar_container);
600 
601    /* create menus */
602    create_imageview_menus (iw);
603 
604    iw->priv->flags &= ~GimvImageWinCreatingFlag;
605 
606    gtk_widget_grab_focus (iw->iv->draw_area);
607 
608    ImageWinList = g_list_append (ImageWinList, iw);
609 }
610 
611 
612 GtkWidget *
gimv_image_win_new(GimvImageInfo * info)613 gimv_image_win_new (GimvImageInfo *info)
614 {
615    GimvImageWin *iw = gtk_type_new (GIMV_TYPE_IMAGE_WIN);
616 
617    gimv_image_view_change_image (iw->iv, info);
618 
619    return GTK_WIDGET (iw);
620 }
621 
622 
623 static void
gimv_image_win_destroy(GtkObject * object)624 gimv_image_win_destroy (GtkObject *object)
625 {
626    GimvImageWin *iw = GIMV_IMAGE_WIN (object);
627 
628    if (iw->priv) {
629       if (iw->priv->flags & GimvImageWinSlideShowPlayingFlag)
630          gimv_image_win_slideshow_stop (iw);
631 
632       if (g_list_length (ImageWinList) == 1 && conf.imgwin_save_win_state)
633          gimv_image_win_save_state (iw);
634 
635       g_free (iw->priv->fs_bg_color);
636       iw->priv->fs_bg_color = NULL;
637 
638       g_free (iw->priv);
639       iw->priv = NULL;
640    }
641 
642    if (iw->iv) {
643       gtk_signal_disconnect_by_func (GTK_OBJECT (iw->iv),
644                                      (GtkSignalFunc) cb_set_list,   iw);
645       gtk_signal_disconnect_by_func (GTK_OBJECT (iw->iv),
646                                      (GtkSignalFunc) cb_unset_list, iw);
647       iw->iv = NULL;
648    }
649 
650    /* update linked list */
651    ImageWinList = g_list_remove (ImageWinList, iw);
652 
653    if (iw == shared_img_win)
654       shared_img_win = NULL;
655 
656    if (GTK_OBJECT_CLASS (parent_class)->destroy)
657       GTK_OBJECT_CLASS (parent_class)->destroy (object);
658 
659    /* quit when last window */
660    if (!gimv_image_win_get_list() && !gimv_thumb_win_get_list()) {
661       gimv_quit();
662    }
663 }
664 
665 
666 static void
gimv_image_win_realize(GtkWidget * widget)667 gimv_image_win_realize (GtkWidget *widget)
668 {
669    GimvImageWin *iw = GIMV_IMAGE_WIN (widget);
670 
671    if (GTK_WIDGET_CLASS (parent_class)->realize)
672       GTK_WIDGET_CLASS (parent_class)->realize (widget);
673 
674    if (iw->priv->flags & GimvImageWinHideFrameFlag)
675       gdk_window_set_decorations (GTK_WIDGET(iw)->window, 0);
676 
677    gtk_widget_realize (iw->menubar_handle);
678 
679    gimv_icon_stock_set_window_icon (GTK_WIDGET(iw)->window, "gimv_icon");
680 }
681 
682 
683 static void
create_imageview_menus(GimvImageWin * iw)684 create_imageview_menus (GimvImageWin *iw)
685 {
686    guint n_menu_items;
687    GtkWidget *zoom_menu, *rotate_menu, *movie_menu, *vmode_menu;
688    gboolean show_scrollbar, keep_buffer;
689 
690    /* main menu */
691    n_menu_items = sizeof (gimv_image_win_menu_items)
692       / sizeof (gimv_image_win_menu_items[0]) - 1;
693    iw->menubar = menubar_create (GTK_WIDGET (iw),
694                                  gimv_image_win_menu_items, n_menu_items,
695                                  "<ImageWinMainMenu>", iw);
696    gtk_container_add(GTK_CONTAINER(iw->menubar_handle), iw->menubar);
697 #ifndef USE_GTK2
698    gtk_menu_bar_set_shadow_type (GTK_MENU_BAR(iw->menubar), GTK_SHADOW_NONE);
699 #endif /* USE_GTK2 */
700    gtk_widget_show (iw->menubar);
701 
702    /* sub menu */
703    n_menu_items = sizeof(gimv_image_win_view_items)
704       / sizeof(gimv_image_win_view_items[0]) - 1;
705    iw->view_menu = menu_create_items(GTK_WIDGET (iw),
706                                      gimv_image_win_view_items,
707                                      n_menu_items, "<ImageWinViewSubMenu>", iw);
708    n_menu_items = sizeof(gimv_image_win_move_items)
709       / sizeof(gimv_image_win_move_items[0]) - 1;
710    iw->move_menu = menu_create_items(GTK_WIDGET (iw),
711                                      gimv_image_win_move_items,
712                                      n_menu_items, "<ImageWinMoveSubMenu>", iw);
713 
714    zoom_menu = gimv_image_view_create_zoom_menu (GTK_WIDGET (iw),
715                                                  iw->iv,
716                                                  "<ImageWinZoomSubMenu>");
717    rotate_menu = gimv_image_view_create_rotate_menu (GTK_WIDGET (iw),
718                                                      iw->iv,
719                                                      "<ImageWinRotateSubMenu>");
720 
721    movie_menu = gimv_image_view_create_movie_menu (GTK_WIDGET (iw),
722                                                    iw->iv,
723                                                    "<ImageWinMovieSubMenu>");
724    vmode_menu = gimv_image_view_create_view_modes_menu (GTK_WIDGET (iw),
725                                                         iw->iv,
726                                                         "<ImageWinViewModesSubMenu>");
727    iw->help_menu = gimvhelp_create_menu (GTK_WIDGET (iw));
728 
729    /* attach sub menus to parent menu */
730    menu_set_submenu (iw->menubar,   "/View",       iw->view_menu);
731    menu_set_submenu (iw->menubar,   "/Move",       iw->move_menu);
732    menu_set_submenu (iw->menubar,   "/Help",       iw->help_menu);
733    menu_set_submenu (iw->view_menu, "/Zoom",       zoom_menu);
734    menu_set_submenu (iw->view_menu, "/Rotate",     rotate_menu);
735    menu_set_submenu (iw->menubar,   "/Movie",      movie_menu);
736    menu_set_submenu (iw->view_menu, "/View modes", vmode_menu);
737 
738    /* popup menu */
739    iw->iv->imageview_popup = iw->view_menu;
740 
741    /* initialize menubar check items */
742    gtk_object_get (GTK_OBJECT (iw->iv),
743                    "show_scrollbar", &show_scrollbar,
744                    "keep_buffer",    &keep_buffer,
745                    NULL);
746 
747    menu_check_item_set_active (iw->menubar, "/File/Memory Buffer", keep_buffer);
748 
749    menu_check_item_set_active (iw->view_menu, "/Menu Bar",
750                                iw->priv->flags & GimvImageWinShowMenuBarFlag);
751    menu_check_item_set_active (iw->view_menu, "/Tool Bar",
752                                iw->priv->flags & GimvImageWinShowToolBarFlag);
753    menu_check_item_set_active (iw->view_menu, "/Slide Show Player",
754                                iw->priv->flags & GimvImageWinShowPlayerFlag);
755    menu_check_item_set_active (iw->view_menu, "/Status Bar",
756                                iw->priv->flags & GimvImageWinShowStatusBarFlag);
757    menu_check_item_set_active (iw->view_menu, "/Scroll Bar",  show_scrollbar);
758    menu_check_item_set_active (iw->view_menu, "/Maximize",
759                                iw->priv->flags & GimvImageWinMaximizeFlag);
760    menu_check_item_set_active (iw->view_menu, "/Full Screen",
761                                iw->priv->flags & GimvImageWinFullScreenFlag);
762 
763    menu_item_set_sensitive (iw->move_menu, "/Next",     FALSE);
764    menu_item_set_sensitive (iw->move_menu, "/Previous", FALSE);
765    menu_item_set_sensitive (iw->move_menu, "/First",    FALSE);
766    menu_item_set_sensitive (iw->move_menu, "/Last",     FALSE);
767 
768    switch (iw->priv->player_visible) {
769    case GimvImageViewPlayerVisibleShow:
770       menu_check_item_set_active (iw->view_menu, "/Player/Show", TRUE);
771       break;
772    case GimvImageViewPlayerVisibleHide:
773       menu_check_item_set_active (iw->view_menu, "/Player/Hide", TRUE);
774       break;
775    case GimvImageViewPlayerVisibleAuto:
776    default:
777       menu_check_item_set_active (iw->view_menu, "/Player/Auto", TRUE);
778       break;
779    }
780 }
781 
782 
783 static GtkWidget *
create_toolbar(GimvImageWin * iw,GtkWidget * container)784 create_toolbar (GimvImageWin *iw, GtkWidget *container)
785 {
786    GtkWidget *toolbar, *button, *spinner, *iconw, *menu;
787    GtkAdjustment *adj;
788    const gchar *rotate_labels[] = {
789       N_("90 degrees CCW"),
790       N_("0 degrees"),
791       N_("90 degrees CW"),
792       N_("180 degrees"),
793       NULL,
794    };
795    gfloat x_scale, y_scale;
796 
797    toolbar = gtkutil_create_toolbar ();
798 
799    /* file open button */
800    iconw = gimv_icon_stock_get_widget ("nfolder");
801    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
802                                     _("Open"),
803                                     _("File Open"),
804                                     _("File Open"),
805                                     iconw,
806                                     GTK_SIGNAL_FUNC (cb_toolbar_open_button),
807                                     NULL);
808 
809    /* preference button */
810    iconw = gimv_icon_stock_get_widget ("prefs");
811    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
812                                     _("Prefs"),
813                                     _("Preference"),
814                                     _("Preference"),
815                                     iconw,
816                                     GTK_SIGNAL_FUNC (cb_toolbar_prefs_button),
817                                     iw);
818 
819    gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
820 
821    /* prev button */
822    iconw = gimv_icon_stock_get_widget ("back");
823    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
824                                     _("Prev"),
825                                     _("Previous Image"),
826                                     _("Previous Image"),
827                                     iconw,
828                                     GTK_SIGNAL_FUNC (cb_toolbar_prev_button),
829                                     iw);
830    iw->button.prev = button;
831    /* gtk_widget_set_sensitive (button, FALSE); */
832 
833    /* next button */
834    iconw = gimv_icon_stock_get_widget ("forward");
835    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
836                                     _("Next"),
837                                     _("Next Image"),
838                                     _("Next Image"),
839                                     iconw,
840                                     GTK_SIGNAL_FUNC (cb_toolbar_next_button),
841                                     iw);
842    iw->button.next = button;
843    /* gtk_widget_set_sensitive (button, FALSE); */
844 
845    gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
846 
847    /* no zoom button */
848    iconw = gimv_icon_stock_get_widget ("no_zoom");
849    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
850                                     _("No Zoom"),
851                                     _("No Zoom"),
852                                     _("No Zoom"),
853                                     iconw,
854                                     GTK_SIGNAL_FUNC (cb_toolbar_no_zoom),
855                                     iw);
856 
857    /* zoom in button */
858    iconw = gimv_icon_stock_get_widget ("zoom_in");
859    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
860                                     _("Zoom in"),
861                                     _("Zoom in"),
862                                     _("Zoom in"),
863                                     iconw,
864                                     GTK_SIGNAL_FUNC (cb_toolbar_zoom_in),
865                                     iw);
866 
867    /* zoom out button */
868    iconw = gimv_icon_stock_get_widget ("zoom_out");
869    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
870                                     _("Zoom out"),
871                                     _("Zoom out"),
872                                     _("Zoom out"),
873                                     iconw,
874                                     GTK_SIGNAL_FUNC (cb_toolbar_zoom_out),
875                                     iw);
876 
877    /* zoom fit button */
878    iconw = gimv_icon_stock_get_widget ("zoom_fit");
879    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
880                                     _("Zoom fit"),
881                                     _("Zoom fit"),
882                                     _("Zoom fit"),
883                                     iconw,
884                                     GTK_SIGNAL_FUNC (cb_toolbar_zoom_fit),
885                                     iw);
886 
887    gtk_object_get (GTK_OBJECT (iw->iv),
888                    "x_scale", &x_scale,
889                    "y_scale", &y_scale,
890                    NULL);
891 
892    /* x scale spinner */
893    adj = (GtkAdjustment *) gtk_adjustment_new (x_scale,
894                                                GIMV_THUMB_WIN_MIN_THUMB_SIZE,
895                                                GIMV_THUMB_WIN_MAX_THUMB_SIZE,
896                                                1.0, 5.0, 0.0);
897    spinner = gtkutil_create_spin_button (adj);
898    gtk_widget_set_name (spinner, "XScaleSpinner");
899    gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), spinner,
900                               _("X Scale"), _("X Scale"));
901    gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
902                        GTK_SIGNAL_FUNC (cb_toolbar_keep_aspect), iw);
903    iw->button.xscale = spinner;
904    gtk_signal_connect (GTK_OBJECT(spinner), "key-press-event",
905                        GTK_SIGNAL_FUNC(cb_scale_spinner_key_press), iw);
906 
907    /* y scale spinner */
908    adj = (GtkAdjustment *) gtk_adjustment_new (y_scale,
909                                                GIMV_THUMB_WIN_MIN_THUMB_SIZE,
910                                                GIMV_THUMB_WIN_MAX_THUMB_SIZE,
911                                                1.0, 5.0, 0.0);
912    spinner = gtkutil_create_spin_button (adj);
913    gtk_widget_set_name (spinner, "YScaleSpinner");
914    gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), spinner,
915                               _("Y Scale"), _("Y Scale"));
916    iw->button.yscale = spinner;
917 
918    /* zoom button */
919    iconw = gimv_icon_stock_get_widget ("zoom");
920    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
921                                     _("Zoom"),
922                                     _("Zoom"),
923                                     _("Zoom"),
924                                     iconw,
925                                     GTK_SIGNAL_FUNC (cb_toolbar_zoom),
926                                     iw);
927 
928    gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
929 
930    /* rotate button */
931    menu = create_option_menu (rotate_labels,
932                               1, cb_rotate_menu, iw);
933    gtk_signal_connect (GTK_OBJECT (menu), "button_press_event",
934                        GTK_SIGNAL_FUNC (cb_rotate_menu_button_press), iw);
935    gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar), menu,
936                               _("Rotate"), _("Rotate the image"));
937    iw->button.rotate = menu;
938 
939    gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
940 
941    /* resize button */
942    iconw = gimv_icon_stock_get_widget ("resize");
943    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
944                                     _("Resize"),
945                                     _("Fit Window Size to Image"),
946                                     _("Fit Window Size to Image"),
947                                     iconw,
948                                     GTK_SIGNAL_FUNC (cb_toolbar_fit_window),
949                                     iw);
950 
951    /* fullscreen button */
952    iconw = gimv_icon_stock_get_widget ("fullscreen");
953    /* button = gtk_toggle_button_new (); */
954    button = gtk_toolbar_append_item(GTK_TOOLBAR (toolbar),
955                                     _("Full"),
956                                     _("Fullscreen"),
957                                     _("Fullscreen"),
958                                     iconw,
959                                     GTK_SIGNAL_FUNC (cb_toolbar_fullscreen),
960                                     iw);
961 
962    gtk_widget_set_sensitive (iw->button.prev, FALSE);
963    gtk_widget_set_sensitive (iw->button.next, FALSE);
964 
965    return toolbar;
966 }
967 
968 
969 static GtkWidget *
create_player_toolbar(GimvImageWin * iw,GtkWidget * container)970 create_player_toolbar (GimvImageWin *iw, GtkWidget *container)
971 {
972    GtkWidget *toolbar;
973    GtkWidget *button;
974    GtkWidget *iconw;
975 
976    toolbar = gtkutil_create_toolbar ();
977 
978    /* previous button */
979    iconw = gimv_icon_stock_get_widget ("prev_t");
980    button = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
981                                      _("First"),
982                                      _("First"), _("First"),
983                                      iconw,
984                                      GTK_SIGNAL_FUNC (cb_first_clicked), iw);
985    iw->player.prev = button;
986 
987    /* Reverse button */
988    iconw = gimv_icon_stock_get_widget ("rw");
989    button = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
990                                      _("Prev"),
991                                      _("Previous"), _("Previous"),
992                                      iconw,
993                                      GTK_SIGNAL_FUNC (cb_prev_clicked), iw);
994    iw->player.rw = button;
995 
996    /* play button */
997    iconw = gimv_icon_stock_get_widget ("play");
998    button = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
999                                      _("Play"),
1000                                      _("Play Slide Show"), _("Play Slide Show"),
1001                                      iconw,
1002                                      GTK_SIGNAL_FUNC (cb_play_clicked), iw);
1003    iw->player.play = button;
1004 
1005    /* stop button */
1006    iconw = gimv_icon_stock_get_widget ("stop2");
1007    button = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1008                                      _("Stop"),
1009                                      _("Stop Slide Show"), _("Stop Slide Show"),
1010                                      iconw,
1011                                      GTK_SIGNAL_FUNC (cb_stop_clicked), iw);
1012    iw->player.stop = button;
1013 
1014    /* Forward button */
1015    iconw = gimv_icon_stock_get_widget ("ff");
1016    button = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1017                                      _("Next"),
1018                                      _("Next"), _("Next"),
1019                                      iconw,
1020                                      GTK_SIGNAL_FUNC (cb_next_clicked), iw);
1021    iw->player.fw = button;
1022 
1023    /* Next button */
1024    iconw = gimv_icon_stock_get_widget ("next_t");
1025    button = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar),
1026                                      _("Last"),
1027                                      _("Last"), _("Last"),
1028                                      iconw,
1029                                      GTK_SIGNAL_FUNC (cb_last_clicked), iw);
1030    iw->player.next = button;
1031 
1032    return toolbar;
1033 }
1034 
1035 
1036 static void
gimv_image_win_set_win_size(GimvImageWin * iw)1037 gimv_image_win_set_win_size (GimvImageWin *iw)
1038 {
1039    gint x_size, y_size, width, height;
1040    gfloat x_scale, y_scale, tmp;
1041    gboolean show_scrollbar;
1042    GimvImageViewOrientation rotate;
1043 
1044    if (!GIMV_IS_IMAGE_WIN (iw)) return;
1045    if (iw->priv->flags & GimvImageWinMaximizeFlag) return;
1046    if (iw->priv->flags & GimvImageWinFullScreenFlag) return;
1047 
1048    gtk_object_get (GTK_OBJECT (iw->iv),
1049                    "x_scale", &x_scale,
1050                    "y_scale", &y_scale,
1051                    NULL);
1052    if (x_scale < 0.001 || y_scale < 0.001) return;
1053 
1054    rotate = gimv_image_view_get_orientation (iw->iv);
1055    if (rotate == 0 || rotate == 2) {
1056       width =  iw->iv->info->width;
1057       height = iw->iv->info->height;
1058    } else {
1059       tmp = x_scale;
1060       x_scale = y_scale;
1061       y_scale = tmp;
1062       width  = iw->iv->info->height;
1063       height = iw->iv->info->width;
1064    }
1065 
1066    x_size = width  * x_scale / 100.0 + 0.5;
1067    y_size = height * y_scale / 100.0 + 0.5;
1068 
1069    if (iw->priv->flags & GimvImageWinShowMenuBarFlag)
1070       y_size += iw->menubar_handle->allocation.height;
1071 
1072    if (iw->priv->flags & GimvImageWinShowToolBarFlag)
1073       y_size += iw->toolbar_handle->allocation.height;
1074 
1075    if (iw->priv->flags & GimvImageWinShowPlayerFlag)
1076       y_size += iw->player_handle->allocation.height;
1077 
1078    if (iw->priv->flags & GimvImageWinShowStatusBarFlag)
1079       y_size += iw->status_bar_container->allocation.height;
1080 
1081    if (GTK_WIDGET_VISIBLE (iw->iv->player_container))
1082       y_size += iw->iv->player_container->allocation.height;
1083 
1084    gtk_object_get (GTK_OBJECT (iw->iv),
1085                    "show_scrollbar", &show_scrollbar,
1086                    NULL);
1087    if (show_scrollbar) {
1088       x_size += iw->iv->vscrollbar->allocation.width;
1089       y_size += iw->iv->hscrollbar->allocation.height;
1090    }
1091 
1092    if (x_size < 1)
1093       x_size = conf.imgwin_width;
1094    if (y_size < 1)
1095       y_size = conf.imgwin_height;
1096 
1097    gdk_window_resize (GTK_WIDGET(iw)->window, x_size, y_size);
1098    gimv_image_view_set_view_position (iw->iv, 0, 0);
1099    gimv_image_view_draw_image (iw->iv);
1100 }
1101 
1102 
1103 static void
gimv_image_win_set_window_title(GimvImageWin * iw)1104 gimv_image_win_set_window_title (GimvImageWin *iw)
1105 {
1106    gchar buf[BUF_SIZE];
1107    const gchar *filename = NULL;
1108    gchar *dirname = NULL, *tmpstr1, *tmpstr2;
1109    gboolean keep_buffer;
1110 
1111    g_return_if_fail (iw);
1112    if (!g_list_find (ImageWinList, iw)) return;
1113 
1114    g_return_if_fail (iw->iv);
1115    if (!g_list_find (gimv_image_view_get_list(), iw->iv)) return;
1116 
1117    if (iw->iv->info && gimv_image_info_get_path (iw->iv->info)) {
1118       filename = g_basename (iw->iv->info->filename);
1119       dirname = g_dirname (iw->iv->info->filename);
1120    } else {
1121       gtk_window_set_title (GTK_WINDOW (iw), GIMV_PROG_NAME);
1122       return;
1123    }
1124 
1125    tmpstr1 = charset_to_internal (filename, conf.charset_filename,
1126                                   conf.charset_auto_detect_fn,
1127                                   conf.charset_filename_mode);
1128    tmpstr2 = charset_to_internal (dirname, conf.charset_filename,
1129                                   conf.charset_auto_detect_fn,
1130                                   conf.charset_filename_mode);
1131 
1132    gtk_object_get (GTK_OBJECT (iw->iv),
1133                    "keep_buffer", &keep_buffer,
1134                    NULL);
1135 
1136    if (tmpstr1 && tmpstr2 && *tmpstr1 && *tmpstr2) {
1137       if (keep_buffer)
1138          g_snprintf (buf, BUF_SIZE, _("%s (%s) - %s - "),
1139                      tmpstr1, tmpstr2, GIMV_PROG_NAME);
1140       else
1141          g_snprintf (buf, BUF_SIZE, _("* %s (%s) - %s - *"),
1142                      tmpstr1, tmpstr2, GIMV_PROG_NAME);
1143       gtk_window_set_title (GTK_WINDOW (iw), buf);
1144    } else {
1145       if (keep_buffer)
1146          g_snprintf (buf, BUF_SIZE, _("- %s -"), GIMV_PROG_NAME);
1147       else
1148          g_snprintf (buf, BUF_SIZE, _("* - %s - *"), GIMV_PROG_NAME);
1149       gtk_window_set_title (GTK_WINDOW (iw), buf);
1150    }
1151 
1152    g_free (tmpstr1);
1153    g_free (tmpstr2);
1154    g_free (dirname);
1155 }
1156 
1157 
1158 static void
gimv_image_win_set_statusbar_info(GimvImageWin * iw)1159 gimv_image_win_set_statusbar_info (GimvImageWin *iw)
1160 {
1161    gchar buf[BUF_SIZE], *tmpstr;
1162    const gchar *filename = _("NONE");
1163    const gchar *format = _("UNKNOWN");
1164    gint width = 0, height = 0;
1165    gboolean keep_buffer;
1166 
1167    g_return_if_fail (iw);
1168    if (!g_list_find (ImageWinList, iw)) return;
1169 
1170    g_return_if_fail (iw->iv);
1171    if (!g_list_find (gimv_image_view_get_list(), iw->iv)) return;
1172 
1173    if (iw->iv->info) {
1174       filename = gimv_image_info_get_path (iw->iv->info);
1175       format = gimv_image_info_get_format (iw->iv->info);
1176       gimv_image_info_get_image_size (iw->iv->info, &width, &height);
1177    }
1178 
1179    tmpstr = charset_to_internal (filename, conf.charset_filename,
1180                                  conf.charset_auto_detect_fn,
1181                                  conf.charset_filename_mode);
1182 
1183    gtk_object_get (GTK_OBJECT (iw->iv),
1184                    "keep_buffer", &keep_buffer,
1185                    NULL);
1186 
1187    if (tmpstr && *tmpstr) {
1188       if (keep_buffer)
1189          g_snprintf (buf, BUF_SIZE, _("%s (Buffer ON)"), tmpstr);
1190       else
1191          g_snprintf (buf, BUF_SIZE, _("%s (Buffer OFF)"), tmpstr);
1192 
1193       gtk_statusbar_push (GTK_STATUSBAR (iw->status_bar1), 1, buf);
1194    } else {
1195       if (keep_buffer)
1196          g_snprintf (buf, BUF_SIZE, _("(Buffer ON)"));
1197       else
1198          g_snprintf (buf, BUF_SIZE, _("(Buffer OFF)"));
1199       gtk_statusbar_push (GTK_STATUSBAR (iw->status_bar1), 1, buf);
1200    }
1201    g_free (tmpstr);
1202 
1203    g_snprintf (buf, BUF_SIZE, "%s %d x %d", format, width, height);
1204    gtk_statusbar_push (GTK_STATUSBAR (iw->status_bar2), 1, buf);
1205 }
1206 
1207 
1208 
1209 /******************************************************************************
1210  *
1211  *   Callback functions for menubar.
1212  *
1213  ******************************************************************************/
1214 static void
cb_file_select(gpointer data,guint action,GtkWidget * widget)1215 cb_file_select (gpointer data, guint action, GtkWidget *widget)
1216 {
1217    create_filebrowser (NULL);
1218 }
1219 
1220 
1221 static void
cb_open_imagewin(gpointer data,guint action,GtkWidget * widget)1222 cb_open_imagewin (gpointer data, guint action, GtkWidget *widget)
1223 {
1224    gimv_image_win_open_window (NULL);
1225 }
1226 
1227 
1228 static void
cb_open_thumbwin(gpointer data,guint action,GtkWidget * widget)1229 cb_open_thumbwin (gpointer data, guint action, GtkWidget *widget)
1230 {
1231    gimv_thumb_win_open_window();
1232 }
1233 
1234 
1235 static void
cb_toggle_buffer(GimvImageWin * iw,guint action,GtkWidget * widget)1236 cb_toggle_buffer (GimvImageWin *iw, guint action, GtkWidget *widget)
1237 {
1238    gboolean keep_buffer;
1239 
1240    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1241 
1242    if (GTK_CHECK_MENU_ITEM(widget)->active) {
1243       gimv_image_view_load_image_buf (iw->iv);
1244       keep_buffer = TRUE;
1245    } else {
1246       keep_buffer = FALSE;
1247       gimv_image_view_free_image_buf (iw->iv);
1248    }
1249 
1250    gtk_object_set (GTK_OBJECT (iw->iv),
1251                    "keep_buffer", keep_buffer,
1252                    NULL);
1253 
1254    gimv_image_win_set_window_title (iw);
1255    gimv_image_win_set_statusbar_info (iw);
1256 }
1257 
1258 
1259 static void
cb_window_close(GimvImageWin * iw,guint action,GtkWidget * widget)1260 cb_window_close (GimvImageWin *iw, guint action, GtkWidget *widget)
1261 {
1262    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1263 
1264    if (iw->priv->flags & GimvImageWinCreatingFlag) return;
1265 
1266    if (iw->priv->flags & GimvImageWinFullScreenFlag) {
1267       menu_check_item_set_active (iw->view_menu, "/Full Screen", FALSE);
1268       return; /* or close window completly? */
1269    }
1270 
1271    gtk_widget_destroy (GTK_WIDGET (iw));
1272 }
1273 
1274 
1275 static void
cb_ignore_alpha(GimvImageWin * iw,guint action,GtkWidget * widget)1276 cb_ignore_alpha (GimvImageWin *iw, guint action, GtkWidget *widget)
1277 {
1278    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1279 
1280    gtk_object_set (GTK_OBJECT (iw->iv),
1281                    "ignore_alpha", GTK_CHECK_MENU_ITEM (widget)->active,
1282                    NULL);
1283    gimv_image_view_show_image (iw->iv);
1284 }
1285 
1286 
1287 static void
cb_toggle_menubar(GimvImageWin * iw,guint action,GtkWidget * widget)1288 cb_toggle_menubar (GimvImageWin *iw, guint action, GtkWidget *widget)
1289 {
1290    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1291 
1292    if (GTK_CHECK_MENU_ITEM(widget)->active) {
1293       gtk_widget_show (iw->menubar_handle);
1294       iw->priv->flags |= GimvImageWinShowMenuBarFlag;
1295    } else {
1296       gtk_widget_hide (iw->menubar_handle);
1297       iw->priv->flags &= ~GimvImageWinShowMenuBarFlag;
1298    }
1299 }
1300 
1301 
1302 static void
cb_toggle_player(GimvImageWin * iw,guint action,GtkWidget * widget)1303 cb_toggle_player (GimvImageWin *iw, guint action, GtkWidget *widget)
1304 {
1305    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1306 
1307    if (GTK_CHECK_MENU_ITEM(widget)->active) {
1308       gtk_widget_show (iw->player_handle);
1309       iw->priv->flags |= GimvImageWinShowPlayerFlag;
1310    } else {
1311       gtk_widget_hide (iw->player_handle);
1312       iw->priv->flags &= ~GimvImageWinShowPlayerFlag;
1313    }
1314 }
1315 
1316 
1317 static void
cb_toggle_toolbar(GimvImageWin * iw,guint action,GtkWidget * widget)1318 cb_toggle_toolbar (GimvImageWin *iw, guint action, GtkWidget *widget)
1319 {
1320    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1321 
1322    if (GTK_CHECK_MENU_ITEM(widget)->active) {
1323       gtk_widget_show (iw->toolbar_handle);
1324       iw->priv->flags |= GimvImageWinShowToolBarFlag;
1325    } else {
1326       gtk_widget_hide (iw->toolbar_handle);
1327       iw->priv->flags &= ~GimvImageWinShowToolBarFlag;
1328    }
1329 }
1330 
1331 
1332 static void
cb_toggle_statusbar(GimvImageWin * iw,guint action,GtkWidget * widget)1333 cb_toggle_statusbar (GimvImageWin *iw, guint action, GtkWidget *widget)
1334 {
1335    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1336 
1337    if (GTK_CHECK_MENU_ITEM(widget)->active) {
1338       gtk_widget_show (iw->status_bar_container);
1339       iw->priv->flags |= GimvImageWinShowStatusBarFlag;
1340    } else {
1341       gtk_widget_hide (iw->status_bar_container);
1342       iw->priv->flags &= ~GimvImageWinShowStatusBarFlag;
1343    }
1344 }
1345 
1346 
1347 static void
cb_toggle_scrollbar(GimvImageWin * iw,guint action,GtkWidget * widget)1348 cb_toggle_scrollbar (GimvImageWin *iw, guint action, GtkWidget *widget)
1349 {
1350    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1351 
1352    if (GTK_CHECK_MENU_ITEM(widget)->active) {
1353       gimv_image_view_show_scrollbar (iw->iv);
1354    } else {
1355       gimv_image_view_hide_scrollbar (iw->iv);
1356    }
1357 }
1358 
1359 
1360 static void
cb_switch_player(GimvImageWin * iw,GimvImageViewPlayerVisibleType visible,GtkWidget * widget)1361 cb_switch_player (GimvImageWin *iw,
1362                   GimvImageViewPlayerVisibleType visible,
1363                   GtkWidget     *widget)
1364 {
1365    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1366    g_return_if_fail (GIMV_IS_IMAGE_VIEW (iw->iv));
1367 
1368    gimv_image_view_set_player_visible (iw->iv, visible);
1369    iw->priv->player_visible = gimv_image_view_get_player_visible (iw->iv);
1370 }
1371 
1372 
1373 static void
cb_toggle_maximize(GimvImageWin * iw,guint action,GtkWidget * widget)1374 cb_toggle_maximize (GimvImageWin *iw, guint action, GtkWidget *widget)
1375 {
1376    GdkWindow *gdk_window = GTK_WIDGET(iw)->window;
1377    gint client_x, client_y, root_x, root_y;
1378    gint width, height;
1379 
1380    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1381 
1382    if (GTK_CHECK_MENU_ITEM(widget)->active) {
1383       gdk_window_get_origin (gdk_window, &root_x, &root_y);
1384       gdk_window_get_geometry (gdk_window, &client_x, &client_y,
1385                                &width, &height, NULL);
1386 
1387       gdk_window_move_resize (gdk_window, -client_x, -client_y,
1388                               gdk_screen_width (), gdk_screen_height ());
1389       gdk_window_raise (gdk_window);
1390       gdk_window_focus (gdk_window, GDK_CURRENT_TIME);
1391 
1392       iw->priv->flags |= GimvImageWinMaximizeFlag;
1393       iw->priv->win_x = root_x - client_x;
1394       iw->priv->win_y = root_y - client_y;
1395       iw->priv->win_width  = width;
1396       iw->priv->win_height = height;
1397    } else {
1398       gdk_window_move_resize (gdk_window,
1399                               iw->priv->win_x, iw->priv->win_y,
1400                               iw->priv->win_width, iw->priv->win_height);
1401       iw->priv->flags &= ~GimvImageWinMaximizeFlag;
1402    }
1403 }
1404 
1405 
1406 static void
cb_toggle_fullscreen(GimvImageWin * iw,guint action,GtkWidget * widget)1407 cb_toggle_fullscreen (GimvImageWin *iw, guint action, GtkWidget *widget)
1408 {
1409    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1410 
1411    if (GTK_CHECK_MENU_ITEM(widget)->active) {
1412       gimv_image_win_fullscreen_show (iw);
1413    } else {
1414       gimv_image_win_fullscreen_hide (iw);
1415    }
1416 }
1417 
1418 
1419 static void
cb_fit_to_image(GimvImageWin * iw,guint action,GtkWidget * widget)1420 cb_fit_to_image (GimvImageWin *iw, guint action, GtkWidget *widget)
1421 {
1422    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1423 
1424    gimv_image_win_set_win_size (iw);
1425 }
1426 
1427 
1428 static void
cb_edit_comment(GimvImageWin * iw,guint action,GtkWidget * menuitem)1429 cb_edit_comment (GimvImageWin *iw, guint action, GtkWidget *menuitem)
1430 {
1431    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1432    g_return_if_fail (iw->iv);
1433 
1434    if (iw->iv->info)
1435       gimv_comment_view_create_window (iw->iv->info);
1436 }
1437 
1438 
1439 #ifdef ENABLE_EXIF
1440 static void
cb_exif(GimvImageWin * iw,guint action,GtkWidget * menuitem)1441 cb_exif (GimvImageWin *iw, guint action, GtkWidget *menuitem)
1442 {
1443    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1444 
1445    if (iw->iv->info)
1446       exif_view_create_window (gimv_image_info_get_path (iw->iv->info),
1447                                GTK_WINDOW (iw));
1448 }
1449 #endif /* ENABLE_EXIF */
1450 
1451 
1452 static void
cb_create_thumb(GimvImageWin * iw,guint action,GtkWidget * widget)1453 cb_create_thumb (GimvImageWin *iw,
1454                  guint        action,
1455                  GtkWidget   *widget)
1456 {
1457    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1458    g_return_if_fail (iw->iv);
1459 
1460    gimv_image_view_create_thumbnail (iw->iv);
1461 }
1462 
1463 
1464 static void
cb_options(GimvImageWin * iw)1465 cb_options (GimvImageWin *iw)
1466 {
1467    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1468 
1469    gimv_prefs_win_open_idle ("/Image Window", GTK_WINDOW (iw));
1470 }
1471 
1472 
1473 static void
cb_move_menu(GimvImageWin * iw,guint action,GtkWidget * widget)1474 cb_move_menu (GimvImageWin *iw,
1475               guint        action,
1476               GtkWidget   *widget)
1477 {
1478    gint num;
1479 
1480    g_return_if_fail (GIMV_IS_IMAGE_WIN(iw));
1481 
1482    switch (action) {
1483    case IMG_FIRST:
1484       gimv_image_view_nth (iw->iv, 0);
1485       break;
1486    case IMG_PREV:
1487       gimv_image_view_prev (iw->iv);
1488       break;
1489    case IMG_NEXT:
1490       gimv_image_view_next (iw->iv);
1491       break;
1492    case IMG_LAST:
1493       if (!gimv_image_view_has_list (iw->iv)) return;
1494       num = gimv_image_view_image_list_length (iw->iv);
1495       gimv_image_view_nth (iw->iv, num - 1);
1496       break;
1497    default:
1498       break;
1499    }
1500 }
1501 
1502 
1503 /******************************************************************************
1504  *
1505  *  callback functions for toolbar.
1506  *
1507  ******************************************************************************/
1508 static void
cb_toolbar_open_button(GtkWidget * widget)1509 cb_toolbar_open_button (GtkWidget *widget)
1510 {
1511    create_filebrowser (NULL);
1512 }
1513 
1514 
1515 static void
cb_toolbar_prefs_button(GtkWidget * widget,GimvImageWin * iw)1516 cb_toolbar_prefs_button (GtkWidget *widget, GimvImageWin *iw)
1517 {
1518    gimv_prefs_win_open_idle ("/Image Window", GTK_WINDOW (iw));
1519 }
1520 
1521 
1522 static void
cb_toolbar_prev_button(GtkWidget * widget,GimvImageWin * iw)1523 cb_toolbar_prev_button  (GtkWidget *widget, GimvImageWin *iw)
1524 {
1525    g_return_if_fail (iw);
1526    gimv_image_view_prev (iw->iv);
1527 }
1528 
1529 
1530 static void
cb_toolbar_next_button(GtkWidget * widget,GimvImageWin * iw)1531 cb_toolbar_next_button  (GtkWidget *widget, GimvImageWin *iw)
1532 {
1533    g_return_if_fail (iw);
1534    gimv_image_view_next (iw->iv);
1535 }
1536 
1537 
1538 static void
cb_toolbar_no_zoom(GtkWidget * widget,GimvImageWin * iw)1539 cb_toolbar_no_zoom (GtkWidget *widget, GimvImageWin *iw)
1540 {
1541    g_return_if_fail (iw);
1542    gimv_image_view_zoom_image (iw->iv, GIMV_IMAGE_VIEW_ZOOM_100, 0, 0);
1543 }
1544 
1545 
1546 static void
cb_toolbar_zoom_in(GtkWidget * widget,GimvImageWin * iw)1547 cb_toolbar_zoom_in (GtkWidget *widget, GimvImageWin *iw)
1548 {
1549    g_return_if_fail (iw);
1550    gimv_image_view_zoom_image (iw->iv, GIMV_IMAGE_VIEW_ZOOM_IN, 0, 0);
1551 }
1552 
1553 
1554 static void
cb_toolbar_zoom_out(GtkWidget * widget,GimvImageWin * iw)1555 cb_toolbar_zoom_out (GtkWidget *widget, GimvImageWin *iw)
1556 {
1557    g_return_if_fail (iw);
1558    gimv_image_view_zoom_image (iw->iv, GIMV_IMAGE_VIEW_ZOOM_OUT, 0, 0);
1559 }
1560 
1561 
1562 static void
cb_toolbar_zoom_fit(GtkWidget * widget,GimvImageWin * iw)1563 cb_toolbar_zoom_fit (GtkWidget *widget, GimvImageWin *iw)
1564 {
1565    g_return_if_fail (iw);
1566    gimv_image_view_zoom_image (iw->iv, GIMV_IMAGE_VIEW_ZOOM_FIT, 0, 0);
1567 }
1568 
1569 
1570 static void
cb_toolbar_zoom(GtkWidget * widget,GimvImageWin * iw)1571 cb_toolbar_zoom (GtkWidget *widget, GimvImageWin *iw)
1572 {
1573    gfloat x_scale, y_scale;
1574    GtkSpinButton *xspin, *yspin;
1575 
1576    g_return_if_fail (iw);
1577 
1578    xspin = GTK_SPIN_BUTTON(iw->button.xscale);
1579    yspin = GTK_SPIN_BUTTON(iw->button.yscale);
1580 
1581    x_scale = gtk_spin_button_get_value_as_float (xspin);
1582    y_scale = gtk_spin_button_get_value_as_float (yspin);
1583 
1584    gimv_image_view_zoom_image (iw->iv, GIMV_IMAGE_VIEW_ZOOM_FREE, x_scale, y_scale);
1585 }
1586 
1587 
1588 static void
cb_toolbar_keep_aspect(GtkWidget * widget,GimvImageWin * iw)1589 cb_toolbar_keep_aspect (GtkWidget *widget, GimvImageWin *iw)
1590 {
1591    gfloat scale;
1592    gboolean keep_aspect;
1593 
1594    g_return_if_fail (iw);
1595 
1596    gtk_object_get (GTK_OBJECT (iw->iv),
1597                    "keep_aspect", &keep_aspect,
1598                    NULL);
1599 
1600    if (!keep_aspect)
1601       return;
1602 
1603    scale = gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (iw->button.xscale));
1604    gtk_spin_button_set_value (GTK_SPIN_BUTTON (iw->button.yscale), scale);
1605 }
1606 
1607 
1608 static void
cb_toolbar_fit_window(GtkWidget * widget,GimvImageWin * iw)1609 cb_toolbar_fit_window (GtkWidget *widget, GimvImageWin *iw)
1610 {
1611    g_return_if_fail (iw);
1612    gimv_image_win_set_win_size (iw);
1613 }
1614 
1615 
1616 static void
cb_toolbar_fullscreen(GtkWidget * widget,GimvImageWin * iw)1617 cb_toolbar_fullscreen (GtkWidget *widget, GimvImageWin *iw)
1618 {
1619    g_return_if_fail (iw);
1620    menu_check_item_set_active (iw->view_menu, "/Full Screen",
1621                                !(iw->priv->flags & GimvImageWinFullScreenFlag));
1622 }
1623 
1624 
1625 static gboolean
cb_scale_spinner_key_press(GtkWidget * widget,GdkEventKey * event,GimvImageWin * iw)1626 cb_scale_spinner_key_press (GtkWidget *widget,
1627                             GdkEventKey *event,
1628                             GimvImageWin *iw)
1629 {
1630    g_return_val_if_fail (iw, FALSE);
1631 
1632    switch (event->keyval) {
1633    case GDK_Escape:
1634       gtk_window_set_focus (GTK_WINDOW (iw), NULL);
1635       return FALSE;
1636    }
1637 
1638    return FALSE;
1639 }
1640 
1641 
1642 static void
cb_rotate_menu(GtkWidget * widget,GimvImageWin * iw)1643 cb_rotate_menu (GtkWidget *widget, GimvImageWin *iw)
1644 {
1645    gint angle;
1646    g_return_if_fail (GTK_IS_MENU_ITEM (widget));
1647    angle = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "num"));
1648    switch (angle)
1649    {
1650    case 0:
1651       angle = 1;
1652       break;
1653    case 1:
1654       angle = 0;
1655       break;
1656    case 2:
1657       angle = 3;
1658       break;
1659    case 3:
1660       angle = 2;
1661       break;
1662    default:
1663       angle = 0;
1664       break;
1665    }
1666 
1667    gimv_image_view_rotate_image (iw->iv, angle);
1668 }
1669 
1670 
1671 static gboolean
cb_rotate_menu_button_press(GtkWidget * widget,GdkEventButton * event,GimvImageWin * iw)1672 cb_rotate_menu_button_press (GtkWidget *widget,
1673                              GdkEventButton *event,
1674                              GimvImageWin *iw)
1675 {
1676    g_return_val_if_fail (GTK_IS_OPTION_MENU (widget), FALSE);
1677 
1678    switch (event->button) {
1679    case 2:
1680       gimv_image_view_rotate_ccw (iw->iv);
1681       return TRUE;
1682    case 3:
1683       gimv_image_view_rotate_cw (iw->iv);
1684       return TRUE;
1685    default:
1686       break;
1687    }
1688 
1689    return FALSE;
1690 }
1691 
1692 
1693 
1694 /******************************************************************************
1695  *
1696  *  callback functions for slideshow player
1697  *
1698  ******************************************************************************/
1699 static void
cb_play_clicked(GtkWidget * button,GimvImageWin * iw)1700 cb_play_clicked (GtkWidget *button, GimvImageWin *iw)
1701 {
1702    g_return_if_fail (iw);
1703 
1704    gimv_image_win_slideshow_play (iw);
1705 }
1706 
1707 
1708 static void
cb_stop_clicked(GtkWidget * button,GimvImageWin * iw)1709 cb_stop_clicked (GtkWidget *button, GimvImageWin *iw)
1710 {
1711    g_return_if_fail (iw);
1712 
1713    gimv_image_win_slideshow_stop (iw);
1714 }
1715 
1716 
1717 static void
cb_prev_clicked(GtkWidget * button,GimvImageWin * iw)1718 cb_prev_clicked (GtkWidget *button, GimvImageWin *iw)
1719 {
1720    g_return_if_fail (iw);
1721 
1722    gimv_image_view_prev (iw->iv);
1723 }
1724 
1725 
1726 static void
cb_next_clicked(GtkWidget * button,GimvImageWin * iw)1727 cb_next_clicked (GtkWidget *button, GimvImageWin *iw)
1728 {
1729    g_return_if_fail (iw);
1730 
1731    gimv_image_view_next (iw->iv);
1732 }
1733 
1734 
1735 static void
cb_first_clicked(GtkWidget * button,GimvImageWin * iw)1736 cb_first_clicked (GtkWidget *button, GimvImageWin *iw)
1737 {
1738    g_return_if_fail (iw);
1739 
1740    gimv_image_view_nth (iw->iv, 0);
1741 }
1742 
1743 
1744 static void
cb_last_clicked(GtkWidget * button,GimvImageWin * iw)1745 cb_last_clicked (GtkWidget *button, GimvImageWin *iw)
1746 {
1747    gint num;
1748 
1749    g_return_if_fail (iw);
1750    g_return_if_fail (GIMV_IS_IMAGE_VIEW (iw->iv));
1751    g_return_if_fail (gimv_image_view_has_list (iw->iv));
1752 
1753    num = gimv_image_view_image_list_length (iw->iv);
1754    gimv_image_view_nth (iw->iv, num - 1);
1755 }
1756 
1757 
1758 static gboolean
cb_seekbar_pressed(GtkWidget * widget,GdkEventButton * event,GimvImageWin * iw)1759 cb_seekbar_pressed (GtkWidget *widget,
1760                     GdkEventButton *event,
1761                     GimvImageWin *iw)
1762 {
1763    g_return_val_if_fail (iw, FALSE);
1764 
1765    iw->priv->flags |= GimvImageWinSlideShowSeekBarDraggingFlag;
1766 
1767    return FALSE;
1768 }
1769 
1770 
1771 static gboolean
cb_seekbar_released(GtkWidget * widget,GdkEventButton * event,GimvImageWin * iw)1772 cb_seekbar_released (GtkWidget *widget,
1773                      GdkEventButton *event,
1774                      GimvImageWin *iw)
1775 {
1776    GtkAdjustment *adj;
1777    gint pos;
1778 
1779    g_return_val_if_fail (iw, FALSE);
1780 
1781    adj = gtk_range_get_adjustment (GTK_RANGE (iw->player.seekbar));
1782    pos = adj->value + 0.5;
1783 
1784    gimv_image_view_nth (iw->iv, pos);
1785 
1786    iw->priv->flags &= ~GimvImageWinSlideShowSeekBarDraggingFlag;
1787 
1788    return FALSE;
1789 }
1790 
1791 
1792 
1793 /******************************************************************************
1794  *
1795  *  other callback functions.
1796  *
1797  ******************************************************************************/
1798 static void
cb_image_changed(GimvImageView * iv,GimvImageWin * iw)1799 cb_image_changed (GimvImageView *iv, GimvImageWin *iw)
1800 {
1801    g_return_if_fail (iw);
1802 
1803    if (!(iw->priv->flags & GimvImageWinSlideShowSeekBarDraggingFlag)) {
1804       gint pos;
1805       GtkAdjustment *adj;
1806 
1807       pos = gimv_image_view_image_list_position (iv);
1808       adj = gtk_range_get_adjustment (GTK_RANGE (iw->player.seekbar));
1809       adj->value = pos;
1810       gtk_adjustment_changed (adj);
1811    }
1812 
1813    /* set statu bar */
1814    gimv_image_win_set_statusbar_info (iw);
1815    /* set title */
1816    gimv_image_win_set_window_title (iw);
1817 }
1818 
1819 
1820 static void
cb_load_start(GimvImageView * iv,GimvImageInfo * info,GimvImageWin * iw)1821 cb_load_start (GimvImageView *iv, GimvImageInfo *info, GimvImageWin *iw)
1822 {
1823    g_return_if_fail (iw);
1824 
1825    gimv_image_win_set_sensitive (iw, FALSE);
1826 }
1827 
1828 
1829 static void
cb_load_end(GimvImageView * iv,GimvImageInfo * info,gboolean cancel,GimvImageWin * iw)1830 cb_load_end (GimvImageView *iv,
1831              GimvImageInfo *info,
1832              gboolean cancel,
1833              GimvImageWin *iw)
1834 {
1835    g_return_if_fail (iw);
1836 
1837    gimv_image_win_set_sensitive (iw, TRUE);
1838 }
1839 
1840 
1841 static void
cb_set_list(GimvImageView * iv,GimvImageWin * iw)1842 cb_set_list (GimvImageView *iv, GimvImageWin *iw)
1843 {
1844    gint num, pos;
1845    GtkAdjustment *adj;
1846 
1847    g_return_if_fail (iw);
1848    g_return_if_fail (GIMV_IS_IMAGE_VIEW (iv));
1849 
1850    gtk_widget_set_sensitive (iw->button.prev, TRUE);
1851    gtk_widget_set_sensitive (iw->button.next, TRUE);
1852 
1853    /* player */
1854    gtk_widget_set_sensitive (iw->player.play,    TRUE);
1855    gtk_widget_set_sensitive (iw->player.stop,    FALSE);
1856    gtk_widget_set_sensitive (iw->player.rw,      TRUE);
1857    gtk_widget_set_sensitive (iw->player.fw,      TRUE);
1858    gtk_widget_set_sensitive (iw->player.prev,    TRUE);
1859    gtk_widget_set_sensitive (iw->player.next,    TRUE);
1860    gtk_widget_set_sensitive (iw->player.seekbar, TRUE);
1861 
1862    num = gimv_image_view_image_list_length (iv);
1863    pos = gimv_image_view_image_list_position (iv);
1864 
1865    adj = gtk_range_get_adjustment (GTK_RANGE (iw->player.seekbar));
1866 
1867    adj->lower          = 0.0;
1868    adj->upper          = num;
1869    adj->value          = pos;
1870    adj->step_increment = 1.0;
1871    adj->page_increment = 1.0;
1872    adj->page_size      = 1.0;
1873    gtk_adjustment_changed (adj);
1874 
1875    menu_item_set_sensitive (iw->move_menu, "/Next",     TRUE);
1876    menu_item_set_sensitive (iw->move_menu, "/Previous", TRUE);
1877    menu_item_set_sensitive (iw->move_menu, "/First",    TRUE);
1878    menu_item_set_sensitive (iw->move_menu, "/Last",     TRUE);
1879 }
1880 
1881 
1882 static void
cb_unset_list(GimvImageView * iv,GimvImageWin * iw)1883 cb_unset_list (GimvImageView *iv, GimvImageWin *iw)
1884 {
1885    GtkAdjustment *adj;
1886 
1887    g_return_if_fail (iw);
1888    g_return_if_fail (GIMV_IS_IMAGE_VIEW (iv));
1889 
1890    gtk_widget_set_sensitive (iw->button.prev, FALSE);
1891    gtk_widget_set_sensitive (iw->button.next, FALSE);
1892 
1893    /* player */
1894    gtk_widget_set_sensitive (iw->player.play,    FALSE);
1895    gtk_widget_set_sensitive (iw->player.stop,    FALSE);
1896    gtk_widget_set_sensitive (iw->player.rw,      FALSE);
1897    gtk_widget_set_sensitive (iw->player.fw,      FALSE);
1898    gtk_widget_set_sensitive (iw->player.prev,    FALSE);
1899    gtk_widget_set_sensitive (iw->player.next,    FALSE);
1900    gtk_widget_set_sensitive (iw->player.seekbar, FALSE);
1901 
1902    adj = gtk_range_get_adjustment (GTK_RANGE (iw->player.seekbar));
1903    adj->value = 0;
1904    gtk_adjustment_changed (adj);
1905 
1906    menu_item_set_sensitive (iw->move_menu, "/Next",     FALSE);
1907    menu_item_set_sensitive (iw->move_menu, "/Previous", FALSE);
1908    menu_item_set_sensitive (iw->move_menu, "/First",    FALSE);
1909    menu_item_set_sensitive (iw->move_menu, "/Last",     FALSE);
1910 }
1911 
1912 
1913 static void
cb_rendered(GimvImageView * iv,GimvImageWin * iw)1914 cb_rendered (GimvImageView *iv, GimvImageWin *iw)
1915 {
1916    gfloat x_scale, y_scale;
1917    GimvImageViewOrientation rotate;
1918    gint angle = 1;
1919 
1920    g_return_if_fail (iw);
1921    if (!g_list_find (ImageWinList, iw)) return;
1922 
1923    g_return_if_fail (iw->iv);
1924    if (!g_list_find (gimv_image_view_get_list(), iw->iv)) return;
1925 
1926    /* set statu bar */
1927    gimv_image_win_set_statusbar_info (iw);
1928 
1929    /* set title */
1930    gimv_image_win_set_window_title (iw);
1931 
1932    /* resize window */
1933    if (!(iw->priv->flags & GimvImageWinMaximizeFlag) && conf.imgwin_fit_to_image)
1934       gimv_image_win_set_win_size (iw);
1935 
1936    gtk_object_get (GTK_OBJECT (iw->iv),
1937                    "x_scale",     &x_scale,
1938                    "y_scale",     &y_scale,
1939                    "orientation", &rotate,
1940                    NULL);
1941 
1942    switch (rotate) {
1943    case GIMV_IMAGE_VIEW_ROTATE_0:
1944       angle = 1;
1945       break;
1946    case GIMV_IMAGE_VIEW_ROTATE_90:
1947       angle = 0;
1948       break;
1949    case GIMV_IMAGE_VIEW_ROTATE_180:
1950       angle = 3;
1951       break;
1952    case GIMV_IMAGE_VIEW_ROTATE_270:
1953       angle = 2;
1954       break;
1955    default:
1956       break;
1957    }
1958 
1959    if (iw->button.xscale)
1960       gtk_spin_button_set_value (GTK_SPIN_BUTTON (iw->button.xscale), x_scale);
1961    if (iw->button.yscale)
1962       gtk_spin_button_set_value (GTK_SPIN_BUTTON (iw->button.yscale), y_scale);
1963    if (iw->button.rotate)
1964       gtk_option_menu_set_history (GTK_OPTION_MENU (iw->button.rotate),
1965                                    angle);
1966 }
1967 
1968 
1969 static void
cb_toggle_aspect(GimvImageView * iv,gboolean keep_aspect,GimvImageWin * iw)1970 cb_toggle_aspect (GimvImageView *iv, gboolean keep_aspect, GimvImageWin *iw)
1971 {
1972    g_return_if_fail (iw);
1973 
1974    gtk_widget_set_sensitive (iw->button.yscale, !keep_aspect);
1975    if (keep_aspect)
1976       gtk_widget_hide (iw->button.yscale);
1977    else
1978       gtk_widget_show (iw->button.yscale);
1979 }
1980 
1981 
1982 static gboolean
cb_draw_area_key_press(GtkWidget * widget,GdkEventKey * event,GimvImageWin * iw)1983 cb_draw_area_key_press (GtkWidget *widget,
1984                         GdkEventKey *event,
1985                         GimvImageWin *iw)
1986 {
1987    g_return_val_if_fail (iw, FALSE);
1988 
1989    switch (event->keyval) {
1990    case GDK_Escape:
1991       if (iw->priv->flags & GimvImageWinMaximizeFlag) {
1992          menu_check_item_set_active (iw->view_menu, "/Maximize",
1993                                      !(iw->priv->flags & GimvImageWinMaximizeFlag));
1994       }
1995       return FALSE;
1996    default:
1997       break;
1998    }
1999 
2000    return FALSE;
2001 }
2002 
2003 
2004 static gint
gimv_image_view_button_action(GimvImageView * iv,GdkEventButton * event,gint num)2005 gimv_image_view_button_action (GimvImageView *iv, GdkEventButton *event, gint num)
2006 {
2007    gint mx, my;
2008 
2009    gimv_image_view_get_view_position (iv, &mx, &my);
2010 
2011    switch (abs (num)) {
2012    case MOUSE_PRESS_NEXT:
2013       gimv_image_view_next (iv);
2014       break;
2015    case MOUSE_PRESS_PREV:
2016       gimv_image_view_prev (iv);
2017       break;
2018    case MOUSE_PRESS_POPUP:
2019       gimv_image_view_popup_menu (iv, event);
2020       break;
2021    case MOUSE_PRESS_ZOOM_IN:
2022       gimv_image_view_zoom_image (iv, GIMV_IMAGE_VIEW_ZOOM_IN, 0, 0);
2023       break;
2024    case MOUSE_PRESS_ZOOM_OUT:
2025       gimv_image_view_zoom_image (iv, GIMV_IMAGE_VIEW_ZOOM_OUT, 0, 0);
2026       break;
2027    case MOUSE_PRESS_FIT:
2028       gimv_image_view_zoom_image (iv, GIMV_IMAGE_VIEW_ZOOM_FIT, 0, 0);
2029       break;
2030    case MOUSE_PRESS_ROTATE_CCW:
2031       gimv_image_view_rotate_ccw (iv);
2032       break;
2033    case MOUSE_PRESS_ROTATE_CW:
2034       gimv_image_view_rotate_cw (iv);
2035       break;
2036    case MOUSE_PRESS_NAVWIN:
2037       gimv_image_view_open_navwin (iv, event->x_root, event->y_root);
2038       break;
2039    case MOUSE_PRESS_UP:
2040       my += 20;
2041       gimv_image_view_moveto (iv, mx, my);
2042       break;
2043    case MOUSE_PRESS_DOWN:
2044       my -= 20;
2045       gimv_image_view_moveto (iv, mx, my);
2046       break;
2047    case MOUSE_PRESS_LEFT:
2048       mx += 20;
2049       gimv_image_view_moveto (iv, mx, my);
2050       break;
2051    case MOUSE_PRESS_RIGHT:
2052       mx -= 20;
2053       gimv_image_view_moveto (iv, mx, my);
2054       break;
2055    default:
2056       break;
2057    }
2058 
2059    return TRUE;
2060 }
2061 
2062 
2063 static gint
cb_imageview_pressed(GimvImageView * iv,GdkEventButton * event,GimvImageWin * iw)2064 cb_imageview_pressed (GimvImageView *iv, GdkEventButton *event, GimvImageWin *iw)
2065 {
2066    gint num;
2067 
2068    g_return_val_if_fail (iv, TRUE);
2069    g_return_val_if_fail (event, TRUE);
2070 
2071    num = prefs_mouse_get_num_from_event (event, conf.imgview_mouse_button);
2072    if (num > 0)
2073       return gimv_image_view_button_action (iv, event, num);
2074 
2075    return TRUE;
2076 }
2077 
2078 
2079 static gint
cb_imageview_clicked(GimvImageView * iv,GdkEventButton * event,GimvImageWin * iw)2080 cb_imageview_clicked (GimvImageView *iv, GdkEventButton *event, GimvImageWin *iw)
2081 {
2082    gint num;
2083 
2084    g_return_val_if_fail (iv, TRUE);
2085    g_return_val_if_fail (event, TRUE);
2086 
2087    num = prefs_mouse_get_num_from_event (event, conf.imgview_mouse_button);
2088    if (num < 0)
2089       return gimv_image_view_button_action (iv, event, num);
2090 
2091    return TRUE;
2092 }
2093 
2094 
2095 /******************************************************************************
2096  *
2097  *   fullscreen related functions.
2098  *
2099  ******************************************************************************/
2100 static void
show_cursor(GimvImageWin * iw)2101 show_cursor (GimvImageWin *iw)
2102 {
2103    GdkCursor *cursor;
2104 
2105    g_return_if_fail (iw);
2106    g_return_if_fail (iw->iv);
2107    g_return_if_fail (iw->iv->draw_area);
2108    g_return_if_fail (GTK_WIDGET_MAPPED (iw->iv->draw_area));
2109 
2110    cursor = cursor_get (iw->iv->draw_area->window,
2111                         CURSOR_HAND_OPEN);
2112    gdk_window_set_cursor (iw->iv->draw_area->window,
2113                           cursor);
2114    gdk_cursor_destroy (cursor);
2115 }
2116 
2117 
2118 static void
hide_cursor(GimvImageWin * iw)2119 hide_cursor (GimvImageWin *iw)
2120 {
2121    GdkCursor *cursor;
2122 
2123    g_return_if_fail (iw);
2124    g_return_if_fail (iw->iv);
2125    g_return_if_fail (iw->iv->draw_area);
2126    g_return_if_fail (GTK_WIDGET_MAPPED (iw->iv->draw_area));
2127 
2128    cursor = cursor_get (iw->iv->draw_area->window,
2129                         CURSOR_VOID);
2130    gdk_window_set_cursor (iw->iv->draw_area->window,
2131                           cursor);
2132    gdk_cursor_destroy (cursor);
2133 }
2134 
2135 
2136 static gint
timeout_hide_cursor(gpointer data)2137 timeout_hide_cursor (gpointer data)
2138 {
2139    GimvImageWin *iw = data;
2140 
2141    hide_cursor (iw);
2142    iw->priv->hide_cursor_timer_id = 0;
2143 
2144    return FALSE;
2145 }
2146 
2147 
2148 static gboolean
cb_fullscreen_key_press(GtkWidget * widget,GdkEventKey * event,GimvImageWin * iw)2149 cb_fullscreen_key_press (GtkWidget *widget,
2150                          GdkEventKey *event,
2151                          GimvImageWin *iw)
2152 {
2153    g_return_val_if_fail (iw, FALSE);
2154 
2155    switch (event->keyval) {
2156    case GDK_Escape:
2157       if (iw->priv->flags & GimvImageWinCreatingFlag) return TRUE;
2158       menu_check_item_set_active (iw->view_menu, "/Full Screen", FALSE);
2159       return TRUE;
2160    default:
2161       break;
2162    }
2163 
2164 #ifdef USE_GTK2
2165    gtk_accel_groups_activate (G_OBJECT (iw),
2166                               event->keyval, event->state);
2167 #else /* USE_GTK2 */
2168    gtk_accel_groups_activate (GTK_OBJECT (iw),
2169                               event->keyval, event->state);
2170 #endif /* USE_GTK2 */
2171 
2172    return TRUE;
2173 }
2174 
2175 
2176 static gboolean
cb_fullscreen_motion_notify(GtkWidget * widget,GdkEventButton * bevent,gpointer data)2177 cb_fullscreen_motion_notify (GtkWidget *widget,
2178                              GdkEventButton *bevent,
2179                              gpointer data)
2180 {
2181    GimvImageWin *iw = data;
2182 
2183    gdk_window_get_pointer (widget->window, NULL, NULL, NULL);
2184    show_cursor (iw);
2185 
2186    if (iw->priv->hide_cursor_timer_id != 0)
2187       gtk_timeout_remove (iw->priv->hide_cursor_timer_id);
2188    iw->priv->hide_cursor_timer_id
2189       = gtk_timeout_add (IMGWIN_FULLSCREEN_HIDE_CURSOR_DELAY,
2190                          timeout_hide_cursor,
2191                          iw);
2192 
2193    return FALSE;
2194 }
2195 
2196 
2197 static void
set_menu_sensitive(GimvImageWin * iw,gboolean sensitive)2198 set_menu_sensitive (GimvImageWin *iw, gboolean sensitive)
2199 {
2200    g_return_if_fail (iw);
2201 
2202    menu_item_set_sensitive (iw->menubar,   "/File/Open...",     sensitive);
2203    menu_item_set_sensitive (iw->menubar,   "/File/Open Image Window",
2204                             sensitive);
2205    menu_item_set_sensitive (iw->menubar,   "/File/Open Thumbnail Window",
2206                             sensitive);
2207    menu_item_set_sensitive (iw->menubar,   "/File/Quit",        sensitive);
2208    menu_item_set_sensitive (iw->menubar,   "/Edit/Options...",  sensitive);
2209    menu_item_set_sensitive (iw->view_menu, "/Menu Bar",         sensitive);
2210    menu_item_set_sensitive (iw->view_menu, "/Tool Bar",         sensitive);
2211    menu_item_set_sensitive (iw->view_menu, "/Slide Show Player",sensitive);
2212    menu_item_set_sensitive (iw->view_menu, "/Status Bar",       sensitive);
2213    menu_item_set_sensitive (iw->view_menu, "/Scroll Bar",       sensitive);
2214    menu_item_set_sensitive (iw->view_menu, "/Fit to Image",     sensitive);
2215    menu_item_set_sensitive (iw->view_menu, "/Maximize",         sensitive);
2216    gtk_widget_set_sensitive (iw->help_menu, sensitive);
2217 }
2218 
2219 
2220 void
gimv_image_win_fullscreen_show(GimvImageWin * iw)2221 gimv_image_win_fullscreen_show (GimvImageWin *iw)
2222 {
2223    g_return_if_fail (GIMV_IS_IMAGE_WIN (iw));
2224 
2225    if (iw->fullscreen) return;
2226 
2227    gtk_signal_emit (GTK_OBJECT(iw),
2228                     gimv_image_win_signals[SHOW_FULLSCREEN_SIGNAL]);
2229 }
2230 
2231 
2232 void
gimv_image_win_fullscreen_hide(GimvImageWin * iw)2233 gimv_image_win_fullscreen_hide (GimvImageWin *iw)
2234 {
2235    g_return_if_fail (GIMV_IS_IMAGE_WIN (iw));
2236 
2237    if (!iw->fullscreen) return;
2238 
2239    gtk_signal_emit (GTK_OBJECT(iw),
2240                     gimv_image_win_signals[HIDE_FULLSCREEN_SIGNAL]);
2241 }
2242 
2243 
2244 #if HAVE_X11_EXTENSIONS_XINERAMA_H
2245 #  include <X11/Xlib.h>
2246 #  include <X11/extensions/Xinerama.h>
2247 #  include <gdk/gdkx.h>
2248 #endif
2249 static gboolean
get_fullscreen_geometory(GimvImageWin * iw,GdkRectangle * area)2250 get_fullscreen_geometory (GimvImageWin *iw, GdkRectangle *area)
2251 {
2252    /*
2253    int width, height;
2254    int x, y;
2255    */
2256 #ifdef HAVE_X11_EXTENSIONS_XINERAMA_H
2257    Display *dpy;
2258    XineramaScreenInfo *xinerama;
2259    int i, count;
2260 #endif
2261 
2262    g_return_val_if_fail (area, FALSE);
2263 
2264    area->x = 0;
2265    area->y = 0;
2266    area->width = gdk_screen_width ();
2267    area->height = gdk_screen_height ();
2268 
2269 #ifdef HAVE_X11_EXTENSIONS_XINERAMA_H
2270    dpy = GDK_DISPLAY ();
2271    if (!XineramaIsActive (dpy)) return FALSE;
2272 
2273    xinerama = XineramaQueryScreens (dpy, &count);
2274    for (i = 0; i < count; i++) {
2275       if (area->x >= xinerama[i].x_org && area->y >= xinerama[i].y_org &&
2276           area->x < xinerama[i].x_org + xinerama[i].width &&
2277           area->y < xinerama[i].y_org + xinerama[i].height)
2278       {
2279          area->x = xinerama[i].x_org;
2280          area->y = xinerama[i].y_org;
2281          area->width = xinerama[i].width;
2282          area->height = xinerama[i].height;
2283          return TRUE;
2284       }
2285    }
2286 
2287    area->x = xinerama[0].x_org;
2288    area->y = xinerama[0].y_org;
2289    area->width = xinerama[0].width;
2290    area->height = xinerama[0].height;
2291 
2292    return TRUE;
2293 #else
2294    return FALSE;
2295 #endif
2296 }
2297 
2298 
2299 static void
gimv_image_win_real_show_fullscreen(GimvImageWin * iw)2300 gimv_image_win_real_show_fullscreen (GimvImageWin *iw)
2301 {
2302    GdkRectangle area;
2303    gboolean need_resize;
2304 
2305    g_return_if_fail (iw);
2306 
2307    iw->priv->flags |= GimvImageWinFullScreenFlag;
2308 
2309    /* create window */
2310    iw->fullscreen = gtk_window_new (GTK_WINDOW_POPUP);
2311 
2312    gtk_window_set_wmclass (GTK_WINDOW (iw->fullscreen), "",
2313                            "gimv_fullscreen");
2314    gtk_window_set_default_size (GTK_WINDOW (iw->fullscreen),
2315                                 gdk_screen_width (),
2316                                 gdk_screen_height ());
2317 
2318    gtk_signal_connect (GTK_OBJECT (iw->fullscreen),
2319                        "key_press_event",
2320                        (GtkSignalFunc) cb_fullscreen_key_press,
2321                        iw);
2322    gtk_signal_connect (GTK_OBJECT (iw->fullscreen),
2323                        "motion_notify_event",
2324                        (GtkSignalFunc) cb_fullscreen_motion_notify,
2325                        iw);
2326 
2327    /* set draw widget */
2328    if (iw->priv->fs_bg_color) {
2329       GtkStyle *style;
2330       GdkColor *color = g_new0 (GdkColor, 1);
2331 
2332       /* save current color */
2333       style = gtk_widget_get_style (iw->iv->draw_area);
2334       *color = style->bg[GTK_STATE_NORMAL];
2335       gtk_object_set_data_full (GTK_OBJECT (iw->fullscreen),
2336                                 "GimvImageWin::FullScreen::OrigColor",
2337                                 color,
2338                                 (GtkDestroyNotify) g_free);
2339 
2340       /* set bg color */
2341       gimv_image_view_set_bg_color (iw->iv,
2342                                     iw->priv->fs_bg_color->red,
2343                                     iw->priv->fs_bg_color->green,
2344                                     iw->priv->fs_bg_color->blue);
2345    }
2346 
2347    gtk_widget_show (iw->fullscreen);
2348 
2349    need_resize = get_fullscreen_geometory (iw, &area);
2350 
2351 #if (GTK_MAJOR_VERION >= 2) && (GTK_MINOR_VERSION >= 2)
2352    gdk_window_fullscreen (iw->fullscreen->window);
2353    if (need_resize) {
2354       gtk_window_move (iw->fullscreen, area.x, area.y);
2355       gtk_window_resize (GTK_WINDOW (iw->fullscreen),
2356                          area.width, area.height);
2357    }
2358 #else /* (GTK_MAJOR_VERION >= 2) && (GTK_MINOR_VERSION >= 2) */
2359    gtk_widget_set_uposition (iw->fullscreen, area.x, area.y);
2360    gtk_window_set_default_size (GTK_WINDOW (iw->fullscreen),
2361                                 area.width, area.height);
2362 #endif /* (GTK_MAJOR_VERION >= 2) && (GTK_MINOR_VERSION >= 2) */
2363 
2364    gimv_image_view_set_fullscreen (iw->iv, GTK_WINDOW (iw->fullscreen));
2365 
2366    set_menu_sensitive (iw, FALSE);
2367 
2368    gdk_keyboard_grab (iw->fullscreen->window, TRUE, GDK_CURRENT_TIME);
2369    gtk_grab_add (iw->fullscreen);
2370    gtk_widget_grab_focus (GTK_WIDGET (iw->iv));
2371 
2372    /* enable auto hide cursor stuff */
2373    iw->priv->hide_cursor_timer_id
2374       = gtk_timeout_add (IMGWIN_FULLSCREEN_HIDE_CURSOR_DELAY,
2375                          timeout_hide_cursor,
2376                          iw);
2377 }
2378 
2379 
2380 static void
gimv_image_win_real_hide_fullscreen(GimvImageWin * iw)2381 gimv_image_win_real_hide_fullscreen (GimvImageWin *iw)
2382 {
2383    GdkColor *color;
2384 
2385    g_return_if_fail (iw);
2386 
2387    /* restore draw widget */
2388    color = gtk_object_get_data (GTK_OBJECT (iw->fullscreen),
2389                                 "GimvImageWin::FullScreen::OrigColor");
2390    if (color)
2391       gimv_image_view_set_bg_color (iw->iv, color->red, color->green, color->blue);
2392 
2393    gimv_image_view_unset_fullscreen (iw->iv);
2394 
2395    gtk_widget_grab_focus (GTK_WIDGET (iw->iv));
2396 
2397    /* disable auto hide cursor stuff */
2398    if (iw->priv->hide_cursor_timer_id != 0)
2399       gtk_timeout_remove (iw->priv->hide_cursor_timer_id);
2400    show_cursor (iw);
2401 
2402    /* restore sensitivity */
2403    set_menu_sensitive (iw, TRUE);
2404 
2405    gtk_widget_destroy (iw->fullscreen);
2406    iw->fullscreen = NULL;
2407    iw->priv->flags &= ~GimvImageWinFullScreenFlag;
2408 }
2409 
2410 
2411 
2412 /******************************************************************************
2413  *
2414  *   public functions.
2415  *
2416  ******************************************************************************/
2417 GList *
gimv_image_win_get_list(void)2418 gimv_image_win_get_list (void)
2419 {
2420    return ImageWinList;
2421 }
2422 
2423 
2424 GimvImageWin *
gimv_image_win_get_shared_window(void)2425 gimv_image_win_get_shared_window (void)
2426 {
2427    return shared_img_win;
2428 }
2429 
2430 
2431 void
gimv_image_win_player_set_sensitive_all(GimvImageWin * iw,gboolean sensitive)2432 gimv_image_win_player_set_sensitive_all (GimvImageWin *iw, gboolean sensitive)
2433 {
2434    g_return_if_fail (iw);
2435 
2436    gtk_widget_set_sensitive (iw->player.prev,    sensitive);
2437    gtk_widget_set_sensitive (iw->player.rw,      sensitive);
2438    gtk_widget_set_sensitive (iw->player.play,    sensitive);
2439    gtk_widget_set_sensitive (iw->player.stop,    sensitive);
2440    gtk_widget_set_sensitive (iw->player.fw,      sensitive);
2441    gtk_widget_set_sensitive (iw->player.next,    sensitive);
2442    gtk_widget_set_sensitive (iw->player.seekbar, sensitive);
2443 }
2444 
2445 
2446 void
gimv_image_win_change_image(GimvImageWin * iw,GimvImageInfo * info)2447 gimv_image_win_change_image (GimvImageWin *iw, GimvImageInfo *info)
2448 {
2449    GList *node;
2450    gint default_zoom;
2451 
2452    g_return_if_fail (iw);
2453 
2454    node = g_list_find (ImageWinList, iw);
2455    if (!node) return;
2456 
2457    if (conf.imgwin_raise_window
2458        && GTK_WIDGET (iw)->window
2459        && !(iw->priv->flags & GimvImageWinFullScreenFlag))
2460    {
2461       gdk_window_raise (GTK_WIDGET (iw)->window);
2462       gdk_window_focus (GTK_WIDGET (iw)->window, GDK_CURRENT_TIME);
2463    }
2464 
2465    gimv_image_view_change_image (iw->iv, info);
2466 
2467    node = g_list_find (ImageWinList, iw);
2468    if (!node) return;
2469 
2470    /* If imgview_default_zoom is set to any of the "FIT" options
2471     * (i.e, the image is to be fit to the window in some form), and
2472     * imgwin_fit_to_image is set (i.e, the window is to be fit to the
2473     * image), we have a problem - what window size to use?  If we're
2474     * maximized or running in full screen mode, there's no problem,
2475     * othewise use the window size in the configuration options.
2476     * Not a great solution; maybe there should be a warning to
2477     * the user if both options are set together.
2478     */
2479 
2480    gtk_object_get (GTK_OBJECT (iw->iv),
2481                    "default_zoom", &default_zoom,
2482                    NULL);
2483    if ((default_zoom > 1) && conf.imgwin_fit_to_image
2484        && !(iw->priv->flags & GimvImageWinMaximizeFlag))
2485    {
2486       gdk_window_resize (GTK_WIDGET(iw)->window,
2487                          conf.imgwin_width,
2488                          conf.imgwin_height);
2489    }
2490 }
2491 
2492 
2493 void
gimv_image_win_set_sensitive(GimvImageWin * iw,gboolean sensitive)2494 gimv_image_win_set_sensitive (GimvImageWin *iw, gboolean sensitive)
2495 {
2496    g_return_if_fail (iw);
2497 
2498    gtk_widget_set_sensitive (iw->menubar, sensitive);
2499 }
2500 
2501 
2502 void
gimv_image_win_save_state(GimvImageWin * iw)2503 gimv_image_win_save_state (GimvImageWin *iw)
2504 {
2505    g_return_if_fail (GIMV_IS_IMAGE_WIN (iw));
2506 
2507    if (iw->priv->flags & GimvImageWinNotSaveStateFlag) return;
2508 
2509    if (!(iw->priv->flags & GimvImageWinMaximizeFlag)) {
2510       conf.imgwin_width  = GTK_WIDGET(iw)->allocation.width;
2511       conf.imgwin_height = GTK_WIDGET(iw)->allocation.height;
2512    } else {
2513       conf.imgwin_width  = iw->priv->win_width;
2514       conf.imgwin_height = iw->priv->win_height;
2515    }
2516 
2517    conf.imgwin_show_menubar    = iw->priv->flags & GimvImageWinShowMenuBarFlag;
2518    conf.imgwin_show_toolbar    = iw->priv->flags & GimvImageWinShowToolBarFlag;
2519    conf.imgwin_show_player     = iw->priv->flags & GimvImageWinShowPlayerFlag;
2520    conf.imgwin_show_statusbar  = iw->priv->flags & GimvImageWinShowStatusBarFlag;
2521    conf.imgview_player_visible = iw->priv->player_visible;
2522    gtk_object_get (GTK_OBJECT (iw->iv),
2523                    "show_scrollbar",   &conf.imgview_scrollbar,
2524                    "continuance_play", &conf.imgview_movie_continuance,
2525                    NULL);
2526 }
2527 
2528 
2529 GimvImageWin *
gimv_image_win_open_window(GimvImageInfo * info)2530 gimv_image_win_open_window (GimvImageInfo *info)
2531 {
2532    GimvImageWin *iw;
2533 
2534    iw = GIMV_IMAGE_WIN (gimv_image_win_new (info));
2535    gtk_widget_show (GTK_WIDGET (iw));
2536 
2537    return GIMV_IMAGE_WIN (iw);
2538 }
2539 
2540 
2541 GimvImageWin *
gimv_image_win_open_shared_window(GimvImageInfo * info)2542 gimv_image_win_open_shared_window (GimvImageInfo *info)
2543 {
2544    GimvImageWin *iw;
2545 
2546    if (shared_img_win) {
2547       iw = shared_img_win;
2548       gimv_image_win_change_image (iw, info);
2549    } else {
2550       iw = GIMV_IMAGE_WIN (gimv_image_win_new (info));
2551       shared_img_win = iw;
2552       gtk_widget_show (GTK_WIDGET (iw));
2553    }
2554 
2555    return iw;
2556 }
2557 
2558 
2559 GimvImageWin *
gimv_image_win_open_window_auto(GimvImageInfo * info)2560 gimv_image_win_open_window_auto (GimvImageInfo *info)
2561 {
2562    GimvImageWin *iw;
2563 
2564    if (conf.imgwin_open_new_win) {
2565       iw = gimv_image_win_open_window (info);
2566    } else {
2567       iw = gimv_image_win_open_shared_window (info);
2568    }
2569 
2570    return iw;
2571 }
2572 
2573 
2574 static gboolean
timeout_slideshow(GimvImageWin * iw)2575 timeout_slideshow (GimvImageWin *iw)
2576 {
2577    GList *current;
2578    GimvImageViewPlayableStatus status;
2579 
2580    current = gimv_image_view_image_list_current (iw->iv);
2581 
2582    if ((current
2583         && !g_list_next (current)
2584         && !(iw->priv->flags & GimvImageWinSlideShowRepeatFlag))
2585        || !(iw->priv->flags & GimvImageWinSlideShowPlayingFlag))
2586    {
2587       gimv_image_win_slideshow_stop (iw);
2588       return FALSE;
2589    }
2590 
2591    // Movies, in contrast to pictues, should not be interrupted during slideshows.
2592    status = gimv_image_view_playable_get_status(iw->iv);
2593    if (status != GimvImageViewPlayableDisable &&
2594        status != GimvImageViewPlayableStop)
2595    {
2596       return TRUE;
2597    }
2598 
2599    gimv_image_view_next (iw->iv);
2600 
2601    return TRUE;
2602 }
2603 
2604 
2605 void
gimv_image_win_slideshow_play(GimvImageWin * iw)2606 gimv_image_win_slideshow_play (GimvImageWin *iw)
2607 {
2608    g_return_if_fail (iw);
2609 
2610    if (iw->priv->slideshow_interval > 0) {
2611       iw->priv->flags |= GimvImageWinSlideShowPlayingFlag;
2612       iw->priv->slideshow_timer_id
2613          = gtk_timeout_add (iw->priv->slideshow_interval,
2614                             (GtkFunction) timeout_slideshow, iw);
2615    }
2616 
2617    gtk_widget_set_sensitive (iw->player.play, FALSE);
2618    gtk_widget_set_sensitive (iw->player.stop, TRUE);
2619 }
2620 
2621 
2622 void
gimv_image_win_slideshow_stop(GimvImageWin * iw)2623 gimv_image_win_slideshow_stop (GimvImageWin *iw)
2624 {
2625    g_return_if_fail (iw);
2626 
2627    if (!(iw->priv->flags & GimvImageWinSlideShowPlayingFlag)) return;
2628 
2629    iw->priv->flags &= ~GimvImageWinSlideShowPlayingFlag;
2630 
2631    if (iw->priv->slideshow_timer_id)
2632       gtk_timeout_remove (iw->priv->slideshow_timer_id);
2633    iw->priv->slideshow_timer_id = 0;
2634 
2635    gtk_widget_set_sensitive (iw->player.play, TRUE);
2636    gtk_widget_set_sensitive (iw->player.stop, FALSE);
2637 }
2638 
2639 
2640 void
gimv_image_win_slideshow_set_interval(GimvImageWin * iw,guint interval)2641 gimv_image_win_slideshow_set_interval (GimvImageWin *iw, guint interval)
2642 {
2643    g_return_if_fail (iw);
2644 
2645    iw->priv->slideshow_interval = interval;
2646    if (iw->priv->flags & GimvImageWinSlideShowPlayingFlag) {
2647       gimv_image_win_slideshow_stop (iw);
2648       gimv_image_win_slideshow_play (iw);
2649    }
2650 }
2651 
2652 
2653 void
gimv_image_win_slideshow_set_repeat(GimvImageWin * iw,gboolean repeat)2654 gimv_image_win_slideshow_set_repeat (GimvImageWin *iw, gboolean repeat)
2655 {
2656    g_return_if_fail (iw);
2657 
2658    if (repeat)
2659       iw->priv->flags |= GimvImageWinSlideShowRepeatFlag;
2660    else
2661       iw->priv->flags &= ~GimvImageWinSlideShowRepeatFlag;
2662 }
2663 
2664 
2665 void
gimv_image_win_show_menubar(GimvImageWin * iw,gboolean show)2666 gimv_image_win_show_menubar (GimvImageWin *iw, gboolean show)
2667 {
2668    g_return_if_fail (GIMV_IS_IMAGE_WIN (iw));
2669    menu_check_item_set_active (iw->view_menu, "/Menu Bar", show);
2670 }
2671 
2672 
2673 void
gimv_image_win_show_toolbar(GimvImageWin * iw,gboolean show)2674 gimv_image_win_show_toolbar (GimvImageWin *iw, gboolean show)
2675 {
2676    g_return_if_fail (GIMV_IS_IMAGE_WIN (iw));
2677    menu_check_item_set_active (iw->view_menu, "/Tool Bar", show);
2678 }
2679 
2680 
2681 void
gimv_image_win_show_player(GimvImageWin * iw,gboolean show)2682 gimv_image_win_show_player (GimvImageWin *iw, gboolean show)
2683 {
2684    g_return_if_fail (GIMV_IS_IMAGE_WIN (iw));
2685    menu_check_item_set_active (iw->view_menu, "/Slide Show Player", show);
2686 }
2687 
2688 
2689 void
gimv_image_win_show_statusbar(GimvImageWin * iw,gboolean show)2690 gimv_image_win_show_statusbar (GimvImageWin *iw, gboolean show)
2691 {
2692    g_return_if_fail (GIMV_IS_IMAGE_WIN (iw));
2693    menu_check_item_set_active (iw->view_menu, "/Status Bar", show);
2694 }
2695 
2696 
2697 void
gimv_image_win_set_maximize(GimvImageWin * iw,gboolean show)2698 gimv_image_win_set_maximize (GimvImageWin *iw, gboolean show)
2699 {
2700    g_return_if_fail (GIMV_IS_IMAGE_WIN (iw));
2701    menu_check_item_set_active (iw->view_menu, "/Maximize", show);
2702 }
2703 
2704 
2705 void
gimv_image_win_set_fullscreen(GimvImageWin * iw,gboolean show)2706 gimv_image_win_set_fullscreen (GimvImageWin *iw, gboolean show)
2707 {
2708    g_return_if_fail (GIMV_IS_IMAGE_WIN (iw));
2709    menu_check_item_set_active (iw->view_menu, "/Full Screen", show);
2710 }
2711 
2712 
2713 void
gimv_image_win_set_fullscreen_bg_color(GimvImageWin * iw,gint red,gint green,gint blue)2714 gimv_image_win_set_fullscreen_bg_color (GimvImageWin *iw,
2715                                         gint red, gint green, gint blue)
2716 {
2717    g_return_if_fail (GIMV_IS_IMAGE_WIN (iw));
2718 
2719    if (!iw->priv->fs_bg_color)
2720       iw->priv->fs_bg_color = g_new0 (GdkColor, 1);
2721 
2722    iw->priv->fs_bg_color->red   = red;
2723    iw->priv->fs_bg_color->green = green;
2724    iw->priv->fs_bg_color->blue  = blue;
2725 }
2726 
2727 
2728 void
gimv_image_win_set_flags(GimvImageWin * iw,GimvImageWinFlags flags)2729 gimv_image_win_set_flags (GimvImageWin  *iw, GimvImageWinFlags flags)
2730 {
2731    g_return_if_fail (GIMV_IS_IMAGE_WIN (iw));
2732    iw->priv->flags |= flags;
2733 }
2734 
2735 
2736 void
gimv_image_win_unset_flags(GimvImageWin * iw,GimvImageWinFlags flags)2737 gimv_image_win_unset_flags (GimvImageWin  *iw, GimvImageWinFlags flags)
2738 {
2739    g_return_if_fail (GIMV_IS_IMAGE_WIN (iw));
2740    iw->priv->flags &= ~flags;
2741 }
2742 
2743