]> Pileus Git - ~andy/gtk/blob - gdk/quartz/gdkimage-quartz.c
Include "config.h" instead of <config.h> Command used: find -name
[~andy/gtk] / gdk / quartz / gdkimage-quartz.c
1 /* gdkimage-quartz.c
2  *
3  * Copyright (C) 2005 Imendio AB
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22
23 #include "gdk.h"
24 #include "gdkimage.h"
25 #include "gdkprivate-quartz.h"
26
27 static GObjectClass *parent_class;
28
29 GdkImage *
30 _gdk_quartz_image_copy_to_image (GdkDrawable *drawable,
31                                  GdkImage    *image,
32                                  gint         src_x,
33                                  gint         src_y,
34                                  gint         dest_x,
35                                  gint         dest_y,
36                                  gint         width,
37                                  gint         height)
38 {
39   GdkScreen *screen;
40   
41   g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_QUARTZ (drawable), NULL);
42   g_return_val_if_fail (image != NULL || (dest_x == 0 && dest_y == 0), NULL);
43
44   screen = gdk_drawable_get_screen (drawable);
45   if (!image)
46     image = _gdk_image_new_for_depth (screen, GDK_IMAGE_FASTEST, NULL, 
47                                       width, height,
48                                       gdk_drawable_get_depth (drawable));
49   
50   if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable))
51     {
52       GdkPixmapImplQuartz *pix_impl;
53       gint bytes_per_row;
54       guchar *data;
55       int x, y;
56
57       pix_impl = GDK_PIXMAP_IMPL_QUARTZ (drawable);
58       data = (guchar *)(pix_impl->data);
59
60       if (src_x + width > pix_impl->width || src_y + height > pix_impl->height)
61         {
62           g_warning ("Out of bounds copy-area for pixmap -> image conversion\n");
63           return image;
64         }
65
66       switch (gdk_drawable_get_depth (drawable))
67         {
68         case 24:
69           bytes_per_row = pix_impl->width * 4;
70           for (y = 0; y < height; y++)
71             {
72               guchar *src = data + ((y + src_y) * bytes_per_row) + (src_x * 4);
73
74               for (x = 0; x < width; x++)
75                 {
76                   gint32 pixel;
77           
78                   /* RGB24, 4 bytes per pixel, skip first. */
79                   pixel = src[0] << 16 | src[1] << 8 | src[2];
80                   src += 4;
81
82                   gdk_image_put_pixel (image, dest_x + x, dest_y + y, pixel);
83                 }
84             }
85           break;
86
87         case 32:
88           bytes_per_row = pix_impl->width * 4;
89           for (y = 0; y < height; y++)
90             {
91               guchar *src = data + ((y + src_y) * bytes_per_row) + (src_x * 4);
92
93               for (x = 0; x < width; x++)
94                 {
95                   gint32 pixel;
96           
97                   /* ARGB32, 4 bytes per pixel. */
98                   pixel = src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3];
99                   src += 4;
100
101                   gdk_image_put_pixel (image, dest_x + x, dest_y + y, pixel);
102                 }
103             }
104           break;
105
106         case 1: /* TODO: optimize */
107           bytes_per_row = pix_impl->width;
108           for (y = 0; y < height; y++)
109             {
110               guchar *src = data + ((y + src_y) * bytes_per_row) + src_x;
111
112               for (x = 0; x < width; x++)
113                 {
114                   gint32 pixel;
115           
116                   /* 8 bits */
117                   pixel = src[0];
118                   src++;
119
120                   gdk_image_put_pixel (image, dest_x + x, dest_y + y, pixel);
121                 }
122             }
123           break;
124
125         default:
126           g_warning ("Unsupported bit depth %d\n", gdk_drawable_get_depth (drawable));
127           return image;
128         }
129     }
130   else if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable))
131     {
132       GdkQuartzView *view;
133       NSBitmapImageRep *rep;
134       NSRect rect;
135       guchar *data;
136       int x, y;
137       NSSize size;
138
139       view = GDK_WINDOW_IMPL_QUARTZ (drawable)->view;
140
141       /* We return the image even if we can't copy to it. */
142       if (![view lockFocusIfCanDraw])
143         return image;
144
145       rect = NSMakeRect (src_x, src_y, width, height);
146
147       rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect: rect];
148       [view unlockFocus];
149           
150       data = [rep bitmapData];
151       size = [rep size];
152
153       for (y = 0; y < size.height; y++)
154         {
155           guchar *src = data + y * [rep bytesPerRow];
156
157           for (x = 0; x < size.width; x++)
158             {
159               gint32 pixel;
160
161               if (image->byte_order == GDK_LSB_FIRST)
162                 pixel = src[0] << 8 | src[1] << 16 |src[2] << 24;
163               else
164                 pixel = src[0] << 16 | src[1] << 8 |src[2];
165
166               src += 3;
167
168               gdk_image_put_pixel (image, dest_x + x, dest_y + y, pixel);
169             }
170         }
171
172       [rep release];
173     }
174
175   return image;
176 }
177
178 static void
179 gdk_image_finalize (GObject *object)
180 {
181   GdkImage *image = GDK_IMAGE (object);
182
183   g_free (image->mem);
184
185   G_OBJECT_CLASS (parent_class)->finalize (object);
186 }
187
188 static void
189 gdk_image_class_init (GdkImageClass *klass)
190 {
191   GObjectClass *object_class = G_OBJECT_CLASS (klass);
192
193   parent_class = g_type_class_peek_parent (klass);
194   
195   object_class->finalize = gdk_image_finalize;
196 }
197
198 GType
199 gdk_image_get_type (void)
200 {
201   static GType object_type = 0;
202
203   if (!object_type)
204     {
205       static const GTypeInfo object_info =
206       {
207         sizeof (GdkImageClass),
208         (GBaseInitFunc) NULL,
209         (GBaseFinalizeFunc) NULL,
210         (GClassInitFunc) gdk_image_class_init,
211         NULL,           /* class_finalize */
212         NULL,           /* class_data */
213         sizeof (GdkImage),
214         0,              /* n_preallocs */
215         (GInstanceInitFunc) NULL,
216       };
217       
218       object_type = g_type_register_static (G_TYPE_OBJECT,
219                                             "GdkImage",
220                                             &object_info,
221                                             0);
222     }
223   
224   return object_type;
225 }
226
227 GdkImage *
228 gdk_image_new_bitmap (GdkVisual *visual, gpointer data, gint width, gint height)
229 {
230   /* We don't implement this function because it's broken, deprecated and 
231    * tricky to implement. */
232   g_warning ("This function is unimplemented");
233
234   return NULL;
235 }
236
237 GdkImage*
238 _gdk_image_new_for_depth (GdkScreen    *screen,
239                           GdkImageType  type,
240                           GdkVisual    *visual,
241                           gint          width,
242                           gint          height,
243                           gint          depth)
244 {
245   GdkImage *image;
246
247   if (visual)
248     depth = visual->depth;
249
250   g_assert (depth == 24 || depth == 32);
251
252   image = g_object_new (gdk_image_get_type (), NULL);
253   image->type = type;
254   image->visual = visual;
255   image->width = width;
256   image->height = height;
257   image->depth = depth;
258
259   image->byte_order = (G_BYTE_ORDER == G_LITTLE_ENDIAN) ? GDK_LSB_FIRST : GDK_MSB_FIRST;
260
261   /* We only support images with bpp 4 */
262   image->bpp = 4;
263   image->bpl = image->width * image->bpp;
264   image->bits_per_pixel = image->bpp * 8;
265   
266   image->mem = g_malloc (image->bpl * image->height);
267   memset (image->mem, 0x00, image->bpl * image->height);
268
269   return image;
270 }
271
272 guint32
273 gdk_image_get_pixel (GdkImage *image,
274                      gint x,
275                      gint y)
276 {
277   guchar *ptr;
278
279   g_return_val_if_fail (image != NULL, 0);
280   g_return_val_if_fail (x >= 0 && x < image->width, 0);
281   g_return_val_if_fail (y >= 0 && y < image->height, 0);
282
283   ptr = image->mem + y * image->bpl + x * image->bpp;
284
285   return *(guint32 *)ptr;
286 }
287
288 void
289 gdk_image_put_pixel (GdkImage *image,
290                      gint x,
291                      gint y,
292                      guint32 pixel)
293 {
294   guchar *ptr;
295
296   ptr = image->mem + y * image->bpl + x * image->bpp;
297
298   *(guint32 *)ptr = pixel;
299 }
300
301 gint
302 _gdk_windowing_get_bits_for_depth (GdkDisplay *display,
303                                    gint        depth)
304 {
305   if (depth == 24 || depth == 32)
306     return 32;
307   else
308     g_assert_not_reached ();
309
310   return 0;
311 }