]> Pileus Git - ~andy/gtk/blob - gdk/gdkvisual.c
changed some debugging messages to be prefixed by "Gdk:".
[~andy/gtk] / gdk / gdkvisual.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 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.
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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free
16  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 #include <X11/Xlib.h>
19 #include <X11/Xutil.h>
20 #include "gdk.h"
21 #include "gdkprivate.h"
22
23
24 static void  gdk_visual_add            (GdkVisual *visual);
25 static void  gdk_visual_decompose_mask (gulong     mask,
26                                         gint      *shift,
27                                         gint      *prec);
28 static guint gdk_visual_hash           (Visual    *key);
29 static gint  gdk_visual_compare        (Visual    *a,
30                                         Visual    *b);
31
32
33 static GdkVisualPrivate *system_visual;
34 static GdkVisualPrivate *visuals;
35 static gint nvisuals;
36
37 static gint available_depths[4];
38 static gint navailable_depths;
39
40 static GdkVisualType available_types[6];
41 static gint navailable_types;
42
43 static gchar* visual_names[] =
44 {
45   "static gray",
46   "grayscale",
47   "static color",
48   "pseudo color",
49   "true color",
50   "direct color",
51 };
52
53 static GHashTable *visual_hash = NULL;
54
55 void
56 gdk_visual_init ()
57 {
58   static gint possible_depths[6] = { 32, 24, 16, 15, 8, 1 };
59   static GdkVisualType possible_types[6] =
60     {
61       GDK_VISUAL_DIRECT_COLOR,
62       GDK_VISUAL_TRUE_COLOR,
63       GDK_VISUAL_PSEUDO_COLOR,
64       GDK_VISUAL_STATIC_COLOR,
65       GDK_VISUAL_GRAYSCALE,
66       GDK_VISUAL_STATIC_GRAY
67     };
68
69   static gint npossible_depths = 6;
70   static gint npossible_types = 6;
71
72   XVisualInfo *visual_list;
73   XVisualInfo visual_template;
74   GdkVisualPrivate temp_visual;
75   Visual *default_xvisual;
76   int nxvisuals;
77   int i, j;
78
79   visual_template.screen = gdk_screen;
80   visual_list = XGetVisualInfo (gdk_display, VisualScreenMask, &visual_template, &nxvisuals);
81   visuals = g_new (GdkVisualPrivate, nxvisuals);
82
83   default_xvisual = DefaultVisual (gdk_display, gdk_screen);
84
85   nvisuals = 0;
86   for (i = 0; i < nxvisuals; i++)
87     {
88       if (visual_list[i].depth >= 1)
89         {
90 #ifdef __cplusplus
91           switch (visual_list[i].c_class)
92 #else /* __cplusplus */
93           switch (visual_list[i].class)
94 #endif /* __cplusplus */
95             {
96             case StaticGray:
97               visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_GRAY;
98               break;
99             case GrayScale:
100               visuals[nvisuals].visual.type = GDK_VISUAL_GRAYSCALE;
101               break;
102             case StaticColor:
103               visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_COLOR;
104               break;
105             case PseudoColor:
106               visuals[nvisuals].visual.type = GDK_VISUAL_PSEUDO_COLOR;
107               break;
108             case TrueColor:
109               visuals[nvisuals].visual.type = GDK_VISUAL_TRUE_COLOR;
110               break;
111             case DirectColor:
112               visuals[nvisuals].visual.type = GDK_VISUAL_DIRECT_COLOR;
113               break;
114             }
115
116           visuals[nvisuals].visual.depth = visual_list[i].depth;
117           visuals[nvisuals].visual.byte_order =
118             (ImageByteOrder(gdk_display) == LSBFirst) ?
119             GDK_LSB_FIRST : GDK_MSB_FIRST;
120           visuals[nvisuals].visual.red_mask = visual_list[i].red_mask;
121           visuals[nvisuals].visual.green_mask = visual_list[i].green_mask;
122           visuals[nvisuals].visual.blue_mask = visual_list[i].blue_mask;
123           visuals[nvisuals].visual.colormap_size = visual_list[i].colormap_size;
124           visuals[nvisuals].visual.bits_per_rgb = visual_list[i].bits_per_rgb;
125           visuals[nvisuals].xvisual = visual_list[i].visual;
126
127           if ((visuals[nvisuals].visual.type == GDK_VISUAL_TRUE_COLOR) ||
128               (visuals[nvisuals].visual.type == GDK_VISUAL_DIRECT_COLOR))
129             {
130               gdk_visual_decompose_mask (visuals[nvisuals].visual.red_mask,
131                                          &visuals[nvisuals].visual.red_shift,
132                                          &visuals[nvisuals].visual.red_prec);
133
134               gdk_visual_decompose_mask (visuals[nvisuals].visual.green_mask,
135                                          &visuals[nvisuals].visual.green_shift,
136                                          &visuals[nvisuals].visual.green_prec);
137
138               gdk_visual_decompose_mask (visuals[nvisuals].visual.blue_mask,
139                                          &visuals[nvisuals].visual.blue_shift,
140                                          &visuals[nvisuals].visual.blue_prec);
141             }
142           else
143             {
144               visuals[nvisuals].visual.red_mask = 0;
145               visuals[nvisuals].visual.red_shift = 0;
146               visuals[nvisuals].visual.red_prec = 0;
147
148               visuals[nvisuals].visual.green_mask = 0;
149               visuals[nvisuals].visual.green_shift = 0;
150               visuals[nvisuals].visual.green_prec = 0;
151
152               visuals[nvisuals].visual.blue_mask = 0;
153               visuals[nvisuals].visual.blue_shift = 0;
154               visuals[nvisuals].visual.blue_prec = 0;
155             }
156
157           nvisuals += 1;
158         }
159     }
160
161   XFree (visual_list);
162
163   for (i = 0; i < nvisuals; i++)
164     {
165       for (j = i+1; j < nvisuals; j++)
166         {
167           if (visuals[j].visual.depth >= visuals[i].visual.depth)
168             {
169               if ((visuals[j].visual.depth == 8) && (visuals[i].visual.depth == 8))
170                 {
171                   if (visuals[j].visual.type == GDK_VISUAL_PSEUDO_COLOR)
172                     {
173                       temp_visual = visuals[j];
174                       visuals[j] = visuals[i];
175                       visuals[i] = temp_visual;
176                     }
177                   else if ((visuals[i].visual.type != GDK_VISUAL_PSEUDO_COLOR) &&
178                            visuals[j].visual.type > visuals[i].visual.type)
179                     {
180                       temp_visual = visuals[j];
181                       visuals[j] = visuals[i];
182                       visuals[i] = temp_visual;
183                     }
184                 }
185               else if ((visuals[j].visual.depth > visuals[i].visual.depth) ||
186                        ((visuals[j].visual.depth == visuals[i].visual.depth) &&
187                         (visuals[j].visual.type > visuals[i].visual.type)))
188                 {
189                   temp_visual = visuals[j];
190                   visuals[j] = visuals[i];
191                   visuals[i] = temp_visual;
192                 }
193             }
194         }
195     }
196
197   for (i = 0; i < nvisuals; i++)
198     if (default_xvisual->visualid == visuals[i].xvisual->visualid)
199       {
200         system_visual = &visuals[i];
201         break;
202       }
203
204 #ifdef G_ENABLE_DEBUG 
205   if (gdk_debug_flags & GDK_DEBUG_MISC)
206     for (i = 0; i < nvisuals; i++)
207       g_print ("Gdk: visual: %s: %d\n",
208                visual_names[visuals[i].visual.type],
209                visuals[i].visual.depth);
210 #endif /* G_ENABLE_DEBUG */
211
212   navailable_depths = 0;
213   for (i = 0; i < npossible_depths; i++)
214     {
215       for (j = 0; j < nvisuals; j++)
216         {
217           if (visuals[j].visual.depth == possible_depths[i])
218             {
219               available_depths[navailable_depths++] = visuals[j].visual.depth;
220               break;
221             }
222         }
223     }
224
225   if (navailable_depths == 0)
226     g_error ("unable to find a usable depth");
227
228   navailable_types = 0;
229   for (i = 0; i < npossible_types; i++)
230     {
231       for (j = 0; j < nvisuals; j++)
232         {
233           if (visuals[j].visual.type == possible_types[i])
234             {
235               available_types[navailable_types++] = visuals[j].visual.type;
236               break;
237             }
238         }
239     }
240
241   for (i = 0; i < nvisuals; i++)
242     gdk_visual_add ((GdkVisual*) &visuals[i]);
243
244   if (npossible_types == 0)
245     g_error ("unable to find a usable visual type");
246 }
247
248 GdkVisual*
249 gdk_visual_ref (GdkVisual *visual)
250 {
251   return visual;
252 }
253
254 void
255 gdk_visual_unref (GdkVisual *visual)
256 {
257   return;
258 }
259
260 gint
261 gdk_visual_get_best_depth ()
262 {
263   return available_depths[0];
264 }
265
266 GdkVisualType
267 gdk_visual_get_best_type ()
268 {
269   return available_types[0];
270 }
271
272 GdkVisual*
273 gdk_visual_get_system ()
274 {
275   return ((GdkVisual*) system_visual);
276 }
277
278 GdkVisual*
279 gdk_visual_get_best ()
280 {
281   return ((GdkVisual*) &(visuals[0]));
282 }
283
284 GdkVisual*
285 gdk_visual_get_best_with_depth (gint depth)
286 {
287   GdkVisual *return_val;
288   int i;
289
290   return_val = NULL;
291   for (i = 0; i < nvisuals; i++)
292     if (depth == visuals[i].visual.depth)
293       {
294         return_val = (GdkVisual*) &(visuals[i]);
295         break;
296       }
297
298   return return_val;
299 }
300
301 GdkVisual*
302 gdk_visual_get_best_with_type (GdkVisualType visual_type)
303 {
304   GdkVisual *return_val;
305   int i;
306
307   return_val = NULL;
308   for (i = 0; i < nvisuals; i++)
309     if (visual_type == visuals[i].visual.type)
310       {
311         return_val = (GdkVisual*) &(visuals[i]);
312         break;
313       }
314
315   return return_val;
316 }
317
318 GdkVisual*
319 gdk_visual_get_best_with_both (gint          depth,
320                                GdkVisualType visual_type)
321 {
322   GdkVisual *return_val;
323   int i;
324
325   return_val = NULL;
326   for (i = 0; i < nvisuals; i++)
327     if ((depth == visuals[i].visual.depth) &&
328         (visual_type == visuals[i].visual.type))
329       {
330         return_val = (GdkVisual*) &(visuals[i]);
331         break;
332       }
333
334   return return_val;
335 }
336
337 void
338 gdk_query_depths  (gint **depths,
339                    gint  *count)
340 {
341   *count = navailable_depths;
342   *depths = available_depths;
343 }
344
345 void
346 gdk_query_visual_types (GdkVisualType **visual_types,
347                         gint           *count)
348 {
349   *count = navailable_types;
350   *visual_types = available_types;
351 }
352
353 GList*
354 gdk_list_visuals (void)
355 {
356   GList *list;
357   guint i;
358
359   list = NULL;
360   for (i = 0; i < nvisuals; ++i)
361     list = g_list_append (list, (gpointer) &visuals[i]);
362
363   return list;
364 }
365
366
367 GdkVisual*
368 gdk_visual_lookup (Visual *xvisual)
369 {
370   GdkVisual *visual;
371
372   if (!visual_hash)
373     return NULL;
374
375   visual = g_hash_table_lookup (visual_hash, xvisual);
376   return visual;
377 }
378
379 GdkVisual*
380 gdkx_visual_get (VisualID xvisualid)
381 {
382   int i;
383
384   for (i = 0; i < nvisuals; i++)
385     if (xvisualid == visuals[i].xvisual->visualid)
386       return (GdkVisual*) &visuals[i];
387
388   return NULL;
389 }
390
391
392 static void
393 gdk_visual_add (GdkVisual *visual)
394 {
395   GdkVisualPrivate *private;
396
397   if (!visual_hash)
398     visual_hash = g_hash_table_new ((GHashFunc) gdk_visual_hash,
399                                     (GCompareFunc) gdk_visual_compare);
400
401   private = (GdkVisualPrivate*) visual;
402
403   g_hash_table_insert (visual_hash, private->xvisual, visual);
404 }
405
406 static void
407 gdk_visual_decompose_mask (gulong  mask,
408                            gint   *shift,
409                            gint   *prec)
410 {
411   *shift = 0;
412   *prec = 0;
413
414   while (!(mask & 0x1))
415     {
416       (*shift)++;
417       mask >>= 1;
418     }
419
420   while (mask & 0x1)
421     {
422       (*prec)++;
423       mask >>= 1;
424     }
425 }
426
427 static guint
428 gdk_visual_hash (Visual *key)
429 {
430   return key->visualid;
431 }
432
433 static gint
434 gdk_visual_compare (Visual *a,
435                     Visual *b)
436 {
437   return (a->visualid == b->visualid);
438 }