1 /* Window-specific OpenGL functions implementation.
3 Copyright (c) 1999 Lionel Ulmer
8 #include "wine/exception.h"
11 #include "debugtools.h"
21 #include "opengl_ext.h"
23 DEFAULT_DEBUG_CHANNEL(opengl);
25 typedef struct wine_glcontext {
29 struct wine_glcontext *next;
30 struct wine_glcontext *prev;
32 static Wine_GLContext *context_array;
34 static inline Wine_GLContext *get_context_from_GLXContext(GLXContext ctx) {
35 Wine_GLContext *ret = context_array;
36 while (ret != NULL) if (ctx == ret->ctx) break; else ret = ret->next;
40 static inline void free_context(Wine_GLContext *context) {
41 if (context->next != NULL) context->next->prev = context->prev;
42 if (context->prev != NULL) context->prev->next = context->next;
43 else context_array = context->next;
45 HeapFree(GetProcessHeap(), 0, context);
48 static inline Wine_GLContext *alloc_context(void) {
51 ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLContext));
52 ret->next = context_array;
53 if (context_array != NULL) context_array->prev = ret;
54 else context_array = ret;
60 static int XGLErrorFlag = 0;
61 static int XGLErrorHandler(Display *dpy, XErrorEvent *event) {
65 /* filter for page-fault exceptions */
66 static WINE_EXCEPTION_FILTER(page_fault)
68 return EXCEPTION_EXECUTE_HANDLER;
71 /***********************************************************************
74 HGLRC WINAPI wglCreateContext(HDC hdc) {
75 DC * dc = DC_GetDCPtr( hdc );
76 X11DRV_PDEVICE *physDev;
80 TRACE("(%08x)\n", hdc);
87 physDev = (X11DRV_PDEVICE *)dc->physDev;
89 /* First, get the visual for the choosen pixel format */
90 vis = physDev->visuals[physDev->current_pf - 1];
93 ERR("NULL visual !!!\n");
94 /* Need to set errors here */
98 /* The context will be allocated in the wglMakeCurrent call */
100 ret = alloc_context();
105 TRACE(" creating context %p (GL context creation delayed)\n", ret);
110 /***********************************************************************
111 * wglCreateLayerContext
113 HGLRC WINAPI wglCreateLayerContext(HDC hdc,
115 FIXME("(%08x,%d): stub !\n", hdc, iLayerPlane);
120 /***********************************************************************
123 BOOL WINAPI wglCopyContext(HGLRC hglrcSrc,
126 FIXME("(%p,%p,%d)\n", hglrcSrc, hglrcDst, mask);
131 /***********************************************************************
134 BOOL WINAPI wglDeleteContext(HGLRC hglrc) {
135 int (*WineXHandler)(Display *, XErrorEvent *);
136 Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
139 TRACE("(%p)\n", hglrc);
142 /* A game (Half Life not to name it) deletes twice the same context. To prevent
143 crashes, run with our own error function enabled */
144 XSync(display, False);
146 WineXHandler = XSetErrorHandler(XGLErrorHandler);
148 glXDestroyContext(display, ctx->ctx);
149 XSync(display, False);
152 if (XGLErrorHandler == 0) free_context(ctx);
154 __EXCEPT(page_fault) {
160 XSetErrorHandler(WineXHandler);
162 WARN("Error deleting context !\n");
163 SetLastError(ERROR_INVALID_HANDLE);
171 /***********************************************************************
172 * wglDescribeLayerPlane
174 BOOL WINAPI wglDescribeLayerPlane(HDC hdc,
178 LPLAYERPLANEDESCRIPTOR plpd) {
179 FIXME("(%08x,%d,%d,%d,%p)\n", hdc, iPixelFormat, iLayerPlane, nBytes, plpd);
184 /***********************************************************************
185 * wglGetCurrentContext
187 HGLRC WINAPI wglGetCurrentContext(void) {
194 gl_ctx = glXGetCurrentContext();
195 ret = get_context_from_GLXContext(gl_ctx);
198 TRACE(" returning %p (GL context %p)\n", ret, gl_ctx);
203 /***********************************************************************
206 HDC WINAPI wglGetCurrentDC(void) {
213 gl_ctx = glXGetCurrentContext();
214 ret = get_context_from_GLXContext(gl_ctx);
218 TRACE(" returning %08x (GL context %p - Wine context %p)\n", ret->hdc, gl_ctx, ret);
221 TRACE(" no Wine context found for GLX context %p\n", gl_ctx);
226 /***********************************************************************
227 * wglGetLayerPaletteEntries
229 int WINAPI wglGetLayerPaletteEntries(HDC hdc,
233 const COLORREF *pcr) {
234 FIXME("(): stub !\n");
239 static int compar(const void *elt_a, const void *elt_b) {
240 return strcmp(((OpenGL_extension *) elt_a)->name,
241 ((OpenGL_extension *) elt_b)->name);
244 /***********************************************************************
247 void* WINAPI wglGetProcAddress(LPCSTR lpszProc) {
249 static HMODULE hm = 0;
251 TRACE("(%s)\n", lpszProc);
254 hm = GetModuleHandleA("opengl32");
256 /* First, look if it's not already defined in the 'standard' OpenGL functions */
257 if ((local_func = GetProcAddress(hm, lpszProc)) != NULL) {
258 TRACE(" found function in 'standard' OpenGL functions (%p)\n", local_func);
262 /* After that, look at the extensions defined in the Linux OpenGL library */
263 if ((local_func = glXGetProcAddressARB(lpszProc)) == NULL) {
267 /* Remove the 3 last letters (EXT, ARB, ...).
269 I know that some extensions have more than 3 letters (MESA, NV,
270 INTEL, ...), but this is only a stop-gap measure to fix buggy
271 OpenGL drivers (moreover, it is only useful for old 1.0 apps
272 that query the glBindTextureEXT extension).
274 strncpy(buf, lpszProc, strlen(lpszProc) - 3);
275 buf[strlen(lpszProc) - 3] = '\0';
276 TRACE(" extension not found in the Linux OpenGL library, checking against libGL bug with %s..\n", buf);
278 ret = GetProcAddress(hm, buf);
280 TRACE(" found function in main OpenGL library (%p) !\n", ret);
285 OpenGL_extension ext;
286 OpenGL_extension *ret;
288 ext.name = (char *) lpszProc;
289 ret = (OpenGL_extension *) bsearch(&ext, extension_registry,
290 extension_registry_size, sizeof(OpenGL_extension), compar);
293 TRACE(" returning function (%p)\n", ret->func);
294 *(ret->func_ptr) = local_func;
298 ERR("Extension defined in the OpenGL library but NOT in opengl_ext.c... Please report (lionel.ulmer@free.fr) !\n");
304 /***********************************************************************
307 BOOL WINAPI wglMakeCurrent(HDC hdc,
311 TRACE("(%08x,%p)\n", hdc, hglrc);
315 ret = glXMakeCurrent(display,
320 DC * dc = DC_GetDCPtr( hdc );
323 ERR("Null DC !!!\n");
326 X11DRV_PDEVICE *physDev;
327 Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
329 physDev =(X11DRV_PDEVICE *)dc->physDev;
331 if (ctx->ctx == NULL) {
333 ctx->ctx = glXCreateContext(display, ctx->vis, NULL, True);
335 TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
339 ret = glXMakeCurrent(display,
345 TRACE(" returning %s\n", (ret ? "True" : "False"));
349 /***********************************************************************
350 * wglRealizeLayerPalette
352 BOOL WINAPI wglRealizeLayerPalette(HDC hdc,
360 /***********************************************************************
361 * wglSetLayerPaletteEntries
363 int WINAPI wglSetLayerPaletteEntries(HDC hdc,
367 const COLORREF *pcr) {
368 FIXME("(): stub !\n");
373 /***********************************************************************
376 BOOL WINAPI wglShareLists(HGLRC hglrc1,
378 Wine_GLContext *org = (Wine_GLContext *) hglrc1;
379 Wine_GLContext *dest = (Wine_GLContext *) hglrc2;
381 TRACE("(%p, %p)\n", org, dest);
383 if (dest->ctx != NULL) {
384 ERR("Could not share display lists, context already created !\n");
387 if (org->ctx == NULL) {
389 org->ctx = glXCreateContext(display, org->vis, NULL, True);
391 TRACE(" created a delayed OpenGL context (%p) for Wine context %p\n", org->ctx, org);
395 /* Create the destination context with display lists shared */
396 dest->ctx = glXCreateContext(display, dest->vis, org->ctx, True);
398 TRACE(" created a delayed OpenGL context (%p) for Wine context %p sharing lists with OpenGL ctx %p\n", dest->ctx, dest, org->ctx);
404 /***********************************************************************
405 * wglSwapLayerBuffers
407 BOOL WINAPI wglSwapLayerBuffers(HDC hdc,
409 FIXME("(): stub !\n");
414 /***********************************************************************
417 BOOL WINAPI wglUseFontBitmapsA(HDC hdc,
421 DC * dc = DC_GetDCPtr( hdc );
422 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
423 fontObject* pfo = XFONT_GetFontObject( physDev->font );
424 Font fid = pfo->fs->fid;
426 TRACE("(%08x, %ld, %ld, %ld)\n", hdc, first, count, listBase);
429 /* I assume that the glyphs are at the same position for X and for Windows */
430 glXUseXFont(fid, first, count, listBase);
436 /***********************************************************************
437 * wglUseFontOutlinesA
439 BOOL WINAPI wglUseFontOutlinesA(HDC hdc,
446 LPGLYPHMETRICSFLOAT lpgmf) {
447 FIXME("(): stub !\n");
452 /* This is for brain-dead applications that use OpenGL functions before even
453 creating a rendering context.... */
454 DECL_GLOBAL_CONSTRUCTOR(OpenGL_create_default_context) {
456 XVisualInfo template;
461 template.visualid = XVisualIDFromVisual(visual);
462 vis = XGetVisualInfo(display, VisualIDMask, &template, &num);
463 cx=glXCreateContext(display, vis, 0, GL_TRUE);
464 glXMakeCurrent(display, X11DRV_GetXRootWindow(), cx);
467 context_array = NULL;