~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to app/widgets/gimpview.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* The GIMP -- an image manipulation program
 
1
/* GIMP - The GNU Image Manipulation Program
2
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3
3
 *
4
4
 * gimpview.c
5
 
 * Copyright (C) 2001 Michael Natterer <mitch@gimp.org>
 
5
 * Copyright (C) 2001-2006 Michael Natterer <mitch@gimp.org>
6
6
 *
7
7
 * This program is free software; you can redistribute it and/or modify
8
8
 * it under the terms of the GNU General Public License as published by
32
32
 
33
33
#include "widgets-types.h"
34
34
 
 
35
#include "core/gimpcontext.h"
35
36
#include "core/gimpmarshal.h"
36
37
#include "core/gimpviewable.h"
37
38
 
42
43
#include "gimpviewrenderer-utils.h"
43
44
 
44
45
 
45
 
#define VIEW_EVENT_MASK (GDK_BUTTON_PRESS_MASK   | \
46
 
                         GDK_BUTTON_RELEASE_MASK | \
47
 
                         GDK_ENTER_NOTIFY_MASK   | \
48
 
                         GDK_LEAVE_NOTIFY_MASK)
49
 
 
50
 
 
51
46
enum
52
47
{
 
48
  SET_VIEWABLE,
53
49
  CLICKED,
54
50
  DOUBLE_CLICKED,
55
51
  CONTEXT,
57
53
};
58
54
 
59
55
 
60
 
static void        gimp_view_class_init           (GimpViewClass    *klass);
61
 
static void        gimp_view_init                 (GimpView         *view);
62
 
 
63
56
static void        gimp_view_destroy              (GtkObject        *object);
64
57
static void        gimp_view_realize              (GtkWidget        *widget);
65
58
static void        gimp_view_unrealize            (GtkWidget        *widget);
80
73
static gboolean    gimp_view_leave_notify_event   (GtkWidget        *widget,
81
74
                                                   GdkEventCrossing *event);
82
75
 
 
76
static void        gimp_view_real_set_viewable    (GimpView         *view,
 
77
                                                   GimpViewable     *old,
 
78
                                                   GimpViewable     *viewable);
 
79
 
83
80
static void        gimp_view_update_callback      (GimpViewRenderer *renderer,
84
81
                                                   GimpView         *view);
85
82
 
86
83
static GimpViewable * gimp_view_drag_viewable     (GtkWidget        *widget,
87
 
                                                   gpointer          data);
88
 
 
89
 
 
 
84
                                                   GimpContext     **context,
 
85
                                                   gpointer          data);
 
86
static GdkPixbuf    * gimp_view_drag_pixbuf       (GtkWidget        *widget,
 
87
                                                   gpointer          data);
 
88
 
 
89
 
 
90
G_DEFINE_TYPE (GimpView, gimp_view, GTK_TYPE_WIDGET)
 
91
 
 
92
#define parent_class gimp_view_parent_class
90
93
 
91
94
static guint view_signals[LAST_SIGNAL] = { 0 };
92
95
 
93
 
static GtkWidgetClass *parent_class = NULL;
94
 
 
95
 
 
96
 
GType
97
 
gimp_view_get_type (void)
98
 
{
99
 
  static GType view_type = 0;
100
 
 
101
 
  if (! view_type)
102
 
    {
103
 
      static const GTypeInfo view_info =
104
 
      {
105
 
        sizeof (GimpViewClass),
106
 
        NULL,           /* base_init */
107
 
        NULL,           /* base_finalize */
108
 
        (GClassInitFunc) gimp_view_class_init,
109
 
        NULL,           /* class_finalize */
110
 
        NULL,           /* class_data */
111
 
        sizeof (GimpView),
112
 
        0,              /* n_preallocs */
113
 
        (GInstanceInitFunc) gimp_view_init,
114
 
      };
115
 
 
116
 
      view_type = g_type_register_static (GTK_TYPE_WIDGET,
117
 
                                          "GimpView",
118
 
                                          &view_info, 0);
119
 
    }
120
 
 
121
 
  return view_type;
122
 
}
123
96
 
124
97
static void
125
98
gimp_view_class_init (GimpViewClass *klass)
127
100
  GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
128
101
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
129
102
 
130
 
  parent_class = g_type_class_peek_parent (klass);
 
103
  view_signals[SET_VIEWABLE] =
 
