VisUtil.c revision 258a0ebe
1/*
2
3Copyright 1986, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30#include "Xlibint.h"
31#include "Xutil.h"
32#include <stdio.h>
33#include "reallocarray.h"
34
35/*
36 *	This procedure returns a list of visual information structures
37 *	that match the specified attributes given in the visual information
38 *	template.
39 *
40 *	If no visuals exist that match the specified attributes, a NULL is
41 *	returned.
42 *
43 *	The choices for visual_info_mask are:
44 *
45 *		VisualNoMask
46 *		VisualIDMask
47 *		VisualScreenMask
48 *		VisualDepthMask
49 *		VisualClassMask
50 *		VisualRedMaskMask
51 *		VisualGreenMaskMask
52 *		VisualBlueMaskMask
53 *		VisualColormapSizeMask
54 *		VisualBitsPerRGBMask
55 *		VisualAllMask
56 */
57
58XVisualInfo *XGetVisualInfo(
59    Display *dpy,
60    register long visual_info_mask,
61    register XVisualInfo *visual_info_template,
62    int *nitems)	/* RETURN */
63{
64
65  register Visual *vp;
66  register Depth *dp;
67  Screen *sp;
68  int ii,screen_s,screen_e,total,count;
69  register XVisualInfo *vip,*vip_base;
70
71  /* NOTE: NO HIGH PERFORMING CODE TO BE FOUND HERE */
72
73  LockDisplay(dpy);
74
75  /* ALLOCATE THE ORIGINAL BUFFER; REALLOCED LATER IF OVERFLOW OCCURS;
76     FREED AT END IF NO VISUALS ARE FOUND */
77
78  count = 0;
79  total = 10;
80  if (! (vip_base = vip = Xmallocarray(total, sizeof(XVisualInfo)))) {
81      UnlockDisplay(dpy);
82      return (XVisualInfo *) NULL;
83  }
84
85  /* DETERMINE IF WE DO ALL SCREENS OR ONLY ONE */
86
87  screen_s = 0;
88  screen_e = dpy->nscreens;
89  if (visual_info_mask & VisualScreenMask)
90    {
91      screen_s = visual_info_template->screen;
92      if (screen_s < 0 || screen_s >= screen_e)
93	  screen_e = screen_s;
94      else
95	  screen_e = screen_s + 1;
96    }
97
98  /* LOOP THROUGH SCREENS */
99
100  for (ii=screen_s; ii<screen_e; ii++)
101    {
102      sp = (Screen *)(&dpy->screens[ii]);
103
104      /* LOOP THROUGH DEPTHS */
105
106      for (dp=sp->depths; dp < (sp->depths + sp->ndepths); dp++)
107        {
108          if ((visual_info_mask & VisualDepthMask) &&
109	      (dp->depth != visual_info_template->depth)) continue;
110
111          /* LOOP THROUGH VISUALS */
112
113	  if (dp->visuals) {
114	    for (vp=dp->visuals; vp<(dp->visuals + dp->nvisuals); vp++) {
115              if ((visual_info_mask & VisualIDMask) &&
116                (vp->visualid != visual_info_template->visualid)) continue;
117              if ((visual_info_mask & VisualClassMask) &&
118                (vp->class != visual_info_template->class)) continue;
119              if ((visual_info_mask & VisualRedMaskMask) &&
120                (vp->red_mask != visual_info_template->red_mask)) continue;
121              if ((visual_info_mask & VisualGreenMaskMask) &&
122                (vp->green_mask != visual_info_template->green_mask)) continue;
123              if ((visual_info_mask & VisualBlueMaskMask) &&
124                (vp->blue_mask != visual_info_template->blue_mask)) continue;
125              if ((visual_info_mask & VisualColormapSizeMask) &&
126                (vp->map_entries != visual_info_template->colormap_size)) continue;
127              if ((visual_info_mask & VisualBitsPerRGBMask) &&
128                (vp->bits_per_rgb != visual_info_template->bits_per_rgb)) continue;
129
130              /* YEA!!! WE FOUND A GOOD ONE */
131
132              if (count+1 > total)
133                {
134		  XVisualInfo *old_vip_base = vip_base;
135                  total += 10;
136                  if (! (vip_base = Xreallocarray(vip_base, total,
137                                                  sizeof(XVisualInfo)))) {
138		      Xfree(old_vip_base);
139		      UnlockDisplay(dpy);
140		      return (XVisualInfo *) NULL;
141		  }
142                  vip = &vip_base[count];
143                }
144
145              count++;
146
147              vip->visual = _XVIDtoVisual(dpy, vp->visualid);
148              vip->visualid = vp->visualid;
149              vip->screen = ii;
150              vip->depth = dp->depth;
151              vip->class = vp->class;
152              vip->red_mask = vp->red_mask;
153              vip->green_mask = vp->green_mask;
154              vip->blue_mask = vp->blue_mask;
155              vip->colormap_size = vp->map_entries;
156              vip->bits_per_rgb = vp->bits_per_rgb;
157
158              vip++;
159
160            } /* END OF LOOP ON VISUALS */
161	  } /* END OF IF THERE ARE ANY VISUALS AT THIS DEPTH */
162
163        } /* END OF LOOP ON DEPTHS */
164
165    } /* END OF LOOP ON SCREENS */
166
167  UnlockDisplay(dpy);
168
169  if (count)
170    {
171      *nitems = count;
172      return vip_base;
173    }
174
175  Xfree(vip_base);
176  *nitems = 0;
177  return NULL;
178}
179
180
181/*
182 *	This procedure will return the visual information for a visual
183 *      that matches the specified depth and class for a screen.  Since
184 *	multiple visuals may exist that match the specified depth and
185 *	class, which visual chosen is undefined.
186 *
187 *	If a visual is found, True is returned as the function value,
188 *	otherwise False is returned.
189 */
190
191Status XMatchVisualInfo(
192	Display *dpy,
193	int screen,
194	int depth,
195	int class,
196	XVisualInfo *visual_info) /* RETURNED */
197{
198
199  Visual *vp;
200  Depth *dp;
201  Screen *sp;
202  int ii,jj;
203
204  if (screen < 0 || screen >= dpy->nscreens)
205      return False;
206
207  LockDisplay(dpy);
208
209  sp = (Screen *)(&dpy->screens[screen]);
210
211  dp = sp->depths;
212
213  for (ii=0; ii < sp->ndepths; ii++)
214    {
215
216    /* LOOK THROUGH DEPTHS FOR THE WANTED DEPTH */
217
218    if (dp->depth == depth)
219      {
220        vp = dp->visuals;
221
222        /* LOOK THROUGH VISUALS FOR THE WANTED CLASS */
223
224	/* if nvisuals == 0 then vp will be NULL */
225        for (jj=0; jj<dp->nvisuals; jj++)
226          {
227            if (vp->class == class)
228              {
229		visual_info->visual = _XVIDtoVisual(dpy, vp->visualid);
230		visual_info->visualid = vp->visualid;
231		visual_info->screen = screen;
232		visual_info->depth = depth;
233		visual_info->class = vp->class;
234		visual_info->red_mask = vp->red_mask;
235		visual_info->green_mask = vp->green_mask;
236		visual_info->blue_mask = vp->blue_mask;
237		visual_info->colormap_size = vp->map_entries;
238		visual_info->bits_per_rgb = vp->bits_per_rgb;
239                UnlockDisplay(dpy);
240                return True;
241              }
242            vp++;
243          }
244      }
245
246    dp++;
247
248    }
249
250  UnlockDisplay(dpy);
251
252  return False;
253
254}
255