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_nav_win.c,v 1.4 2004/03/07 11:53:31 makeinu Exp $
22  */
23 
24 /*
25  * These codes are mostly taken from gThumb.
26  * gThumb code Copyright (C) 2001 The Free Software Foundation, Inc.
27  * gThumb author: Paolo Bacchilega
28  */
29 
30 #include <math.h>
31 
32 #include "gimageview.h"
33 
34 #include "gimv_nav_win.h"
35 #include "gtk2-compat.h"
36 
37 
38 #define PEN_WIDTH         3       /* Square border width. */
39 #define BORDER_WIDTH      4       /* Window border width. */
40 
41 
42 enum {
43    MOVE_SIGNAL,
44    LAST_SIGNAL
45 };
46 
47 
48 static GtkWindowClass *parent_class = NULL;
49 static gint gimv_nav_win_signals[LAST_SIGNAL] = {0};
50 
51 
52 /* object class */
53 static void     gimv_nav_win_class_init     (GimvNavWinClass *klass);
54 static void     gimv_nav_win_init           (GimvNavWin      *navwin);
55 static void     gimv_nav_win_destroy        (GtkObject       *object);
56 
57 /* widget class */
58 static void     gimv_nav_win_realize        (GtkWidget       *widget);
59 static void     gimv_nav_win_unrealize      (GtkWidget       *widget);
60 static gboolean gimv_nav_win_expose         (GtkWidget       *widget,
61                                              GdkEventExpose  *event);
62 static gboolean gimv_nav_win_key_press      (GtkWidget       *widget,
63                                              GdkEventKey     *event);
64 static gboolean gimv_nav_win_button_release (GtkWidget       *widget,
65                                              GdkEventButton  *event);
66 static gboolean gimv_nav_win_motion_notify  (GtkWidget       *widget,
67                                              GdkEventMotion  *event);
68 /* nav_win class */
69 static void      navwin_draw_sqr            (GimvNavWin      *navwin,
70                                              gboolean         undraw,
71                                              gint             x,
72                                              gint             y);
73 static void      get_sqr_origin_as_double   (GimvNavWin      *navwin,
74                                              gint             mx,
75                                              gint             my,
76                                              gdouble         *x,
77                                              gdouble         *y);
78 static void      navwin_update_view         (GimvNavWin      *navwin);
79 static void      navwin_draw                (GimvNavWin      *navwin);
80 static void      navwin_grab_pointer        (GimvNavWin      *navwin);
81 static void      navwin_set_win_pos_size    (GimvNavWin *navwin);
82 
83 
84 GtkType
gimv_nav_win_get_type(void)85 gimv_nav_win_get_type (void)
86 {
87    static GtkType gimv_nav_win_type = 0;
88 
89    if (!gimv_nav_win_type) {
90       static const GtkTypeInfo gimv_nav_win_info = {
91          "GimvNavWin",
92          sizeof (GimvNavWin),
93          sizeof (GimvNavWinClass),
94          (GtkClassInitFunc) gimv_nav_win_class_init,
95          (GtkObjectInitFunc) gimv_nav_win_init,
96          NULL,
97          NULL,
98          (GtkClassInitFunc) NULL,
99       };
100 
101       gimv_nav_win_type = gtk_type_unique (GTK_TYPE_WINDOW,
102                                            &gimv_nav_win_info);
103    }
104 
105    return gimv_nav_win_type;
106 }
107 
108 
109 static void
gimv_nav_win_class_init(GimvNavWinClass * klass)110 gimv_nav_win_class_init (GimvNavWinClass *klass)
111 {
112    GtkObjectClass *object_class;
113    GtkWidgetClass *widget_class;
114 
115    object_class = (GtkObjectClass *) klass;
116    widget_class = (GtkWidgetClass *) klass;
117    parent_class = gtk_type_class (GTK_TYPE_WINDOW);
118 
119    object_class->destroy = gimv_nav_win_destroy;
120 
121    widget_class->realize              = gimv_nav_win_realize;
122    widget_class->unrealize            = gimv_nav_win_unrealize;
123    widget_class->expose_event         = gimv_nav_win_expose;
124    widget_class->key_press_event      = gimv_nav_win_key_press;
125    widget_class->button_release_event = gimv_nav_win_button_release;
126    widget_class->motion_notify_event  = gimv_nav_win_motion_notify;
127 
128    gimv_nav_win_signals[MOVE_SIGNAL]
129       = gtk_signal_new ("move",
130                         GTK_RUN_FIRST,
131                         GTK_CLASS_TYPE(object_class),
132                         GTK_SIGNAL_OFFSET (GimvNavWinClass, move),
133                         gtk_marshal_NONE__INT_INT,
134                         GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
135 
136    gtk_object_class_add_signals (object_class,
137                                  gimv_nav_win_signals,
138                                  LAST_SIGNAL);
139 }
140 
141 
142 static void
gimv_nav_win_init(GimvNavWin * navwin)143 gimv_nav_win_init (GimvNavWin *navwin)
144 {
145    navwin->fix_x_pos = navwin->fix_x_pos = 1;
146 
147    navwin->gc           = NULL;
148    navwin->pixmap       = NULL;
149    navwin->mask         = NULL;
150 
151    navwin->out_frame = gtk_frame_new (NULL);
152    gtk_frame_set_shadow_type (GTK_FRAME (navwin->out_frame), GTK_SHADOW_OUT);
153    gtk_container_add (GTK_CONTAINER (navwin), navwin->out_frame);
154    gtk_widget_show (navwin->out_frame);
155 
156    navwin->in_frame = gtk_frame_new (NULL);
157    gtk_frame_set_shadow_type (GTK_FRAME (navwin->in_frame), GTK_SHADOW_IN);
158    gtk_container_add (GTK_CONTAINER (navwin->out_frame), navwin->in_frame);
159    gtk_widget_show (navwin->in_frame);
160 
161    navwin->preview = gtk_drawing_area_new ();
162    gtk_container_add (GTK_CONTAINER (navwin->in_frame), navwin->preview);
163    gtk_widget_show (navwin->preview);
164 }
165 
166 
167 static void
gimv_nav_win_destroy(GtkObject * object)168 gimv_nav_win_destroy (GtkObject *object)
169 {
170    GimvNavWin *navwin = GIMV_NAV_WIN (object);
171 
172    if (navwin->pixmap)
173       gdk_pixmap_unref (navwin->pixmap);
174    navwin->pixmap = NULL;
175 
176    if (GTK_OBJECT_CLASS (parent_class)->destroy)
177       GTK_OBJECT_CLASS (parent_class)->destroy (object);
178 }
179 
180 
181 static void
gimv_nav_win_realize(GtkWidget * widget)182 gimv_nav_win_realize (GtkWidget *widget)
183 {
184    GimvNavWin *navwin;
185 
186    g_return_if_fail (GIMV_IS_NAV_WIN (widget));
187 
188    navwin = GIMV_NAV_WIN (widget);
189 
190    if (GTK_WIDGET_CLASS (parent_class)->realize)
191       GTK_WIDGET_CLASS (parent_class)->realize (widget);
192 
193    if (!navwin->gc) {
194       navwin->gc = gdk_gc_new (widget->window);
195       gdk_gc_set_function (navwin->gc, GDK_INVERT);
196       gdk_gc_set_line_attributes (navwin->gc,
197                                   PEN_WIDTH,
198                                   GDK_LINE_SOLID,
199                                   GDK_CAP_BUTT,
200                                   GDK_JOIN_MITER);
201    }
202 }
203 
204 
205 static void
gimv_nav_win_unrealize(GtkWidget * widget)206 gimv_nav_win_unrealize (GtkWidget *widget)
207 {
208    GimvNavWin *navwin;
209 
210    g_return_if_fail (GIMV_IS_NAV_WIN (widget));
211 
212    navwin = GIMV_NAV_WIN (widget);
213 
214    if (navwin->gc)
215       gdk_gc_destroy (navwin->gc);
216    navwin->gc = NULL;
217 
218    if (GTK_WIDGET_CLASS (parent_class)->unrealize)
219       GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
220 }
221 
222 
223 static gboolean
gimv_nav_win_expose(GtkWidget * widget,GdkEventExpose * event)224 gimv_nav_win_expose (GtkWidget *widget,
225                      GdkEventExpose *event)
226 {
227    GimvNavWin *navwin;
228 
229    g_return_val_if_fail (GIMV_IS_NAV_WIN (widget), FALSE);
230 
231    navwin = GIMV_NAV_WIN (widget);
232 
233    navwin_draw (navwin);
234 
235    if(gtk_grab_get_current() != GTK_WIDGET (navwin))
236       navwin_grab_pointer(navwin);
237 
238    if (GTK_WIDGET_CLASS (parent_class)->expose_event)
239       return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
240 
241    return FALSE;
242 }
243 
244 
245 static gboolean
gimv_nav_win_key_press(GtkWidget * widget,GdkEventKey * event)246 gimv_nav_win_key_press (GtkWidget *widget,
247                         GdkEventKey *event)
248 {
249    GimvNavWin *navwin;
250    gboolean move = FALSE;
251    gint mx, my;
252    guint keyval;
253    GdkModifierType modval;
254 
255    g_return_val_if_fail (GIMV_IS_NAV_WIN (widget), FALSE);
256 
257    navwin = GIMV_NAV_WIN (widget);
258 
259    mx = navwin->view_pos_x;
260    my = navwin->view_pos_y;
261 
262    keyval = event->keyval;
263    modval = event->state;
264 
265    if (keyval == GDK_Left) {
266       mx -= 10;
267       move = TRUE;
268    } else if (keyval == GDK_Right) {
269       mx += 10;
270       move = TRUE;
271    } else if (keyval == GDK_Up) {
272       my -= 10;
273       move = TRUE;
274    } else if (keyval == GDK_Down) {
275       my += 10;
276       move = TRUE;
277    }
278 
279    if (move) {
280       if (navwin->fix_x_pos < 0) mx = navwin->fix_x_pos;
281       if (navwin->fix_y_pos < 0) my = navwin->fix_y_pos;
282       navwin->view_pos_x = mx;
283       navwin->view_pos_y = my;
284       gtk_signal_emit (GTK_OBJECT (navwin),
285                        gimv_nav_win_signals[MOVE_SIGNAL],
286                        mx, my);
287       mx *= navwin->factor;
288       my *= navwin->factor;
289       navwin_draw_sqr (navwin, TRUE, mx, my);
290    }
291 
292    if (GTK_WIDGET_CLASS (parent_class)->key_press_event)
293       return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
294 
295    return FALSE;
296 }
297 
298 
299 static gboolean
gimv_nav_win_button_release(GtkWidget * widget,GdkEventButton * event)300 gimv_nav_win_button_release  (GtkWidget *widget,
301                               GdkEventButton *event)
302 {
303    GimvNavWin *navwin;
304 
305    g_return_val_if_fail (GIMV_IS_NAV_WIN (widget), FALSE);
306 
307    navwin = GIMV_NAV_WIN (widget);
308 
309    switch (event->button) {
310    case 1:
311       gtk_signal_emit_stop_by_name (GTK_OBJECT (widget),
312                                     "button_release_event");
313       gimv_nav_win_hide (navwin);
314       /* gtk_widget_destroy (GTK_WIDGET (navwin)); */
315       return TRUE;
316       break;
317    default:
318       break;
319    }
320 
321    if (GTK_WIDGET_CLASS (parent_class)->button_release_event)
322       return GTK_WIDGET_CLASS (parent_class)->button_release_event (widget, event);
323 
324    return FALSE;
325 }
326 
327 
328 static gboolean
gimv_nav_win_motion_notify(GtkWidget * widget,GdkEventMotion * event)329 gimv_nav_win_motion_notify (GtkWidget *widget,
330                             GdkEventMotion *event)
331 {
332    GimvNavWin *navwin;
333    GdkModifierType mask;
334    gint mx, my;
335    gdouble x, y;
336 
337    g_return_val_if_fail (GIMV_IS_NAV_WIN (widget), FALSE);
338 
339    navwin = GIMV_NAV_WIN (widget);
340 
341    gdk_window_get_pointer (widget->window, &mx, &my, &mask);
342    get_sqr_origin_as_double (navwin, mx, my, &x, &y);
343 
344    mx = (gint) x;
345    my = (gint) y;
346    navwin_draw_sqr (navwin, TRUE, mx, my);
347 
348    mx = (gint) (x / navwin->factor);
349    my = (gint) (y / navwin->factor);
350    if (navwin->fix_x_pos < 0) mx = navwin->fix_x_pos;
351    if (navwin->fix_y_pos < 0) my = navwin->fix_y_pos;
352 
353    gtk_signal_emit (GTK_OBJECT (navwin),
354                     gimv_nav_win_signals[MOVE_SIGNAL],
355                     mx, my);
356 
357    if (GTK_WIDGET_CLASS (parent_class)->motion_notify_event)
358       return GTK_WIDGET_CLASS (parent_class)->motion_notify_event (widget, event);
359 
360    return FALSE;
361 }
362 
363 
364 GtkWidget *
gimv_nav_win_new(GdkPixmap * pixmap,GdkBitmap * mask,gint image_width,gint image_height,gint view_width,gint view_height,gint fpos_x,gint fpos_y)365 gimv_nav_win_new (GdkPixmap *pixmap, GdkBitmap *mask,
366                   gint image_width, gint image_height,
367                   gint view_width, gint view_height,
368                   gint fpos_x, gint fpos_y)
369 {
370    GimvNavWin *navwin;
371 
372    g_return_val_if_fail (pixmap, NULL);
373 
374    navwin = GIMV_NAV_WIN (gtk_object_new (GIMV_TYPE_NAV_WIN,
375                                           "type", GTK_WINDOW_POPUP,
376                                           NULL));
377 
378    navwin->pixmap = gdk_pixmap_ref (pixmap);
379    if (mask) navwin->mask = gdk_bitmap_ref (mask);
380 
381    navwin->x_root = 0;
382    navwin->y_root = 0;
383 
384    navwin->image_width  = image_width;
385    navwin->image_height = image_height;
386 
387    navwin->view_width   = view_width;
388    navwin->view_height  = view_height;
389    navwin->view_pos_x   = fpos_x;
390    navwin->view_pos_y   = fpos_y;
391 
392    navwin_update_view (navwin);
393 
394    return GTK_WIDGET (navwin);
395 }
396 
397 
398 void
gimv_nav_win_show(GimvNavWin * navwin,gint x_root,gint y_root)399 gimv_nav_win_show (GimvNavWin *navwin, gint x_root, gint y_root)
400 {
401    g_return_if_fail (GIMV_IS_NAV_WIN (navwin));
402 
403    navwin->x_root = x_root;
404    navwin->y_root = y_root;
405 
406    navwin_update_view (navwin);
407    navwin_set_win_pos_size (navwin);
408 
409    gtk_widget_show (GTK_WIDGET (navwin));
410    navwin_grab_pointer (navwin);
411 }
412 
413 
414 void
gimv_nav_win_hide(GimvNavWin * navwin)415 gimv_nav_win_hide (GimvNavWin *navwin)
416 {
417    g_return_if_fail (GIMV_IS_NAV_WIN (navwin));
418 
419    gdk_keyboard_ungrab (GDK_CURRENT_TIME);
420    gtk_grab_remove (GTK_WIDGET (navwin));
421 
422    gtk_widget_hide (GTK_WIDGET (navwin));
423 }
424 
425 
426 void
gimv_nav_win_set_pixmap(GimvNavWin * navwin,GdkPixmap * pixmap,GdkBitmap * mask,gint image_width,gint image_height)427 gimv_nav_win_set_pixmap (GimvNavWin *navwin,
428                          GdkPixmap *pixmap, GdkBitmap *mask,
429                          gint image_width, gint image_height)
430 {
431    g_return_if_fail (GIMV_IS_NAV_WIN (navwin));
432    g_return_if_fail (pixmap);
433 
434    if (navwin->pixmap)
435       gdk_pixmap_unref (navwin->pixmap);
436    navwin->pixmap = NULL;
437    navwin->mask   = NULL;
438 
439    navwin->pixmap = gdk_pixmap_ref (pixmap);
440    if (mask) navwin->mask = gdk_bitmap_ref (mask);
441 
442    navwin->image_width  = image_width;
443    navwin->image_height = image_height;
444 
445    if (GTK_WIDGET_MAPPED (navwin)) {
446       navwin_update_view (navwin);
447       navwin_set_win_pos_size (navwin);
448       navwin_draw (navwin);
449    }
450 }
451 
452 
453 void
gimv_nav_win_set_orig_image_size(GimvNavWin * navwin,gint width,gint height)454 gimv_nav_win_set_orig_image_size (GimvNavWin *navwin,
455                                   gint width, gint height)
456 {
457    g_return_if_fail (GIMV_IS_NAV_WIN (navwin));
458 
459    navwin->image_width  = width;
460    navwin->image_height = height;
461 
462    if (GTK_WIDGET_MAPPED (navwin)) {
463       navwin_update_view (navwin);
464       navwin_draw (navwin);
465    }
466 }
467 
468 
469 void
gimv_nav_win_set_view_size(GimvNavWin * navwin,gint width,gint height)470 gimv_nav_win_set_view_size (GimvNavWin *navwin,
471                             gint width, gint height)
472 {
473    g_return_if_fail (GIMV_IS_NAV_WIN (navwin));
474 
475    navwin->view_width  = width;
476    navwin->view_height = height;
477 
478    if (GTK_WIDGET_MAPPED (navwin)) {
479       navwin_update_view (navwin);
480       navwin_draw (navwin);
481    }
482 }
483 
484 
485 void
gimv_nav_win_set_view_position(GimvNavWin * navwin,gint x,gint y)486 gimv_nav_win_set_view_position (GimvNavWin *navwin,
487                                 gint x, gint y)
488 {
489    g_return_if_fail (GIMV_IS_NAV_WIN (navwin));
490 
491    navwin->view_pos_x = x;
492    navwin->view_pos_y = y;
493 
494    if (GTK_WIDGET_MAPPED (navwin)) {
495       navwin_update_view (navwin);
496       navwin_draw (navwin);
497    }
498 }
499 
500 
501 
502 /******************************************************************************
503  *
504  *   Private functions.
505  *
506  ******************************************************************************/
507 static void
navwin_draw_sqr(GimvNavWin * navwin,gboolean undraw,gint x,gint y)508 navwin_draw_sqr (GimvNavWin *navwin,
509                  gboolean undraw,
510                  gint x,
511                  gint y)
512 {
513    if ((navwin->sqr_x == x) && (navwin->sqr_y == y) && undraw)
514       return;
515 
516    if ((navwin->sqr_x == 0)
517        && (navwin->sqr_y == 0)
518        && (navwin->sqr_width == navwin->popup_width)
519        && (navwin->sqr_height == navwin->popup_height))
520       return;
521 
522    if (undraw) {
523       gdk_draw_rectangle (navwin->preview->window,
524                           navwin->gc, FALSE,
525                           navwin->sqr_x + 1,
526                           navwin->sqr_y + 1,
527                           navwin->sqr_width - PEN_WIDTH,
528                           navwin->sqr_height - PEN_WIDTH);
529    }
530 
531    gdk_draw_rectangle (navwin->preview->window,
532                        navwin->gc, FALSE,
533                        x + 1,
534                        y + 1,
535                        navwin->sqr_width - PEN_WIDTH,
536                        navwin->sqr_height - PEN_WIDTH);
537 
538    navwin->sqr_x = x;
539    navwin->sqr_y = y;
540 }
541 
542 
543 static void
get_sqr_origin_as_double(GimvNavWin * navwin,gint mx,gint my,gdouble * x,gdouble * y)544 get_sqr_origin_as_double (GimvNavWin *navwin,
545                           gint mx,
546                           gint my,
547                           gdouble *x,
548                           gdouble *y)
549 {
550    *x = MIN (mx - BORDER_WIDTH, GIMV_NAV_WIN_SIZE);
551    *y = MIN (my - BORDER_WIDTH, GIMV_NAV_WIN_SIZE);
552 
553    if (*x - navwin->sqr_width / 2.0 < 0.0)
554       *x = navwin->sqr_width / 2.0;
555 
556    if (*y - navwin->sqr_height / 2.0 < 0.0)
557       *y = navwin->sqr_height / 2.0;
558 
559    if (*x + navwin->sqr_width / 2.0 > navwin->popup_width - 0)
560       *x = navwin->popup_width - 0 - navwin->sqr_width / 2.0;
561 
562    if (*y + navwin->sqr_height / 2.0 > navwin->popup_height - 0)
563       *y = navwin->popup_height - 0 - navwin->sqr_height / 2.0;
564 
565    *x = *x - navwin->sqr_width / 2.0;
566    *y = *y - navwin->sqr_height / 2.0;
567 }
568 
569 
570 static void
navwin_update_view(GimvNavWin * navwin)571 navwin_update_view (GimvNavWin *navwin)
572 {
573    gint popup_x, popup_y;
574    gint popup_width, popup_height;
575    gint w, h, x_pos, y_pos;
576    gdouble factor;
577 
578    w = navwin->image_width;
579    h = navwin->image_height;
580 
581    factor = MIN ((gdouble) (GIMV_NAV_WIN_SIZE) / w,
582                  (gdouble) (GIMV_NAV_WIN_SIZE) / h);
583    navwin->factor = factor;
584 
585    /* Popup window size. */
586    popup_width  = MAX ((gint) floor (factor * w + 0.5), 1);
587    popup_height = MAX ((gint) floor (factor * h + 0.5), 1);
588 
589    gtk_drawing_area_size (GTK_DRAWING_AREA (navwin->preview),
590                           popup_width,
591                           popup_height);
592 
593    /* The square. */
594    x_pos = navwin->view_pos_x;
595    y_pos = navwin->view_pos_y;
596 
597    navwin->sqr_width = navwin->view_width * factor;
598    navwin->sqr_width = MAX (navwin->sqr_width, BORDER_WIDTH);
599    navwin->sqr_width = MIN (navwin->sqr_width, popup_width);
600 
601    navwin->sqr_height = navwin->view_height * factor;
602    navwin->sqr_height = MAX (navwin->sqr_height, BORDER_WIDTH);
603    navwin->sqr_height = MIN (navwin->sqr_height, popup_height);
604 
605    navwin->sqr_x = x_pos * factor;
606    if (navwin->sqr_x < 0) navwin->sqr_x = 0;
607    navwin->sqr_y = y_pos * factor;
608    if (navwin->sqr_y < 0) navwin->sqr_y = 0;
609 
610    /* fix x (or y) if image is smaller than frame */
611    if (navwin->view_width  > navwin->image_width)
612       navwin->fix_x_pos = x_pos;
613    else
614       navwin->fix_x_pos = 1;
615    if (navwin->view_height > navwin->image_height)
616       navwin->fix_y_pos = y_pos;
617    else
618       navwin->fix_y_pos = 1;
619 
620    /* Popup window position. */
621    popup_x = MIN (navwin->x_root - navwin->sqr_x
622                   - BORDER_WIDTH
623                   - navwin->sqr_width / 2,
624                   gdk_screen_width () - popup_width - BORDER_WIDTH * 2);
625    popup_y = MIN (navwin->y_root - navwin->sqr_y
626                   - BORDER_WIDTH
627                   - navwin->sqr_height / 2,
628                   gdk_screen_height () - popup_height - BORDER_WIDTH * 2);
629 
630    navwin->popup_x      = popup_x;
631    navwin->popup_y      = popup_y;
632    navwin->popup_width  = popup_width;
633    navwin->popup_height = popup_height;
634 
635    navwin->view_pos_x   = x_pos;
636    navwin->view_pos_y   = y_pos;
637 
638    gtk_widget_draw (navwin->preview, NULL);
639 }
640 
641 
642 static void
navwin_grab_pointer(GimvNavWin * navwin)643 navwin_grab_pointer (GimvNavWin *navwin)
644 {
645    GdkCursor *cursor;
646 
647    gtk_grab_add (GTK_WIDGET (navwin));
648 
649    cursor = gdk_cursor_new (GDK_CROSSHAIR);
650 
651    gdk_pointer_grab (GTK_WIDGET (navwin)->window, TRUE,
652                      GDK_BUTTON_RELEASE_MASK |
653                      GDK_POINTER_MOTION_HINT_MASK |
654                      GDK_BUTTON_MOTION_MASK |
655                      GDK_EXTENSION_EVENTS_ALL,
656                      navwin->preview->window,
657                      cursor, 0);
658 
659    gdk_cursor_destroy (cursor);
660 
661    /* Capture keyboard events. */
662    gdk_keyboard_grab (GTK_WIDGET (navwin)->window, TRUE, GDK_CURRENT_TIME);
663    gtk_widget_grab_focus (GTK_WIDGET (navwin));
664 }
665 
666 
667 static void
navwin_draw(GimvNavWin * navwin)668 navwin_draw (GimvNavWin *navwin)
669 {
670    g_return_if_fail (GIMV_IS_NAV_WIN (navwin));
671 
672    gdk_draw_pixmap (navwin->preview->window,
673                     navwin->preview->style->white_gc,
674                     navwin->pixmap,
675                     0, 0, 0, 0, -1, -1);
676 
677    navwin_draw_sqr (navwin, FALSE,
678                     navwin->sqr_x,
679                     navwin->sqr_y);
680 }
681 
682 
683 static void
navwin_set_win_pos_size(GimvNavWin * navwin)684 navwin_set_win_pos_size (GimvNavWin *navwin)
685 {
686    g_return_if_fail (GIMV_IS_NAV_WIN (navwin));
687 
688 #ifdef USE_GTK2
689    gtk_window_move   (GTK_WINDOW (navwin),
690                       navwin->popup_x,
691                       navwin->popup_y);
692    gtk_window_resize (GTK_WINDOW (navwin),
693                       navwin->popup_width  + BORDER_WIDTH * 2,
694                       navwin->popup_height + BORDER_WIDTH * 2);
695 #else /* USE_GTK2 */
696    gtk_widget_set_uposition (GTK_WIDGET (navwin),
697                              navwin->popup_x,
698                              navwin->popup_y);
699    gtk_widget_set_usize     (GTK_WIDGET (navwin),
700                              navwin->popup_width  + BORDER_WIDTH * 2,
701                              navwin->popup_height + BORDER_WIDTH * 2);
702 #endif /* USE_GTK2 */
703 }
704