1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
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.
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.
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.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team.
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>
35 #include "gdkdirectfb.h"
36 #include "gdkprivate-directfb.h"
38 #include "gdkscreen.h"
39 #include "gdkvisual.h"
42 struct _GdkVisualClass
44 GObjectClass parent_class;
48 static void gdk_visual_decompose_mask (gulong mask,
51 static GdkVisualDirectFB * gdk_directfb_visual_create (DFBSurfacePixelFormat pixelformat);
54 static DFBSurfacePixelFormat formats[] =
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};
72 gdk_visual_finalize (GObject *object)
74 g_error ("A GdkVisual object was finalized. This should not happen");
78 gdk_visual_class_init (GObjectClass *class)
80 class->finalize = gdk_visual_finalize;
84 gdk_visual_get_type (void)
86 static GType object_type = 0;
90 const GTypeInfo object_info =
92 sizeof (GdkVisualClass),
94 (GBaseFinalizeFunc) NULL,
95 (GClassInitFunc) gdk_visual_class_init,
96 NULL, /* class_finalize */
97 NULL, /* class_data */
98 sizeof (GdkVisualDirectFB),
100 (GInstanceInitFunc) NULL,
103 object_type = g_type_register_static (G_TYPE_OBJECT,
114 DFBDisplayLayerConfig dlc;
115 DFBSurfaceDescription desc;
116 IDirectFBSurface *dest;
120 _gdk_display->layer->GetConfiguration (_gdk_display->layer, &dlc);
121 g_assert( dlc.pixelformat != DSPF_UNKNOWN);
123 dest = gdk_display_dfb_create_surface(_gdk_display,dlc.pixelformat,8,8);
124 g_assert (dest != NULL);
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.
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().
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
139 for (i = 0; i < G_N_ELEMENTS (formats); i++)
141 IDirectFBSurface *src;
142 DFBAccelerationMask acc;
144 desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
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)
153 visuals[i] = gdk_directfb_visual_create (formats[i]);
155 dest->GetAccelerationMask (dest, src, &acc);
157 if (acc & DFXL_BLIT || formats[i] == dlc.pixelformat)
159 system_visual = GDK_VISUAL (visuals[i]);
165 dest->Release (dest);
167 //fallback to ARGB must be supported
170 g_assert (visuals[DSPF_ARGB] != NULL);
171 system_visual = GDK_VISUAL(visuals[DSPF_ARGB]);
174 g_assert (system_visual != NULL);
178 gdk_visual_get_best_depth (void)
180 return system_visual->depth;
184 gdk_visual_get_best_type (void)
186 return system_visual->type;
190 gdk_screen_get_system_visual (GdkScreen *screen)
192 g_assert( system_visual);
193 return system_visual;
197 gdk_visual_get_best (void)
199 return system_visual;
203 gdk_visual_get_best_with_depth (gint depth)
207 for (i = 0; visuals[i]; i++)
210 GdkVisual *visual = GDK_VISUAL (visuals[i]);
212 if (depth == visual->depth)
221 gdk_visual_get_best_with_type (GdkVisualType visual_type)
225 for (i = 0; visuals[i]; i++)
228 GdkVisual *visual = GDK_VISUAL (visuals[i]);
230 if (visual_type == visual->type)
239 gdk_visual_get_best_with_both (gint depth,
240 GdkVisualType visual_type)
244 for (i = 0; visuals[i]; i++)
247 GdkVisual *visual = GDK_VISUAL (visuals[i]);
249 if (depth == visual->depth && visual_type == visual->type)
254 return system_visual;
258 gdk_query_depths (gint **depths,
263 for (i = 0; available_depths[i]; i++)
267 *depths = available_depths;
271 gdk_query_visual_types (GdkVisualType **visual_types,
276 for (i = 0; available_types[i]; i++)
280 *visual_types = available_types;
284 gdk_screen_list_visuals (GdkScreen *screen)
289 for (i = 0; visuals[i]; i++)
291 GdkVisual * vis = GDK_VISUAL(visuals[i]);
292 list = g_list_append (list,vis);
299 * gdk_directfb_visual_by_format:
300 * @pixel_format: the pixel_format of the requested visual
302 * This function is specific to the DirectFB backend. It allows
303 * to specify a GdkVisual by @pixel_format.
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.
311 * Return value: a pointer to the GdkVisual or %NULL if the
312 * pixel_format is unsupported.
315 gdk_directfb_visual_by_format (DFBSurfacePixelFormat pixel_format)
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]);
324 /* none matched, try to create a new one for this pixel_format */
326 DFBSurfaceDescription desc;
327 IDirectFBSurface *test;
329 desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
332 desc.pixelformat = pixel_format;
334 if ( _gdk_display->directfb->CreateSurface ( _gdk_display->directfb, &desc, &test) != DFB_OK)
337 test->Release (test);
340 return GDK_VISUAL(gdk_directfb_visual_create (pixel_format));
344 gdk_visual_get_screen (GdkVisual *visual)
346 g_return_val_if_fail (GDK_IS_VISUAL (visual), NULL);
348 return gdk_screen_get_default ();
352 gdk_visual_decompose_mask (gulong mask,
359 while (!(mask & 0x1))
372 static GdkVisualDirectFB *
373 gdk_directfb_visual_create (DFBSurfacePixelFormat pixelformat)
378 for (i = 0; i < G_N_ELEMENTS (formats); i++)
379 if (formats[i] == pixelformat)
382 if (i == G_N_ELEMENTS (formats))
384 g_warning ("unsupported pixelformat");
388 visual = g_object_new (GDK_TYPE_VISUAL, NULL);
393 visual->type = GDK_VISUAL_PSEUDO_COLOR;
394 visual->bits_per_rgb = 8;
398 visual->type = GDK_VISUAL_STATIC_COLOR;
399 visual->bits_per_rgb = 3;
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;
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;
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;
429 g_assert_not_reached ();
432 #if G_BYTE_ORDER == G_BIG_ENDIAN
433 visual->byte_order = GDK_MSB_FIRST;
435 visual->byte_order = GDK_LSB_FIRST;
438 visual->depth = DFB_BITS_PER_PIXEL (pixelformat);
440 switch (visual->type)
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);
450 /* the number of possible levels per color component */
451 visual->colormap_size = 1 << MAX (visual->red_prec,
452 MAX (visual->green_prec,
456 case GDK_VISUAL_STATIC_COLOR:
457 case GDK_VISUAL_PSEUDO_COLOR:
458 visual->colormap_size = 1 << visual->depth;
460 visual->red_mask = 0;
461 visual->red_shift = 0;
462 visual->red_prec = 0;
464 visual->green_mask = 0;
465 visual->green_shift = 0;
466 visual->green_prec = 0;
468 visual->blue_mask = 0;
469 visual->blue_shift = 0;
470 visual->blue_prec = 0;
475 g_assert_not_reached ();
478 ((GdkVisualDirectFB *)visual)->format = pixelformat;
480 for (i = 0; available_depths[i]; i++)
481 if (available_depths[i] == visual->depth)
483 if (!available_depths[i])
484 available_depths[i] = visual->depth;
486 for (i = 0; available_types[i]; i++)
487 if (available_types[i] == visual->type)
489 if (!available_types[i])
490 available_types[i] = visual->type;
492 return (GdkVisualDirectFB *) visual;