Added support for OpenGL.
[wine] / dlls / opengl32 / wgl.c
1 /* Window-specific OpenGL functions implementation.
2
3      Copyright (c) 1999 Lionel Ulmer
4 */
5
6 #include <stdlib.h>
7
8 #include "config.h"
9 #include "debugtools.h"
10 #include "gdi.h"
11 #include "dc.h"
12 #include "windef.h"
13 #include "wine_gl.h"
14 #include "x11drv.h"
15
16 #include "wgl.h"
17 #include "opengl_ext.h"
18
19 DEFAULT_DEBUG_CHANNEL(opengl)
20
21 HGLRC WINAPI wglCreateContext(HDC hdc) {
22   DC * dc = DC_GetDCPtr( hdc );
23   X11DRV_PDEVICE *physDev;
24   XVisualInfo *vis;
25   GLXContext ret;
26
27   TRACE("(%08x)\n", hdc);
28
29   if (dc == NULL) {
30     ERR("Null DC !!!\n");
31     return NULL;
32   }
33   
34   physDev = (X11DRV_PDEVICE *)dc->physDev;
35
36   /* First, get the visual for the choosen pixel format */
37   vis = physDev->visuals[physDev->current_pf - 1];
38
39   if (vis == NULL) {
40     ERR("NULL visual !!!\n");
41     /* Need to set errors here */
42     return NULL;
43   }
44   
45   ENTER_GL();
46   ret = glXCreateContext(display, vis, NULL, True);
47   LEAVE_GL();
48
49   return (HGLRC) ret;
50 }
51
52 HGLRC WINAPI wglCreateLayerContext(HDC hdc,
53                                    int iLayerPlane) {
54   FIXME("(%08x,%d): stub !\n", hdc, iLayerPlane);
55
56   return NULL;
57 }
58
59 BOOL WINAPI wglCopyContext(HGLRC hglrcSrc,
60                            HGLRC hglrcDst,
61                            UINT mask) {
62   FIXME("(%p,%p,%d)\n", hglrcSrc, hglrcDst, mask);
63
64   return FALSE;
65 }
66
67 BOOL WINAPI wglDeleteContext(HGLRC hglrc) {
68   FIXME("(%p): stub !\n", hglrc);
69
70   return FALSE;
71 }
72
73 BOOL WINAPI wglDescribeLayerPlane(HDC hdc,
74                                   int iPixelFormat,
75                                   int iLayerPlane,
76                                   UINT nBytes,
77                                   LPLAYERPLANEDESCRIPTOR plpd) {
78   FIXME("(%08x,%d,%d,%d,%p)\n", hdc, iPixelFormat, iLayerPlane, nBytes, plpd);
79
80   return FALSE;
81 }
82
83 HGLRC WINAPI wglGetCurrentContext(void) {
84   GLXContext ret;
85
86   TRACE("()\n");
87
88   ENTER_GL();
89   ret = glXGetCurrentContext();
90   LEAVE_GL();
91
92   TRACE(" returning %p\n", ret);
93   
94   return ret;
95 }
96
97 HDC WINAPI wglGetCurrentDC(void) {
98   GLXContext ret;
99
100   ENTER_GL();
101   ret = glXGetCurrentContext();
102   LEAVE_GL();
103
104   if (ret == NULL) {
105     TRACE("() no current context -> returning NULL\n");
106     return 0;
107   } else {
108     FIXME("()\n");
109
110     return 0;
111   }
112 }
113
114 int WINAPI wglGetLayerPaletteEntries(HDC hdc,
115                                      int iLayerPlane,
116                                      int iStart,
117                                      int cEntries,
118                                      const COLORREF *pcr) {
119   FIXME("(): stub !\n");
120
121   return 0;
122 }
123
124 static int compar(const void *elt_a, const void *elt_b) {
125   return strcmp(((OpenGL_extension *) elt_a)->name,
126                 ((OpenGL_extension *) elt_b)->name);
127 }
128
129 void* WINAPI wglGetProcAddress(LPCSTR  lpszProc) {
130   void *local_func;
131   static HMODULE hm = 0;
132
133   TRACE("(%s)\n", lpszProc);
134
135   if (hm == 0)
136       hm = GetModuleHandleA("opengl32");
137
138   /* First, look if it's not already defined in the 'standard' OpenGL functions */
139   if ((local_func = GetProcAddress(hm, lpszProc)) != NULL) {
140     TRACE("Found function in 'standard' OpenGL functions (%p)\n", local_func);
141     return local_func;
142   }
143
144   /* After that, look at the extensions defined in the Linux OpenGL library */
145   if ((local_func = glXGetProcAddressARB(lpszProc)) == NULL) {
146     char buf[256];
147     void *ret = NULL;
148     
149     /* Remove the 3 last letters (EXT, ARB, ...).
150        
151        I know that some extensions have more than 3 letters (MESA, NV,
152        INTEL, ...), but this is only a stop-gap measure to fix buggy
153        OpenGL drivers (moreover, it is only useful for old 1.0 apps
154        that query the glBindTextureEXT extension).
155     */
156     strncpy(buf, lpszProc, strlen(lpszProc) - 3);
157     buf[strlen(lpszProc) - 3] = '\0';
158     TRACE("Extension not found in the Linux OpenGL library, checking against libGL bug with %s..\n", buf);
159     
160     ret = GetProcAddress(hm, buf);
161     if (ret != NULL) {
162       TRACE("Found function in main OpenGL library (%p) !\n", ret);
163     }
164
165     return ret;
166   } else {
167     OpenGL_extension  ext;
168     OpenGL_extension *ret;
169
170     ext.name = (char *) lpszProc;
171     ret = (OpenGL_extension *) bsearch(&ext, extension_registry,
172                                        extension_registry_size, sizeof(OpenGL_extension), compar);
173
174     if (ret != NULL) {
175       TRACE("Returning function  (%p)\n", ret->func);
176       *(ret->func_ptr) = local_func;
177
178       return ret->func;
179     } else {
180       ERR("Extension defined in the OpenGL library but NOT in opengl_ext.c... Please report (lionel.ulmer@free.fr) !\n");
181       return NULL;
182     }
183   }
184 }
185
186 BOOL WINAPI wglMakeCurrent(HDC hdc,
187                            HGLRC hglrc) {
188   DC * dc = DC_GetDCPtr( hdc );
189   X11DRV_PDEVICE *physDev;
190   BOOL ret;
191
192   TRACE("(%08x,%p)\n", hdc, hglrc);
193
194   if (dc == NULL) {
195     ERR("Null DC !!!\n");
196     return FALSE;
197   }
198   
199   physDev =(X11DRV_PDEVICE *)dc->physDev;
200
201   ENTER_GL();
202   ret = glXMakeCurrent(display, physDev->drawable, (GLXContext) hglrc);
203   LEAVE_GL();
204   
205   return ret;
206 }
207
208 BOOL WINAPI wglRealizeLayerPalette(HDC hdc,
209                                    int iLayerPlane,
210                                    BOOL bRealize) {
211   FIXME("()\n");
212
213   return FALSE;
214 }
215
216 int WINAPI wglSetLayerPaletteEntries(HDC hdc,
217                                      int iLayerPlane,
218                                      int iStart,
219                                      int cEntries,
220                                      const COLORREF *pcr) {
221   FIXME("(): stub !\n");
222
223   return 0;
224 }
225
226 BOOL WINAPI wglShareLists(HGLRC hglrc1,
227                           HGLRC hglrc2) {
228   FIXME("(): stub !\n");
229
230   return FALSE;
231 }
232
233 BOOL WINAPI wglSwapLayerBuffers(HDC hdc,
234                                 UINT fuPlanes) {
235   FIXME("(): stub !\n");
236
237   return FALSE;
238 }
239
240 BOOL WINAPI wglUseFontBitmaps(HDC hdc,
241                               DWORD first,
242                               DWORD count,
243                               DWORD listBase) {
244   FIXME("(): stub !\n");
245
246   return FALSE;
247 }
248  
249 BOOL WINAPI wglUseFontOutlines(HDC hdc,
250                                DWORD first,
251                                DWORD count,
252                                DWORD listBase,
253                                FLOAT deviation,
254                                FLOAT extrusion,
255                                int format,
256                                LPGLYPHMETRICSFLOAT lpgmf) {
257   FIXME("(): stub !\n");
258
259   return FALSE;
260 }
261
262 /* This is for brain-dead applications that use OpenGL functions before even
263    creating a rendering context.... */
264 DECL_GLOBAL_CONSTRUCTOR(OpenGL_create_default_context) {
265   int num;
266   XVisualInfo template;
267   XVisualInfo *vis;
268   GLXContext cx;
269
270   ENTER_GL();
271   template.visualid = XVisualIDFromVisual(visual);
272   vis = XGetVisualInfo(display, VisualIDMask, &template, &num);
273   cx=glXCreateContext(display, vis, 0, GL_TRUE);
274   glXMakeCurrent(display, X11DRV_GetXRootWindow(), cx);
275   LEAVE_GL();
276 }