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