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