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 Library 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 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library 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-1999. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
32 static void gdk_visual_add (GdkVisual *visual);
33 static void gdk_visual_decompose_mask (gulong mask,
36 static guint gdk_visual_hash (Visual *key);
37 static gint gdk_visual_compare (Visual *a,
41 static GdkVisualPrivate *system_visual;
42 static GdkVisualPrivate *visuals;
45 static gint available_depths[7];
46 static gint navailable_depths;
48 static GdkVisualType available_types[6];
49 static gint navailable_types;
53 static const gchar* visual_names[] =
63 #endif /* G_ENABLE_DEBUG */
65 static GHashTable *visual_hash = NULL;
68 gdk_visual_init (void)
81 static const gint possible_depths[7] = { 32, 24, 16, 15, 8, 4, 1 };
82 static const GdkVisualType possible_types[6] =
84 GDK_VISUAL_DIRECT_COLOR,
85 GDK_VISUAL_TRUE_COLOR,
86 GDK_VISUAL_PSEUDO_COLOR,
87 GDK_VISUAL_STATIC_COLOR,
89 GDK_VISUAL_STATIC_GRAY
92 static const gint npossible_depths = sizeof(possible_depths)/sizeof(gint);
93 static const gint npossible_types = sizeof(possible_types)/sizeof(GdkVisualType);
95 int rastercaps, numcolors, sizepalette, colorres, bitspixel;
96 Visual *default_xvisual;
97 GdkVisualPrivate temp_visual;
102 visuals = g_new (GdkVisualPrivate, nxvisuals);
105 for (i = 0; i < nxvisuals; i++)
109 bitspixel = GetDeviceCaps (gdk_DC, BITSPIXEL);
110 rastercaps = GetDeviceCaps (gdk_DC, RASTERCAPS);
111 default_xvisual = g_new (Visual, 1);
112 visuals[nvisuals].xvisual = default_xvisual;
113 visuals[nvisuals].xvisual->visualid = nvisuals;
114 visuals[nvisuals].xvisual->bitspixel = bitspixel;
116 if (rastercaps & RC_PALETTE)
118 visuals[nvisuals].visual.type = GDK_VISUAL_PSEUDO_COLOR;
119 numcolors = GetDeviceCaps (gdk_DC, NUMCOLORS);
120 sizepalette = GetDeviceCaps (gdk_DC, SIZEPALETTE);
121 colorres = GetDeviceCaps (gdk_DC, COLORRES);
122 visuals[nvisuals].xvisual->map_entries = sizepalette;
124 else if (bitspixel == 1)
126 visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_GRAY;
127 visuals[nvisuals].xvisual->map_entries = 2;
129 else if (bitspixel == 4)
131 visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_COLOR;
132 visuals[nvisuals].xvisual->map_entries = 16;
134 else if (bitspixel == 8)
136 visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_COLOR;
137 visuals[nvisuals].xvisual->map_entries = 256;
139 else if (bitspixel == 16)
141 visuals[nvisuals].visual.type = GDK_VISUAL_TRUE_COLOR;
143 /* This code by Mike Enright,
144 * see http://www.users.cts.com/sd/m/menright/display.html
146 memset (&bmi, 0, sizeof (bmi));
147 bmi.bi.biSize = sizeof (bmi.bi);
149 hbm = CreateCompatibleBitmap (gdk_DC, 1, 1);
150 GetDIBits (gdk_DC, hbm, 0, 1, NULL,
151 (BITMAPINFO *) &bmi, DIB_RGB_COLORS);
152 GetDIBits (gdk_DC, hbm, 0, 1, NULL,
153 (BITMAPINFO *) &bmi, DIB_RGB_COLORS);
156 if (bmi.bi.biCompression != BI_BITFIELDS)
158 /* Either BI_RGB or BI_RLE_something
159 * .... or perhaps (!!) something else.
160 * Theoretically biCompression might be
161 * mmioFourCC('c','v','i','d') but I doubt it.
163 if (bmi.bi.biCompression == BI_RGB)
167 visuals[nvisuals].visual.red_mask = 0x00007C00;
168 visuals[nvisuals].visual.green_mask = 0x000003E0;
169 visuals[nvisuals].visual.blue_mask = 0x0000001F;
173 g_assert_not_reached ();
179 bmi.u.fields[0] | bmi.u.fields[1] | bmi.u.fields[2];
188 visuals[nvisuals].visual.red_mask = bmi.u.fields[0];
189 visuals[nvisuals].visual.green_mask = bmi.u.fields[1];
190 visuals[nvisuals].visual.blue_mask = bmi.u.fields[2];
193 /* Old, incorrect (but still working) code. */
195 visuals[nvisuals].visual.red_mask = 0x0000F800;
196 visuals[nvisuals].visual.green_mask = 0x000007E0;
197 visuals[nvisuals].visual.blue_mask = 0x0000001F;
199 visuals[nvisuals].visual.red_mask = 0x00007C00;
200 visuals[nvisuals].visual.green_mask = 0x000003E0;
201 visuals[nvisuals].visual.blue_mask = 0x0000001F;
205 else if (bitspixel == 24 || bitspixel == 32)
207 visuals[nvisuals].visual.type = GDK_VISUAL_TRUE_COLOR;
208 visuals[nvisuals].visual.red_mask = 0x00FF0000;
209 visuals[nvisuals].visual.green_mask = 0x0000FF00;
210 visuals[nvisuals].visual.blue_mask = 0x000000FF;
213 g_error ("gdk_visual_init: unsupported BITSPIXEL: %d\n", bitspixel);
215 visuals[nvisuals].visual.depth = bitspixel;
216 visuals[nvisuals].visual.byte_order = GDK_LSB_FIRST;
217 visuals[nvisuals].visual.bits_per_rgb = 42; /* Not used? */
219 if ((visuals[nvisuals].visual.type == GDK_VISUAL_TRUE_COLOR) ||
220 (visuals[nvisuals].visual.type == GDK_VISUAL_DIRECT_COLOR))
222 gdk_visual_decompose_mask (visuals[nvisuals].visual.red_mask,
223 &visuals[nvisuals].visual.red_shift,
224 &visuals[nvisuals].visual.red_prec);
226 gdk_visual_decompose_mask (visuals[nvisuals].visual.green_mask,
227 &visuals[nvisuals].visual.green_shift,
228 &visuals[nvisuals].visual.green_prec);
230 gdk_visual_decompose_mask (visuals[nvisuals].visual.blue_mask,
231 &visuals[nvisuals].visual.blue_shift,
232 &visuals[nvisuals].visual.blue_prec);
233 visuals[nvisuals].xvisual->map_entries =
234 1 << (MAX (visuals[nvisuals].visual.red_prec,
235 MAX (visuals[nvisuals].visual.green_prec,
236 visuals[nvisuals].visual.blue_prec)));
240 visuals[nvisuals].visual.red_mask = 0;
241 visuals[nvisuals].visual.red_shift = 0;
242 visuals[nvisuals].visual.red_prec = 0;
244 visuals[nvisuals].visual.green_mask = 0;
245 visuals[nvisuals].visual.green_shift = 0;
246 visuals[nvisuals].visual.green_prec = 0;
248 visuals[nvisuals].visual.blue_mask = 0;
249 visuals[nvisuals].visual.blue_shift = 0;
250 visuals[nvisuals].visual.blue_prec = 0;
252 visuals[nvisuals].visual.colormap_size = visuals[nvisuals].xvisual->map_entries;
258 for (i = 0; i < nvisuals; i++)
260 for (j = i+1; j < nvisuals; j++)
262 if (visuals[j].visual.depth >= visuals[i].visual.depth)
264 if ((visuals[j].visual.depth == 8) && (visuals[i].visual.depth == 8))
266 if (visuals[j].visual.type == GDK_VISUAL_PSEUDO_COLOR)
268 temp_visual = visuals[j];
269 visuals[j] = visuals[i];
270 visuals[i] = temp_visual;
272 else if ((visuals[i].visual.type != GDK_VISUAL_PSEUDO_COLOR) &&
273 visuals[j].visual.type > visuals[i].visual.type)
275 temp_visual = visuals[j];
276 visuals[j] = visuals[i];
277 visuals[i] = temp_visual;
280 else if ((visuals[j].visual.depth > visuals[i].visual.depth) ||
281 ((visuals[j].visual.depth == visuals[i].visual.depth) &&
282 (visuals[j].visual.type > visuals[i].visual.type)))
284 temp_visual = visuals[j];
285 visuals[j] = visuals[i];
286 visuals[i] = temp_visual;
292 for (i = 0; i < nvisuals; i++)
293 if (default_xvisual->visualid == visuals[i].xvisual->visualid)
295 system_visual = &visuals[i];
299 navailable_depths = 0;
300 for (i = 0; i < npossible_depths; i++)
302 for (j = 0; j < nvisuals; j++)
304 if (visuals[j].visual.depth == possible_depths[i])
306 available_depths[navailable_depths++] = visuals[j].visual.depth;
312 if (navailable_depths == 0)
313 g_error ("unable to find a usable depth");
315 navailable_types = 0;
316 for (i = 0; i < npossible_types; i++)
318 for (j = 0; j < nvisuals; j++)
320 if (visuals[j].visual.type == possible_types[i])
322 available_types[navailable_types++] = visuals[j].visual.type;
328 for (i = 0; i < nvisuals; i++)
329 gdk_visual_add ((GdkVisual*) &visuals[i]);
331 if (npossible_types == 0)
332 g_error ("unable to find a usable visual type");
336 gdk_visual_ref (GdkVisual *visual)
342 gdk_visual_unref (GdkVisual *visual)
348 gdk_visual_get_best_depth (void)
350 return available_depths[0];
354 gdk_visual_get_best_type (void)
356 return available_types[0];
360 gdk_visual_get_system (void)
362 return ((GdkVisual*) system_visual);
366 gdk_visual_get_best (void)
368 return ((GdkVisual*) &(visuals[0]));
372 gdk_visual_get_best_with_depth (gint depth)
374 GdkVisual *return_val;
378 for (i = 0; i < nvisuals; i++)
379 if (depth == visuals[i].visual.depth)
381 return_val = (GdkVisual*) &(visuals[i]);
389 gdk_visual_get_best_with_type (GdkVisualType visual_type)
391 GdkVisual *return_val;
395 for (i = 0; i < nvisuals; i++)
396 if (visual_type == visuals[i].visual.type)
398 return_val = (GdkVisual*) &(visuals[i]);
406 gdk_visual_get_best_with_both (gint depth,
407 GdkVisualType visual_type)
409 GdkVisual *return_val;
413 for (i = 0; i < nvisuals; i++)
414 if ((depth == visuals[i].visual.depth) &&
415 (visual_type == visuals[i].visual.type))
417 return_val = (GdkVisual*) &(visuals[i]);
425 gdk_query_depths (gint **depths,
428 *count = navailable_depths;
429 *depths = available_depths;
433 gdk_query_visual_types (GdkVisualType **visual_types,
436 *count = navailable_types;
437 *visual_types = available_types;
441 gdk_list_visuals (void)
447 for (i = 0; i < nvisuals; ++i)
448 list = g_list_append (list, (gpointer) &visuals[i]);
454 gdk_visual_lookup (Visual *xvisual)
461 visual = g_hash_table_lookup (visual_hash, xvisual);
466 gdkx_visual_get (VisualID xvisualid)
470 for (i = 0; i < nvisuals; i++)
471 if (xvisualid == visuals[i].xvisual->visualid)
472 return (GdkVisual*) &visuals[i];
478 gdk_visual_add (GdkVisual *visual)
480 GdkVisualPrivate *private;
483 visual_hash = g_hash_table_new ((GHashFunc) gdk_visual_hash,
484 (GCompareFunc) gdk_visual_compare);
486 private = (GdkVisualPrivate*) visual;
488 g_hash_table_insert (visual_hash, private->xvisual, visual);
492 gdk_visual_decompose_mask (gulong mask,
499 while (!(mask & 0x1))
512 /* This hash stuff is pretty useless on Windows, as there is only
516 gdk_visual_hash (Visual *key)
518 return key->visualid;
522 gdk_visual_compare (Visual *a,
525 return (a->visualid == b->visualid);