Commit 81a081c1 authored by Jon Turney's avatar Jon Turney
Browse files

Cygwin/X: AIGLX using native WGL



A rewrite of the XWin DDX AIGLX code to actually make it do something useful again

Signed-off-by: Jon Turney's avatarJon TURNEY <jon.turney@dronecode.org.uk>
Reviewed-by: default avatarColin Harrison <colin.harrison@virgin.net>
parent ffaae7c0
......@@ -2220,6 +2220,7 @@ hw/dmx/Makefile
hw/vfb/Makefile
hw/xnest/Makefile
hw/xwin/Makefile
hw/xwin/glx/Makefile
hw/xquartz/Makefile
hw/xquartz/GL/Makefile
hw/xquartz/bundle/Makefile
......
......@@ -99,8 +99,8 @@ extern HMODULE g_hmodCommonControls;
extern FARPROC g_fpTrackMouseEvent;
extern Bool g_fNoHelpMessageBox;
extern Bool g_fSilentDupError;
extern Bool g_fNativeGl;
/*
* Function prototypes
*/
......@@ -187,6 +187,17 @@ winClipboardShutdown (void)
}
#endif
void
ddxPushProviders(void)
{
#ifdef XWIN_GLX_WINDOWS
if (g_fNativeGl)
{
/* install the native GL provider */
glxWinPushNativeProvider();
}
#endif
}
#if defined(DDXBEFORERESET)
/*
......@@ -890,6 +901,11 @@ winUseMsg (void)
ErrorF ("-[no]unixkill\n"
"\tCtrl+Alt+Backspace exits the X Server.\n");
#ifdef XWIN_GLX_WINDOWS
ErrorF ("-[no]wgl\n"
"\tEnable the GLX extension to use the native Windows WGL interface for accelerated OpenGL\n");
#endif
ErrorF ("-[no]winkill\n"
"\tAlt+F4 exits the X Server.\n");
......
......@@ -13,9 +13,10 @@ DEFS_CLIPBOARD = -DXWIN_CLIPBOARD
endif
if XWIN_GLX_WINDOWS
SRCS_GLX_WINDOWS = \
winpriv.c
GLX_DIR = glx
DEFS_GLX_WINDOWS = -DXWIN_GLX_WINDOWS
XWIN_GLX_LIBS = $(top_builddir)/hw/xwin/glx/libXwinGLX.la
XWIN_GLX_LINK_FLAGS = -lopengl32
endif
if XWIN_MULTIWINDOW
......@@ -125,7 +126,6 @@ SRCS = InitInput.c \
$(top_srcdir)/mi/miinitext.c \
$(top_srcdir)/fb/fbcmap_mi.c \
$(SRCS_CLIPBOARD) \
$(SRCS_GLX_WINDOWS) \
$(SRCS_MULTIWINDOW) \
$(SRCS_MULTIWINDOWEXTWM) \
$(SRCS_NATIVEGDI) \
......@@ -146,14 +146,13 @@ XWin_SOURCES = $(SRCS)
INCLUDES = -I$(top_srcdir)/miext/rootless
XWin_DEPENDENCIES = $(XWIN_LIBS)
XWin_LDADD = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS)
XWin_DEPENDENCIES = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS)
XWin_LDADD = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS)
XWin_LDFLAGS = -mwindows -static
.rc.o:
$(AM_V_GEN)$(WINDRES) --use-temp-file -i $< --input-format=rc -o $@ -O coff -I $(top_builddir)/include
XWin_LDFLAGS = -mwindows -static
winprefsyacc.h: winprefsyacc.c
winprefslex.c: winprefslex.l winprefsyacc.c winprefsyacc.h
......@@ -164,12 +163,8 @@ AM_YFLAGS = -d
AM_LFLAGS = -i
AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \
$(XWINMODULES_CFLAGS) \
-DXFree86Server
GLX_EXTRAS = \
glx/glwindows.h \
glx/glwrap.c \
glx/indirect.c
-DXFree86Server \
-I$(top_srcdir)
MAN_SRCS = XWin.man.pre XWinrc.man.pre
......@@ -198,7 +193,6 @@ install-exec-hook:
(cd $(DESTDIR)$(bindir) && rm -f X && $(LN_S) XWin$(EXEEXT) X)
EXTRA_DIST = \
$(GLX_EXTRAS) \
$(MAN_SRCS) \
$(xwinconfig_DATA) \
X.ico \
......@@ -226,3 +220,6 @@ EXTRA_DIST = \
relink:
$(AM_V_at)rm -f XWin$(EXEEXT) && $(MAKE) XWin$(EXEEXT)
SUBDIRS = $(GLX_DIR) .
DIST_SUBDIRS = glx .
# ignore downloaded and generated files
generated_gl_wrappers.c
generated_wgl_wrappers.c
gl.spec
gl.tm
wgl.tm
wglext.spec
wglext.h
noinst_LTLIBRARIES = libXwinGLX.la
libXwinGLX_la_SOURCES = \
winpriv.c \
glwindows.h \
glwrap.c \
indirect.c \
wgl_ext_api.c
if XWIN_MULTIWINDOW
DEFS_MULTIWINDOW = -DXWIN_MULTIWINDOW
endif
if XWIN_MULTIWINDOWEXTWM
DEFS_MULTIWINDOWEXTWM = -DXWIN_MULTIWINDOWEXTWM
endif
DEFS = $(DEFS_MULTIWINDOW) $(DEFS_MULTIWINDOWEXTWM)
INCLUDES = -I$(top_srcdir)/miext/rootless
AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \
$(XWINMODULES_CFLAGS) \
-I$(top_srcdir) \
-I$(top_srcdir)/hw/xwin/
glwrap.c: generated_gl_wrappers.c
wgl_ext_api.c: generated_wgl_wrappers.c wglext.h
wgl_ext_api.h: wglext.h
indirect.c: wgl_ext_api.h
SPEC_FILES = gl.spec gl.tm wglext.spec wgl.tm
gl.spec:
wget http://www.opengl.org/registry/api/gl.spec
gl.tm:
wget http://www.opengl.org/registry/api/gl.tm
wglext.spec:
wget http://www.opengl.org/registry/api/wglext.spec
wgl.tm:
wget http://www.opengl.org/registry/api/wgl.tm
generated_gl_wrappers.c: gen_gl_wrappers.py gl.spec gl.tm
./gen_gl_wrappers.py --spec=gl.spec --typemap=gl.tm --dispatch-header=$(top_srcdir)/glx/dispatch.h --staticwrappers >generated_gl_wrappers.c
generated_wgl_wrappers.c: gen_gl_wrappers.py wglext.spec wgl.tm
./gen_gl_wrappers.py --spec=wglext.spec --typemap=wgl.tm --prefix=wgl --preresolve >generated_wgl_wrappers.c
wglext.h:
wget http://www.opengl.org/registry/api/wglext.h
BUILT_SOURCES = generated_gl_wrappers.c generated_wgl_wrappers.c
CLEANFILES = $(BUILT_SOURCES)
DISTCLEANFILES = $(SPEC_FILES) wglext.h
EXTRA_DIST = gen_gl_wrappers.py $(SPEC_FILES) wglext.h
#!/usr/bin/python
#
# Comedy python script to generate cdecl to stdcall wrappers for GL functions
#
# This is designed to operate on OpenGL spec files from
# http://www.opengl.org/registry/api/
#
#
# Copyright (c) Jon TURNEY 2009
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the sale,
# use or other dealings in this Software without prior written authorization.
#
import sys
import re
import getopt
dispatchheader = ''
prefix = 'gl'
preresolve = False
staticwrappers = False
opts, args = getopt.getopt(sys.argv[1:], "", ['spec=', 'typemap=', 'dispatch-header=', 'prefix=', 'preresolve', 'staticwrappers' ])
for o,a in opts:
if o == '--typemap' :
typemapfile = a
elif o == '--dispatch-header' :
dispatchheader = a
elif o == '--spec' :
specfile = a
elif o == '--prefix' :
prefix = a
elif o == '--preresolve' :
preresolve = True
elif o == '--staticwrappers' :
staticwrappers = True
#
# look for all the SET_ macros in dispatch.h, this is the set of functions
# we need to generate
#
dispatch = {}
if dispatchheader :
fh = open(dispatchheader)
dispatchh = fh.readlines()
dispatch_regex = re.compile(r'#define\sSET_(\S*)\(')
for line in dispatchh :
line = line.strip()
m1 = dispatch_regex.search(line)
if m1 :
dispatch[m1.group(1)] = 1
del dispatch['by_offset']
#
# read the typemap .tm file
#
typemap = {}
fh = open(typemapfile)
tm = fh.readlines()
typemap_regex = re.compile(r'#define\sSET_(\S*)\(')
for line in tm :
# ignore everything after a '#' as a comment
hash = line.find('#')
if hash != -1 :
line = line[:hash-1]
# ignore blank lines
if line.startswith('#') or len(line) == 0 :
continue
l = line.split(',')
typemap[l[0]] = l[3].strip()
# interestingly, * is not a C type
if typemap['void'] == '*' :
typemap['void'] = 'void'
#
# crudely parse the .spec file
#
r1 = re.compile(r'\t(\S*)\s+(\S*.*)')
r2 = re.compile(r'(.*)\((.*)\)')
r3 = re.compile(r'glWindowPos.*MESA')
r4 = re.compile(r'gl.*Program(s|)NV')
r5 = re.compile(r'glGetVertexAttribfvNV')
wrappers = {}
fh = open(specfile)
glspec = fh.readlines()
param_count = 0
for line in glspec :
line = line.rstrip()
# ignore everything after a '#' as a comment
hash = line.find('#')
if hash != -1 :
line = line[:hash-1]
# ignore blank lines
if line.startswith('#') or len(line) == 0 :
continue
# lines containing ':' aren't intersting to us
if line.count(':') != 0 :
continue
# attributes of each function follow the name, indented by a tab
if not line.startswith('\t') :
m1 = r2.search(line)
if m1 :
function = m1.group(1)
arglist_use = m1.group(2)
wrappers[function] = {}
# near and far might be reserved words or macros so can't be used as formal parameter names
arglist_use = arglist_use.replace('near','zNear')
arglist_use = arglist_use.replace('far','zFar')
wrappers[function]['arglist_use'] = arglist_use
param_count = 0
else :
m1 = r1.search(line)
if m1 :
attribute = m1.group(1)
value = m1.group(2)
# make param attributes unique and ordered
if attribute == 'param' :
attribute = 'param' + '%02d' % param_count
param_count += 1
wrappers[function][attribute] = value
#
# now emit code
#
print '/* Automatically generated by ' + sys.argv[0] + ' DO NOT EDIT */'
print '/* from ' + specfile + ' and typemap ' + typemapfile + ' */'
print ''
#
# if required, emit code for non-lazy function resolving
#
if preresolve :
for w in sorted(wrappers.keys()) :
funcname = prefix + w
print 'RESOLVE_DECL(PFN' + funcname.upper() + 'PROC);'
print ''
print 'void ' + prefix + 'ResolveExtensionProcs(void)'
print '{'
for w in sorted(wrappers.keys()) :
funcname = prefix + w
print ' PRERESOLVE(PFN' + funcname.upper() + 'PROC, "' + funcname + '");'
print '}\n'
#
# now emit the wrappers
# for GL 1.0 and 1.1 functions, generate stdcall wrappers which call the function directly
# for GL 1.2+ functions, generate wrappers which use wglGetProcAddress()
#
for w in sorted(wrappers.keys()) :
funcname = prefix + w
returntype = wrappers[w]['return']
if returntype != 'void' :
returntype = typemap[returntype]
# Avoid generating wrappers which aren't referenced by the dispatch table
if dispatchheader and not dispatch.has_key(w) :
print '/* No wrapper for ' + funcname + ', not in dispatch table */'
continue
# manufacture arglist
# if no param attributes were found, it should be 'void'
al = []
for k in sorted(wrappers[w].keys()) :
if k.startswith('param') :
l = wrappers[w][k].split()
# near and far might be reserved words or macros so can't be used as formal parameter names
l[0] = l[0].replace('near','zNear')
l[0] = l[0].replace('far','zFar')
if l[2] == 'in' :
if l[3] == 'array' :
arg = 'const ' + typemap[l[1]] + ' *' + l[0]
else :
arg = typemap[l[1]] + ' ' + l[0]
elif l[2] == 'out' :
arg = typemap[l[1]] + ' *' + l[0]
al.append(arg)
if len(al) == 0 :
arglist = 'void'
else:
arglist = ', '.join(al)
if wrappers[w]['category'].startswith('VERSION_1_0') or wrappers[w]['category'].startswith('VERSION_1_1') :
if staticwrappers :
print 'static',
print returntype + ' ' + funcname + 'Wrapper(' + arglist + ')'
print '{'
print ' if (glxWinDebugSettings.enable' + prefix.upper() + 'callTrace) ErrorF("'+ funcname + '\\n");'
print ' glWinDirectProcCalls++;'
if returntype.lower() == 'void' :
print ' ' + funcname + '(',
else :
print ' /* returntype was ' + returntype.lower() + '*/'
print ' return ' + funcname + '(',
if arglist != 'void' :
print wrappers[w]['arglist_use'],
print ');'
print "}\n"
else:
if staticwrappers :
print 'static',
print returntype + ' ' + funcname + 'Wrapper(' + arglist + ')'
print '{'
stringname = funcname
#
# special case: Windows OpenGL implementations are far more likely to have GL_ARB_window_pos than GL_MESA_window_pos,
# so arrange for the wrapper to use the ARB strings to find functions...
#
m2 = r3.search(funcname)
if m2 :
stringname = stringname.replace('MESA','ARB')
#
# special case: likewise, implementations are more likely to have GL_ARB_vertex_program than GL_NV_vertex_program,
# especially if they are not NV implementations, so arrange for the wrapper to use ARB strings to find functions
#
m3 = r4.search(funcname)
if m3 :
stringname = stringname.replace('NV','ARB')
m4 = r5.search(funcname)
if m4 :
stringname = stringname.replace('NV','ARB')
pfntypename = 'PFN' + funcname.upper() + 'PROC'
if returntype.lower() == 'void' :
print ' RESOLVE(' + pfntypename + ', "' + stringname + '");'
print ' if (glxWinDebugSettings.enable' + prefix.upper() + 'callTrace) ErrorF("'+ funcname + '\\n");'
print ' RESOLVED_PROC(' + pfntypename + ')(',
else :
print ' RESOLVE_RET(' + pfntypename + ', "' + stringname + '", FALSE);'
print ' if (glxWinDebugSettings.enable' + prefix.upper() + 'callTrace) ErrorF("'+ funcname + '\\n");'
print ' return RESOLVED_PROC(' + pfntypename + ')(',
if arglist != 'void' :
print wrappers[w]['arglist_use'],
print ');'
print "}\n"
# generate function to setup the dispatch table, which sets each
# dispatch table entry to point to it's wrapper function
# (assuming we were able to make one)
if dispatchheader :
print 'void glWinSetupDispatchTable(void)'
print '{'
print ' struct _glapi_table *disp = _glapi_get_dispatch();'
for d in sorted(dispatch.keys()) :
if wrappers.has_key(d) :
print ' SET_'+ d + '(disp, ' + prefix + d + 'Wrapper);'
else :
print '#warning No wrapper for ' + prefix + d + ' !'
print '}'
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/Xwindows.h>
#include <GL/gl.h>
#include <GL/glext.h>
/*
* File: glwindows.h
* Purpose: Header for GLX implementation using native Windows OpenGL library
*
* Authors: Alexander Gottwald
* Jon TURNEY
*
* Copyright (c) Jon TURNEY 2009
* Copyright (c) Alexander Gottwald 2004
*
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <glxserver.h>
#include <glxext.h>
#include <windowstr.h>
#include <resource.h>
#include <GL/glxint.h>
#include <GL/glxtokens.h>
#include <scrnintstr.h>
#include <glxserver.h>
#include <glxscreens.h>
#include <glxdrawable.h>
#include <glxcontext.h>
#include <glxext.h>
#include <glxutil.h>
#include <glxscreens.h>
#include <GL/internal/glcore.h>
#include <stdlib.h>
typedef struct {
unsigned enableDebug : 1;
unsigned enableTrace : 1;
unsigned dumpPFD : 1;
unsigned dumpHWND : 1;
unsigned dumpDC : 1;
} glWinDebugSettingsRec, *glWinDebugSettingsPtr;
extern glWinDebugSettingsRec glWinDebugSettings;
#include <GL/gl.h>
typedef struct {
int num_vis;
__GLcontextModes *modes;
void **priv;
/* wrapped screen functions */
RealizeWindowProcPtr RealizeWindow;
UnrealizeWindowProcPtr UnrealizeWindow;
CopyWindowProcPtr CopyWindow;
} glWinScreenRec;
extern glWinScreenRec glWinScreens[MAXSCREENS];
#define glWinGetScreenPriv(pScreen) &glWinScreens[pScreen->myNum]
#define glWinScreenPriv(pScreen) glWinScreenRec *pScreenPriv = glWinGetScreenPriv(pScreen);
unsigned int enableDebug : 1;
unsigned int enableTrace : 1;
unsigned int dumpPFD : 1;
unsigned int dumpHWND : 1;
unsigned int dumpDC : 1;
unsigned int enableGLcallTrace : 1;
unsigned int enableWGLcallTrace :1;
} glxWinDebugSettingsRec;
extern glxWinDebugSettingsRec glxWinDebugSettings;
void glWinCallDelta(void);
void glxWinPushNativeProvider(void);
const GLubyte* glGetStringWrapperNonstatic(GLenum name);
void glAddSwapHintRectWINWrapperNonstatic(GLint x, GLint y, GLsizei width, GLsizei height);
void glWinSetupDispatchTable(void);
#if 1
#define GLWIN_TRACE() if (glWinDebugSettings.enableTrace) ErrorF("%s:%d: Trace\n", __FUNCTION__, __LINE__ )
#define GLWIN_TRACE_MSG(msg, args...) if (glWinDebugSettings.enableTrace) ErrorF("%s:%d: " msg, __FUNCTION__, __LINE__, ##args )
#define GLWIN_DEBUG_MSG(msg, args...) if (glWinDebugSettings.enableDebug) ErrorF("%s:%d: " msg, __FUNCTION__, __LINE__, ##args )
#define GLWIN_DEBUG_MSG2(msg, args...) if (glWinDebugSettings.enableDebug) ErrorF(msg, ##args )
#define GLWIN_TRACE_MSG(msg, args...) if (glxWinDebugSettings.enableTrace) ErrorF(msg " [%s:%d]\n" , ##args , __FUNCTION__, __LINE__ )
#define GLWIN_DEBUG_MSG(msg, args...) if (glxWinDebugSettings.enableDebug) ErrorF(msg " [%s:%d]\n" , ##args , __FUNCTION__, __LINE__ )
#else
#define GLWIN_TRACE()
#define GLWIN_TRACE_MSG(a, ...)
#define GLWIN_DEBUG_MSG(a, ...)
#define GLWIN_DEBUG_MSG2(a, ...)
#endif
This diff is collapsed.
This diff is collapsed.