]> Pileus Git - ~andy/gtk/blob - modules/other/gail/gailimage.c
Include "config.h" instead of <config.h> Command used: find -name
[~andy/gtk] / modules / other / gail / gailimage.c
1 /* GAIL - The GNOME Accessibility Implementation Library
2  * Copyright 2001 Sun Microsystems Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "config.h"
21
22 #include <string.h>
23 #include <gtk/gtk.h>
24 #include "gailimage.h"
25
26 static void      gail_image_class_init         (GailImageClass *klass);
27 static void      gail_image_init               (GailImage      *image);
28 static void      gail_image_initialize         (AtkObject       *accessible,
29                                                 gpointer        data);
30 static G_CONST_RETURN gchar* gail_image_get_name  (AtkObject     *accessible);
31
32
33 static void      atk_image_interface_init      (AtkImageIface  *iface);
34
35 static G_CONST_RETURN gchar *
36                  gail_image_get_image_description (AtkImage     *image);
37 static void      gail_image_get_image_position    (AtkImage     *image,
38                                                    gint         *x,
39                                                    gint         *y,
40                                                    AtkCoordType coord_type);
41 static void      gail_image_get_image_size     (AtkImage        *image,
42                                                 gint            *width,
43                                                 gint            *height);
44 static gboolean  gail_image_set_image_description (AtkImage     *image,
45                                                 const gchar     *description);
46 static void      gail_image_finalize           (GObject         *object);
47
48 G_DEFINE_TYPE_WITH_CODE (GailImage, gail_image, GAIL_TYPE_WIDGET,
49                          G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_interface_init))
50
51 static void
52 gail_image_class_init (GailImageClass *klass)
53 {
54   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
55   AtkObjectClass  *class = ATK_OBJECT_CLASS (klass);
56
57   gobject_class->finalize = gail_image_finalize;
58   class->initialize = gail_image_initialize;
59   class->get_name = gail_image_get_name;
60 }
61
62 static void
63 gail_image_init (GailImage *image)
64 {
65   image->image_description = NULL;
66 }
67
68 static void
69 gail_image_initialize (AtkObject *accessible,
70                        gpointer data)
71 {
72   ATK_OBJECT_CLASS (gail_image_parent_class)->initialize (accessible, data);
73
74   accessible->role = ATK_ROLE_ICON;
75 }
76
77 /* Copied from gtktoolbar.c, keep in sync */
78 static gchar *
79 elide_underscores (const gchar *original)
80 {
81   gchar *q, *result;
82   const gchar *p, *end;
83   gsize len;
84   gboolean last_underscore;
85   
86   if (!original)
87     return NULL;
88
89   len = strlen (original);
90   q = result = g_malloc (len + 1);
91   last_underscore = FALSE;
92   
93   end = original + len;
94   for (p = original; p < end; p++)
95     {
96       if (!last_underscore && *p == '_')
97         last_underscore = TRUE;
98       else
99         {
100           last_underscore = FALSE;
101           if (original + 2 <= p && p + 1 <= end && 
102               p[-2] == '(' && p[-1] == '_' && p[0] != '_' && p[1] == ')')
103             {
104               q--;
105               *q = '\0';
106               p++;
107             }
108           else
109             *q++ = *p;
110         }
111     }
112
113   if (last_underscore)
114     *q++ = '_';
115   
116   *q = '\0';
117   
118   return result;
119 }
120
121 static G_CONST_RETURN gchar*
122 gail_image_get_name (AtkObject *accessible)
123 {
124   GtkWidget* widget;
125   GtkImage *image;
126   GailImage *image_accessible;
127   GtkStockItem stock_item;
128   const gchar *name;
129
130   name = ATK_OBJECT_CLASS (gail_image_parent_class)->get_name (accessible);
131   if (name)
132     return name;
133
134   widget = GTK_ACCESSIBLE (accessible)->widget;
135   /*
136    * State is defunct
137    */
138   if (widget == NULL)
139     return NULL;
140
141   g_return_val_if_fail (GTK_IS_IMAGE (widget), NULL);
142   image = GTK_IMAGE (widget);
143   image_accessible = GAIL_IMAGE (accessible);
144
145   g_free (image_accessible->stock_name);
146   image_accessible->stock_name = NULL;
147
148   if (image->storage_type != GTK_IMAGE_STOCK ||
149       image->data.stock.stock_id == NULL)
150     return NULL;
151
152   if (!gtk_stock_lookup (image->data.stock.stock_id, &stock_item))
153     return NULL;
154
155   image_accessible->stock_name = elide_underscores (stock_item.label);
156   return image_accessible->stock_name;
157 }
158
159 static void
160 atk_image_interface_init (AtkImageIface *iface)
161 {
162   iface->get_image_description = gail_image_get_image_description;
163   iface->get_image_position = gail_image_get_image_position;
164   iface->get_image_size = gail_image_get_image_size;
165   iface->set_image_description = gail_image_set_image_description;
166 }
167
168 static G_CONST_RETURN gchar * 
169 gail_image_get_image_description (AtkImage     *image)
170 {
171   GailImage* aimage = GAIL_IMAGE (image);
172
173   return aimage->image_description;
174 }
175
176 static void
177 gail_image_get_image_position (AtkImage     *image,
178                                gint         *x,
179                                gint         *y,
180                                AtkCoordType coord_type)
181 {
182   atk_component_get_position (ATK_COMPONENT (image), x, y, coord_type);
183 }
184
185 static void
186 gail_image_get_image_size (AtkImage *image, 
187                            gint     *width,
188                            gint     *height)
189 {
190   GtkWidget* widget;
191   GtkImage *gtk_image;
192   GtkImageType image_type;
193
194   widget = GTK_ACCESSIBLE (image)->widget;
195   if (widget == 0)
196   {
197     /* State is defunct */
198     *height = -1;
199     *width = -1;
200     return;
201   }
202
203   gtk_image = GTK_IMAGE(widget);
204
205   image_type = gtk_image_get_storage_type(gtk_image);
206  
207   switch(image_type) {
208     case GTK_IMAGE_PIXMAP:
209     {   
210       GdkPixmap *pixmap;
211       gtk_image_get_pixmap(gtk_image, &pixmap, NULL);
212       gdk_drawable_get_size (pixmap, width, height);
213       break;
214     }
215     case GTK_IMAGE_PIXBUF:
216     {
217       GdkPixbuf *pixbuf;
218       pixbuf = gtk_image_get_pixbuf(gtk_image);
219       *height = gdk_pixbuf_get_height(pixbuf);
220       *width = gdk_pixbuf_get_width(pixbuf);
221       break;
222     }
223     case GTK_IMAGE_IMAGE:
224     {
225       GdkImage *gdk_image;
226       gtk_image_get_image(gtk_image, &gdk_image, NULL);
227       *height = gdk_image->height;
228       *width = gdk_image->width;
229       break;
230     }
231     case GTK_IMAGE_STOCK:
232     {
233       GtkIconSize size;
234       GtkSettings *settings;
235       settings = gtk_settings_get_for_screen (gtk_widget_get_screen (widget));
236       gtk_image_get_stock(gtk_image, NULL, &size);
237       gtk_icon_size_lookup_for_settings (settings, size, width, height);
238       break;
239     }
240     case GTK_IMAGE_ICON_SET:
241     {
242       GtkIconSize size;
243       GtkSettings *settings;
244       settings = gtk_settings_get_for_screen (gtk_widget_get_screen (widget));
245       gtk_image_get_icon_set(gtk_image, NULL, &size);
246       gtk_icon_size_lookup_for_settings (settings, size, width, height);
247       break;
248     }
249     case GTK_IMAGE_ANIMATION:
250     {
251       GdkPixbufAnimation *animation;
252       animation = gtk_image_get_animation(gtk_image);
253       *height = gdk_pixbuf_animation_get_height(animation);
254       *width = gdk_pixbuf_animation_get_width(animation);
255       break;
256     }
257     default:
258     {
259       *height = -1;
260       *width = -1;
261       break;
262     }
263   }
264 }
265
266 static gboolean
267 gail_image_set_image_description (AtkImage     *image,
268                                   const gchar  *description)
269 {
270   GailImage* aimage = GAIL_IMAGE (image);
271
272   g_free (aimage->image_description);
273   aimage->image_description = g_strdup (description);
274   return TRUE;
275 }
276
277 static void
278 gail_image_finalize (GObject      *object)
279 {
280   GailImage *aimage = GAIL_IMAGE (object);
281
282   g_free (aimage->image_description);
283   g_free (aimage->stock_name);
284
285   G_OBJECT_CLASS (gail_image_parent_class)->finalize (object);
286 }