aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xorg-server/configure.ac8
-rw-r--r--xorg-server/glx/extension_string.c1
-rw-r--r--xorg-server/glx/extension_string.h1
-rw-r--r--xorg-server/glx/glxcmds.c2
-rw-r--r--xorg-server/glx/glxcontext.h4
-rw-r--r--xorg-server/glx/glxdrawable.h2
-rw-r--r--xorg-server/glx/glxdri.c2
-rw-r--r--xorg-server/glx/glxdri2.c102
-rw-r--r--xorg-server/glx/glxdriswrast.c2
-rw-r--r--xorg-server/glx/glxext.c5
-rw-r--r--xorg-server/glx/glxscreens.c1
-rw-r--r--xorg-server/glx/glxserver.h20
-rw-r--r--xorg-server/glx/swap_interval.c7
-rw-r--r--xorg-server/hw/kdrive/linux/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/common/xf86Xinput.c62
-rw-r--r--xorg-server/hw/xfree86/doc/man/xorg.conf.man.pre67
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.c403
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.h129
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2ext.c217
-rw-r--r--xorg-server/hw/xfree86/x86emu/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/x86emu/sys.c181
-rw-r--r--xorg-server/hw/xquartz/bundle/Info.plist.cpp4
-rw-r--r--xorg-server/hw/xquartz/quartzKeyboard.c4
-rw-r--r--xorg-server/hw/xquartz/xpr/x-hook.c3
-rw-r--r--xorg-server/include/protocol-versions.h2
25 files changed, 1164 insertions, 69 deletions
diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac
index e0ddd48f2..8c1085b29 100644
--- a/xorg-server/configure.ac
+++ b/xorg-server/configure.ac
@@ -754,12 +754,12 @@ RECORDPROTO="recordproto >= 1.13.99.1"
SCRNSAVERPROTO="scrnsaverproto >= 1.1"
RESOURCEPROTO="resourceproto"
DRIPROTO="xf86driproto >= 2.1.0"
-DRI2PROTO="dri2proto >= 2.1"
+DRI2PROTO="dri2proto >= 2.2"
XINERAMAPROTO="xineramaproto"
BIGFONTPROTO="xf86bigfontproto >= 1.2.0"
XCALIBRATEPROTO="xcalibrateproto"
DGAPROTO="xf86dgaproto >= 2.0.99.1"
-GLPROTO="glproto >= 1.4.9"
+GLPROTO="glproto >= 1.4.10"
DMXPROTO="dmxproto >= 2.2.99.1"
VIDMODEPROTO="xf86vidmodeproto >= 2.2.99.1"
WINDOWSWMPROTO="windowswmproto"
@@ -2112,9 +2112,9 @@ AC_TRY_COMPILE([
AC_DEFINE_DIR(PROJECTROOT, prefix, [Overall prefix])
-BUILD_DATE="$(date +'%Y%m%d')"
+BUILD_DATE="`date +'%Y%m%d'`"
AC_SUBST([BUILD_DATE])
-BUILD_TIME="$(date +'1%H%M%S')"
+BUILD_TIME="`date +'1%H%M%S'`"
AC_SUBST([BUILD_TIME])
DIX_CFLAGS="-DHAVE_DIX_CONFIG_H $XSERVER_CFLAGS"
diff --git a/xorg-server/glx/extension_string.c b/xorg-server/glx/extension_string.c
index 9d110cf98..7721cb056 100644
--- a/xorg-server/glx/extension_string.c
+++ b/xorg-server/glx/extension_string.c
@@ -82,6 +82,7 @@ static const struct extension_info known_glx_extensions[] = {
{ GLX(SGIX_fbconfig), VER(1,3), Y, },
{ GLX(SGIX_pbuffer), VER(1,3), Y, },
{ GLX(SGIX_visual_select_group), VER(0,0), Y, },
+ { GLX(INTEL_swap_event), VER(1,4), N, },
{ NULL }
};
diff --git a/xorg-server/glx/extension_string.h b/xorg-server/glx/extension_string.h
index 98e91bc18..912534a04 100644
--- a/xorg-server/glx/extension_string.h
+++ b/xorg-server/glx/extension_string.h
@@ -50,6 +50,7 @@ enum {
SGIX_fbconfig_bit,
SGIX_pbuffer_bit,
SGIX_visual_select_group_bit,
+ INTEL_swap_event_bit,
__NUM_GLX_EXTS,
};
diff --git a/xorg-server/glx/glxcmds.c b/xorg-server/glx/glxcmds.c
index eedab652f..77afbf4b1 100644
--- a/xorg-server/glx/glxcmds.c
+++ b/xorg-server/glx/glxcmds.c
@@ -1481,7 +1481,7 @@ int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
return error;
if (pGlxDraw->type == DRAWABLE_WINDOW &&
- (*pGlxDraw->swapBuffers)(pGlxDraw) == GL_FALSE)
+ (*pGlxDraw->swapBuffers)(cl->client, pGlxDraw) == GL_FALSE)
return __glXError(GLXBadDrawable);
return Success;
diff --git a/xorg-server/glx/glxcontext.h b/xorg-server/glx/glxcontext.h
index 70a14115d..79bc083a8 100644
--- a/xorg-server/glx/glxcontext.h
+++ b/xorg-server/glx/glxcontext.h
@@ -55,6 +55,10 @@ struct __GLXcontext {
unsigned long mask);
int (*forceCurrent) (__GLXcontext *context);
+ Bool (*wait) (__GLXcontext *context,
+ __GLXclientState *cl,
+ int *error);
+
__GLXtextureFromPixmap *textureFromPixmap;
/*
diff --git a/xorg-server/glx/glxdrawable.h b/xorg-server/glx/glxdrawable.h
index 3f165ed4f..2a365c505 100644
--- a/xorg-server/glx/glxdrawable.h
+++ b/xorg-server/glx/glxdrawable.h
@@ -45,7 +45,7 @@ enum {
struct __GLXdrawable {
void (*destroy)(__GLXdrawable *private);
- GLboolean (*swapBuffers)(__GLXdrawable *);
+ GLboolean (*swapBuffers)(ClientPtr client, __GLXdrawable *);
void (*copySubBuffer)(__GLXdrawable *drawable,
int x, int y, int w, int h);
void (*waitX)(__GLXdrawable *);
diff --git a/xorg-server/glx/glxdri.c b/xorg-server/glx/glxdri.c
index 6122653b0..21e44d12d 100644
--- a/xorg-server/glx/glxdri.c
+++ b/xorg-server/glx/glxdri.c
@@ -245,7 +245,7 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
}
static GLboolean
-__glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate)
+__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *basePrivate)
{
__GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
__GLXDRIscreen *screen =
diff --git a/xorg-server/glx/glxdri2.c b/xorg-server/glx/glxdri2.c
index ed7dc80ba..69fd39b3b 100644
--- a/xorg-server/glx/glxdri2.c
+++ b/xorg-server/glx/glxdri2.c
@@ -70,6 +70,7 @@ struct __GLXDRIscreen {
const __DRIcoreExtension *core;
const __DRIdri2Extension *dri2;
+ const __DRI2flushExtension *flush;
const __DRIcopySubBufferExtension *copySubBuffer;
const __DRIswapControlExtension *swapControl;
const __DRItexBufferExtension *texBuffer;
@@ -132,17 +133,6 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable,
DRI2BufferFrontLeft, DRI2BufferBackLeft);
}
-static GLboolean
-__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
-{
- __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
-
- __glXDRIdrawableCopySubBuffer(drawable, 0, 0,
- private->width, private->height);
-
- return TRUE;
-}
-
static void
__glXDRIdrawableWaitX(__GLXdrawable *drawable)
{
@@ -177,9 +167,74 @@ __glXDRIdrawableWaitGL(__GLXdrawable *drawable)
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
}
+static void
+__glXdriSwapEvent(ClientPtr client, void *data, int type, CARD64 ust,
+ CARD64 msc, CARD64 sbc)
+{
+ __GLXdrawable *drawable = data;
+ xGLXBufferSwapComplete wire;
+
+ if (!drawable->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK)
+ return;
+
+ wire.type = __glXEventBase + GLX_BufferSwapComplete;
+ switch (type) {
+ case DRI2_EXCHANGE_COMPLETE:
+ wire.event_type = GLX_EXCHANGE_COMPLETE_INTEL;
+ break;
+ case DRI2_BLIT_COMPLETE:
+ wire.event_type = GLX_BLIT_COMPLETE_INTEL;
+ break;
+ case DRI2_FLIP_COMPLETE:
+ wire.event_type = GLX_FLIP_COMPLETE_INTEL;
+ break;
+ default:
+ /* unknown swap completion type */
+ break;
+ }
+ wire.sequenceNumber = client->sequence;
+ wire.drawable = drawable->drawId;
+ wire.ust_hi = ust >> 32;
+ wire.ust_lo = ust & 0xffffffff;
+ wire.msc_hi = msc >> 32;
+ wire.msc_lo = msc & 0xffffffff;
+ wire.sbc_hi = sbc >> 32;
+ wire.sbc_lo = sbc & 0xffffffff;
+
+ WriteEventsToClient(client, 1, (xEvent *) &wire);
+}
+
+/*
+ * Copy or flip back to front, honoring the swap interval if possible.
+ *
+ * If the kernel supports it, we request an event for the frame when the
+ * swap should happen, then perform the copy when we receive it.
+ */
+static GLboolean
+__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable)
+{
+ __GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable;
+ __GLXDRIscreen *screen = priv->screen;
+ CARD64 unused;
+
+ if (screen->flush)
+ (*screen->flush->flushInvalidate)(priv->driDrawable);
+
+ if (DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused,
+ __glXdriSwapEvent, drawable->pDraw) != Success)
+ return FALSE;
+
+ return TRUE;
+}
+
static int
__glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval)
{
+ if (interval <= 0) /* || interval > BIGNUM? */
+ return GLX_BAD_VALUE;
+
+ DRI2SwapInterval(drawable->pDraw, interval);
+
return 0;
}
@@ -241,6 +296,18 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext)
read->driDrawable);
}
+static Bool
+__glXDRIcontextWait(__GLXcontext *baseContext,
+ __GLXclientState *cl, int *error)
+{
+ if (DRI2WaitSwap(cl->client, baseContext->drawPriv->pDraw)) {
+ *error = cl->client->noClientException;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
#ifdef __DRI_TEX_BUFFER
static int
@@ -346,6 +413,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
context->base.copy = __glXDRIcontextCopy;
context->base.forceCurrent = __glXDRIcontextForceCurrent;
context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
+ context->base.wait = __glXDRIcontextWait;
context->driContext =
(*screen->dri2->createNewContext)(screen->driScreen,
@@ -550,6 +618,10 @@ initializeExtensions(__GLXDRIscreen *screen)
"GLX_MESA_copy_sub_buffer");
LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
+ /* FIXME: only if DDX supports it */
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_INTEL_swap_event\n");
+
for (i = 0; extensions[i]; i++) {
#ifdef __DRI_READ_DRAWABLE
if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
@@ -581,6 +653,14 @@ initializeExtensions(__GLXDRIscreen *screen)
LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n");
}
#endif
+
+#ifdef __DRI2_FLUSH
+ if (strcmp(extensions[i]->name, __DRI2_FLUSH) == 0 &&
+ extensions[i]->version >= __DRI2_FLUSH_VERSION) {
+ screen->flush = (__DRI2flushExtension *) extensions[i];
+ }
+#endif
+
/* Ignore unknown extensions */
}
}
diff --git a/xorg-server/glx/glxdriswrast.c b/xorg-server/glx/glxdriswrast.c
index 20f9f90d6..c647d83ca 100644
--- a/xorg-server/glx/glxdriswrast.c
+++ b/xorg-server/glx/glxdriswrast.c
@@ -108,7 +108,7 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
}
static GLboolean
-__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
+__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable)
{
__GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
const __DRIcoreExtension *core = private->screen->core;
diff --git a/xorg-server/glx/glxext.c b/xorg-server/glx/glxext.c
index 751ea7297..59bcfbed2 100644
--- a/xorg-server/glx/glxext.c
+++ b/xorg-server/glx/glxext.c
@@ -267,6 +267,7 @@ GLboolean __glXErrorOccured(void)
}
static int __glXErrorBase;
+int __glXEventBase;
int __glXError(int error)
{
@@ -403,6 +404,7 @@ void GlxExtensionInit(void)
}
__glXErrorBase = extEntry->errorBase;
+ __glXEventBase = extEntry->eventBase;
}
/************************************************************************/
@@ -446,6 +448,9 @@ __GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
}
}
+ if (cx->wait && (*cx->wait)(cx, cl, error))
+ return NULL;
+
if (cx == __glXLastContext) {
/* No need to re-bind */
return cx;
diff --git a/xorg-server/glx/glxscreens.c b/xorg-server/glx/glxscreens.c
index 674e2c681..58d8ee0b4 100644
--- a/xorg-server/glx/glxscreens.c
+++ b/xorg-server/glx/glxscreens.c
@@ -181,6 +181,7 @@ static char GLXServerExtensions[] =
"GLX_SGIX_fbconfig "
"GLX_SGIX_pbuffer "
"GLX_MESA_copy_sub_buffer "
+ "GLX_INTEL_swap_event"
;
/*
diff --git a/xorg-server/glx/glxserver.h b/xorg-server/glx/glxserver.h
index 80f1b28f9..1daf97758 100644
--- a/xorg-server/glx/glxserver.h
+++ b/xorg-server/glx/glxserver.h
@@ -56,7 +56,14 @@
#include <GL/gl.h>
#include <GL/glxproto.h>
-/* For glxscreens.h */
+/*
+** GLX resources.
+*/
+typedef XID GLXContextID;
+typedef XID GLXPixmap;
+typedef XID GLXDrawable;
+
+typedef struct __GLXclientStateRec __GLXclientState;
typedef struct __GLXdrawable __GLXdrawable;
typedef struct __GLXcontext __GLXcontext;
@@ -71,15 +78,6 @@ typedef struct __GLXcontext __GLXcontext;
#define False 0
#endif
-/*
-** GLX resources.
-*/
-typedef XID GLXContextID;
-typedef XID GLXPixmap;
-typedef XID GLXDrawable;
-
-typedef struct __GLXclientStateRec __GLXclientState;
-
extern __GLXscreen *glxGetScreen(ScreenPtr pScreen);
extern __GLXclientState *glxGetClient(ClientPtr pClient);
@@ -251,4 +249,6 @@ extern int __glXImageSize(GLenum format, GLenum type,
extern unsigned glxMajorVersion;
extern unsigned glxMinorVersion;
+extern int __glXEventBase;
+
#endif /* !__GLX_server_h__ */
diff --git a/xorg-server/glx/swap_interval.c b/xorg-server/glx/swap_interval.c
index 3a5242022..0bae3247e 100644
--- a/xorg-server/glx/swap_interval.c
+++ b/xorg-server/glx/swap_interval.c
@@ -53,8 +53,6 @@ int DoSwapInterval(__GLXclientState *cl, GLbyte *pc, int do_swap)
cx = __glXLookupContextByTag(cl, tag);
- LogMessage(X_ERROR, "%s: cx = %p, GLX screen = %p\n", __func__,
- cx, (cx == NULL) ? NULL : cx->pGlxScreen);
if ((cx == NULL) || (cx->pGlxScreen == NULL)) {
client->errorValue = tag;
return __glXError(GLXBadContext);
@@ -68,7 +66,7 @@ int DoSwapInterval(__GLXclientState *cl, GLbyte *pc, int do_swap)
if (cx->drawPriv == NULL) {
client->errorValue = tag;
- return __glXError(GLXBadDrawable);
+ return BadValue;
}
pc += __GLX_VENDPRIV_HDR_SIZE;
@@ -76,6 +74,9 @@ int DoSwapInterval(__GLXclientState *cl, GLbyte *pc, int do_swap)
? bswap_32(*(int *)(pc + 0))
: *(int *)(pc + 0);
+ if (interval <= 0)
+ return BadValue;
+
(void) (*cx->pGlxScreen->swapInterval)(cx->drawPriv, interval);
return Success;
}
diff --git a/xorg-server/hw/kdrive/linux/Makefile.am b/xorg-server/hw/kdrive/linux/Makefile.am
index fe4a3d183..93e5d2f9f 100644
--- a/xorg-server/hw/kdrive/linux/Makefile.am
+++ b/xorg-server/hw/kdrive/linux/Makefile.am
@@ -8,7 +8,7 @@ noinst_LTLIBRARIES = liblinux.la
liblinux_la_SOURCES =
-liblinux_la_SOURCES += linux.c klinux.h
+liblinux_la_SOURCES += linux.c
if KDRIVE_KBD
liblinux_la_SOURCES += keyboard.c
diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c
index 57db056d8..df774a155 100644
--- a/xorg-server/hw/xfree86/common/xf86Xinput.c
+++ b/xorg-server/hw/xfree86/common/xf86Xinput.c
@@ -121,7 +121,7 @@ ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
/* common settings (available via device properties) */
tempf = xf86SetRealOption(list, "ConstantDeceleration", 1.0);
- if(tempf > 1.0){
+ if (tempf > 1.0) {
xf86Msg(X_CONFIG, "%s: (accel) constant deceleration by %.1f\n",
devname, tempf);
prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
@@ -130,7 +130,7 @@ ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
}
tempf = xf86SetRealOption(list, "AdaptiveDeceleration", 1.0);
- if(tempf > 1.0){
+ if (tempf > 1.0) {
xf86Msg(X_CONFIG, "%s: (accel) adaptive deceleration by %.1f\n",
devname, tempf);
prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
@@ -144,8 +144,7 @@ ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
if (XIChangeDeviceProperty(pDev, prop, XA_INTEGER, 32,
- PropModeReplace, 1, &tempi, FALSE) == Success)
- {
+ PropModeReplace, 1, &tempi, FALSE) == Success) {
xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i\n", devname,
tempi);
} else {
@@ -156,20 +155,19 @@ ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
/* set scaling */
tempf = xf86SetRealOption(list, "ExpectedRate", 0);
prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
- if(tempf > 0){
+ if (tempf > 0) {
tempf = 1000.0 / tempf;
XIChangeDeviceProperty(pDev, prop, float_prop, 32,
PropModeReplace, 1, &tempf, FALSE);
- }else{
+ } else {
tempf = xf86SetRealOption(list, "VelocityScale", s->corr_mul);
XIChangeDeviceProperty(pDev, prop, float_prop, 32,
PropModeReplace, 1, &tempf, FALSE);
}
tempi = xf86SetIntOption(list, "VelocityTrackerCount", -1);
- if(tempi > 1){
+ if (tempi > 1)
InitTrackers(s, tempi);
- }
s->initial_range = xf86SetIntOption(list, "VelocityInitialRange",
s->initial_range);
@@ -177,7 +175,7 @@ ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
s->max_diff = xf86SetRealOption(list, "VelocityAbsDiff", s->max_diff);
tempf = xf86SetRealOption(list, "VelocityRelDiff", -1);
- if(tempf >= 0){
+ if (tempf >= 0) {
xf86Msg(X_CONFIG, "%s: (accel) max rel. velocity difference: %.1f%%\n",
devname, tempf*100.0);
s->max_rel_diff = tempf;
@@ -198,40 +196,40 @@ ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
static void
ApplyAccelerationSettings(DeviceIntPtr dev){
- int scheme;
+ int scheme, i;
DeviceVelocityPtr pVel;
LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
char* schemeStr;
- if(dev->valuator){
+ if (dev->valuator && dev->ptrfeed) {
schemeStr = xf86SetStrOption(local->options, "AccelerationScheme", "");
scheme = dev->valuator->accelScheme.number;
- if(!xf86NameCmp(schemeStr, "predictable"))
+ if (!xf86NameCmp(schemeStr, "predictable"))
scheme = PtrAccelPredictable;
- if(!xf86NameCmp(schemeStr, "lightweight"))
+ if (!xf86NameCmp(schemeStr, "lightweight"))
scheme = PtrAccelLightweight;
- if(!xf86NameCmp(schemeStr, "none"))
+ if (!xf86NameCmp(schemeStr, "none"))
scheme = PtrAccelNoOp;
/* reinit scheme if needed */
- if(dev->valuator->accelScheme.number != scheme){
- if(dev->valuator->accelScheme.AccelCleanupProc){
+ if (dev->valuator->accelScheme.number != scheme) {
+ if (dev->valuator->accelScheme.AccelCleanupProc) {
dev->valuator->accelScheme.AccelCleanupProc(dev);
}
- if(InitPointerAccelerationScheme(dev, scheme)){
+ if (InitPointerAccelerationScheme(dev, scheme)) {
xf86Msg(X_CONFIG, "%s: (accel) selected scheme %s/%i\n",
local->name, schemeStr, scheme);
- }else{
+ } else {
xf86Msg(X_CONFIG, "%s: (accel) could not init scheme %s\n",
local->name, schemeStr);
scheme = dev->valuator->accelScheme.number;
}
- }else{
+ } else {
xf86Msg(X_CONFIG, "%s: (accel) keeping acceleration scheme %i\n",
local->name, scheme);
}
@@ -239,13 +237,37 @@ ApplyAccelerationSettings(DeviceIntPtr dev){
xfree(schemeStr);
/* process special configuration */
- switch(scheme){
+ switch (scheme) {
case PtrAccelPredictable:
pVel = GetDevicePredictableAccelData(dev);
ProcessVelocityConfiguration (dev, local->name, local->options,
pVel);
break;
}
+
+ i = xf86SetIntOption(local->options, "AccelerationNumerator",
+ dev->ptrfeed->ctrl.num);
+ if (i >= 0)
+ dev->ptrfeed->ctrl.num = i;
+
+ i = xf86SetIntOption(local->options, "AccelerationDenominator",
+ dev->ptrfeed->ctrl.den);
+ if (i > 0)
+ dev->ptrfeed->ctrl.den = i;
+
+ i = xf86SetIntOption(local->options, "AccelerationThreshold",
+ dev->ptrfeed->ctrl.threshold);
+ if (i >= 0)
+ dev->ptrfeed->ctrl.threshold = i;
+
+ /* mostly a no-op anyway */
+ (*dev->ptrfeed->CtrlProc)(dev, &dev->ptrfeed->ctrl);
+
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration factor: %.3f\n",
+ local->name, ((float)dev->ptrfeed->ctrl.num)/
+ ((float)dev->ptrfeed->ctrl.den));
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration threshold: %i\n",
+ local->name, dev->ptrfeed->ctrl.threshold);
}
}
diff --git a/xorg-server/hw/xfree86/doc/man/xorg.conf.man.pre b/xorg-server/hw/xfree86/doc/man/xorg.conf.man.pre
index 5b98bda63..222530b41 100644
--- a/xorg-server/hw/xfree86/doc/man/xorg.conf.man.pre
+++ b/xorg-server/hw/xfree86/doc/man/xorg.conf.man.pre
@@ -914,7 +914,72 @@ X Input extension. This option controls the startup behavior only, a device
may be reattached or set floating at runtime.
.TP 7
.BI "Option \*qSendDragEvents\*q \*q" boolean \*q
-???
+Send core events while dragging. Enabled by default.
+.PP
+For pointing devices, the following options control how the pointer
+is accelerated or decelerated with respect to physical device motion. Most of
+these can be adjusted at runtime, see the xinput(1) man page for details. Only
+the most important acceleration options are discussed here.
+.TP 7
+.BI "Option \*qAccelerationProfile\*q \*q" integer \*q
+Select the profile. In layman's terms, the profile constitutes the "feeling" of
+the acceleration. More formally, it defines how the transfer function (actual
+acceleration as a function of current device velocity and acceleration controls)
+is constructed. This is mainly a matter of personal preference.
+.PP
+.RS 6
+.nf
+.B " 0 classic (mostly compatible)"
+.B "-1 none (only constant deceleration is applied)"
+.B " 1 device-dependent"
+.B " 2 polynomial (polynomial function)"
+.B " 3 smooth linear (soft knee, then linear)"
+.B " 4 simple (normal when slow, otherwise accelerated)"
+.B " 5 power (power function)"
+.B " 6 linear (more speed, more acceleration)"
+.B " 7 limited (like linear, but maxes out at threshold)"
+.fi
+.RE
+.TP 7
+.BI "Option \*qConstantDeceleration\*q \*q" real \*q
+Makes the pointer go
+.B deceleration
+times slower than normal. Most useful for high-resolution devices.
+.TP 7
+.BI "Option \*qAdaptiveDeceleration\*q \*q" real \*q
+Allows to actually decelerate the pointer when going slow. At most, it will be
+.B adaptive deceleration
+times slower. Enables precise pointer placement without sacrificing speed.
+.TP 7
+.BI "Option \*qAccelerationScheme\*q \*q" string \*q
+Selects the scheme, which is the underlying algorithm.
+.PP
+.RS 7
+.nf
+.B "predictable default algorithm (behaving more predictable)"
+.B "lightweight old acceleration code (as specified in the X protocol spec)"
+.B "none no acceleration or deceleration"
+.fi
+.RE
+.TP 7
+.BI "Option \*qAccelerationNumerator\*q \*q" integer \*q
+.TP 7
+.BI "Option \*qAccelerationDenominator\*q \*q" integer \*q
+Set numerator and denominator of the acceleration factor. The acceleration
+factor is a rational which, together with threshold, can be used to tweak
+profiles to suit the users needs. The
+.B simple
+and
+.B limited
+profiles use it directly (i.e. they accelerate by the factor), for other
+profiles it should hold that a higher acceleration factor leads to a faster
+pointer. Typically, 1 is unaccelerated and values up to 5 are sensible.
+.TP 7
+.BI "Option \*qAccelerationThreshold\*q \*q" integer \*q
+Set the threshold, which is roughly the velocity (usually device units per 10
+ms) required for acceleration to become effective. The precise effect varies
+with the profile however.
+
.SH "INPUTCLASS SECTION"
The config file may have multiple
.B InputClass
diff --git a/xorg-server/hw/xfree86/dri2/dri2.c b/xorg-server/hw/xfree86/dri2/dri2.c
index d15ced112..3db826e91 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.c
+++ b/xorg-server/hw/xfree86/dri2/dri2.c
@@ -34,10 +34,12 @@
#include <xorg-config.h>
#endif
+#include <errno.h>
#include <xf86drm.h>
#include "xf86Module.h"
#include "scrnintstr.h"
#include "windowstr.h"
+#include "dixstruct.h"
#include "dri2.h"
#include "xf86VGAarbiter.h"
@@ -56,9 +58,17 @@ typedef struct _DRI2Drawable {
int height;
DRI2BufferPtr *buffers;
int bufferCount;
- unsigned int pendingSequence;
+ unsigned int swapsPending;
+ ClientPtr blockedClient;
+ int swap_interval;
+ CARD64 swap_count;
+ CARD64 target_sbc; /* -1 means no SBC wait outstanding */
+ CARD64 last_swap_target; /* most recently queued swap target */
+ int swap_limit; /* for N-buffering */
} DRI2DrawableRec, *DRI2DrawablePtr;
+typedef struct _DRI2Screen *DRI2ScreenPtr;
+
typedef struct _DRI2Screen {
const char *driverName;
const char *deviceName;
@@ -68,9 +78,12 @@ typedef struct _DRI2Screen {
DRI2CreateBufferProcPtr CreateBuffer;
DRI2DestroyBufferProcPtr DestroyBuffer;
DRI2CopyRegionProcPtr CopyRegion;
+ DRI2ScheduleSwapProcPtr ScheduleSwap;
+ DRI2GetMSCProcPtr GetMSC;
+ DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
HandleExposuresProcPtr HandleExposures;
-} DRI2ScreenRec, *DRI2ScreenPtr;
+} DRI2ScreenRec;
static DRI2ScreenPtr
DRI2GetScreen(ScreenPtr pScreen)
@@ -84,6 +97,9 @@ DRI2GetDrawable(DrawablePtr pDraw)
WindowPtr pWin;
PixmapPtr pPixmap;
+ if (!pDraw)
+ return NULL;
+
if (pDraw->type == DRAWABLE_WINDOW)
{
pWin = (WindowPtr) pDraw;
@@ -119,6 +135,13 @@ DRI2CreateDrawable(DrawablePtr pDraw)
pPriv->height = pDraw->height;
pPriv->buffers = NULL;
pPriv->bufferCount = 0;
+ pPriv->swapsPending = 0;
+ pPriv->blockedClient = NULL;
+ pPriv->swap_count = 0;
+ pPriv->target_sbc = -1;
+ pPriv->swap_interval = 1;
+ pPriv->last_swap_target = -1;
+ pPriv->swap_limit = 1; /* default to double buffering */
if (pDraw->type == DRAWABLE_WINDOW)
{
@@ -308,6 +331,50 @@ DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
out_count, TRUE);
}
+/*
+ * In the direct rendered case, we throttle the clients that have more
+ * than their share of outstanding swaps (and thus busy buffers) when a
+ * new GetBuffers request is received. In the AIGLX case, we allow the
+ * client to get the new buffers, but throttle when the next GLX request
+ * comes in (see __glXDRIcontextWait()).
+ */
+Bool
+DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw)
+{
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return FALSE;
+
+ /* Throttle to swap limit */
+ if ((pPriv->swapsPending >= pPriv->swap_limit) &&
+ !pPriv->blockedClient) {
+ ResetCurrentRequest(client);
+ client->sequence--;
+ IgnoreClient(client);
+ pPriv->blockedClient = client;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+DRI2BlockClient(ClientPtr client, DrawablePtr pDraw)
+{
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return;
+
+ if (pPriv->blockedClient == NULL) {
+ IgnoreClient(client);
+ pPriv->blockedClient = client;
+ }
+}
+
int
DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
unsigned int dest, unsigned int src)
@@ -338,6 +405,324 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
return Success;
}
+/* Can this drawable be page flipped? */
+Bool
+DRI2CanFlip(DrawablePtr pDraw)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ WindowPtr pWin, pRoot;
+ PixmapPtr pWinPixmap, pRootPixmap;
+
+ if (pDraw->type == DRAWABLE_PIXMAP)
+ return TRUE;
+
+ pRoot = WindowTable[pScreen->myNum];
+ pRootPixmap = pScreen->GetWindowPixmap(pRoot);
+
+ pWin = (WindowPtr) pDraw;
+ pWinPixmap = pScreen->GetWindowPixmap(pWin);
+ if (pRootPixmap != pWinPixmap)
+ return FALSE;
+ if (!REGION_EQUAL(pScreen, &pWin->clipList, &pRoot->winSize))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Can we do a pixmap exchange instead of a blit? */
+Bool
+DRI2CanExchange(DrawablePtr pDraw)
+{
+ return FALSE;
+}
+
+void
+DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
+ unsigned int tv_sec, unsigned int tv_usec)
+{
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return;
+
+ ProcDRI2WaitMSCReply(client, ((CARD64)tv_sec * 1000000) + tv_usec,
+ frame, pPriv->swap_count);
+
+ if (pPriv->blockedClient)
+ AttendClient(pPriv->blockedClient);
+
+ pPriv->blockedClient = NULL;
+}
+
+static void
+DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame,
+ unsigned int tv_sec, unsigned int tv_usec)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return;
+ }
+
+ /*
+ * Swap completed. Either wake up an SBC waiter or a client that was
+ * blocked due to GLX activity during a swap.
+ */
+ if (pPriv->target_sbc != -1 &&
+ pPriv->target_sbc >= pPriv->swap_count) {
+ ProcDRI2WaitMSCReply(client, ((CARD64)tv_sec * 1000000) + tv_usec,
+ frame, pPriv->swap_count);
+ pPriv->target_sbc = -1;
+
+ AttendClient(pPriv->blockedClient);
+ pPriv->blockedClient = NULL;
+ } else if (pPriv->target_sbc == -1) {
+ if (pPriv->blockedClient)
+ AttendClient(pPriv->blockedClient);
+ pPriv->blockedClient = NULL;
+ }
+}
+
+void
+DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
+ unsigned int tv_sec, unsigned int tv_usec, int type,
+ DRI2SwapEventPtr swap_complete, void *swap_data)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2DrawablePtr pPriv;
+ CARD64 ust = 0;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return;
+ }
+
+ if (pPriv->refCount == 0) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable refcount\n", __func__);
+ xfree(pPriv);
+ return;
+ }
+
+ ust = ((CARD64)tv_sec * 1000000) + tv_usec;
+ if (swap_complete)
+ swap_complete(client, swap_data, type, ust, frame, pPriv->swap_count);
+
+ pPriv->swapsPending--;
+ pPriv->swap_count++;
+
+ DRI2WakeClient(client, pDraw, frame, tv_sec, tv_usec);
+}
+
+Bool
+DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable)
+{
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
+
+ /* If we're currently waiting for a swap on this drawable, reset
+ * the request and suspend the client. We only support one
+ * blocked client per drawable. */
+ if ((pPriv->swapsPending) &&
+ pPriv->blockedClient == NULL) {
+ ResetCurrentRequest(client);
+ client->sequence--;
+ DRI2BlockClient(client, pDrawable);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+int
+DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
+ CARD64 divisor, CARD64 remainder, CARD64 *swap_target,
+ DRI2SwapEventPtr func, void *data)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ DRI2BufferPtr pDestBuffer = NULL, pSrcBuffer = NULL;
+ CARD64 ust;
+ int ret, i;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return BadDrawable;
+ }
+
+ for (i = 0; i < pPriv->bufferCount; i++) {
+ if (pPriv->buffers[i]->attachment == DRI2BufferFrontLeft)
+ pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i];
+ if (pPriv->buffers[i]->attachment == DRI2BufferBackLeft)
+ pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i];
+ }
+ if (pSrcBuffer == NULL || pDestBuffer == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: drawable has no back or front?\n", __func__);
+ return BadDrawable;
+ }
+
+ /* Old DDX, just blit */
+ if (!ds->ScheduleSwap) {
+ BoxRec box;
+ RegionRec region;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDraw->width;
+ box.y2 = pDraw->height;
+ REGION_INIT(pScreen, &region, &box, 0);
+
+ pPriv->swapsPending++;
+
+ (*ds->CopyRegion)(pDraw, &region, pDestBuffer, pSrcBuffer);
+ DRI2SwapComplete(client, pDraw, target_msc, 0, 0, DRI2_BLIT_COMPLETE,
+ func, data);
+ return Success;
+ }
+
+ /*
+ * In the simple glXSwapBuffers case, all params will be 0, and we just
+ * need to schedule a swap for the last swap target + the swap interval.
+ * If the last swap target hasn't been set yet, call into the driver
+ * to get the current count.
+ */
+ if (target_msc == 0 && divisor == 0 && remainder == 0 &&
+ pPriv->last_swap_target < 0) {
+ ret = (*ds->GetMSC)(pDraw, &ust, &target_msc);
+ if (!ret) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: driver failed to return current MSC\n",
+ __func__);
+ return BadDrawable;
+ }
+ }
+
+ /* First swap needs to initialize last_swap_target */
+ if (pPriv->last_swap_target < 0)
+ pPriv->last_swap_target = target_msc;
+
+ /*
+ * Swap target for this swap is last swap target + swap interval since
+ * we have to account for the current swap count, interval, and the
+ * number of pending swaps.
+ */
+ *swap_target = pPriv->last_swap_target + pPriv->swap_interval;
+
+ ret = (*ds->ScheduleSwap)(client, pDraw, pDestBuffer, pSrcBuffer,
+ swap_target, divisor, remainder, func, data);
+ if (!ret) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: driver failed to schedule swap\n", __func__);
+ return BadDrawable;
+ }
+
+ pPriv->swapsPending++;
+ pPriv->last_swap_target = *swap_target;
+
+ return Success;
+}
+
+void
+DRI2SwapInterval(DrawablePtr pDrawable, int interval)
+{
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
+
+ /* fixme: check against arbitrary max? */
+
+ pPriv->swap_interval = interval;
+}
+
+int
+DRI2GetMSC(DrawablePtr pDraw, CARD64 *ust, CARD64 *msc, CARD64 *sbc)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ Bool ret;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI2] %s: bad drawable\n", __func__);
+ return BadDrawable;
+ }
+
+ if (!ds->GetMSC) {
+ *ust = 0;
+ *msc = 0;
+ *sbc = pPriv->swap_count;
+ return Success;
+ }
+
+ /*
+ * Spec needs to be updated to include unmapped or redirected
+ * drawables
+ */
+
+ ret = (*ds->GetMSC)(pDraw, ust, msc);
+ if (!ret)
+ return BadDrawable;
+
+ *sbc = pPriv->swap_count;
+
+ return Success;
+}
+
+int
+DRI2WaitMSC(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
+ CARD64 divisor, CARD64 remainder)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ DRI2DrawablePtr pPriv;
+ Bool ret;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return BadDrawable;
+
+ /* Old DDX just completes immediately */
+ if (!ds->ScheduleWaitMSC) {
+ DRI2WaitMSCComplete(client, pDraw, target_msc, 0, 0);
+
+ return Success;
+ }
+
+ ret = (*ds->ScheduleWaitMSC)(client, pDraw, target_msc, divisor, remainder);
+ if (!ret)
+ return BadDrawable;
+
+ return Success;
+}
+
+int
+DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc,
+ CARD64 *ust, CARD64 *msc, CARD64 *sbc)
+{
+ DRI2DrawablePtr pPriv;
+
+ pPriv = DRI2GetDrawable(pDraw);
+ if (pPriv == NULL)
+ return BadDrawable;
+
+ if (pPriv->swap_count >= target_sbc)
+ return Success;
+
+ pPriv->target_sbc = target_sbc;
+ DRI2BlockClient(client, pDraw);
+
+ return Success;
+}
+
void
DRI2DestroyDrawable(DrawablePtr pDraw)
{
@@ -363,7 +748,11 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
xfree(pPriv->buffers);
}
- xfree(pPriv);
+ /* If the window is destroyed while we have a swap pending, don't
+ * actually free the priv yet. We'll need it in the DRI2SwapComplete()
+ * callback and we'll free it there once we're done. */
+ if (!pPriv->swapsPending)
+ xfree(pPriv);
if (pDraw->type == DRAWABLE_WINDOW)
{
@@ -421,7 +810,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
return FALSE;
}
- ds = xalloc(sizeof *ds);
+ ds = xcalloc(1, sizeof *ds);
if (!ds)
return FALSE;
@@ -433,6 +822,12 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
ds->DestroyBuffer = info->DestroyBuffer;
ds->CopyRegion = info->CopyRegion;
+ if (info->version >= 4) {
+ ds->ScheduleSwap = info->ScheduleSwap;
+ ds->ScheduleWaitMSC = info->ScheduleWaitMSC;
+ ds->GetMSC = info->GetMSC;
+ }
+
dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n");
diff --git a/xorg-server/hw/xfree86/dri2/dri2.h b/xorg-server/hw/xfree86/dri2/dri2.h
index 175471aae..dd59297df 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.h
+++ b/xorg-server/hw/xfree86/dri2/dri2.h
@@ -47,6 +47,9 @@ typedef struct {
} DRI2BufferRec, *DRI2BufferPtr;
typedef DRI2BufferRec DRI2Buffer2Rec, *DRI2Buffer2Ptr;
+typedef void (*DRI2SwapEventPtr)(ClientPtr client, void *data, int type,
+ CARD64 ust, CARD64 msc, CARD64 sbc);
+
typedef DRI2BufferPtr (*DRI2CreateBuffersProcPtr)(DrawablePtr pDraw,
unsigned int *attachments,
@@ -58,20 +61,98 @@ typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw,
RegionPtr pRegion,
DRI2BufferPtr pDestBuffer,
DRI2BufferPtr pSrcBuffer);
-
typedef void (*DRI2WaitProcPtr)(WindowPtr pWin,
unsigned int sequence);
-
+/**
+ * Schedule a buffer swap
+ *
+ * This callback is used to support glXSwapBuffers and the OML_sync_control
+ * extension (see it for a description of the params).
+ *
+ * Drivers should queue an event for the frame count that satisfies the
+ * parameters passed in. If the event is in the future (i.e. the conditions
+ * aren't currently satisfied), the server may block the client at the next
+ * GLX request using DRI2WaitSwap. When the event arrives, drivers should call
+ * \c DRI2SwapComplete, which will handle waking the client and returning
+ * the appropriate data.
+ *
+ * The DDX is responsible for doing a flip, exchange, or blit of the swap
+ * when the corresponding event arrives. The \c DRI2CanFlip and
+ * \c DRI2CanExchange functions can be used as helpers for this purpose.
+ *
+ * \param client client pointer (used for block/unblock)
+ * \param pDraw drawable whose count we want
+ * \param pDestBuffer current front buffer
+ * \param pSrcBuffer current back buffer
+ * \param target_msc frame count to wait for
+ * \param divisor divisor for condition equation
+ * \param remainder remainder for division equation
+ * \param func function to call when the swap completes
+ * \param data data for the callback \p func.
+ */
+typedef int (*DRI2ScheduleSwapProcPtr)(ClientPtr client,
+ DrawablePtr pDraw,
+ DRI2BufferPtr pDestBuffer,
+ DRI2BufferPtr pSrcBuffer,
+ CARD64 *target_msc,
+ CARD64 divisor,
+ CARD64 remainder,
+ DRI2SwapEventPtr func,
+ void *data);
typedef DRI2BufferPtr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw,
unsigned int attachment,
unsigned int format);
typedef void (*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw,
DRI2BufferPtr buffer);
-
+/**
+ * Get current media stamp counter values
+ *
+ * This callback is used to support the SGI_video_sync and OML_sync_control
+ * extensions.
+ *
+ * Drivers should return the current frame counter and the timestamp from
+ * when the returned frame count was last incremented.
+ *
+ * The count should correspond to the screen where the drawable is currently
+ * visible. If the drawable isn't visible (e.g. redirected), the server
+ * should return BadDrawable to the client, pending GLX spec updates to
+ * define this behavior.
+ *
+ * \param pDraw drawable whose count we want
+ * \param ust timestamp from when the count was last incremented.
+ * \param mst current frame count
+ */
+typedef int (*DRI2GetMSCProcPtr)(DrawablePtr pDraw, CARD64 *ust,
+ CARD64 *msc);
+/**
+ * Schedule a frame count related wait
+ *
+ * This callback is used to support the SGI_video_sync and OML_sync_control
+ * extensions. See those specifications for details on how to handle
+ * the divisor and remainder parameters.
+ *
+ * Drivers should queue an event for the frame count that satisfies the
+ * parameters passed in. If the event is in the future (i.e. the conditions
+ * aren't currently satisfied), the driver should block the client using
+ * \c DRI2BlockClient. When the event arrives, drivers should call
+ * \c DRI2WaitMSCComplete, which will handle waking the client and returning
+ * the appropriate data.
+ *
+ * \param client client pointer (used for block/unblock)
+ * \param pDraw drawable whose count we want
+ * \param target_msc frame count to wait for
+ * \param divisor divisor for condition equation
+ * \param remainder remainder for division equation
+ */
+typedef int (*DRI2ScheduleWaitMSCProcPtr)(ClientPtr client,
+ DrawablePtr pDraw,
+ CARD64 target_msc,
+ CARD64 divisor,
+ CARD64 remainder);
/**
* Version of the DRI2InfoRec structure defined in this header
*/
-#define DRI2INFOREC_VERSION 3
+#define DRI2INFOREC_VERSION 4
typedef struct {
unsigned int version; /**< Version of this struct */
@@ -83,9 +164,13 @@ typedef struct {
DRI2DestroyBufferProcPtr DestroyBuffer;
DRI2CopyRegionProcPtr CopyRegion;
DRI2WaitProcPtr Wait;
-
+ DRI2ScheduleSwapProcPtr ScheduleSwap;
+ DRI2GetMSCProcPtr GetMSC;
+ DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
} DRI2InfoRec, *DRI2InfoPtr;
+extern _X_EXPORT int DRI2EventBase;
+
extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr pScreen,
DRI2InfoPtr info);
@@ -137,4 +222,38 @@ extern _X_EXPORT DRI2BufferPtr *DRI2GetBuffersWithFormat(DrawablePtr pDraw,
int *width, int *height, unsigned int *attachments, int count,
int *out_count);
+extern _X_EXPORT void DRI2SwapInterval(DrawablePtr pDrawable, int interval);
+extern _X_EXPORT int DRI2SwapBuffers(ClientPtr client, DrawablePtr pDrawable,
+ CARD64 target_msc, CARD64 divisor,
+ CARD64 remainder, CARD64 *swap_target,
+ DRI2SwapEventPtr func, void *data);
+extern _X_EXPORT Bool DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable);
+
+extern _X_EXPORT int DRI2GetMSC(DrawablePtr pDrawable, CARD64 *ust,
+ CARD64 *msc, CARD64 *sbc);
+extern _X_EXPORT int DRI2WaitMSC(ClientPtr client, DrawablePtr pDrawable,
+ CARD64 target_msc, CARD64 divisor,
+ CARD64 remainder);
+extern _X_EXPORT int ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust,
+ CARD64 msc, CARD64 sbc);
+extern _X_EXPORT int DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw,
+ CARD64 target_sbc, CARD64 *ust, CARD64 *msc,
+ CARD64 *sbc);
+extern _X_EXPORT Bool DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw);
+
+extern _X_EXPORT Bool DRI2CanFlip(DrawablePtr pDraw);
+
+extern _X_EXPORT Bool DRI2CanExchange(DrawablePtr pDraw);
+
+extern _X_EXPORT void DRI2BlockClient(ClientPtr client, DrawablePtr pDraw);
+
+extern _X_EXPORT void DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw,
+ int frame, unsigned int tv_sec,
+ unsigned int tv_usec, int type,
+ DRI2SwapEventPtr swap_complete,
+ void *swap_data);
+extern _X_EXPORT void DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw,
+ int frame, unsigned int tv_sec,
+ unsigned int tv_usec);
+
#endif
diff --git a/xorg-server/hw/xfree86/dri2/dri2ext.c b/xorg-server/hw/xfree86/dri2/dri2ext.c
index 7d6064acb..3e6b03e4e 100644
--- a/xorg-server/hw/xfree86/dri2/dri2ext.c
+++ b/xorg-server/hw/xfree86/dri2/dri2ext.c
@@ -259,6 +259,9 @@ ProcDRI2GetBuffers(ClientPtr client)
&pDrawable, &status))
return status;
+ if (DRI2ThrottleClient(client, pDrawable))
+ return client->noClientException;
+
attachments = (unsigned int *) &stuff[1];
buffers = DRI2GetBuffers(pDrawable, &width, &height,
attachments, stuff->count, &count);
@@ -283,6 +286,9 @@ ProcDRI2GetBuffersWithFormat(ClientPtr client)
&pDrawable, &status))
return status;
+ if (DRI2ThrottleClient(client, pDrawable))
+ return client->noClientException;
+
attachments = (unsigned int *) &stuff[1];
buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height,
attachments, stuff->count, &count);
@@ -329,6 +335,204 @@ ProcDRI2CopyRegion(ClientPtr client)
return client->noClientException;
}
+static void
+load_swap_reply(xDRI2SwapBuffersReply *rep, CARD64 sbc)
+{
+ rep->swap_hi = sbc >> 32;
+ rep->swap_lo = sbc & 0xffffffff;
+}
+
+static CARD64
+vals_to_card64(CARD32 lo, CARD32 hi)
+{
+ return (CARD64)hi << 32 | lo;
+}
+
+static void
+DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc,
+ CARD64 sbc)
+{
+ xDRI2BufferSwapComplete event;
+
+ event.type = DRI2EventBase + DRI2_BufferSwapComplete;
+ event.sequenceNumber = client->sequence;
+ event.event_type = type;
+ event.ust_hi = (CARD64)ust >> 32;
+ event.ust_lo = ust & 0xffffffff;
+ event.msc_hi = (CARD64)msc >> 32;
+ event.msc_lo = msc & 0xffffffff;
+ event.sbc_hi = (CARD64)sbc >> 32;
+ event.sbc_lo = sbc & 0xffffffff;
+
+ WriteEventsToClient(client, 1, (xEvent *)&event);
+}
+
+static int
+ProcDRI2SwapBuffers(ClientPtr client)
+{
+ REQUEST(xDRI2SwapBuffersReq);
+ xDRI2SwapBuffersReply rep;
+ DrawablePtr pDrawable;
+ CARD64 target_msc, divisor, remainder, swap_target;
+ int status;
+
+ REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq);
+
+ if (!validDrawable(client, stuff->drawable,
+ DixReadAccess | DixWriteAccess, &pDrawable, &status))
+ return status;
+
+ target_msc = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi);
+ divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi);
+ remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi);
+
+ status = DRI2SwapBuffers(client, pDrawable, target_msc, divisor, remainder,
+ &swap_target, DRI2SwapEvent, pDrawable);
+ if (status != Success)
+ return BadDrawable;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ load_swap_reply(&rep, swap_target);
+
+ WriteToClient(client, sizeof(xDRI2SwapBuffersReply), &rep);
+
+ return client->noClientException;
+}
+
+static void
+load_msc_reply(xDRI2MSCReply *rep, CARD64 ust, CARD64 msc, CARD64 sbc)
+{
+ rep->ust_hi = ust >> 32;
+ rep->ust_lo = ust & 0xffffffff;
+ rep->msc_hi = msc >> 32;
+ rep->msc_lo = msc & 0xffffffff;
+ rep->sbc_hi = sbc >> 32;
+ rep->sbc_lo = sbc & 0xffffffff;
+}
+
+static int
+ProcDRI2GetMSC(ClientPtr client)
+{
+ REQUEST(xDRI2GetMSCReq);
+ xDRI2MSCReply rep;
+ DrawablePtr pDrawable;
+ CARD64 ust, msc, sbc;
+ int status;
+
+ REQUEST_SIZE_MATCH(xDRI2GetMSCReq);
+
+ if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable,
+ &status))
+ return status;
+
+ status = DRI2GetMSC(pDrawable, &ust, &msc, &sbc);
+ if (status != Success)
+ return status;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ load_msc_reply(&rep, ust, msc, sbc);
+
+ WriteToClient(client, sizeof(xDRI2MSCReply), &rep);
+
+ return client->noClientException;
+}
+
+static int
+ProcDRI2WaitMSC(ClientPtr client)
+{
+ REQUEST(xDRI2WaitMSCReq);
+ DrawablePtr pDrawable;
+ CARD64 target, divisor, remainder;
+ int status;
+
+ /* FIXME: in restart case, client may be gone at this point */
+
+ REQUEST_SIZE_MATCH(xDRI2WaitMSCReq);
+
+ if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable,
+ &status))
+ return status;
+
+ target = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi);
+ divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi);
+ remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi);
+
+ status = DRI2WaitMSC(client, pDrawable, target, divisor, remainder);
+ if (status != Success)
+ return status;
+
+ return client->noClientException;
+}
+
+int
+ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust, CARD64 msc, CARD64 sbc)
+{
+ xDRI2MSCReply rep;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ load_msc_reply(&rep, ust, msc, sbc);
+
+ WriteToClient(client, sizeof(xDRI2MSCReply), &rep);
+
+ return client->noClientException;
+}
+
+static int
+ProcDRI2SwapInterval(ClientPtr client)
+{
+ REQUEST(xDRI2SwapIntervalReq);
+ DrawablePtr pDrawable;
+ int status;
+
+ /* FIXME: in restart case, client may be gone at this point */
+
+ REQUEST_SIZE_MATCH(xDRI2SwapIntervalReq);
+
+ if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess,
+ &pDrawable, &status))
+ return status;
+
+ DRI2SwapInterval(pDrawable, stuff->interval);
+
+ return client->noClientException;
+}
+
+static int
+ProcDRI2WaitSBC(ClientPtr client)
+{
+ REQUEST(xDRI2WaitSBCReq);
+ xDRI2MSCReply rep;
+ DrawablePtr pDrawable;
+ CARD64 target, ust, msc, sbc;
+ int status;
+
+ REQUEST_SIZE_MATCH(xDRI2WaitSBCReq);
+
+ if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable,
+ &status))
+ return status;
+
+ target = vals_to_card64(stuff->target_sbc_lo, stuff->target_sbc_hi);
+ status = DRI2WaitSBC(client, pDrawable, target, &ust, &msc, &sbc);
+ if (status != Success)
+ return status;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ load_msc_reply(&rep, ust, msc, sbc);
+
+ WriteToClient(client, sizeof(xDRI2MSCReply), &rep);
+
+ return client->noClientException;
+}
+
static int
ProcDRI2Dispatch (ClientPtr client)
{
@@ -357,6 +561,16 @@ ProcDRI2Dispatch (ClientPtr client)
return ProcDRI2CopyRegion(client);
case X_DRI2GetBuffersWithFormat:
return ProcDRI2GetBuffersWithFormat(client);
+ case X_DRI2SwapBuffers:
+ return ProcDRI2SwapBuffers(client);
+ case X_DRI2GetMSC:
+ return ProcDRI2GetMSC(client);
+ case X_DRI2WaitMSC:
+ return ProcDRI2WaitMSC(client);
+ case X_DRI2WaitSBC:
+ return ProcDRI2WaitSBC(client);
+ case X_DRI2SwapInterval:
+ return ProcDRI2SwapInterval(client);
default:
return BadRequest;
}
@@ -413,6 +627,8 @@ static int DRI2DrawableGone(pointer p, XID id)
return Success;
}
+int DRI2EventBase;
+
static void
DRI2ExtensionInit(void)
{
@@ -429,6 +645,7 @@ DRI2ExtensionInit(void)
NULL,
StandardMinorOpcode);
+ DRI2EventBase = dri2Extension->eventBase;
}
extern Bool noDRI2Extension;
diff --git a/xorg-server/hw/xfree86/x86emu/Makefile.am b/xorg-server/hw/xfree86/x86emu/Makefile.am
index e7368f531..df9697767 100644
--- a/xorg-server/hw/xfree86/x86emu/Makefile.am
+++ b/xorg-server/hw/xfree86/x86emu/Makefile.am
@@ -11,7 +11,7 @@ libx86emu_la_SOURCES = debug.c \
sys.c \
x86emu.h
-INCLUDES = $(XORG_INCS)
+INCLUDES =
AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
diff --git a/xorg-server/hw/xfree86/x86emu/sys.c b/xorg-server/hw/xfree86/x86emu/sys.c
index 2ebf6f157..e15fb0931 100644
--- a/xorg-server/hw/xfree86/x86emu/sys.c
+++ b/xorg-server/hw/xfree86/x86emu/sys.c
@@ -48,13 +48,168 @@
#ifndef NO_SYS_HEADERS
#include <string.h>
#endif
-#include "compiler.h" /* for unaligned access functions */
/*------------------------- Global Variables ------------------------------*/
X86EMU_sysEnv _X86EMU_env; /* Global emulator machine state */
X86EMU_intrFuncs _X86EMU_intrTab[256];
/*----------------------------- Implementation ----------------------------*/
+#if defined(__alpha__) || defined(__alpha)
+/* to cope with broken egcs-1.1.2 :-(((( */
+
+#define ALPHA_UALOADS
+/*
+ * inline functions to do unaligned accesses
+ * from linux/include/asm-alpha/unaligned.h
+ */
+
+/*
+ * EGCS 1.1 knows about arbitrary unaligned loads. Define some
+ * packed structures to talk about such things with.
+ */
+
+#if defined(__GNUC__)
+struct __una_u64 { unsigned long x __attribute__((packed)); };
+struct __una_u32 { unsigned int x __attribute__((packed)); };
+struct __una_u16 { unsigned short x __attribute__((packed)); };
+#endif
+
+static __inline__ unsigned long ldq_u(unsigned long * r11)
+{
+#if defined(__GNUC__)
+ const struct __una_u64 *ptr = (const struct __una_u64 *) r11;
+ return ptr->x;
+#else
+ unsigned long r1,r2;
+ __asm__("ldq_u %0,%3\n\t"
+ "ldq_u %1,%4\n\t"
+ "extql %0,%2,%0\n\t"
+ "extqh %1,%2,%1"
+ :"=&r" (r1), "=&r" (r2)
+ :"r" (r11),
+ "m" (*r11),
+ "m" (*(const unsigned long *)(7+(char *) r11)));
+ return r1 | r2;
+#endif
+}
+
+static __inline__ unsigned long ldl_u(unsigned int * r11)
+{
+#if defined(__GNUC__)
+ const struct __una_u32 *ptr = (const struct __una_u32 *) r11;
+ return ptr->x;
+#else
+ unsigned long r1,r2;
+ __asm__("ldq_u %0,%3\n\t"
+ "ldq_u %1,%4\n\t"
+ "extll %0,%2,%0\n\t"
+ "extlh %1,%2,%1"
+ :"=&r" (r1), "=&r" (r2)
+ :"r" (r11),
+ "m" (*r11),
+ "m" (*(const unsigned long *)(3+(char *) r11)));
+ return r1 | r2;
+#endif
+}
+
+static __inline__ unsigned long ldw_u(unsigned short * r11)
+{
+#if defined(__GNUC__)
+ const struct __una_u16 *ptr = (const struct __una_u16 *) r11;
+ return ptr->x;
+#else
+ unsigned long r1,r2;
+ __asm__("ldq_u %0,%3\n\t"
+ "ldq_u %1,%4\n\t"
+ "extwl %0,%2,%0\n\t"
+ "extwh %1,%2,%1"
+ :"=&r" (r1), "=&r" (r2)
+ :"r" (r11),
+ "m" (*r11),
+ "m" (*(const unsigned long *)(1+(char *) r11)));
+ return r1 | r2;
+#endif
+}
+
+/*
+ * Elemental unaligned stores
+ */
+
+static __inline__ void stq_u(unsigned long r5, unsigned long * r11)
+{
+#if defined(__GNUC__)
+ struct __una_u64 *ptr = (struct __una_u64 *) r11;
+ ptr->x = r5;
+#else
+ unsigned long r1,r2,r3,r4;
+
+ __asm__("ldq_u %3,%1\n\t"
+ "ldq_u %2,%0\n\t"
+ "insqh %6,%7,%5\n\t"
+ "insql %6,%7,%4\n\t"
+ "mskqh %3,%7,%3\n\t"
+ "mskql %2,%7,%2\n\t"
+ "bis %3,%5,%3\n\t"
+ "bis %2,%4,%2\n\t"
+ "stq_u %3,%1\n\t"
+ "stq_u %2,%0"
+ :"=m" (*r11),
+ "=m" (*(unsigned long *)(7+(char *) r11)),
+ "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4)
+ :"r" (r5), "r" (r11));
+#endif
+}
+
+static __inline__ void stl_u(unsigned long r5, unsigned int * r11)
+{
+#if defined(__GNUC__)
+ struct __una_u32 *ptr = (struct __una_u32 *) r11;
+ ptr->x = r5;
+#else
+ unsigned long r1,r2,r3,r4;
+
+ __asm__("ldq_u %3,%1\n\t"
+ "ldq_u %2,%0\n\t"
+ "inslh %6,%7,%5\n\t"
+ "insll %6,%7,%4\n\t"
+ "msklh %3,%7,%3\n\t"
+ "mskll %2,%7,%2\n\t"
+ "bis %3,%5,%3\n\t"
+ "bis %2,%4,%2\n\t"
+ "stq_u %3,%1\n\t"
+ "stq_u %2,%0"
+ :"=m" (*r11),
+ "=m" (*(unsigned long *)(3+(char *) r11)),
+ "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4)
+ :"r" (r5), "r" (r11));
+#endif
+}
+
+static __inline__ void stw_u(unsigned long r5, unsigned short * r11)
+{
+#if defined(__GNUC__)
+ struct __una_u16 *ptr = (struct __una_u16 *) r11;
+ ptr->x = r5;
+#else
+ unsigned long r1,r2,r3,r4;
+
+ __asm__("ldq_u %3,%1\n\t"
+ "ldq_u %2,%0\n\t"
+ "inswh %6,%7,%5\n\t"
+ "inswl %6,%7,%4\n\t"
+ "mskwh %3,%7,%3\n\t"
+ "mskwl %2,%7,%2\n\t"
+ "bis %3,%5,%3\n\t"
+ "bis %2,%4,%2\n\t"
+ "stq_u %3,%1\n\t"
+ "stq_u %2,%0"
+ :"=m" (*r11),
+ "=m" (*(unsigned long *)(1+(char *) r11)),
+ "=&r" (r1), "=&r" (r2), "=&r" (r3), "=&r" (r4)
+ :"r" (r5), "r" (r11));
+#endif
+}
+#endif
/****************************************************************************
PARAMETERS:
@@ -107,7 +262,13 @@ u16 X86API rdw(
}
else
#endif
+#if defined(ALPHA_UALOADS)
val = ldw_u((u16*)(M.mem_base + addr));
+#elif defined(IA64_UALOADS)
+ val = uldw((u16*)(M.mem_base + addr));
+#else
+ val = *(u16*)(M.mem_base + addr);
+#endif
DB( if (DEBUG_MEM_TRACE())
printk("%#08x 2 -> %#x\n", addr, val);)
return val;
@@ -140,7 +301,13 @@ u32 X86API rdl(
}
else
#endif
+#if defined(ALPHA_UALOADS)
val = ldl_u((u32*)(M.mem_base + addr));
+#elif defined(IA64_UALOADS)
+ val = uldl((u32*)(M.mem_base + addr));
+#else
+ val = *(u32*)(M.mem_base + addr);
+#endif
DB( if (DEBUG_MEM_TRACE())
printk("%#08x 4 -> %#x\n", addr, val);)
return val;
@@ -192,7 +359,13 @@ DB( if (DEBUG_MEM_TRACE())
}
else
#endif
+#if defined(ALPHA_UALOADS)
stw_u(val,(u16*)(M.mem_base + addr));
+#elif defined(IA64_UALOADS)
+ ustw(val,(u16*)(M.mem_base + addr));
+#else
+ *(u16*)(M.mem_base + addr) = val;
+#endif
}
/****************************************************************************
@@ -222,7 +395,13 @@ DB( if (DEBUG_MEM_TRACE())
}
else
#endif
+#if defined(ALPHA_UALOADS)
stl_u(val,(u32*)(M.mem_base + addr));
+#elif defined(IA64_UALOADS)
+ ustl(val,(u32*)(M.mem_base + addr));
+#else
+ *(u32*)(M.mem_base + addr) = val;
+#endif
}
/****************************************************************************
diff --git a/xorg-server/hw/xquartz/bundle/Info.plist.cpp b/xorg-server/hw/xquartz/bundle/Info.plist.cpp
index 87214f456..e89d985f4 100644
--- a/xorg-server/hw/xquartz/bundle/Info.plist.cpp
+++ b/xorg-server/hw/xquartz/bundle/Info.plist.cpp
@@ -35,9 +35,9 @@
<string>http://xquartz.macosforge.org/downloads/sparkle/release.xml</string>
#endif
<key>NSHumanReadableCopyright</key>
- <string>© 2003-2009 Apple Inc.
+ <string>© 2003-2010 Apple Inc.
© 2003 XFree86 Project, Inc.
-© 2003-2009 X.org Foundation, Inc.
+© 2003-2010 X.org Foundation, Inc.
</string>
<key>NSMainNibFile</key>
<string>main</string>
diff --git a/xorg-server/hw/xquartz/quartzKeyboard.c b/xorg-server/hw/xquartz/quartzKeyboard.c
index 62b2ebbdf..96b5fa5b6 100644
--- a/xorg-server/hw/xquartz/quartzKeyboard.c
+++ b/xorg-server/hw/xquartz/quartzKeyboard.c
@@ -260,6 +260,7 @@ static void DarwinBuildModifierMaps(darwinKeyboardInfo *info) {
break;
case XK_Mode_switch:
+ ErrorF("DarwinBuildModifierMaps: XK_Mode_switch encountered, unable to determine side.\n");
info->modifierKeycodes[NX_MODIFIERKEY_ALTERNATE][0] = i;
#ifdef NX_MODIFIERKEY_RALTERNATE
info->modifierKeycodes[NX_MODIFIERKEY_RALTERNATE][0] = i;
@@ -388,7 +389,6 @@ void DarwinKeyboardReloadHandler(void) {
pthread_mutex_lock(&keyInfo_mutex); {
/* Initialize our keySyms */
- DarwinBuildModifierMaps(&keyInfo);
keySyms.map = keyInfo.keyMap;
keySyms.mapWidth = GLYPHS_PER_KEY;
keySyms.minKeyCode = MIN_KEYCODE;
@@ -808,5 +808,7 @@ Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info) {
}
}
+ DarwinBuildModifierMaps(info);
+
return TRUE;
}
diff --git a/xorg-server/hw/xquartz/xpr/x-hook.c b/xorg-server/hw/xquartz/xpr/x-hook.c
index 03e7f8553..5b850fe88 100644
--- a/xorg-server/hw/xquartz/xpr/x-hook.c
+++ b/xorg-server/hw/xquartz/xpr/x-hook.c
@@ -79,6 +79,9 @@ X_PFX (hook_run) (x_list *lst, void *arg)
void **data;
int length, i;
+ if(!lst)
+ return;
+
length = X_PFX (list_length) (lst);
fun = xalloc (sizeof (x_hook_function *) * length);
data = xalloc (sizeof (void *) * length);
diff --git a/xorg-server/include/protocol-versions.h b/xorg-server/include/protocol-versions.h
index d688c66b5..c74b7faf0 100644
--- a/xorg-server/include/protocol-versions.h
+++ b/xorg-server/include/protocol-versions.h
@@ -53,7 +53,7 @@
/* DRI2 */
#define SERVER_DRI2_MAJOR_VERSION 1
-#define SERVER_DRI2_MINOR_VERSION 1
+#define SERVER_DRI2_MINOR_VERSION 2
/* Generic event extension */
#define SERVER_GE_MAJOR_VERSION 1