source: trunk/third/gtk/gdk/gdkvisual.c @ 14482

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