]> Pileus Git - ~andy/gtk/blob - gdk/directfb/gdkimage-directfb.c
Fix comment. (gdk_window_set_title): Surround by release pool macros.
[~andy/gtk] / gdk / directfb / gdkimage-directfb.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.
23  */
24
25 /*
26  * GTK+ DirectFB backend
27  * Copyright (C) 2001-2002  convergence integrated media GmbH
28  * Copyright (C) 2002-2004  convergence GmbH
29  * Written by Denis Oliver Kropp <dok@convergence.de> and
30  *            Sven Neumann <sven@convergence.de>
31  */
32
33 #include <config.h>
34 #include "gdk.h"
35
36
37 #include "gdkdirectfb.h"
38 #include "gdkprivate-directfb.h"
39
40 #include "gdkinternals.h"
41
42 #include "gdkimage.h"
43 #include "gdkalias.h"
44
45
46 static GList    *image_list   = NULL;
47 static gpointer  parent_class = NULL;
48
49 static void gdk_directfb_image_destroy (GdkImage      *image);
50 static void gdk_image_init             (GdkImage      *image);
51 static void gdk_image_class_init       (GdkImageClass *klass);
52 static void gdk_image_finalize         (GObject       *object);
53
54 GType
55 gdk_image_get_type (void)
56 {
57   static GType object_type = 0;
58
59   if (!object_type)
60     {
61       static const GTypeInfo object_info =
62         {
63           sizeof (GdkImageClass),
64           (GBaseInitFunc) NULL,
65           (GBaseFinalizeFunc) NULL,
66           (GClassInitFunc) gdk_image_class_init,
67           NULL,           /* class_finalize */
68           NULL,           /* class_data */
69           sizeof (GdkImage),
70           0,              /* n_preallocs */
71           (GInstanceInitFunc) gdk_image_init,
72         };
73
74       object_type = g_type_register_static (G_TYPE_OBJECT,
75                                             "GdkImage",
76                                             &object_info, 0);
77     }
78
79   return object_type;
80 }
81
82 static void
83 gdk_image_init (GdkImage *image)
84 {
85   image->windowing_data = g_new0 (GdkImageDirectFB, 1);
86   image->mem = NULL;
87
88   image_list = g_list_prepend (image_list, image);
89 }
90
91 static void
92 gdk_image_class_init (GdkImageClass *klass)
93 {
94   GObjectClass *object_class = G_OBJECT_CLASS (klass);
95
96   parent_class = g_type_class_peek_parent (klass);
97
98   object_class->finalize = gdk_image_finalize;
99 }
100
101 static void
102 gdk_image_finalize (GObject *object)
103 {
104   GdkImage *image;
105
106   image = GDK_IMAGE (object);
107
108   image_list = g_list_remove (image_list, image);
109
110   if (image->depth == 1)
111     g_free (image->mem);
112
113   gdk_directfb_image_destroy (image);
114
115   if (G_OBJECT_CLASS (parent_class)->finalize)
116     G_OBJECT_CLASS (parent_class)->finalize (object);
117 }
118
119
120 /* this function is called from the atexit handler! */
121 void
122 _gdk_image_exit (void)
123 {
124   GObject *image;
125
126   while (image_list)
127     {
128       image = image_list->data;
129
130       gdk_image_finalize (image);
131     }
132 }
133
134 GdkImage *
135 gdk_image_new_bitmap (GdkVisual *visual,
136                       gpointer   data,
137                       gint       w,
138                       gint       h)
139 {
140   GdkImage         *image;
141   GdkImageDirectFB *private;
142
143   image = g_object_new (gdk_image_get_type (), NULL);
144   private = image->windowing_data;
145
146   image->type   = GDK_IMAGE_SHARED;
147   image->visual = visual;
148   image->width  = w;
149   image->height = h;
150   image->depth  = 1;
151
152   GDK_NOTE (MISC, g_print ("gdk_image_new_bitmap: %dx%d\n", w, h));
153
154   g_message ("not fully implemented %s", G_GNUC_FUNCTION);
155
156   image->bpl = (w + 7) / 8;
157   image->mem = g_malloc (image->bpl * h);
158 #if G_BYTE_ORDER == G_BIG_ENDIAN
159   image->byte_order = GDK_MSB_FIRST;
160 #else
161   image->byte_order = GDK_LSB_FIRST;
162 #endif
163   image->bpp = 1;
164
165   return image;
166 }
167
168 void
169 _gdk_windowing_image_init (void)
170 {
171 }
172
173 GdkImage*
174 _gdk_image_new_for_depth (GdkScreen    *screen,
175                           GdkImageType  type,
176                           GdkVisual    *visual,
177                           gint          width,
178                           gint          height,
179                           gint          depth)
180 {
181   GdkImage              *image;
182   GdkImageDirectFB      *private;
183   DFBResult              ret;
184   gint                   pitch;
185   DFBSurfacePixelFormat  format;
186   IDirectFBSurface      *surface;
187
188   if (type == GDK_IMAGE_FASTEST || type == GDK_IMAGE_NORMAL)
189     type = GDK_IMAGE_SHARED;
190
191   if (visual)
192     depth = visual->depth;
193
194   switch (depth)
195     {
196     case 8:
197       format = DSPF_LUT8;
198       break;
199     case 15:
200       format = DSPF_ARGB1555;
201       break;
202     case 16:
203       format = DSPF_RGB16;
204       break;
205     case 24:
206       format = DSPF_RGB32;
207       break;
208     case 32:
209       format = DSPF_ARGB;
210       break;
211     default:
212       g_message ("unimplemented %s for depth %d", G_GNUC_FUNCTION, depth);
213       return NULL;
214     }
215
216   surface = gdk_display_dfb_create_surface(_gdk_display,format,width,height);
217   if (!surface)
218     {
219       return NULL;
220     }
221   surface->GetPixelFormat( surface, &format );
222
223   image = g_object_new (gdk_image_get_type (), NULL);
224   private = image->windowing_data;
225
226   private->surface = surface;
227
228   surface->Lock( surface, DSLF_WRITE, &image->mem, &pitch );
229
230   image->type           = type;
231   image->visual         = visual;
232 #if G_BYTE_ORDER == G_BIG_ENDIAN
233   image->byte_order             = GDK_MSB_FIRST;
234 #else
235   image->byte_order     = GDK_LSB_FIRST;
236 #endif
237   image->width          = width;
238   image->height         = height;
239   image->depth          = depth;
240   image->bpp            = DFB_BYTES_PER_PIXEL (format);
241   image->bpl            = pitch;
242   image->bits_per_pixel = DFB_BITS_PER_PIXEL (format);
243
244   image_list = g_list_prepend (image_list, image);
245
246   return image;
247 }
248
249
250 GdkImage*
251 _gdk_directfb_copy_to_image (GdkDrawable *drawable,
252                              GdkImage    *image,
253                              gint         src_x,
254                              gint         src_y,
255                              gint         dest_x,
256                              gint         dest_y,
257                              gint         width,
258                              gint         height)
259 {
260   GdkDrawableImplDirectFB *impl;
261   GdkImageDirectFB        *private;
262   int                      pitch;
263   DFBRectangle             rect = { src_x, src_y, width, height };
264   IDirectFBDisplayLayer *layer = _gdk_display->layer;
265
266   g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_DIRECTFB (drawable), NULL);
267   g_return_val_if_fail (image != NULL || (dest_x == 0 && dest_y == 0), NULL);
268
269   impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
270
271   if (impl->wrapper == _gdk_parent_root)
272     {
273       DFBResult ret;
274
275       ret = layer->SetCooperativeLevel (layer, DLSCL_EXCLUSIVE);
276       if (ret)
277         {
278           DirectFBError ("_gdk_directfb_copy_to_image - SetCooperativeLevel",
279                          ret);
280           return NULL;
281         }
282
283       ret = layer->GetSurface (layer, &impl->surface);
284       if (ret)
285         {
286           layer->SetCooperativeLevel (layer, DLSCL_SHARED);
287           DirectFBError ("_gdk_directfb_copy_to_image - GetSurface", ret);
288           return NULL;
289         }
290     }
291
292   if (! impl->surface)
293     return NULL;
294
295   if (!image)
296     image =  gdk_image_new (GDK_IMAGE_NORMAL,
297                             gdk_visual_get_system (), width, height);
298
299   private = image->windowing_data;
300
301   private->surface->Unlock( private->surface );
302
303   private->surface->Blit( private->surface,
304                           impl->surface, &rect, dest_x, dest_y );
305
306   private->surface->Lock( private->surface, DSLF_WRITE, &image->mem, &pitch );
307   image->bpl = pitch;
308
309   if (impl->wrapper == _gdk_parent_root)
310     {
311       impl->surface->Release (impl->surface);
312       impl->surface = NULL;
313       layer->SetCooperativeLevel (layer, DLSCL_SHARED);
314     }
315
316   return image;
317 }
318
319 guint32
320 gdk_image_get_pixel (GdkImage *image,
321                      gint      x,
322                      gint      y)
323 {
324   guint32 pixel = 0;
325
326   g_return_val_if_fail (GDK_IS_IMAGE (image), 0);
327
328   if (!(x >= 0 && x < image->width && y >= 0 && y < image->height))
329     return 0;
330
331   if (image->depth == 1)
332     pixel = (((guchar *) image->mem)[y * image->bpl + (x >> 3)] & (1 << (7 - (x & 0x7)))) != 0;
333   else
334     {
335       guchar *pixelp = (guchar *) image->mem + y * image->bpl + x * image->bpp;
336
337       switch (image->bpp)
338         {
339         case 1:
340           pixel = *pixelp;
341           break;
342
343         case 2:
344           pixel = pixelp[0] | (pixelp[1] << 8);
345           break;
346
347         case 3:
348           pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
349           break;
350
351         case 4:
352           pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
353           break;
354         }
355     }
356
357   return pixel;
358 }
359
360 void
361 gdk_image_put_pixel (GdkImage *image,
362                      gint       x,
363                      gint       y,
364                      guint32    pixel)
365 {
366   g_return_if_fail (image != NULL);
367
368   if  (!(x >= 0 && x < image->width && y >= 0 && y < image->height))
369     return;
370
371   if (image->depth == 1)
372     if (pixel & 1)
373       ((guchar *) image->mem)[y * image->bpl + (x >> 3)] |= (1 << (7 - (x & 0x7)));
374     else
375       ((guchar *) image->mem)[y * image->bpl + (x >> 3)] &= ~(1 << (7 - (x & 0x7)));
376   else
377     {
378       guchar *pixelp = (guchar *) image->mem + y * image->bpl + x * image->bpp;
379
380       switch (image->bpp)
381         {
382         case 4:
383           pixelp[3] = 0xFF;
384         case 3:
385           pixelp[2] = ((pixel >> 16) & 0xFF);
386         case 2:
387           pixelp[1] = ((pixel >> 8) & 0xFF);
388         case 1:
389           pixelp[0] = (pixel & 0xFF);
390         }
391     }
392 }
393
394 static void
395 gdk_directfb_image_destroy (GdkImage *image)
396 {
397   GdkImageDirectFB *private;
398
399   g_return_if_fail (GDK_IS_IMAGE (image));
400
401   private = image->windowing_data;
402
403   if (!private)
404     return;
405
406   GDK_NOTE (MISC, g_print ("gdk_directfb_image_destroy: %#x\n",
407                            (guint) private->surface));
408
409   private->surface->Unlock( private->surface );
410   private->surface->Release( private->surface );
411
412   g_free (private);
413   image->windowing_data = NULL;
414 }
415
416 gint
417 _gdk_windowing_get_bits_for_depth (GdkDisplay *display,
418                                    gint        depth)
419 {
420   switch (depth)
421     {
422     case 1:
423     case 8:
424       return 8;
425     case 15:
426     case 16:
427       return 16;
428     case 24:
429     case 32:
430       return 32;
431     }
432
433   return 0;
434 }
435
436 #define __GDK_IMAGE_X11_C__
437 #include "gdkaliasdef.c"