hook-glx.c:
Code:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/gl.h>
#include <GL/glx.h>
void hookfunc();
/* glXSwapBuffers() is very appropriate as an "end scene" hook because
* WoW calls it exactly once, at the end of each frame.
*
* Unfortunately WINE needs to be patched to allow hooking this via
* LD_PRELOAD.
*
* 1) Instead of using the default RTLD loader, WINE retrieves the address
* for glXGetProcAddressARB directly from the OpenGL library.
* This is done to enable binary compatibility to systems with or without
* OpenGL.
*
* Solution: patch WINE to use the default loader
*
* 2) WINE gets the pointers to glx functions via glXGetProcAddressARB
*
* => I'm hooking glXGetProcAddressARB and return my own
* pointer to glXSwapBuffers.
*
*/
typedef __GLXextFuncPtr (*fp_glXGetProcAddressARB) (const GLubyte*);
typedef __GLXextFuncPtr (*fp_glXSwapBuffers)(Display* dpy, GLXDrawable drawable);
// glXSwapBuffers
fp_glXSwapBuffers real_glXSwapBuffers;
void my_glXSwapBuffers(Display* dpy, GLXDrawable drawable) {
real_glXSwapBuffers(dpy, drawable);
hookfunc();
}
// glXGetProcAddressARB
__GLXextFuncPtr glXGetProcAddressARB (const GLubyte* procName)
{
__GLXextFuncPtr result;
printf("* hook-glx.c: glXGetProcAddressARB(\"%s\")\n", procName);
// Fetch pointer of actual glXGetProcAddressARB() function
static fp_glXGetProcAddressARB lib_getprocaddr = NULL;
if(!lib_getprocaddr)
{
char* errorstr;
lib_getprocaddr = (fp_glXGetProcAddressARB)
dlsym(RTLD_NEXT, "glXGetProcAddressARB");
if( (errorstr = dlerror()) != NULL )
{
fprintf(stderr, "dlsym fail: %s\n", errorstr);
exit(1);
}
}
result = lib_getprocaddr(procName);
// Return our own function pointers
if( strcmp( (const char*) procName, "glXSwapBuffers" ) == 0 )
{
real_glXSwapBuffers = (fp_glXSwapBuffers) result;
return (__GLXextFuncPtr) my_glXSwapBuffers;
}
// Return default function pointer
return lib_getprocaddr(procName);
}
WINE patch:
Code:
diff -Nru wine-1.1.39.orig/dlls/winex11.drv/opengl.c wine-1.1.39/dlls/winex11.drv/opengl.c
--- wine-1.1.39.orig/dlls/winex11.drv/opengl.c 2010-02-27 02:21:02.973526893 +0100
+++ wine-1.1.39/dlls/winex11.drv/opengl.c 2010-02-27 02:27:11.231401387 +0100
@@ -412,7 +412,7 @@
return FALSE;
}
- pglXGetProcAddressARB = wine_dlsym(opengl_handle, "glXGetProcAddressARB", NULL, 0);
+ pglXGetProcAddressARB = wine_dlsym(RTLD_DEFAULT, "glXGetProcAddressARB", NULL, 0);
if (pglXGetProcAddressARB == NULL) {
ERR("Could not find glXGetProcAddressARB in libGL, disabling OpenGL.\n");
goto failed;