]> Pileus Git - ~andy/gtk/blob - gdk/directfb/gdkvisual-directfb.c
container: suggest parentheses around assignment used as truth value
[~andy/gtk] / gdk / directfb / gdkvisual-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
35 #include "gdkdirectfb.h"
36 #include "gdkprivate-directfb.h"
37
38 #include "gdkscreen.h"
39 #include "gdkvisual.h"
40
41
42 struct _GdkVisualClass
43 {
44   GObjectClass parent_class;
45 };
46
47
48 static void                gdk_visual_decompose_mask  (gulong   mask,
49                                                        gint    *shift,
50                                                        gint    *prec);
51 static GdkVisualDirectFB * gdk_directfb_visual_create (DFBSurfacePixelFormat  pixelformat);
52
53
54 static DFBSurfacePixelFormat formats[] =
55 {
56   DSPF_ARGB,
57   DSPF_LUT8,
58   DSPF_RGB32,
59   DSPF_RGB24,
60   DSPF_RGB16,
61   DSPF_ARGB1555,
62   DSPF_RGB332
63 };
64
65 GdkVisual         * system_visual = NULL;
66 static GdkVisualDirectFB * visuals[G_N_ELEMENTS (formats) + 1] = { NULL };
67 static gint                available_depths[G_N_ELEMENTS (formats) + 1] = {0};
68 static GdkVisualType       available_types[G_N_ELEMENTS (formats) + 1]  = {0};
69
70
71 static void
72 gdk_visual_finalize (GObject *object)
73 {
74   g_error ("A GdkVisual object was finalized. This should not happen");
75 }
76
77 static void
78 gdk_visual_class_init (GObjectClass *class)
79 {
80   class->finalize = gdk_visual_finalize;
81 }
82
83 GType
84 gdk_visual_get_type (void)
85 {
86   static GType object_type = 0;
87
88   if (!object_type)
89     {
90       const GTypeInfo object_info =
91       {
92         sizeof (GdkVisualClass),
93         (GBaseInitFunc) NULL,
94         (GBaseFinalizeFunc) NULL,
95         (GClassInitFunc) gdk_visual_class_init,
96         NULL,           /* class_finalize */
97         NULL,           /* class_data */
98         sizeof (GdkVisualDirectFB),
99         0,              /* n_preallocs */
100         (GInstanceInitFunc) NULL,
101       };
102
103       object_type = g_type_register_static (G_TYPE_OBJECT,
104                                             "GdkVisual",
105                                             &object_info, 0);
106     }
107
108   return object_type;
109 }
110
111 void
112 _gdk_visual_init ()
113 {
114   DFBDisplayLayerConfig  dlc;
115   DFBSurfaceDescription  desc;
116   IDirectFBSurface      *dest;
117   gint                   i, c;
118
119
120   _gdk_display->layer->GetConfiguration (_gdk_display->layer, &dlc);
121   g_assert( dlc.pixelformat != DSPF_UNKNOWN);
122
123   dest = gdk_display_dfb_create_surface(_gdk_display,dlc.pixelformat,8,8);
124   g_assert (dest != NULL);
125
126   /* We could provide all visuals since DirectFB allows us to mix
127      surface formats. Blitting with format conversion can however
128      be incredibly slow, so we've choosen to register only those
129      visuals that can be blitted to the display layer in hardware.
130
131      If you want to use a special pixelformat that is not registered
132      here, you can create it using the DirectFB-specific function
133      gdk_directfb_visual_by_format().
134      Note:
135      changed to do all formats but we should redo this code
136      to ensure the base format ARGB LUT8 RGB etc then add ones supported
137      by the hardware
138    */
139   for (i = 0; i < G_N_ELEMENTS (formats); i++)
140     {
141       IDirectFBSurface    *src;
142       DFBAccelerationMask  acc;
143
144       desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
145       desc.width       = 8;
146       desc.height      = 8;
147       desc.pixelformat = formats[i];
148       //call direct so fail silently  is ok
149       if (_gdk_display->directfb->CreateSurface (_gdk_display->directfb,
150          &desc, &src) != DFB_OK) 
151         continue;
152
153       visuals[i] = gdk_directfb_visual_create (formats[i]);
154
155       dest->GetAccelerationMask (dest, src, &acc);
156
157       if (acc & DFXL_BLIT || formats[i] == dlc.pixelformat)
158         {
159                         system_visual = GDK_VISUAL (visuals[i]);
160         }
161
162       src->Release (src);
163     }
164
165   dest->Release (dest);
166
167   //fallback to ARGB must be supported
168   if (!system_visual)
169     {
170        g_assert (visuals[DSPF_ARGB] != NULL);
171        system_visual = GDK_VISUAL(visuals[DSPF_ARGB]);
172     }
173
174   g_assert (system_visual != NULL);
175 }
176
177 gint
178 gdk_visual_get_best_depth (void)
179 {
180   return system_visual->depth;
181 }
182
183 GdkVisualType
184 gdk_visual_get_best_type (void)
185 {
186   return system_visual->type;
187 }
188
189 GdkVisual*
190 gdk_screen_get_system_visual (GdkScreen *screen)
191 {
192   g_assert( system_visual);
193   return system_visual;
194 }
195
196 GdkVisual*
197 gdk_visual_get_best (void)
198 {
199   return system_visual;
200 }
201
202 GdkVisual*
203 gdk_visual_get_best_with_depth (gint depth)
204 {
205   gint i;
206
207   for (i = 0; visuals[i]; i++)
208     {
209       if( visuals[i] ) {
210         GdkVisual *visual = GDK_VISUAL (visuals[i]);
211
212         if (depth == visual->depth)
213             return visual;
214       }
215     }
216
217   return NULL;
218 }
219
220 GdkVisual*
221 gdk_visual_get_best_with_type (GdkVisualType visual_type)
222 {
223   gint i;
224
225   for (i = 0; visuals[i]; i++)
226     {
227       if( visuals[i] ) {
228         GdkVisual *visual = GDK_VISUAL (visuals[i]);
229
230         if (visual_type == visual->type)
231             return visual;
232       }
233     }
234
235   return NULL;
236 }
237
238 GdkVisual*
239 gdk_visual_get_best_with_both (gint          depth,
240                                GdkVisualType visual_type)
241 {
242   gint i;
243
244   for (i = 0; visuals[i]; i++)
245     {
246       if( visuals[i] ) {
247         GdkVisual *visual = GDK_VISUAL (visuals[i]);
248
249         if (depth == visual->depth && visual_type == visual->type)
250             return visual;
251       }
252     }
253
254   return system_visual;
255 }
256
257 void
258 gdk_query_depths (gint **depths,
259                   gint  *count)
260 {
261   gint i;
262
263   for (i = 0; available_depths[i]; i++)
264     ;
265
266   *count = i;
267   *depths = available_depths;
268 }
269
270 void
271 gdk_query_visual_types (GdkVisualType **visual_types,
272                         gint           *count)
273 {
274   gint i;
275
276   for (i = 0; available_types[i]; i++)
277     ;
278
279   *count = i;
280   *visual_types = available_types;
281 }
282
283 GList *
284 gdk_screen_list_visuals (GdkScreen *screen)
285 {
286   GList *list = NULL;
287   gint   i;
288
289   for (i = 0; visuals[i]; i++)
290    if( visuals[i] ) {
291         GdkVisual * vis = GDK_VISUAL(visuals[i]);
292         list = g_list_append (list,vis);
293    }
294
295   return list;
296 }
297
298 /**
299  * gdk_directfb_visual_by_format:
300  * @pixel_format: the pixel_format of the requested visual
301  *
302  * This function is specific to the DirectFB backend. It allows
303  * to specify a GdkVisual by @pixel_format.
304  *
305  * At startup, only those visuals that can be blitted
306  * hardware-accelerated are registered.  By using
307  * gdk_directfb_visual_by_format() you can retrieve visuals that
308  * don't match this criteria since this function will try to create
309  * a new visual for the desired @pixel_format for you.
310  *
311  * Return value: a pointer to the GdkVisual or %NULL if the
312  * pixel_format is unsupported.
313  **/
314 GdkVisual *
315 gdk_directfb_visual_by_format (DFBSurfacePixelFormat pixel_format)
316 {
317   gint i;
318
319   /* first check if one the registered visuals matches */
320   for (i = 0; visuals[i]; i++)
321     if ( visuals[i] && visuals[i]->format == pixel_format)
322       return GDK_VISUAL (visuals[i]);
323
324   /* none matched, try to create a new one for this pixel_format */
325   {
326     DFBSurfaceDescription  desc;
327     IDirectFBSurface      *test;
328
329     desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
330     desc.width       = 8;
331     desc.height      = 8;
332     desc.pixelformat = pixel_format;
333
334     if ( _gdk_display->directfb->CreateSurface ( _gdk_display->directfb, &desc, &test) != DFB_OK)
335       return NULL;
336
337     test->Release (test);
338   }
339
340   return GDK_VISUAL(gdk_directfb_visual_create (pixel_format));
341 }
342
343 GdkScreen *
344 gdk_visual_get_screen (GdkVisual *visual)
345 {
346   g_return_val_if_fail (GDK_IS_VISUAL (visual), NULL);
347
348   return gdk_screen_get_default ();
349 }
350
351 static void
352 gdk_visual_decompose_mask (gulong  mask,
353                            gint   *shift,
354                            gint   *prec)
355 {
356   *shift = 0;
357   *prec  = 0;
358
359   while (!(mask & 0x1))
360     {
361       (*shift)++;
362       mask >>= 1;
363     }
364
365   while (mask & 0x1)
366     {
367       (*prec)++;
368       mask >>= 1;
369     }
370 }
371
372 static GdkVisualDirectFB *
373 gdk_directfb_visual_create (DFBSurfacePixelFormat  pixelformat)
374 {
375   GdkVisual *visual;
376   gint       i;
377
378   for (i = 0; i < G_N_ELEMENTS (formats); i++)
379     if (formats[i] == pixelformat)
380       break;
381
382   if (i ==  G_N_ELEMENTS (formats))
383     {
384       g_warning ("unsupported pixelformat");
385       return NULL;
386     }
387
388   visual = g_object_new (GDK_TYPE_VISUAL, NULL);
389
390   switch (pixelformat)
391     {
392     case DSPF_LUT8:
393       visual->type         = GDK_VISUAL_PSEUDO_COLOR;
394       visual->bits_per_rgb = 8;
395       break;
396
397     case DSPF_RGB332:
398       visual->type         = GDK_VISUAL_STATIC_COLOR;
399       visual->bits_per_rgb = 3;
400       break;
401
402     case DSPF_ARGB1555:
403       visual->type         = GDK_VISUAL_TRUE_COLOR;
404       visual->red_mask     = 0x00007C00;
405       visual->green_mask   = 0x000003E0;
406       visual->blue_mask    = 0x0000001F;
407       visual->bits_per_rgb = 5;
408       break;
409
410     case DSPF_RGB16:
411       visual->type         = GDK_VISUAL_TRUE_COLOR;
412       visual->red_mask     = 0x0000F800;
413       visual->green_mask   = 0x000007E0;
414       visual->blue_mask    = 0x0000001F;
415       visual->bits_per_rgb = 6;
416       break;
417
418     case DSPF_RGB24:
419     case DSPF_RGB32:
420     case DSPF_ARGB:
421       visual->type         = GDK_VISUAL_TRUE_COLOR;
422       visual->red_mask     = 0x00FF0000;
423       visual->green_mask   = 0x0000FF00;
424       visual->blue_mask    = 0x000000FF;
425       visual->bits_per_rgb = 8;
426       break;
427
428     default:
429       g_assert_not_reached ();
430     }
431
432 #if G_BYTE_ORDER == G_BIG_ENDIAN
433   visual->byte_order = GDK_MSB_FIRST;
434 #else
435   visual->byte_order = GDK_LSB_FIRST;
436 #endif
437
438   visual->depth      = DFB_BITS_PER_PIXEL (pixelformat);
439
440   switch (visual->type)
441     {
442     case GDK_VISUAL_TRUE_COLOR:
443       gdk_visual_decompose_mask (visual->red_mask,
444                                  &visual->red_shift, &visual->red_prec);
445       gdk_visual_decompose_mask (visual->green_mask,
446                                  &visual->green_shift, &visual->green_prec);
447       gdk_visual_decompose_mask (visual->blue_mask,
448                                  &visual->blue_shift, &visual->blue_prec);
449
450       /* the number of possible levels per color component */
451       visual->colormap_size = 1 << MAX (visual->red_prec,
452                                         MAX (visual->green_prec,
453                                              visual->blue_prec));
454       break;
455
456     case GDK_VISUAL_STATIC_COLOR:
457     case GDK_VISUAL_PSEUDO_COLOR:
458       visual->colormap_size = 1 << visual->depth;
459
460       visual->red_mask    = 0;
461       visual->red_shift   = 0;
462       visual->red_prec    = 0;
463
464       visual->green_mask  = 0;
465       visual->green_shift = 0;
466       visual->green_prec  = 0;
467
468       visual->blue_mask   = 0;
469       visual->blue_shift  = 0;
470       visual->blue_prec   = 0;
471
472       break;
473
474     default:
475       g_assert_not_reached ();
476     }
477
478   ((GdkVisualDirectFB *)visual)->format = pixelformat;
479
480   for (i = 0; available_depths[i]; i++)
481     if (available_depths[i] == visual->depth)
482       break;
483   if (!available_depths[i])
484     available_depths[i] = visual->depth;
485
486   for (i = 0; available_types[i]; i++)
487     if (available_types[i] == visual->type)
488       break;
489   if (!available_types[i])
490     available_types[i] = visual->type;
491
492   return (GdkVisualDirectFB *) visual;
493 }