1/*
2 * Copyright © 2008 Red Hat, Inc
3 *
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of the
9 * copyright holders not be used in advertising or publicity
10 * pertaining to distribution of the software without specific,
11 * written prior permission.  The copyright holders make no
12 * representations about the suitability of this software for any
13 * purpose.  It is provided "as is" without express or implied
14 * warranty.
15 *
16 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
21 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
22 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
23 * SOFTWARE.
24 */
25
26#ifdef HAVE_DIX_CONFIG_H
27#include <dix-config.h>
28#endif
29
30#include <stdint.h>
31#include <errno.h>
32#include <sys/time.h>
33#include <GL/gl.h>
34#include <GL/glxtokens.h>
35#include <GL/internal/dri_interface.h>
36#include <os.h>
37#include "glxserver.h"
38#include "glxcontext.h"
39#include "glxscreens.h"
40#include "glxdricommon.h"
41
42static int
43getUST(int64_t *ust)
44{
45    struct timeval  tv;
46
47    if (ust == NULL)
48	return -EFAULT;
49
50    if (gettimeofday(&tv, NULL) == 0) {
51	ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
52	return 0;
53    } else {
54	return -errno;
55    }
56}
57
58const __DRIsystemTimeExtension systemTimeExtension = {
59    { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
60    getUST,
61    NULL,
62};
63
64#define __ATTRIB(attrib, field) \
65    { attrib, offsetof(__GLXconfig, field) }
66
67static const struct { unsigned int attrib, offset; } attribMap[] = {
68    __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE,			rgbBits),
69    __ATTRIB(__DRI_ATTRIB_LEVEL,			level),
70    __ATTRIB(__DRI_ATTRIB_RED_SIZE,			redBits),
71    __ATTRIB(__DRI_ATTRIB_GREEN_SIZE,			greenBits),
72    __ATTRIB(__DRI_ATTRIB_BLUE_SIZE,			blueBits),
73    __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE,			alphaBits),
74    __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE,			depthBits),
75    __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE,			stencilBits),
76    __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE,		accumRedBits),
77    __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE,		accumGreenBits),
78    __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE,		accumBlueBits),
79    __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE,		accumAlphaBits),
80    __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS,		sampleBuffers),
81    __ATTRIB(__DRI_ATTRIB_SAMPLES,			samples),
82    __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER,		doubleBufferMode),
83    __ATTRIB(__DRI_ATTRIB_STEREO,			stereoMode),
84    __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS,			numAuxBuffers),
85    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE,		transparentPixel),
86    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE,	transparentPixel),
87    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE,	transparentRed),
88    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE,	transparentGreen),
89    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE,	transparentBlue),
90    __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE,	transparentAlpha),
91    __ATTRIB(__DRI_ATTRIB_RED_MASK,			redMask),
92    __ATTRIB(__DRI_ATTRIB_GREEN_MASK,			greenMask),
93    __ATTRIB(__DRI_ATTRIB_BLUE_MASK,			blueMask),
94    __ATTRIB(__DRI_ATTRIB_ALPHA_MASK,			alphaMask),
95    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH,		maxPbufferWidth),
96    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT,		maxPbufferHeight),
97    __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS,		maxPbufferPixels),
98    __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH,	optimalPbufferWidth),
99    __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT,	optimalPbufferHeight),
100    __ATTRIB(__DRI_ATTRIB_SWAP_METHOD,			swapMethod),
101    __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB,		bindToTextureRgb),
102    __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA,		bindToTextureRgba),
103    __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE,	bindToMipmapTexture),
104    __ATTRIB(__DRI_ATTRIB_YINVERTED,			yInverted),
105};
106
107#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
108
109static void
110setScalar(__GLXconfig *config, unsigned int attrib, unsigned int value)
111{
112    int i;
113
114    for (i = 0; i < ARRAY_SIZE(attribMap); i++)
115	if (attribMap[i].attrib == attrib) {
116	    *(unsigned int *) ((char *) config + attribMap[i].offset) = value;
117	    return;
118	}
119}
120
121static __GLXconfig *
122createModeFromConfig(const __DRIcoreExtension *core,
123		     const __DRIconfig *driConfig,
124		     unsigned int visualType, unsigned int drawableType)
125{
126    __GLXDRIconfig *config;
127    unsigned int attrib, value;
128    int i;
129
130    config = malloc(sizeof *config);
131
132    config->driConfig = driConfig;
133
134    i = 0;
135    while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) {
136	switch (attrib) {
137	case __DRI_ATTRIB_RENDER_TYPE:
138	    config->config.renderType = 0;
139	    if (value & __DRI_ATTRIB_RGBA_BIT)
140		config->config.renderType |= GLX_RGBA_BIT;
141	    if (value & __DRI_ATTRIB_COLOR_INDEX_BIT)
142		config->config.renderType |= GLX_COLOR_INDEX_BIT;
143	    break;
144	case __DRI_ATTRIB_CONFIG_CAVEAT:
145	    if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
146		config->config.visualRating = GLX_NON_CONFORMANT_CONFIG;
147	    else if (value & __DRI_ATTRIB_SLOW_BIT)
148		config->config.visualRating = GLX_SLOW_CONFIG;
149	    else
150		config->config.visualRating = GLX_NONE;
151	    break;
152	case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS:
153	    config->config.bindToTextureTargets = 0;
154	    if (value & __DRI_ATTRIB_TEXTURE_1D_BIT)
155		config->config.bindToTextureTargets |= GLX_TEXTURE_1D_BIT_EXT;
156	    if (value & __DRI_ATTRIB_TEXTURE_2D_BIT)
157		config->config.bindToTextureTargets |= GLX_TEXTURE_2D_BIT_EXT;
158	    if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT)
159		config->config.bindToTextureTargets |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
160	    break;
161	default:
162	    setScalar(&config->config, attrib, value);
163	    break;
164	}
165    }
166
167    config->config.next = NULL;
168    config->config.xRenderable = GL_TRUE;
169    config->config.visualType = visualType;
170    config->config.drawableType = drawableType;
171
172    return &config->config;
173}
174
175__GLXconfig *
176glxConvertConfigs(const __DRIcoreExtension *core,
177		  const __DRIconfig **configs, unsigned int drawableType)
178{
179    __GLXconfig head, *tail;
180    int i;
181
182    tail = &head;
183    head.next = NULL;
184
185    for (i = 0; configs[i]; i++) {
186	tail->next = createModeFromConfig(core,
187					  configs[i], GLX_TRUE_COLOR,
188					  drawableType);
189	if (tail->next == NULL)
190	    break;
191
192	tail = tail->next;
193    }
194
195    for (i = 0; configs[i]; i++) {
196	tail->next = createModeFromConfig(core,
197					  configs[i], GLX_DIRECT_COLOR,
198					  drawableType);
199	if (tail->next == NULL)
200	    break;
201
202	tail = tail->next;
203    }
204
205    return head.next;
206}
207