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 convergence GmbH
29 * Written by Denis Oliver Kropp <dok@convergence.de> and
30 * Sven Neumann <sven@convergence.de>
42 #include "gdkinternals.h"
43 #include "gdkdirectfb.h"
44 #include "gdkprivate-directfb.h"
49 IDirectFBPalette *palette;
50 } GdkColormapPrivateDirectFB;
53 static void gdk_colormap_finalize (GObject *object);
55 static gint gdk_colormap_alloc_pseudocolors (GdkColormap *colormap,
61 static void gdk_directfb_allocate_color_key (GdkColormap *colormap);
64 G_DEFINE_TYPE (GdkColormap, gdk_colormap, G_TYPE_OBJECT)
67 gdk_colormap_init (GdkColormap *colormap)
70 colormap->colors = NULL;
71 colormap->windowing_data = NULL;
75 gdk_colormap_class_init (GdkColormapClass *klass)
77 GObjectClass *object_class = G_OBJECT_CLASS (klass);
79 object_class->finalize = gdk_colormap_finalize;
83 gdk_colormap_finalize (GObject *object)
85 GdkColormap *colormap = GDK_COLORMAP (object);
86 GdkColormapPrivateDirectFB *private = colormap->windowing_data;
88 g_free (colormap->colors);
92 g_free (private->info);
95 private->palette->Release (private->palette);
98 colormap->windowing_data = NULL;
101 G_OBJECT_CLASS (gdk_colormap_parent_class)->finalize (object);
105 gdk_colormap_new (GdkVisual *visual,
106 gboolean private_cmap)
108 GdkColormap *colormap;
111 g_return_val_if_fail (visual != NULL, NULL);
113 colormap = g_object_new (gdk_colormap_get_type (), NULL);
114 colormap->visual = visual;
115 colormap->size = visual->colormap_size;
117 switch (visual->type)
119 case GDK_VISUAL_PSEUDO_COLOR:
121 IDirectFB *dfb = _gdk_display->directfb;
122 IDirectFBPalette *palette;
123 GdkColormapPrivateDirectFB *private;
124 DFBPaletteDescription dsc;
126 dsc.flags = DPDESC_SIZE;
127 dsc.size = colormap->size;
128 if (!dfb->CreatePalette (dfb, &dsc, &palette))
131 colormap->colors = g_new0 (GdkColor, colormap->size);
133 private = g_new0 (GdkColormapPrivateDirectFB, 1);
134 private->info = g_new0 (GdkColorInfo, colormap->size);
136 if (visual == gdk_visual_get_system())
138 /* save the first (transparent) palette entry */
139 private->info[0].ref_count++;
142 private->palette = palette;
144 colormap->windowing_data = private;
146 gdk_directfb_allocate_color_key (colormap);
150 case GDK_VISUAL_STATIC_COLOR:
151 colormap->colors = g_new0 (GdkColor, colormap->size);
152 for (i = 0; i < colormap->size; i++)
154 GdkColor *color = colormap->colors + i;
157 color->red = (i & 0xE0) << 8 | (i & 0xE0);
158 color->green = (i & 0x1C) << 11 | (i & 0x1C) << 3;
159 color->blue = (i & 0x03) << 14 | (i & 0x03) << 6;
171 gdk_colormap_get_screen (GdkColormap *cmap)
177 gdk_screen_get_system_colormap (GdkScreen *screen)
179 static GdkColormap *colormap = NULL;
183 GdkVisual *visual = gdk_visual_get_system();
185 /* special case PSEUDO_COLOR to use the system palette */
186 if (visual->type == GDK_VISUAL_PSEUDO_COLOR)
188 GdkColormapPrivateDirectFB *private;
189 IDirectFBSurface *surface;
191 colormap = g_object_new (gdk_colormap_get_type (), NULL);
193 colormap->visual = visual;
194 colormap->size = visual->colormap_size;
195 colormap->colors = g_new0 (GdkColor, colormap->size);
197 private = g_new0 (GdkColormapPrivateDirectFB, 1);
198 private->info = g_new0 (GdkColorInfo, colormap->size);
200 surface=GDK_WINDOW_IMPL_DIRECTFB (
201 GDK_WINDOW_OBJECT (_gdk_parent_root)->impl)->drawable.surface;
202 surface->GetPalette (surface, &private->palette);
204 colormap->windowing_data = private;
206 /* save the first (transparent) palette entry */
207 private->info[0].ref_count++;
209 gdk_directfb_allocate_color_key (colormap);
213 colormap = gdk_colormap_new (visual, FALSE);
221 gdk_colormap_free_colors (GdkColormap *colormap,
222 const GdkColor *colors,
225 GdkColormapPrivateDirectFB *private;
228 g_return_if_fail (GDK_IS_COLORMAP (colormap));
229 g_return_if_fail (colors != NULL);
231 private = colormap->windowing_data;
235 for (i = 0; i < ncolors; i++)
237 gint index = colors[i].pixel;
239 if (index < 0 || index >= colormap->size)
242 if (private->info[index].ref_count)
243 private->info[index].ref_count--;
248 gdk_colormap_alloc_colors (GdkColormap *colormap,
258 g_return_val_if_fail (GDK_IS_COLORMAP (colormap), 0);
259 g_return_val_if_fail (colors != NULL, 0);
260 g_return_val_if_fail (success != NULL, 0);
262 switch (colormap->visual->type)
264 case GDK_VISUAL_TRUE_COLOR:
265 visual = colormap->visual;
267 for (i = 0; i < ncolors; i++)
271 >> (16 - visual->red_prec)) << visual->red_shift) +
273 >> (16 - visual->green_prec)) << visual->green_shift) +
275 >> (16 - visual->blue_prec)) << visual->blue_shift));
281 case GDK_VISUAL_PSEUDO_COLOR:
282 return gdk_colormap_alloc_pseudocolors (colormap,
284 writeable, best_match,
288 case GDK_VISUAL_STATIC_COLOR:
289 for (i = 0; i < ncolors; i++)
291 colors[i].pixel = (((colors[i].red & 0xE000) >> 8) |
292 ((colors[i].green & 0xE000) >> 11) |
293 ((colors[i].blue & 0xC000) >> 14));
299 for (i = 0; i < ncolors; i++)
308 gdk_colormap_query_color (GdkColormap *colormap,
314 g_return_if_fail (GDK_IS_COLORMAP (colormap));
316 visual = gdk_colormap_get_visual (colormap);
318 switch (visual->type)
320 case GDK_VISUAL_TRUE_COLOR:
321 result->red = 65535. *
322 (gdouble)((pixel & visual->red_mask) >> visual->red_shift) /
323 ((1 << visual->red_prec) - 1);
325 result->green = 65535. *
326 (gdouble)((pixel & visual->green_mask) >> visual->green_shift) /
327 ((1 << visual->green_prec) - 1);
329 result->blue = 65535. *
330 (gdouble)((pixel & visual->blue_mask) >> visual->blue_shift) /
331 ((1 << visual->blue_prec) - 1);
334 case GDK_VISUAL_STATIC_COLOR:
335 case GDK_VISUAL_PSEUDO_COLOR:
336 if (pixel >= 0 && pixel < colormap->size)
338 result->red = colormap->colors[pixel].red;
339 result->green = colormap->colors[pixel].green;
340 result->blue = colormap->colors[pixel].blue;
343 g_warning ("gdk_colormap_query_color: pixel outside colormap");
346 case GDK_VISUAL_DIRECT_COLOR:
347 case GDK_VISUAL_GRAYSCALE:
348 case GDK_VISUAL_STATIC_GRAY:
350 g_assert_not_reached ();
356 gdk_directfb_colormap_get_palette (GdkColormap *colormap)
358 GdkColormapPrivateDirectFB *private;
360 g_return_val_if_fail (GDK_IS_COLORMAP (colormap), NULL);
362 private = colormap->windowing_data;
364 if (private && private->palette)
365 return private->palette;
371 gdk_colormap_alloc_pseudocolors (GdkColormap *colormap,
378 GdkColormapPrivateDirectFB *private = colormap->windowing_data;
379 IDirectFBPalette *palette;
381 gint remaining = ncolors;
383 palette = private->palette;
385 for (i = 0; i < ncolors; i++)
388 DFBColor lookup = { 0xFF,
390 colors[i].green >> 8,
391 colors[i].blue >> 8 };
397 /* look for an empty slot and allocate a new color */
398 for (j = 0; j < colormap->size; j++)
399 if (private->info[j].ref_count == 0)
403 palette->SetEntries (palette, &lookup, 1, index);
405 private->info[index].flags = GDK_COLOR_WRITEABLE;
407 colors[i].pixel = index;
408 colormap->colors[index] = colors[i];
415 palette->FindBestMatch (palette,
416 lookup.r, lookup.g, lookup.b, lookup.a,
419 if (index < 0 || index > colormap->size)
422 /* check if we have an exact (non-writeable) match */
423 if (private->info[index].ref_count &&
424 !(private->info[index].flags & GDK_COLOR_WRITEABLE))
428 palette->GetEntries (palette, &entry, 1, index);
430 if (entry.a == 0xFF &&
431 entry.r == lookup.r && entry.g == lookup.g && entry.b == lookup.b)
433 colors[i].pixel = index;
439 /* look for an empty slot and allocate a new color */
440 for (j = 0; j < colormap->size; j++)
441 if (private->info[j].ref_count == 0)
445 palette->SetEntries (palette, &lookup, 1, index);
446 private->info[index].flags = 0;
448 colors[i].pixel = index;
449 colormap->colors[index] = colors[i];
454 /* if that failed, use the best match */
456 !(private->info[index].flags & GDK_COLOR_WRITEABLE))
459 g_print ("best match for (%d %d %d) ",
460 colormap->colors[index].red,
461 colormap->colors[index].green,
462 colormap->colors[index].blue);
465 colors[i].pixel = index;
471 /* if we got here, all attempts failed */
475 private->info[index].ref_count++;
478 g_print ("cmap %p: allocated (%d %d %d) %d [%d]\n", colormap,
479 colors[i].red, colors[i].green, colors[i].blue, colors[i].pixel,
480 private->info[index].ref_count);
490 /* dirty hack for color_keying */
492 gdk_directfb_allocate_color_key (GdkColormap *colormap)
494 GdkColormapPrivateDirectFB *private = colormap->windowing_data;
495 IDirectFBPalette *palette = private->palette;
497 if (!gdk_directfb_enable_color_keying)
500 palette->SetEntries (palette, &gdk_directfb_bg_color, 1, 255);
502 colormap->colors[255].pixel = 255;
503 colormap->colors[255].red = ((gdk_directfb_bg_color_key.r << 8)
504 | gdk_directfb_bg_color_key.r);
505 colormap->colors[255].green = ((gdk_directfb_bg_color_key.g << 8)
506 | gdk_directfb_bg_color_key.g);
507 colormap->colors[255].blue = ((gdk_directfb_bg_color_key.b << 8)
508 | gdk_directfb_bg_color_key.b);
510 private->info[255].ref_count++;