Added an unknown VxD error code.
[wine] / graphics / x11drv / opengl.c
1 /* 
2  * X11DRV OpenGL functions
3  *
4  * Copyright 2000 Lionel Ulmer
5  *
6  */
7
8 #include "config.h"
9
10 #include "ts_xlib.h"
11
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include "debugtools.h"
16 #include "gdi.h"
17 #include "x11drv.h"
18 #include "wine_gl.h"
19
20 DEFAULT_DEBUG_CHANNEL(opengl);
21
22 #ifdef HAVE_OPENGL
23
24 static void dump_PIXELFORMATDESCRIPTOR(PIXELFORMATDESCRIPTOR *ppfd) {
25   DPRINTF("  - size / version : %d / %d\n", ppfd->nSize, ppfd->nVersion);
26   DPRINTF("  - dwFlags : ");
27 #define TEST_AND_DUMP(t,tv) if ((t) & (tv)) DPRINTF(#tv " ")
28   TEST_AND_DUMP(ppfd->dwFlags, PFD_DEPTH_DONTCARE);
29   TEST_AND_DUMP(ppfd->dwFlags, PFD_DOUBLEBUFFER);
30   TEST_AND_DUMP(ppfd->dwFlags, PFD_DOUBLEBUFFER_DONTCARE);
31   TEST_AND_DUMP(ppfd->dwFlags, PFD_DRAW_TO_WINDOW);
32   TEST_AND_DUMP(ppfd->dwFlags, PFD_DRAW_TO_BITMAP);
33   TEST_AND_DUMP(ppfd->dwFlags, PFD_GENERIC_ACCELERATED);
34   TEST_AND_DUMP(ppfd->dwFlags, PFD_GENERIC_FORMAT);
35   TEST_AND_DUMP(ppfd->dwFlags, PFD_NEED_PALETTE);
36   TEST_AND_DUMP(ppfd->dwFlags, PFD_NEED_SYSTEM_PALETTE);
37   TEST_AND_DUMP(ppfd->dwFlags, PFD_STEREO);
38   TEST_AND_DUMP(ppfd->dwFlags, PFD_STEREO_DONTCARE);
39   TEST_AND_DUMP(ppfd->dwFlags, PFD_SUPPORT_GDI);
40   TEST_AND_DUMP(ppfd->dwFlags, PFD_SUPPORT_OPENGL);
41   TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_COPY);
42   TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_EXCHANGE);
43   TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_LAYER_BUFFERS);
44 #undef TEST_AND_DUMP
45   DPRINTF("\n");
46   
47   DPRINTF("  - iPixelType : ");
48   switch (ppfd->iPixelType) {
49   case PFD_TYPE_RGBA: DPRINTF("PFD_TYPE_RGBA"); break;
50   case PFD_TYPE_COLORINDEX: DPRINTF("PFD_TYPE_COLORINDEX"); break;
51   }
52   DPRINTF("\n");
53   
54   DPRINTF("  - Color   : %d\n", ppfd->cColorBits);
55   DPRINTF("  - Alpha   : %d\n", ppfd->cAlphaBits);
56   DPRINTF("  - Accum   : %d\n", ppfd->cAccumBits);
57   DPRINTF("  - Depth   : %d\n", ppfd->cDepthBits);
58   DPRINTF("  - Stencil : %d\n", ppfd->cStencilBits);
59   DPRINTF("  - Aux     : %d\n", ppfd->cAuxBuffers);
60   
61   DPRINTF("  - iLayerType : ");
62   switch (ppfd->iLayerType) {
63   case PFD_MAIN_PLANE: DPRINTF("PFD_MAIN_PLANE"); break;
64   case PFD_OVERLAY_PLANE: DPRINTF("PFD_OVERLAY_PLANE"); break;
65   case PFD_UNDERLAY_PLANE: DPRINTF("PFD_UNDERLAY_PLANE"); break;
66   }
67   DPRINTF("\n");
68 }
69      
70 /* X11DRV_ChoosePixelFormat
71
72      Equivalent of glXChooseVisual
73 */
74 int X11DRV_ChoosePixelFormat(DC *dc,
75                              const PIXELFORMATDESCRIPTOR *ppfd) {
76 #define TEST_AND_ADD1(t,a) if (t) att_list[att_pos++] = a
77 #define TEST_AND_ADD2(t,a,b) if (t) { att_list[att_pos++] = a; att_list[att_pos++] = b; }
78 #define NULL_TEST_AND_ADD2(tv,a,b) att_list[att_pos++] = a; att_list[att_pos++] = ((tv) == 0 ? 0 : b)
79 #define ADD2(a,b) att_list[att_pos++] = a; att_list[att_pos++] = b
80   
81   X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
82   int att_list[64];
83   int att_pos = 0;
84   XVisualInfo *vis;
85   
86   if (TRACE_ON(opengl)) {
87     TRACE("(%p,%p)\n", dc, ppfd);
88     
89     dump_PIXELFORMATDESCRIPTOR((PIXELFORMATDESCRIPTOR *) ppfd);
90   }
91
92   /* For the moment, we are dumb : we always allocate a new XVisualInfo structure,
93      we do not try to find an already found that could match */
94   if (physDev->used_visuals == MAX_PIXELFORMATS) {
95     ERR("Maximum number of visuals reached !\n");
96     /* Should SetError here... */
97     return 0;
98   }
99
100   if (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) {
101     ERR("Flag not supported !\n");
102     /* Should SetError here... */
103     return 0;
104   }
105
106   /* Now, build the request to GLX */
107   TEST_AND_ADD1(ppfd->dwFlags & PFD_DOUBLEBUFFER, GLX_DOUBLEBUFFER);
108   TEST_AND_ADD1(ppfd->dwFlags & PFD_STEREO, GLX_STEREO);
109   TEST_AND_ADD1(ppfd->iPixelType == PFD_TYPE_RGBA, GLX_RGBA);
110   TEST_AND_ADD2(ppfd->iPixelType == PFD_TYPE_COLORINDEX, GLX_BUFFER_SIZE, ppfd->cColorBits);
111
112   NULL_TEST_AND_ADD2(ppfd->cDepthBits, GLX_DEPTH_SIZE, 8);
113   /* These flags are not supported yet...
114      
115      NULL_TEST_AND_ADD2(ppfd->cAlphaBits, GLX_ALPHA_SIZE, 8);
116      ADD2(GLX_ACCUM_SIZE, ppfd->cAccumBits); 
117      ADD2(GLX_STENCIL_SIZE, ppfd->cStencilBits);
118      ADD2(GLX_AUX_BUFFERS, ppfd->cAuxBuffers); */
119   att_list[att_pos] = None;
120   
121   ENTER_GL(); {
122     /*
123        This command cannot be used as we need to use the default visual...
124        Let's hope it at least contains some OpenGL functionnalities
125        
126        vis = glXChooseVisual(gdi_display, DefaultScreen(gdi_display), att_list);
127     */
128     int num;
129     XVisualInfo template;
130
131     template.visualid = XVisualIDFromVisual(visual);
132     vis = XGetVisualInfo(gdi_display, VisualIDMask, &template, &num);
133
134     TRACE("Found visual : %p - returns %d\n", vis, physDev->used_visuals + 1);
135   }
136   LEAVE_GL();
137   
138   if (vis == NULL) {
139     ERR("No visual found !\n");
140     /* Should SetError here... */
141     return 0;
142   }
143   physDev->visuals[physDev->used_visuals++] = vis;
144   
145   return physDev->used_visuals;
146 }
147
148 /* X11DRV_DescribePixelFormat
149
150      Get the pixel-format descriptor associated to the given id
151 */
152 int X11DRV_DescribePixelFormat(DC *dc,
153                                int iPixelFormat,
154                                UINT nBytes,
155                                PIXELFORMATDESCRIPTOR *ppfd) {
156   X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
157   XVisualInfo *vis;
158   int value;
159   int rb,gb,bb,ab;
160   
161   TRACE("(%p,%d,%d,%p)\n", dc, iPixelFormat, nBytes, ppfd);
162   
163   if (nBytes < sizeof(PIXELFORMATDESCRIPTOR)) {
164     ERR("Wrong structure size !\n");
165     /* Should set error */
166     return 0;
167   }
168   if ((iPixelFormat > MAX_PIXELFORMATS) ||
169       (iPixelFormat > physDev->used_visuals + 1) ||
170       (iPixelFormat <= 0)) {
171     ERR("Wrong pixel format !\n");
172     /* Should set error */
173     return 0;
174   }
175       
176   if (iPixelFormat == physDev->used_visuals + 1) {
177     int dblBuf[]={GLX_RGBA,GLX_DEPTH_SIZE,16,GLX_DOUBLEBUFFER,None};
178
179     /* Create a 'standard' X Visual */
180     ENTER_GL();
181     vis = glXChooseVisual(gdi_display, DefaultScreen(gdi_display), dblBuf);
182     LEAVE_GL();
183     
184     WARN("Uninitialized Visual. Creating standard (%p) !\n", vis);
185
186     if (vis == NULL) {
187       ERR("Could not create standard visual !\n");
188       /* Should set error */
189       return 0;
190     }
191     
192     physDev->visuals[physDev->used_visuals++] = vis;
193   }
194   vis = physDev->visuals[iPixelFormat - 1];
195
196   memset(ppfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
197   ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
198   ppfd->nVersion = 1;
199   
200   /* These flags are always the same... */
201   ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED;
202   /* Now the flags extraced from the Visual */
203   ENTER_GL();
204   glXGetConfig(gdi_display, vis, GLX_DOUBLEBUFFER, &value); if (value) ppfd->dwFlags |= PFD_DOUBLEBUFFER;
205   glXGetConfig(gdi_display, vis, GLX_STEREO, &value); if (value) ppfd->dwFlags |= PFD_STEREO;
206
207   /* Pixel type */
208   glXGetConfig(gdi_display, vis, GLX_RGBA, &value);
209   if (value)
210     ppfd->iPixelType = PFD_TYPE_RGBA;
211   else
212     ppfd->iPixelType = PFD_TYPE_COLORINDEX;
213
214   /* Color bits */
215   glXGetConfig(gdi_display, vis, GLX_BUFFER_SIZE, &value);
216   ppfd->cColorBits = value;
217
218   /* Red, green, blue and alpha bits / shifts */
219   if (ppfd->iPixelType == PFD_TYPE_RGBA) {
220     glXGetConfig(gdi_display, vis, GLX_RED_SIZE, &rb);
221     glXGetConfig(gdi_display, vis, GLX_GREEN_SIZE, &gb);
222     glXGetConfig(gdi_display, vis, GLX_BLUE_SIZE, &bb);
223     glXGetConfig(gdi_display, vis, GLX_ALPHA_SIZE, &ab);
224
225     ppfd->cRedBits = rb;
226     ppfd->cRedShift = gb + bb + ab;
227     ppfd->cBlueBits = bb;
228     ppfd->cBlueShift = ab;
229     ppfd->cGreenBits = gb;
230     ppfd->cGreenShift = bb + ab;
231     ppfd->cAlphaBits = ab;
232     ppfd->cAlphaShift = 0;
233   } else {
234     ppfd->cRedBits = 0;
235     ppfd->cRedShift = 0;
236     ppfd->cBlueBits = 0;
237     ppfd->cBlueShift = 0;
238     ppfd->cGreenBits = 0;
239     ppfd->cGreenShift = 0;
240     ppfd->cAlphaBits = 0;
241     ppfd->cAlphaShift = 0;
242   }
243   /* Accums : to do ... */
244   
245   /* Depth bits */
246   glXGetConfig(gdi_display, vis, GLX_DEPTH_SIZE, &value);
247   ppfd->cDepthBits = value;
248   LEAVE_GL();
249
250   /* Aux, stencil : to do ... */
251
252   ppfd->iLayerType = PFD_MAIN_PLANE;
253   
254   if (TRACE_ON(opengl)) {
255     dump_PIXELFORMATDESCRIPTOR(ppfd);
256   }
257   
258   return MAX_PIXELFORMATS;
259 }
260
261 /* X11DRV_GetPixelFormat
262
263      Get the pixel-format id used by this DC
264 */
265 int X11DRV_GetPixelFormat(DC *dc) {
266   X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
267   
268   TRACE("(%p): returns %d\n", dc, physDev->current_pf);
269
270   return physDev->current_pf;
271 }
272
273 /* X11DRV_SetPixelFormat
274
275      Set the pixel-format id used by this DC
276 */
277 BOOL X11DRV_SetPixelFormat(DC *dc,
278                            int iPixelFormat,
279                            const PIXELFORMATDESCRIPTOR *ppfd) {
280   X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
281   
282   TRACE("(%p,%d,%p)\n", dc, iPixelFormat, ppfd);
283
284   physDev->current_pf = iPixelFormat;
285   
286   return TRUE;
287 }
288
289 /* X11DRV_SwapBuffers
290
291      Swap the buffers of this DC
292 */
293 BOOL X11DRV_SwapBuffers(DC *dc) {
294   X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
295   
296   TRACE("(%p)\n", dc);
297
298   ENTER_GL();
299   glXSwapBuffers(gdi_display, physDev->drawable);
300   LEAVE_GL();
301   
302   return TRUE;
303 }
304
305 #else  /* defined(HAVE_OPENGL) */
306
307 int X11DRV_ChoosePixelFormat(DC *dc,
308                              const PIXELFORMATDESCRIPTOR *ppfd) {
309   ERR("No OpenGL support compiled in.\n");
310
311   return 0;
312 }
313
314 int X11DRV_DescribePixelFormat(DC *dc,
315                                int iPixelFormat,
316                                UINT nBytes,
317                                PIXELFORMATDESCRIPTOR *ppfd) {
318   ERR("No OpenGL support compiled in.\n");
319   
320   return 0;
321 }
322
323 int X11DRV_GetPixelFormat(DC *dc) {
324   ERR("No OpenGL support compiled in.\n");
325   
326   return 0;
327 }
328
329 BOOL X11DRV_SetPixelFormat(DC *dc,
330                            int iPixelFormat,
331                            const PIXELFORMATDESCRIPTOR *ppfd) {
332   ERR("No OpenGL support compiled in.\n");
333   
334   return FALSE;
335 }
336
337 BOOL X11DRV_SwapBuffers(DC *dc) {
338   ERR("No OpenGL support compiled in.\n");
339   
340   return FALSE;
341 }
342
343 #endif /* defined(HAVE_OPENGL) */