diff options
-rw-r--r-- | glx/glxext.c | 2 | ||||
-rwxr-xr-x | hw/xwin/glx/gen_gl_wrappers.py | 101 | ||||
-rw-r--r-- | hw/xwin/glx/indirect.c | 110 | ||||
-rw-r--r-- | hw/xwin/winlayouts.h | 1 |
4 files changed, 155 insertions, 59 deletions
diff --git a/glx/glxext.c b/glx/glxext.c index d472b93f5..38646260c 100644 --- a/glx/glxext.c +++ b/glx/glxext.c @@ -293,7 +293,7 @@ glxClientCallback(CallbackListPtr *list, void *closure, void *data) c->loseCurrent(c); lastGLContext = NULL; c->currentClient = NULL; - FreeResourceByType(c, __glXContextRes, FALSE); + FreeResourceByType(c->id, __glXContextRes, FALSE); } } diff --git a/hw/xwin/glx/gen_gl_wrappers.py b/hw/xwin/glx/gen_gl_wrappers.py index 69ab1efa9..5f4526b9d 100755 --- a/hw/xwin/glx/gen_gl_wrappers.py +++ b/hw/xwin/glx/gen_gl_wrappers.py @@ -123,6 +123,38 @@ else: errWarn = sys.stderr diag = open(diagFilename, 'w') +def ParseCmdRettype(cmd): + proto = noneStr(cmd.elem.find('proto')) + rettype = noneStr(proto.text) + if rettype.lower() != "void ": + plist = ([t for t in proto.itertext()]) + rettype = ''.join(plist[:-1]) + rettype = rettype.strip() + return rettype + +def ParseCmdParams(cmd): + params = cmd.elem.findall('param') + plist = [] + for param in params: + # construct the formal parameter definition from ptype and name + # elements, also using any text found around these in the + # param element, in the order it appears in the document + paramtype = '' + # also extract the formal parameter name from the name element + paramname = '' + for t in param.iter(): + if t.tag == 'ptype' or t.tag == 'param': + paramtype = paramtype + noneStr(t.text) + if t.tag == 'name': + paramname = t.text + '_' + paramtype = paramtype + ' ' + paramname + if t.tail is not None: + paramtype = paramtype + t.tail.strip() + + plist.append((paramtype, paramname)) + + return plist + class PreResolveOutputGenerator(OutputGenerator): def __init__(self, errFile = sys.stderr, @@ -179,25 +211,16 @@ class WrapperOutputGenerator(OutputGenerator): if prefix == 'wgl' and not name in used_wgl_ext_fns: return - proto=noneStr(cmd.elem.find('proto')) - rettype=noneStr(proto.text) - if rettype.lower()!="void ": - plist = ([t for t in proto.itertext()]) - rettype = ''.join(plist[:-1]) - rettype=rettype.strip() + rettype = ParseCmdRettype(cmd) + plist = ParseCmdParams(cmd) + if staticwrappers: self.outFile.write("static ") self.outFile.write("%s %sWrapper("%(rettype, name)) - params = cmd.elem.findall('param') - plist=[] - for param in params: - paramlist = ([t for t in param.itertext()]) - paramtype = ''.join(paramlist[:-1]) - paramname = paramlist[-1] - plist.append((paramtype, paramname)) + Comma="" if len(plist): for ptype, pname in plist: - self.outFile.write("%s%s%s_"%(Comma, ptype, pname)) + self.outFile.write("%s%s"%(Comma, ptype)) Comma=", " else: self.outFile.write("void") @@ -218,7 +241,7 @@ class WrapperOutputGenerator(OutputGenerator): Comma="" for ptype, pname in plist: - self.outFile.write("%s%s_"%(Comma, pname)) + self.outFile.write("%s%s"%(Comma, pname)) Comma=", " # for GL 1.2+ functions, generate stdcall wrappers which use wglGetProcAddress() @@ -244,7 +267,7 @@ class WrapperOutputGenerator(OutputGenerator): Comma="" for ptype, pname in plist: - self.outFile.write("%s%s_"%(Comma, pname)) + self.outFile.write("%s%s"%(Comma, pname)) Comma=", " self.outFile.write(" );\n}\n\n") @@ -270,24 +293,14 @@ class ThunkOutputGenerator(OutputGenerator): def genCmd(self, cmd, name): OutputGenerator.genCmd(self, cmd, name) - proto=noneStr(cmd.elem.find('proto')) - rettype=noneStr(proto.text) - if rettype.lower()!="void ": - plist = ([t for t in proto.itertext()]) - rettype = ''.join(plist[:-1]) - rettype=rettype.strip() + rettype = ParseCmdRettype(cmd) + plist = ParseCmdParams(cmd) + self.outFile.write("%s %sWrapper("%(rettype, name)) - params = cmd.elem.findall('param') - plist=[] - for param in params: - paramlist = ([t for t in param.itertext()]) - paramtype = ''.join(paramlist[:-1]) - paramname = paramlist[-1] - plist.append((paramtype, paramname)) Comma="" if len(plist): for ptype, pname in plist: - self.outFile.write("%s%s%s_"%(Comma, ptype, pname)) + self.outFile.write("%s%s"%(Comma, ptype)) Comma=", " else: self.outFile.write("void") @@ -303,7 +316,7 @@ class ThunkOutputGenerator(OutputGenerator): Comma="" for ptype, pname in plist: - self.outFile.write("%s%s_"%(Comma, pname)) + self.outFile.write("%s%s"%(Comma, pname)) Comma=", " # for GL 1.2+ functions, generate wrappers which use wglGetProcAddress() @@ -317,7 +330,7 @@ class ThunkOutputGenerator(OutputGenerator): Comma="" for ptype, pname in plist: - self.outFile.write("%s%s_"%(Comma, pname)) + self.outFile.write("%s%s"%(Comma, pname)) Comma=", " self.outFile.write(" );\n}\n\n") @@ -368,28 +381,18 @@ class ShimOutputGenerator(OutputGenerator): def genCmd(self, cmd, name): OutputGenerator.genCmd(self, cmd, name) + # for GL functions which are in the ABI, generate a shim which calls the function via GetProcAddress if not self.OldVersion: return - # for GL functions which are in the ABI, generate a shim which calls the function via GetProcAddress - proto=noneStr(cmd.elem.find('proto')) - rettype=noneStr(proto.text) - if rettype.lower()!="void ": - plist = ([t for t in proto.itertext()]) - rettype = ''.join(plist[:-1]) - rettype=rettype.strip() + rettype = ParseCmdRettype(cmd) + plist = ParseCmdParams(cmd) + self.outFile.write("%s %s("%(rettype, name)) - params = cmd.elem.findall('param') - plist=[] - for param in params: - paramlist = ([t for t in param.itertext()]) - paramtype = ''.join(paramlist[:-1]) - paramname = paramlist[-1] - plist.append((paramtype, paramname)) Comma="" if len(plist): for ptype, pname in plist: - self.outFile.write("%s%s%s_"%(Comma, ptype, pname)) + self.outFile.write("%s%s"%(Comma, ptype)) Comma=", " else: self.outFile.write("void") @@ -401,7 +404,7 @@ class ShimOutputGenerator(OutputGenerator): if len(plist): Comma="" for ptype, pname in plist: - self.outFile.write("%s %s %s_"%(Comma, ptype, pname)) + self.outFile.write("%s %s"%(Comma, ptype)) Comma=", " else: self.outFile.write("void") @@ -417,7 +420,7 @@ class ShimOutputGenerator(OutputGenerator): Comma="" for ptype, pname in plist: - self.outFile.write("%s%s_"%(Comma, pname)) + self.outFile.write("%s%s"%(Comma, pname)) Comma=", " self.outFile.write(" );\n}\n\n") diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c index 6db6a48c4..e874cd501 100644 --- a/hw/xwin/glx/indirect.c +++ b/hw/xwin/glx/indirect.c @@ -479,6 +479,29 @@ glxLogExtensions(const char *prefix, const char *extensions) free(str); } +static struct sigaction old_act; +extern Bool install_os_signal_handler; + +static void +glxWinScreenProbeSigHandler(int signo, siginfo_t * sip, void *context) +{ + // log a message + ErrorFSigSafe("segfault in WGL during glxWinScreenProbe()\n"); + + // show a messagebox + MessageBox(NULL, + "A crash occurred while initializing Windows OpenGL.\n" + "\n" + "Please try updating the display driver.\n" + "\n" + "You can disable the use of Windows OpenGL by starting the X server using the -nowgl option.", + XVENDORNAMESHORT, + MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND); + + // and pass on to previous sighandler + (*old_act.sa_sigaction)(signo, sip, context); +} + /* This is called by GlxExtensionInit() asking the GLX provider if it can handle the screen... */ static __GLXscreen * glxWinScreenProbe(ScreenPtr pScreen) @@ -511,8 +534,11 @@ glxWinScreenProbe(ScreenPtr pScreen) return NULL; // Select the native GL implementation (WGL) - if (glWinSelectImplementation(1)) + if (glWinSelectImplementation(1)) { + LogMessage(X_ERROR, "AIGLX: WGL not available\n"); + free(screen); return NULL; + } // create window class #define WIN_GL_TEST_WINDOW_CLASS "XWinGLTest" @@ -523,7 +549,7 @@ glxWinScreenProbe(ScreenPtr pScreen) WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = DefWindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; @@ -538,22 +564,74 @@ glxWinScreenProbe(ScreenPtr pScreen) } } + // The following tests seem particularly prone to crashing somewhere in the + // display driver's OpenGL implementation. So temporarily install a special + // SIGSEGV handler so we can offer some remedial advice... + if (install_os_signal_handler) + { + struct sigaction act; + sigemptyset(&act.sa_mask); + act.sa_sigaction = glxWinScreenProbeSigHandler; + act.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &act, &old_act); + } + // create an invisible window for a scratch DC hwnd = CreateWindowExA(0, WIN_GL_TEST_WINDOW_CLASS, "XWin GL Renderer Capabilities Test Window", 0, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); - if (hwnd == NULL) + if (hwnd == NULL) { LogMessage(X_ERROR, "AIGLX: Couldn't create a window for render capabilities testing\n"); + goto error; + } hdc = GetDC(hwnd); + if (!hdc) { + LogMessage(X_ERROR, "AIGLX: Couldn't create a DC for render capabilities testing\n"); + goto error; + } + + // we must set a pixel format before we can create a context + { + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DEPTH_DONTCARE | PFD_DOUBLEBUFFER_DONTCARE | PFD_STEREO_DONTCARE, + PFD_TYPE_RGBA, + 24, + 0, 0, 0, 0, 0, 0, + 0, + 0, + 0, + 0, 0, 0, 0, + 0, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + int iPixelFormat = ChoosePixelFormat(hdc, &pfd); + if (iPixelFormat == 0) { + LogMessage(X_ERROR, "AIGLX: ChoosePixelFormat failed\n"); + goto error; + } + + if (!SetPixelFormat(hdc, iPixelFormat, NULL)) { + LogMessage(X_ERROR, "AIGLX: SetPixelFormat %d failed\n", iPixelFormat); + goto error; + } + LogMessage(X_INFO, "AIGLX: Testing pixelFormatIndex %d\n",iPixelFormat); + } - // we must set a pixel format before we can create a context, just use the first one... - SetPixelFormat(hdc, 1, NULL); hglrc = wglCreateContext(hdc); - wglMakeCurrent(hdc, hglrc); + if (!wglMakeCurrent(hdc, hglrc)) { + ErrorF("glxWinScreenProbe: wglMakeCurrent error: %08x dc %p ctx %p\n", + (unsigned)GetLastError(), hdc, hglrc); + } // initialize wgl extension proc pointers (don't call them before here...) // (but we need to have a current context for them to be resolvable) @@ -565,6 +643,8 @@ glxWinScreenProbe(ScreenPtr pScreen) gl_renderer = (const char *) glGetString(GL_RENDERER); ErrorF("GL_RENDERER: %s\n", gl_renderer); gl_extensions = (const char *) glGetString(GL_EXTENSIONS); + if (!gl_extensions) + gl_extensions = ""; wgl_extensions = wglGetExtensionsStringARBWrapper(hdc); if (!wgl_extensions) wgl_extensions = ""; @@ -574,10 +654,15 @@ glxWinScreenProbe(ScreenPtr pScreen) glxLogExtensions("WGL_EXTENSIONS: ", wgl_extensions); } + if (!gl_renderer) { + LogMessage(X_ERROR, + "AIGLX: Native renderer not identified\n"); + goto error; + } + if (strcasecmp(gl_renderer, "GDI Generic") == 0) { - free(screen); LogMessage(X_ERROR, - "AIGLX: Won't use generic native renderer as it is not accelerated\n"); + "AIGLX: Won't use the generic native renderer as it is not accelerated\n"); goto error; } @@ -688,7 +773,6 @@ glxWinScreenProbe(ScreenPtr pScreen) If we still didn't get any fbConfigs, we can't provide GLX for this screen */ if (screen->base.numFBConfigs <= 0) { - free(screen); LogMessage(X_ERROR, "AIGLX: No fbConfigs could be made from native OpenGL pixel formats\n"); goto error; @@ -753,9 +837,17 @@ glxWinScreenProbe(ScreenPtr pScreen) // Note that WGL is active on this screen winSetScreenAiglxIsActive(pScreen); + // Restore the previous sighandler + sigaction(SIGSEGV, &old_act, NULL); + return &screen->base; error: + // Restore the previous sighandler + sigaction(SIGSEGV, &old_act, NULL); + + free(screen); + // Something went wrong and we can't use the native GL implementation // so make sure the mesa GL implementation is selected instead glWinSelectImplementation(0); diff --git a/hw/xwin/winlayouts.h b/hw/xwin/winlayouts.h index 8b6b98407..34aff9939 100644 --- a/hw/xwin/winlayouts.h +++ b/hw/xwin/winlayouts.h @@ -74,6 +74,7 @@ WinKBLayoutRec winKBLayouts[] = { {0x00010410, -1, "pc105", "it", NULL, NULL, "Italian (142)"}, {0xa0000410, -1, "macbook79", "it", "mac", NULL, "Italiano (Apple)"}, {0x00000411, 7, "jp106", "jp", NULL, NULL, "Japanese"}, + {0x00000412, -1, "kr106", "kr", NULL, NULL, "Korean"}, {0x00000413, -1, "pc105", "nl", NULL, NULL, "Dutch"}, {0x00000813, -1, "pc105", "be", NULL, NULL, "Dutch (Belgian)"}, {0x00000414, -1, "pc105", "no", NULL, NULL, "Norwegian"}, |