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