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