diff --git a/Makefile.in b/Makefile.in index 53d51081771..9b0d7b436b4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -40,7 +40,7 @@ LIBRARIES = \ unicode/libwine_unicode.$(LIBEXT) # Dlls that we need to link against (should go away) -LINKABLE_DLLS = winspool.drv x11drv.dll user32.dll gdi32.dll kernel32.dll ntdll.dll +LINKABLE_DLLS = winspool.drv user32.dll gdi32.dll kernel32.dll ntdll.dll # Libraries symlinks to create at the top level LIBSYMLINKS = \ @@ -118,9 +118,6 @@ libwine_uuid.a: ole/libwine_uuid.a libwinspool.drv.$(LIBEXT): dlls/winspool.drv$(DLLEXT) $(RM) $@ && $(LN_S) dlls/winspool.drv$(DLLEXT) $@ -libx11drv.dll.$(LIBEXT): dlls/x11drv.dll$(DLLEXT) - $(RM) $@ && $(LN_S) dlls/x11drv.dll$(DLLEXT) $@ - libuser32.dll.$(LIBEXT): dlls/user32.dll$(DLLEXT) $(RM) $@ && $(LN_S) dlls/user32.dll$(DLLEXT) $@ diff --git a/dlls/Makefile.in b/dlls/Makefile.in index 6a48e3244a9..c882f68dc21 100644 --- a/dlls/Makefile.in +++ b/dlls/Makefile.in @@ -651,9 +651,8 @@ olepro32/olepro32.dll$(DLLEXT): dummy oleaut32.dll$(DLLEXT) ntdll.dll$(DLLEXT) olesvr/olesvr32.dll$(DLLEXT): dummy kernel32.dll$(DLLEXT) ntdll.dll$(DLLEXT) @cd olesvr && $(MAKE) olesvr32.dll$(DLLEXT) -opengl32/opengl32.dll$(DLLEXT): dummy user32.dll$(DLLEXT) x11drv.dll$(DLLEXT) \ - kernel32.dll$(DLLEXT) ntdll.dll$(DLLEXT) libx11drv.dll.$(LIBEXT) libkernel32.dll.$(LIBEXT) \ - libntdll.dll.$(LIBEXT) +opengl32/opengl32.dll$(DLLEXT): dummy user32.dll$(DLLEXT) gdi32.dll$(DLLEXT) \ + kernel32.dll$(DLLEXT) ntdll.dll$(DLLEXT) @cd opengl32 && $(MAKE) opengl32.dll$(DLLEXT) psapi/psapi.dll$(DLLEXT): dummy kernel32.dll$(DLLEXT) ntdll.dll$(DLLEXT) @@ -833,9 +832,6 @@ libntdll.dll.$(LIBEXT): ntdll/ntdll.dll$(DLLEXT) libgdi32.dll.$(LIBEXT): gdi/gdi32.dll$(DLLEXT) $(RM) $@ && $(LN_S) gdi/gdi32.dll$(DLLEXT) $@ -libx11drv.dll.$(LIBEXT): x11drv/x11drv.dll$(DLLEXT) - $(RM) $@ && $(LN_S) x11drv/x11drv.dll$(DLLEXT) $@ - libuser32.dll.$(LIBEXT): user/user32.dll$(DLLEXT) $(RM) $@ && $(LN_S) user/user32.dll$(DLLEXT) $@ diff --git a/dlls/opengl32/Makefile.in b/dlls/opengl32/Makefile.in index e114280e4e2..dcbedc63e4c 100644 --- a/dlls/opengl32/Makefile.in +++ b/dlls/opengl32/Makefile.in @@ -3,7 +3,10 @@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = opengl32.dll -IMPORTS = x11drv.dll kernel32.dll ntdll.dll +EXTRALIBS = $(LIBTSX11) $(X_LIBS) $(XLIB) + +LDDLLFLAGS = @LDDLLFLAGS@ +SYMBOLFILE = $(MODULE).tmp.o C_SRCS = \ wgl.c \ diff --git a/dlls/opengl32/opengl32.spec b/dlls/opengl32/opengl32.spec index 48f60ca306a..5d715eabb21 100644 --- a/dlls/opengl32/opengl32.spec +++ b/dlls/opengl32/opengl32.spec @@ -3,7 +3,7 @@ type win32 init OpenGL32_Init import user32.dll -import x11drv.dll +import gdi32.dll import kernel32.dll import ntdll.dll diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index f19f28e9dd2..94335482c5b 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -22,70 +22,104 @@ #include #include -#include "wine/exception.h" - -#include "wine/debug.h" -#include "gdi.h" #include "windef.h" +#include "winbase.h" +#include "winuser.h" #include "winerror.h" #include "wine_gl.h" #include "x11drv.h" -#include "x11font.h" -#include "msvcrt/excpt.h" #include "wgl.h" #include "opengl_ext.h" +#include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(opengl); static GLXContext default_cx = NULL; +static Display *default_display; /* display to use for default context */ typedef struct wine_glcontext { HDC hdc; + Display *display; GLXContext ctx; XVisualInfo *vis; struct wine_glcontext *next; struct wine_glcontext *prev; } Wine_GLContext; -static Wine_GLContext *context_array; +static Wine_GLContext *context_list; -static inline Wine_GLContext *get_context_from_GLXContext(GLXContext ctx) { - Wine_GLContext *ret = context_array; - while (ret != NULL) if (ctx == ret->ctx) break; else ret = ret->next; - return ret; +static inline Wine_GLContext *get_context_from_GLXContext(GLXContext ctx) +{ + Wine_GLContext *ret; + for (ret = context_list; ret; ret = ret->next) if (ctx == ret->ctx) break; + return ret; } - -static inline void free_context(Wine_GLContext *context) { + +static inline void free_context(Wine_GLContext *context) +{ if (context->next != NULL) context->next->prev = context->prev; if (context->prev != NULL) context->prev->next = context->next; - else context_array = context->next; + else context_list = context->next; HeapFree(GetProcessHeap(), 0, context); } -static inline Wine_GLContext *alloc_context(void) { +static inline Wine_GLContext *alloc_context(void) +{ Wine_GLContext *ret; - ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLContext)); - ret->next = context_array; - if (context_array != NULL) context_array->prev = ret; - else context_array = ret; - + if ((ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLContext)))) + { + ret->next = context_list; + if (context_list) context_list->prev = ret; + context_list = ret; + } return ret; } - -static int XGLErrorFlag = 0; -static int XGLErrorHandler(Display *dpy, XErrorEvent *event) { - XGLErrorFlag = 1; - return 0; -} -/* filter for page-fault exceptions */ -static WINE_EXCEPTION_FILTER(page_fault) +inline static BOOL is_valid_context( Wine_GLContext *ctx ) { - return EXCEPTION_EXECUTE_HANDLER; + Wine_GLContext *ptr; + for (ptr = context_list; ptr; ptr = ptr->next) if (ptr == ctx) break; + return (ptr != NULL); } +/* retrieve the X display to use on a given DC */ +inline static Display *get_display( HDC hdc ) +{ + Display *display; + enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY; + + if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, + sizeof(display), (LPSTR)&display )) display = NULL; + return display; +} + + +/* retrieve the X drawable to use on a given DC */ +inline static Drawable get_drawable( HDC hdc ) +{ + Drawable drawable; + enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE; + + if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, + sizeof(drawable), (LPSTR)&drawable )) drawable = 0; + return drawable; +} + + +/* retrieve the X drawable to use on a given DC */ +inline static Font get_font( HDC hdc ) +{ + Font font; + enum x11drv_escape_codes escape = X11DRV_GET_FONT; + + if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, + sizeof(font), (LPSTR)&font )) font = 0; + return font; +} + + /*********************************************************************** * wglCreateContext (OPENGL32.@) */ @@ -95,12 +129,14 @@ HGLRC WINAPI wglCreateContext(HDC hdc) Wine_GLContext *ret; int num; XVisualInfo template; + Display *display = get_display( hdc ); TRACE("(%08x)\n", hdc); /* First, get the visual in use by the X11DRV */ + if (!display) return 0; template.visualid = GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" ); - vis = XGetVisualInfo(gdi_display, VisualIDMask, &template, &num); + vis = XGetVisualInfo(display, VisualIDMask, &template, &num); if (vis == NULL) { ERR("NULL visual !!!\n"); @@ -113,6 +149,7 @@ HGLRC WINAPI wglCreateContext(HDC hdc) ret = alloc_context(); LEAVE_GL(); ret->hdc = hdc; + ret->display = display; ret->vis = vis; TRACE(" creating context %p (GL context creation delayed)\n", ret); @@ -143,34 +180,23 @@ BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, /*********************************************************************** * wglDeleteContext (OPENGL32.@) */ -BOOL WINAPI wglDeleteContext(HGLRC hglrc) { - int (*WineXHandler)(Display *, XErrorEvent *); +BOOL WINAPI wglDeleteContext(HGLRC hglrc) +{ Wine_GLContext *ctx = (Wine_GLContext *) hglrc; - BOOL ret; - + BOOL ret = TRUE; + TRACE("(%p)\n", hglrc); ENTER_GL(); - /* A game (Half Life not to name it) deletes twice the same context. To prevent - crashes, run with our own error function enabled */ - XSync(gdi_display, False); - XGLErrorFlag = 0; - WineXHandler = XSetErrorHandler(XGLErrorHandler); - __TRY { - glXDestroyContext(gdi_display, ctx->ctx); - XSync(gdi_display, False); - XFlush(gdi_display); - - if (XGLErrorHandler == 0) free_context(ctx); + /* A game (Half Life not to name it) deletes twice the same context, + * so make sure it is valid first */ + if (is_valid_context( ctx )) + { + if (ctx->ctx) glXDestroyContext(ctx->display, ctx->ctx); + free_context(ctx); } - __EXCEPT(page_fault) { - XGLErrorFlag = 1; - } - __ENDTRY - - ret = TRUE; - XSetErrorHandler(WineXHandler); - if (XGLErrorFlag) { + else + { WARN("Error deleting context !\n"); SetLastError(ERROR_INVALID_HANDLE); ret = FALSE; @@ -331,39 +357,20 @@ BOOL WINAPI wglMakeCurrent(HDC hdc, TRACE("(%08x,%p)\n", hdc, hglrc); + ENTER_GL(); if (hglrc == NULL) { - ENTER_GL(); - ret = glXMakeCurrent(gdi_display, - None, - NULL); - LEAVE_GL(); + ret = glXMakeCurrent(default_display, None, NULL); } else { - DC * dc = DC_GetDCPtr( hdc ); - - if (dc == NULL) { - ERR("Null DC !!!\n"); - ret = FALSE; - } else { - X11DRV_PDEVICE *physDev; Wine_GLContext *ctx = (Wine_GLContext *) hglrc; - - physDev =(X11DRV_PDEVICE *)dc->physDev; + Drawable drawable = get_drawable( hdc ); if (ctx->ctx == NULL) { - ENTER_GL(); - ctx->ctx = glXCreateContext(gdi_display, ctx->vis, NULL, True); - LEAVE_GL(); + ctx->ctx = glXCreateContext(ctx->display, ctx->vis, NULL, True); TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx); } - - ENTER_GL(); - ret = glXMakeCurrent(gdi_display, - physDev->drawable, - ctx->ctx); - LEAVE_GL(); - GDI_ReleaseObj( hdc ); - } + ret = glXMakeCurrent(ctx->display, drawable, ctx->ctx); } + LEAVE_GL(); TRACE(" returning %s\n", (ret ? "True" : "False")); return ret; } @@ -408,14 +415,14 @@ BOOL WINAPI wglShareLists(HGLRC hglrc1, } else { if (org->ctx == NULL) { ENTER_GL(); - org->ctx = glXCreateContext(gdi_display, org->vis, NULL, True); + org->ctx = glXCreateContext(org->display, org->vis, NULL, True); LEAVE_GL(); TRACE(" created a delayed OpenGL context (%p) for Wine context %p\n", org->ctx, org); } ENTER_GL(); /* Create the destination context with display lists shared */ - dest->ctx = glXCreateContext(gdi_display, dest->vis, org->ctx, True); + dest->ctx = glXCreateContext(org->display, dest->vis, org->ctx, True); LEAVE_GL(); TRACE(" created a delayed OpenGL context (%p) for Wine context %p sharing lists with OpenGL ctx %p\n", dest->ctx, dest, org->ctx); } @@ -439,11 +446,9 @@ BOOL WINAPI wglSwapLayerBuffers(HDC hdc, BOOL WINAPI wglUseFontBitmapsA(HDC hdc, DWORD first, DWORD count, - DWORD listBase) { - DC * dc = DC_GetDCPtr( hdc ); - X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev; - fontObject* pfo = XFONT_GetFontObject( physDev->font ); - Font fid = pfo->fs->fid; + DWORD listBase) +{ + Font fid = get_font( hdc ); TRACE("(%08x, %ld, %ld, %ld)\n", hdc, first, count, listBase); @@ -451,7 +456,6 @@ BOOL WINAPI wglUseFontBitmapsA(HDC hdc, /* I assume that the glyphs are at the same position for X and for Windows */ glXUseXFont(fid, first, count, listBase); LEAVE_GL(); - GDI_ReleaseObj( hdc ); return TRUE; } @@ -474,18 +478,29 @@ BOOL WINAPI wglUseFontOutlinesA(HDC hdc, /* This is for brain-dead applications that use OpenGL functions before even creating a rendering context.... */ -static void process_attach(void) { +static BOOL process_attach(void) +{ XWindowAttributes win_attr; Visual *rootVisual; int num; XVisualInfo template; + HDC hdc; XVisualInfo *vis = NULL; Window root = (Window)GetPropA( GetDesktopWindow(), "__wine_x11_whole_window" ); if (!root) { ERR("X11DRV not loaded. Cannot create default context.\n"); - return; + return FALSE; + } + + hdc = GetDC(0); + default_display = get_display( hdc ); + ReleaseDC( 0, hdc ); + if (!default_display) + { + ERR("X11DRV not loaded. Cannot get display for screen DC.\n"); + return FALSE; } ENTER_GL(); @@ -495,7 +510,7 @@ static void process_attach(void) { Window was created using the standard X11DRV visual, and glXMakeCurrent can't deal with mismatched visuals. Note that the Root Window visual may not be double buffered, so apps actually attempting to render this way may flicker */ - if (XGetWindowAttributes( gdi_display, root, &win_attr )) + if (XGetWindowAttributes( default_display, root, &win_attr )) { rootVisual = win_attr.visual; } @@ -503,25 +518,25 @@ static void process_attach(void) { { /* Get the default visual, since we can't seem to get the attributes from the Root Window. Let's hope that the Root Window Visual matches the DefaultVisual */ - rootVisual = DefaultVisual( gdi_display, DefaultScreen(gdi_display) ); + rootVisual = DefaultVisual( default_display, DefaultScreen(default_display) ); } template.visualid = XVisualIDFromVisual(rootVisual); - vis = XGetVisualInfo(gdi_display, VisualIDMask, &template, &num); - if (vis != NULL) default_cx = glXCreateContext(gdi_display, vis, 0, GL_TRUE); - if (default_cx != NULL) glXMakeCurrent(gdi_display, root, default_cx); + vis = XGetVisualInfo(default_display, VisualIDMask, &template, &num); + if (vis != NULL) default_cx = glXCreateContext(default_display, vis, 0, GL_TRUE); + if (default_cx != NULL) glXMakeCurrent(default_display, root, default_cx); XFree(vis); LEAVE_GL(); if (default_cx == NULL) { ERR("Could not create default context.\n"); } - - context_array = NULL; + return TRUE; } -static void process_detach(void) { - glXDestroyContext(gdi_display, default_cx); +static void process_detach(void) +{ + glXDestroyContext(default_display, default_cx); } /*********************************************************************** @@ -529,13 +544,13 @@ static void process_detach(void) { */ BOOL WINAPI OpenGL32_Init( HINSTANCE hinst, DWORD reason, LPVOID reserved ) { - switch(reason) { - case DLL_PROCESS_ATTACH: - process_attach(); - break; - case DLL_PROCESS_DETACH: - process_detach(); - break; - } - return TRUE; + switch(reason) + { + case DLL_PROCESS_ATTACH: + return process_attach(); + case DLL_PROCESS_DETACH: + process_detach(); + break; + } + return TRUE; } diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c index da0680e8884..dc7001fa509 100644 --- a/graphics/x11drv/init.c +++ b/graphics/x11drv/init.c @@ -29,6 +29,7 @@ #include "wine/debug.h" #include "winnt.h" #include "x11drv.h" +#include "x11font.h" #include "ddrawi.h" WINE_DEFAULT_DEBUG_CHANNEL(x11drv); @@ -286,6 +287,8 @@ INT X11DRV_GetDeviceCaps( DC *dc, INT cap ) INT X11DRV_ExtEscape( DC *dc, INT escape, INT in_count, LPCVOID in_data, INT out_count, LPVOID out_data ) { + X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev; + switch(escape) { case QUERYESCSUPPORT: @@ -295,6 +298,8 @@ INT X11DRV_ExtEscape( DC *dc, INT escape, INT in_count, LPCVOID in_data, { case DCICOMMAND: return DD_HAL_VERSION; + case X11DRV_ESCAPE: + return TRUE; } } break; @@ -307,6 +312,36 @@ INT X11DRV_ExtEscape( DC *dc, INT escape, INT in_count, LPCVOID in_data, return X11DRV_DCICommand(in_count, lpCmd, out_data); } break; + + case X11DRV_ESCAPE: + if (in_data && in_count >= sizeof(enum x11drv_escape_codes)) + { + switch(*(enum x11drv_escape_codes *)in_data) + { + case X11DRV_GET_DISPLAY: + if (out_count >= sizeof(Display *)) + { + *(Display **)out_data = gdi_display; + return TRUE; + } + break; + case X11DRV_GET_DRAWABLE: + if (out_count >= sizeof(Drawable)) + { + *(Drawable *)out_data = physDev->drawable; + return TRUE; + } + break; + case X11DRV_GET_FONT: + if (out_count >= sizeof(Font)) + { + fontObject* pfo = XFONT_GetFontObject( physDev->font ); + *(Font *)out_data = pfo->fs->fid; + return TRUE; + } + } + } + break; } return 0; } diff --git a/include/x11drv.h b/include/x11drv.h index 4ba45cc1b46..d5fa2a3dfec 100644 --- a/include/x11drv.h +++ b/include/x11drv.h @@ -329,6 +329,16 @@ extern int X11DRV_PALETTE_SetMapping(struct tagPALETTEOBJ *palPtr, UINT uStart, extern int X11DRV_PALETTE_UpdateMapping(struct tagPALETTEOBJ *palPtr); extern BOOL X11DRV_PALETTE_IsDark(int pixel); +/* GDI escapes */ + +#define X11DRV_ESCAPE 6789 +enum x11drv_escape_codes +{ + X11DRV_GET_DISPLAY, /* get X11 display for a DC */ + X11DRV_GET_DRAWABLE, /* get current drawable for a DC */ + X11DRV_GET_FONT, /* get current X font for a DC */ +}; + /************************************************************************** * X11 USER driver */