104
    g_signal_new ("set-viewable",
 
105
                  G_TYPE_FROM_CLASS (klass),
 
106
                  G_SIGNAL_RUN_FIRST,
 
107
                  G_STRUCT_OFFSET (GimpViewClass, set_viewable),
 
108
                  NULL, NULL,
 
109
                  gimp_marshal_VOID__OBJECT_OBJECT,
 
110
                  G_TYPE_NONE, 2,
 
111
                  GIMP_TYPE_VIEWABLE, GIMP_TYPE_VIEWABLE);
131
112
 
132
113
  view_signals[CLICKED] =
133
114
    g_signal_new ("clicked",
140
121
                  GDK_TYPE_MODIFIER_TYPE);
141
122
 
142
123
  view_signals[DOUBLE_CLICKED] =
143
 
    g_signal_new ("double_clicked",
 
124
    g_signal_new ("double-clicked",
144
125
                  G_TYPE_FROM_CLASS (klass),
145
126
                  G_SIGNAL_RUN_FIRST,
146
127
                  G_STRUCT_OFFSET (GimpViewClass, double_clicked),
172
153
  widget_class->enter_notify_event   = gimp_view_enter_notify_event;
173
154
  widget_class->leave_notify_event   = gimp_view_leave_notify_event;
174
155
 
 
156
  klass->set_viewable                = gimp_view_real_set_viewable;
175
157
  klass->clicked                     = NULL;
176
158
  klass->double_clicked              = NULL;
177
159
  klass->context                     = NULL;
182
164
{
183
165
  GTK_WIDGET_SET_FLAGS (view, GTK_NO_WINDOW);
184
166
 
 
167
  gtk_widget_add_events (GTK_WIDGET (view), (GDK_BUTTON_PRESS_MASK   |
 
168
                                             GDK_BUTTON_RELEASE_MASK |
 
169
                                             GDK_ENTER_NOTIFY_MASK   |
 
170
                                             GDK_LEAVE_NOTIFY_MASK));
 
171
 
 
172
  view->event_window      = NULL;
185
173
  view->viewable          = NULL;
186
174
  view->renderer          = NULL;
187
175
 
191
179
  view->expand            = FALSE;
192
180
 
193
181
  view->in_button         = FALSE;
 
182
  view->has_grab          = FALSE;
 
183
  view->press_state       = 0;
194
184
}
195
185
 
196
186
static void
220
210
  GTK_WIDGET_CLASS (parent_class)->realize (widget);
221
211
 
222
212
  attributes.window_type = GDK_WINDOW_CHILD;
223
 
  attributes.x      = widget->allocation.x;
224
 
  attributes.y      = widget->allocation.y;
225
 
  attributes.width  = widget->allocation.width;
226
 
  attributes.height = widget->allocation.height;
227
 
 
228
 
  attributes.wclass = GDK_INPUT_ONLY;
229
 
  attributes.event_mask = gtk_widget_get_events (widget);
230
 
  attributes.event_mask |= VIEW_EVENT_MASK;
 
213
  attributes.x           = widget->allocation.x;
 
214
  attributes.y           = widget->allocation.y;
 
215
  attributes.width       = widget->allocation.width;
 
216
  attributes.height      = widget->allocation.height;
 
217
  attributes.wclass      = GDK_INPUT_ONLY;
 
218
  attributes.event_mask  = gtk_widget_get_events (widget);
231
219
 
232
220
  attributes_mask = GDK_WA_X | GDK_WA_Y;
233
221
 
271
259
  GimpView *view = GIMP_VIEW (widget);
272
260
 
273
261
  if (view->has_grab)
274
 
    gtk_grab_remove (widget);
 
262
    {
 
263
      gtk_grab_remove (widget);
 
264
      view->has_grab = FALSE;
 
265
    }
275
266
 
276
267
  if (view->event_window)
277
268
    gdk_window_hide (view->event_window);
394
385
 
395
386
static gboolean
396
387
gimp_view_expose_event (GtkWidget      *widget,
397
 
                           GdkEventExpose *event)
 
388
                        GdkEventExpose *event)
398
389
{
399
 
  if (! GTK_WIDGET_DRAWABLE (widget))
400
 
    return FALSE;
401
 
 
402
 
  gimp_view_renderer_draw (GIMP_VIEW (widget)->renderer,
403
 
                           widget->window, widget,
404
 
                           &widget->allocation,
405
 
                           &event->area);
 
390
  if (GTK_WIDGET_DRAWABLE (widget))
 
391
    {
 
392
      gimp_view_renderer_draw (GIMP_VIEW (widget)->renderer,
 
393
                               widget->window, widget,
 
394
                               &widget->allocation,
 
395
                               &event->area);
 
396
    }
406
397
 
407
398
  return FALSE;
408
399
}
450
441
          if (view->show_popup && view->viewable)
451
442
            {
452
443
              gimp_view_popup_show (widget, bevent,
 
444
                                    view->renderer->context,
453
445
                                    view->viewable,
454
446
                                    view->renderer->width,
455
447
                                    view->renderer->height,
462
454
 
463
455
          if (bevent->button == 2)
464
456
            gimp_view_popup_show (widget, bevent,
 
457
                                  view->renderer->context,
465
458
                                  view->viewable,
466
459
                                  view->renderer->width,
467
460
                                  view->renderer->height,
495
488
  if (bevent->button == 1)
496
489
    {
497
490
      gtk_grab_remove (widget);
498
 
 
499
491
      view->has_grab = FALSE;
500
492
 
501
493
      if (view->clickable && view->in_button)
502
494
        {
503
 
          g_signal_emit (widget, view_signals[CLICKED], 0,
504
 
                         view->press_state);
 
495
          g_signal_emit (widget, view_signals[CLICKED], 0, view->press_state);
505
496
        }
506
497
    }
507
498
  else
544
535
  return FALSE;
545
536
}
546
537
 
 
538
static void
 
539
gimp_view_real_set_viewable (GimpView     *view,
 
540
                             GimpViewable *old,
 
541
                             GimpViewable *viewable)
 
542
{
 
543
  GType viewable_type = G_TYPE_NONE;
 
544
 
 
545
  if (viewable == view->viewable)
 
546
    return;
 
547
 
 
548
  if (viewable)
 
549
    {
 
550
      viewable_type = G_TYPE_FROM_INSTANCE (viewable);
 
551
 
 
552
      g_return_if_fail (g_type_is_a (viewable_type,
 
553
                                     view->renderer->viewable_type));
 
554
    }
 
555
 
 
556
  if (view->viewable)
 
557
    {
 
558
      g_object_remove_weak_pointer (G_OBJECT (view->viewable),
 
559
                                    (gpointer) &view->viewable);
 
560
 
 
561
      if (! viewable && ! view->renderer->is_popup)
 
562
        {
 
563
          if (gimp_dnd_viewable_source_remove (GTK_WIDGET (view),
 
564
                                               G_TYPE_FROM_INSTANCE (view->viewable)))
 
565
            {
 
566
              if (gimp_viewable_get_size (view->viewable, NULL, NULL))
 
567
                gimp_dnd_pixbuf_source_remove (GTK_WIDGET (view));
 
568
 
 
569
              gtk_drag_source_unset (GTK_WIDGET (view));
 
570
            }
 
571
        }
 
572
    }
 
573
  else if (viewable && ! view->renderer->is_popup)
 
574
    {
 
575
      if (gimp_dnd_drag_source_set_by_type (GTK_WIDGET (view),
 
576
                                            GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
 
577
                                            viewable_type,
 
578
                                            GDK_ACTION_COPY))
 
579
        {
 
580
          gimp_dnd_viewable_source_add (GTK_WIDGET (view),
 
581
                                        viewable_type,
 
582
                                        gimp_view_drag_viewable,
 
583
                                        NULL);
 
584
 
 
585
          if (gimp_viewable_get_size (viewable, NULL, NULL))
 
586
            gimp_dnd_pixbuf_source_add (GTK_WIDGET (view),
 
587
                                        gimp_view_drag_pixbuf,
 
588
                                        NULL);
 
589
        }
 
590
    }
 
591
 
 
592
  gimp_view_renderer_set_viewable (view->renderer, viewable);
 
593
  view->viewable = viewable;
 
594
 
 
595
  if (view->viewable)
 
596
    {
 
597
      g_object_add_weak_pointer (G_OBJECT (view->viewable),
 
598
                                 (gpointer) &view->viewable);
 
599
    }
 
600
}
547
601
 
548
602
/*  public functions  */
549
603
 
550
604
GtkWidget *
551
 
gimp_view_new (GimpViewable *viewable,
 
605
gimp_view_new (GimpContext  *context,
 
606
               GimpViewable *viewable,
552
607
               gint          size,
553
608
               gint          border_width,
554
609
               gboolean      is_popup)
555
610
{
556
611
  GtkWidget *view;
557
612
 
 
613
  g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);
558
614
  g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
559
615
 
560
 
  view = gimp_view_new_by_types (GIMP_TYPE_VIEW,
 
616
  view = gimp_view_new_by_types (context,
 
617
                                 GIMP_TYPE_VIEW,
561
618
                                 G_TYPE_FROM_INSTANCE (viewable),
562
619
                                 size, border_width, is_popup);
563
620
 
570
627
}
571
628
 
572
629
GtkWidget *
573
 
gimp_view_new_full (GimpViewable *viewable,
 
630
gimp_view_new_full (GimpContext  *context,
 
631
                    GimpViewable *viewable,
574
632
                    gint          width,
575
633
                    gint          height,
576
634
                    gint          border_width,
580
638
{
581
639
  GtkWidget *view;
582
640
 
 
641
  g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);
583
642
  g_return_val_if_fail (GIMP_IS_VIEWABLE (viewable), NULL);
584
643
 
585
 
  view = gimp_view_new_full_by_types (GIMP_TYPE_VIEW,
 
644
  view = gimp_view_new_full_by_types (context,
 
645
                                      GIMP_TYPE_VIEW,
586
646
                                      G_TYPE_FROM_INSTANCE (viewable),
587
647
                                      width, height, border_width,
588
648
                                      is_popup, clickable, show_popup);
596
656
}
597
657
 
598
658
GtkWidget *
599
 
gimp_view_new_by_types (GType    view_type,
600
 
                        GType    viewable_type,
601
 
                        gint     size,
602
 
                        gint     border_width,
603
 
                        gboolean is_popup)
 
659
gimp_view_new_by_types (GimpContext *context,
 
660
                        GType        view_type,
 
661
                        GType        viewable_type,
 
662
                        gint         size,
 
663
                        gint         border_width,
 
664
                        gboolean     is_popup)
604
665
{
605
666
  GimpViewRenderer *renderer;
606
667
  GimpView         *view;
607
668
 
 
669
  g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);
608
670
  g_return_val_if_fail (g_type_is_a (view_type, GIMP_TYPE_VIEW), NULL);
609
671
  g_return_val_if_fail (g_type_is_a (viewable_type, GIMP_TYPE_VIEWABLE), NULL);
610
672
  g_return_val_if_fail (size >  0 &&
612
674
  g_return_val_if_fail (border_width >= 0 &&
613
675
                        border_width <= GIMP_VIEW_MAX_BORDER_WIDTH, NULL);
614
676
 
615
 
  renderer = gimp_view_renderer_new (viewable_type, size,
 
677
  renderer = gimp_view_renderer_new (context, viewable_type, size,
616
678
                                     border_width, is_popup);
617
679
 
618
680
  g_return_val_if_fail (renderer != NULL, NULL);
629
691
}
630
692
 
631
693
GtkWidget *
632
 
gimp_view_new_full_by_types (GType    view_type,
633
 
                             GType    viewable_type,
634
 
                             gint     width,
635
 
                             gint     height,
636
 
                             gint     border_width,
637
 
                             gboolean is_popup,
638
 
                             gboolean clickable,
639
 
                             gboolean show_popup)
 
694
gimp_view_new_full_by_types (GimpContext *context,
 
695
                             GType        view_type,
 
696
                             GType        viewable_type,
 
697
                             gint         width,
 
698
                             gint         height,
 
699
                             gint         border_width,
 
700
                             gboolean     is_popup,
 
701
                             gboolean     clickable,
 
702
                             gboolean     show_popup)
640
703
{
641
704
  GimpViewRenderer *renderer;
642
705
  GimpView         *view;
643
706
 
 
707
  g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);
644
708
  g_return_val_if_fail (g_type_is_a (view_type, GIMP_TYPE_VIEW), NULL);
645
709
  g_return_val_if_fail (g_type_is_a (viewable_type, GIMP_TYPE_VIEWABLE), NULL);
646
710
  g_return_val_if_fail (width >  0 &&
650
714
  g_return_val_if_fail (border_width >= 0 &&
651
715
                        border_width <= GIMP_VIEW_MAX_BORDER_WIDTH, NULL);
652
716
 
653
 
  renderer = gimp_view_renderer_new_full (viewable_type, width, height,
654
 
                                          border_width, is_popup);
 
717
  renderer = gimp_view_renderer_new_full (context, viewable_type,
 
718
                                          width, height, border_width,
 
719
                                          is_popup);
655
720
 
656
721
  g_return_val_if_fail (renderer != NULL, NULL);
657
722
 
668
733
  return GTK_WIDGET (view);
669
734
}
670
735
 
 
736
GimpViewable *
 
737
gimp_view_get_viewable (GimpView *view)
 
738
{
 
739
  g_return_val_if_fail (GIMP_IS_VIEW (view), NULL);
 
740
 
 
741
  return view->viewable;
 
742
}
 
743
 
671
744
void
672
745
gimp_view_set_viewable (GimpView     *view,
673
746
                        GimpViewable *viewable)
674
747
{
675
 
  GType viewable_type = G_TYPE_NONE;
676
 
 
677
748
  g_return_if_fail (GIMP_IS_VIEW (view));
678
749
  g_return_if_fail (viewable == NULL || GIMP_IS_VIEWABLE (viewable));
679
750
 
680
751
  if (viewable == view->viewable)
681
752
    return;
682
753
 
683
 
  if (viewable)
684
 
    {
685
 
      viewable_type = G_TYPE_FROM_INSTANCE (viewable);
686
 
 
687
 
      g_return_if_fail (g_type_is_a (viewable_type,
688
 
                                     view->renderer->viewable_type));
689
 
    }
690
 
 
691
 
  if (view->viewable)
692
 
    {
693
 
      g_object_remove_weak_pointer (G_OBJECT (view->viewable),
694
 
                                    (gpointer *) &view->viewable);
695
 
 
696
 
      if (! viewable && ! view->renderer->is_popup)
697
 
        {
698
 
          if (gimp_dnd_viewable_source_remove (GTK_WIDGET (view),
699
 
                                               G_TYPE_FROM_INSTANCE (view->viewable)))
700
 
            {
701
 
              gtk_drag_source_unset (GTK_WIDGET (view));
702
 
            }
703
 
        }
704
 
    }
705
 
  else if (viewable && ! view->renderer->is_popup)
706
 
    {
707
 
      if (gimp_dnd_drag_source_set_by_type (GTK_WIDGET (view),
708
 
                                            GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
709
 
                                            viewable_type,
710
 
                                            GDK_ACTION_COPY))
711
 
        {
712
 
          gimp_dnd_viewable_source_add (GTK_WIDGET (view),
713
 
                                        viewable_type,
714
 
                                        gimp_view_drag_viewable,
715
 
                                        NULL);
716
 
        }
717
 
    }
718
 
 
719
 
  gimp_view_renderer_set_viewable (view->renderer, viewable);
720
 
  view->viewable = viewable;
721
 
 
722
 
  if (view->viewable)
723
 
    {
724
 
      g_object_add_weak_pointer (G_OBJECT (view->viewable),
725
 
                                 (gpointer *) &view->viewable);
726
 
    }
 
754
  g_signal_emit (view, view_signals[SET_VIEWABLE], 0, view->viewable, viewable);
727
755
}
728
756
 
729
757
void
768
796
}
769
797
 
770
798
static GimpViewable *
771
 
gimp_view_drag_viewable (GtkWidget *widget,
772
 
                         gpointer   data)
 
799
gimp_view_drag_viewable (GtkWidget    *widget,
 
800
                         GimpContext **context,
 
801
                         gpointer      data)
773
802
{
 
803
  if (context)
 
804
    *context = GIMP_VIEW (widget)->renderer->context;
 
805
 
774
806
  return GIMP_VIEW (widget)->viewable;
775
807
}
 
808
 
 
809
static GdkPixbuf *
 
810
gimp_view_drag_pixbuf (GtkWidget *widget,
 
811
                       gpointer   data)
 
812
{
 
813
  GimpView     *view     = GIMP_VIEW (widget);
 
814
  GimpViewable *viewable = view->viewable;
 
815
  gint          width;
 
816
  gint          height;
 
817
 
 
818
  if (viewable && gimp_viewable_get_size (viewable, &width, &height))
 
819
    return gimp_viewable_get_new_pixbuf (viewable, view->renderer->context,
 
820
                                         width, height);
 
821
 
 
822
  return NULL;
 
823
}