Merge remote-tracking branch 'jeremyhu/master'

This commit is contained in:
Keith Packard 2011-10-24 18:12:23 -07:00
commit d9d3a01ffc
8 changed files with 545 additions and 201 deletions

View File

@ -87,6 +87,12 @@ XORG_PROG_RAWCPP
# easier overrides at build time. # easier overrides at build time.
XSERVER_CFLAGS='$(CWARNFLAGS)' XSERVER_CFLAGS='$(CWARNFLAGS)'
dnl Explicitly add -fno-strict-aliasing since this option should disappear
dnl from util-macros CWARNFLAGS
if test "x$GCC" = xyes ; then
XSERVER_CFLAGS="$XSERVER_CFLAGS -fno-strict-aliasing"
fi
dnl Check for dtrace program (needed to build Xserver dtrace probes) dnl Check for dtrace program (needed to build Xserver dtrace probes)
dnl Also checks for <sys/sdt.h>, since some Linux distros have an dnl Also checks for <sys/sdt.h>, since some Linux distros have an
dnl ISDN trace program named dtrace dnl ISDN trace program named dtrace

View File

@ -198,8 +198,6 @@ xnestCollectEvents(void)
case DestroyNotify: case DestroyNotify:
if (xnestParentWindow != (Window) 0 && if (xnestParentWindow != (Window) 0 &&
X.xdestroywindow.window == xnestParentWindow) X.xdestroywindow.window == xnestParentWindow)
CloseWellKnownConnections();
OsCleanup(1);
exit (0); exit (0);
break; break;

View File

@ -114,11 +114,13 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
int int
xnestKeyboardProc(DeviceIntPtr pDev, int onoff) xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
{ {
XModifierKeymap *modifier_keymap;
KeySym *keymap; KeySym *keymap;
int mapWidth; int mapWidth;
int min_keycode, max_keycode; int min_keycode, max_keycode;
KeySymsRec keySyms; KeySymsRec keySyms;
int i; CARD8 modmap[MAP_LENGTH];
int i, j;
XKeyboardState values; XKeyboardState values;
XkbDescPtr xkb; XkbDescPtr xkb;
int op, event, error, major, minor; int op, event, error, major, minor;
@ -130,7 +132,7 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
#ifdef _XSERVER64 #ifdef _XSERVER64
{ {
KeySym64 *keymap64; KeySym64 *keymap64;
int i, len; int len;
keymap64 = XGetKeyboardMapping(xnestDisplay, keymap64 = XGetKeyboardMapping(xnestDisplay,
min_keycode, min_keycode,
max_keycode - min_keycode + 1, max_keycode - min_keycode + 1,
@ -147,7 +149,17 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
max_keycode - min_keycode + 1, max_keycode - min_keycode + 1,
&mapWidth); &mapWidth);
#endif #endif
memset(modmap, 0, sizeof(modmap));
modifier_keymap = XGetModifierMapping(xnestDisplay);
for (j = 0; j < 8; j++)
for(i = 0; i < modifier_keymap->max_keypermod; i++) {
CARD8 keycode;
if ((keycode = modifier_keymap->modifiermap[j * modifier_keymap->max_keypermod + i]))
modmap[keycode] |= 1<<j;
}
XFreeModifiermap(modifier_keymap);
keySyms.minKeyCode = min_keycode; keySyms.minKeyCode = min_keycode;
keySyms.maxKeyCode = max_keycode; keySyms.maxKeyCode = max_keycode;
keySyms.mapWidth = mapWidth; keySyms.mapWidth = mapWidth;
@ -165,7 +177,12 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb); XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
InitKeyboardDeviceStruct(pDev, NULL, InitKeyboardDeviceStruct(pDev, NULL,
xnestBell, xnestChangeKeyboardControl); xnestBell, xnestChangeKeyboardControl);
XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode,
keySyms.maxKeyCode - keySyms.minKeyCode + 1,
modmap, serverClient);
XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
XkbFreeKeyboard(xkb, 0, False); XkbFreeKeyboard(xkb, 0, False);
free(keymap); free(keymap);

View File

@ -621,7 +621,7 @@ void OsVendorInit(void)
char *lf; char *lf;
char *home = getenv("HOME"); char *home = getenv("HOME");
assert(home); assert(home);
assert(0 < asprintf(&lf, "%s/Library/Logs/X11.%s.log", home, bundle_id_prefix)); assert(0 < asprintf(&lf, "%s/Library/Logs/%s.X11.log", home, bundle_id_prefix));
LogInit(lf, ".old"); LogInit(lf, ".old");
free(lf); free(lf);

View File

@ -2,7 +2,7 @@
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
Copyright 2000 VA Linux Systems, Inc. Copyright 2000 VA Linux Systems, Inc.
Copyright (c) 2002, 2009 Apple Computer, Inc. Copyright (c) 2002, 2009-2011 Apple Inc.
All Rights Reserved. All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
@ -102,6 +102,9 @@ ProcAppleDRIQueryVersion(
if (client->swapped) { if (client->swapped) {
swaps(&rep.sequenceNumber); swaps(&rep.sequenceNumber);
swapl(&rep.length); swapl(&rep.length);
swaps(&rep.majorVersion);
swaps(&rep.minorVersion);
swapl(&rep.patchVersion);
} }
WriteToClient(client, sizeof(xAppleDRIQueryVersionReply), (char *)&rep); WriteToClient(client, sizeof(xAppleDRIQueryVersionReply), (char *)&rep);
return Success; return Success;
@ -133,6 +136,11 @@ ProcAppleDRIQueryDirectRenderingCapable(
if (!LocalClient(client)) if (!LocalClient(client))
rep.isCapable = 0; rep.isCapable = 0;
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
}
WriteToClient(client, WriteToClient(client,
sizeof(xAppleDRIQueryDirectRenderingCapableReply), (char *)&rep); sizeof(xAppleDRIQueryDirectRenderingCapableReply), (char *)&rep);
return Success; return Success;
@ -157,6 +165,13 @@ ProcAppleDRIAuthConnection(
ErrorF("Failed to authenticate %u\n", (unsigned int)stuff->magic); ErrorF("Failed to authenticate %u\n", (unsigned int)stuff->magic);
rep.authenticated = 0; rep.authenticated = 0;
} }
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.authenticated); /* Yes, this is a CARD32 ... sigh */
}
WriteToClient(client, sizeof(xAppleDRIAuthConnectionReply), (char *)&rep); WriteToClient(client, sizeof(xAppleDRIAuthConnectionReply), (char *)&rep);
return Success; return Success;
} }
@ -216,6 +231,14 @@ ProcAppleDRICreateSurface(
rep.key_1 = key[1]; rep.key_1 = key[1];
rep.uid = sid; rep.uid = sid;
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.key_0);
swapl(&rep.key_1);
swapl(&rep.uid);
}
WriteToClient(client, sizeof(xAppleDRICreateSurfaceReply), (char *)&rep); WriteToClient(client, sizeof(xAppleDRICreateSurfaceReply), (char *)&rep);
return Success; return Success;
} }
@ -277,9 +300,8 @@ ProcAppleDRICreatePixmap(ClientPtr client)
rep.stringLength = strlen(path) + 1; rep.stringLength = strlen(path) + 1;
/* No need for swapping, because this only runs if LocalClient is true. */
rep.type = X_Reply; rep.type = X_Reply;
rep.length = sizeof(rep) + rep.stringLength; rep.length = bytes_to_int32(rep.stringLength);
rep.sequenceNumber = client->sequence; rep.sequenceNumber = client->sequence;
rep.width = width; rep.width = width;
rep.height = height; rep.height = height;
@ -290,8 +312,19 @@ ProcAppleDRICreatePixmap(ClientPtr client)
if(sizeof(rep) != sz_xAppleDRICreatePixmapReply) if(sizeof(rep) != sz_xAppleDRICreatePixmapReply)
ErrorF("error sizeof(rep) is %zu\n", sizeof(rep)); ErrorF("error sizeof(rep) is %zu\n", sizeof(rep));
WriteReplyToClient(client, sizeof(rep), &rep); if (client->swapped) {
(void)WriteToClient(client, rep.stringLength, path); swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.stringLength);
swapl(&rep.width);
swapl(&rep.height);
swapl(&rep.pitch);
swapl(&rep.bpp);
swapl(&rep.size);
}
WriteToClient(client, sizeof(rep), &rep);
WriteToClient(client, rep.stringLength, path);
return Success; return Success;
} }
@ -376,6 +409,77 @@ SProcAppleDRIQueryVersion(
return ProcAppleDRIQueryVersion(client); return ProcAppleDRIQueryVersion(client);
} }
static int
SProcAppleDRIQueryDirectRenderingCapable(
register ClientPtr client
)
{
REQUEST(xAppleDRIQueryDirectRenderingCapableReq);
swaps(&stuff->length);
swapl(&stuff->screen);
return ProcAppleDRIQueryDirectRenderingCapable(client);
}
static int
SProcAppleDRIAuthConnection(
register ClientPtr client
)
{
REQUEST(xAppleDRIAuthConnectionReq);
swaps(&stuff->length);
swapl(&stuff->screen);
swapl(&stuff->magic);
return ProcAppleDRIAuthConnection(client);
}
static int
SProcAppleDRICreateSurface(
register ClientPtr client
)
{
REQUEST(xAppleDRICreateSurfaceReq);
swaps(&stuff->length);
swapl(&stuff->screen);
swapl(&stuff->drawable);
swapl(&stuff->client_id);
return ProcAppleDRICreateSurface(client);
}
static int
SProcAppleDRIDestroySurface(
register ClientPtr client
)
{
REQUEST(xAppleDRIDestroySurfaceReq);
swaps(&stuff->length);
swapl(&stuff->screen);
swapl(&stuff->drawable);
return ProcAppleDRIDestroySurface(client);
}
static int
SProcAppleDRICreatePixmap(
register ClientPtr client
)
{
REQUEST(xAppleDRICreatePixmapReq);
swaps(&stuff->length);
swapl(&stuff->screen);
swapl(&stuff->drawable);
return ProcAppleDRICreatePixmap(client);
}
static int
SProcAppleDRIDestroyPixmap(
register ClientPtr client
)
{
REQUEST(xAppleDRIDestroyPixmapReq);
swaps(&stuff->length);
swapl(&stuff->drawable);
return ProcAppleDRIDestroyPixmap(client);
}
static int static int
SProcAppleDRIDispatch ( SProcAppleDRIDispatch (
register ClientPtr client register ClientPtr client
@ -383,15 +487,30 @@ SProcAppleDRIDispatch (
{ {
REQUEST(xReq); REQUEST(xReq);
/* It is bound to be non-local when there is byte swapping */
if (!LocalClient(client))
return DRIErrorBase + AppleDRIClientNotLocal;
/* only local clients are allowed DRI access */
switch (stuff->data) switch (stuff->data)
{ {
case X_AppleDRIQueryVersion: case X_AppleDRIQueryVersion:
return SProcAppleDRIQueryVersion(client); return SProcAppleDRIQueryVersion(client);
case X_AppleDRIQueryDirectRenderingCapable:
return SProcAppleDRIQueryDirectRenderingCapable(client);
}
if (!LocalClient(client))
return DRIErrorBase + AppleDRIClientNotLocal;
switch (stuff->data)
{
case X_AppleDRIAuthConnection:
return SProcAppleDRIAuthConnection(client);
case X_AppleDRICreateSurface:
return SProcAppleDRICreateSurface(client);
case X_AppleDRIDestroySurface:
return SProcAppleDRIDestroySurface(client);
case X_AppleDRICreatePixmap:
return SProcAppleDRICreatePixmap(client);
case X_AppleDRIDestroyPixmap:
return SProcAppleDRIDestroyPixmap(client);
default: default:
return BadRequest; return BadRequest;
} }

View File

@ -42,209 +42,225 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define APPLEDRINAME "Apple-DRI" #define APPLEDRINAME "Apple-DRI"
#define APPLE_DRI_MAJOR_VERSION 1 /* current version numbers */ #define APPLE_DRI_MAJOR_VERSION 1 /* current version numbers */
#define APPLE_DRI_MINOR_VERSION 0 #define APPLE_DRI_MINOR_VERSION 0
#define APPLE_DRI_PATCH_VERSION 0 #define APPLE_DRI_PATCH_VERSION 0
typedef struct _AppleDRIQueryVersion { typedef struct _AppleDRIQueryVersion
CARD8 reqType; /* always DRIReqCode */ {
CARD8 driReqType; /* always X_DRIQueryVersion */ CARD8 reqType; /* always DRIReqCode */
CARD16 length B16; CARD8 driReqType; /* always X_DRIQueryVersion */
CARD16 length B16;
} xAppleDRIQueryVersionReq; } xAppleDRIQueryVersionReq;
#define sz_xAppleDRIQueryVersionReq 4 #define sz_xAppleDRIQueryVersionReq 4
typedef struct { typedef struct
BYTE type; /* X_Reply */ {
BOOL pad1; BYTE type; /* X_Reply */
CARD16 sequenceNumber B16; BOOL pad1;
CARD32 length B32; CARD16 sequenceNumber B16;
CARD16 majorVersion B16; /* major version of DRI protocol */ CARD32 length B32;
CARD16 minorVersion B16; /* minor version of DRI protocol */ CARD16 majorVersion B16; /* major version of DRI protocol */
CARD32 patchVersion B32; /* patch version of DRI protocol */ CARD16 minorVersion B16; /* minor version of DRI protocol */
CARD32 pad3 B32; CARD32 patchVersion B32; /* patch version of DRI protocol */
CARD32 pad4 B32; CARD32 pad3 B32;
CARD32 pad5 B32; CARD32 pad4 B32;
CARD32 pad6 B32; CARD32 pad5 B32;
CARD32 pad6 B32;
} xAppleDRIQueryVersionReply; } xAppleDRIQueryVersionReply;
#define sz_xAppleDRIQueryVersionReply 32 #define sz_xAppleDRIQueryVersionReply 32
typedef struct _AppleDRIQueryDirectRenderingCapable { typedef struct _AppleDRIQueryDirectRenderingCapable
CARD8 reqType; /* always DRIReqCode */ {
CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */ CARD8 reqType; /* always DRIReqCode */
CARD16 length B16; CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */
CARD32 screen B32; CARD16 length B16;
CARD32 screen B32;
} xAppleDRIQueryDirectRenderingCapableReq; } xAppleDRIQueryDirectRenderingCapableReq;
#define sz_xAppleDRIQueryDirectRenderingCapableReq 8 #define sz_xAppleDRIQueryDirectRenderingCapableReq 8
typedef struct { typedef struct
BYTE type; /* X_Reply */ {
BOOL pad1; BYTE type; /* X_Reply */
CARD16 sequenceNumber B16; BOOL pad1;
CARD32 length B32; CARD16 sequenceNumber B16;
BOOL isCapable; CARD32 length B32;
BOOL pad2; BOOL isCapable;
BOOL pad3; BOOL pad2;
BOOL pad4; BOOL pad3;
CARD32 pad5 B32; BOOL pad4;
CARD32 pad6 B32; CARD32 pad5 B32;
CARD32 pad7 B32; CARD32 pad6 B32;
CARD32 pad8 B32; CARD32 pad7 B32;
CARD32 pad9 B32; CARD32 pad8 B32;
CARD32 pad9 B32;
} xAppleDRIQueryDirectRenderingCapableReply; } xAppleDRIQueryDirectRenderingCapableReply;
#define sz_xAppleDRIQueryDirectRenderingCapableReply 32 #define sz_xAppleDRIQueryDirectRenderingCapableReply 32
typedef struct _AppleDRIAuthConnection { typedef struct _AppleDRIAuthConnection
CARD8 reqType; /* always DRIReqCode */ {
CARD8 driReqType; /* always X_DRICloseConnection */ CARD8 reqType; /* always DRIReqCode */
CARD16 length B16; CARD8 driReqType; /* always X_DRICloseConnection */
CARD32 screen B32; CARD16 length B16;
CARD32 magic B32; CARD32 screen B32;
CARD32 magic B32;
} xAppleDRIAuthConnectionReq; } xAppleDRIAuthConnectionReq;
#define sz_xAppleDRIAuthConnectionReq 12 #define sz_xAppleDRIAuthConnectionReq 12
typedef struct { typedef struct
BYTE type; {
BOOL pad1; BYTE type;
CARD16 sequenceNumber B16; BOOL pad1;
CARD32 length B32; CARD16 sequenceNumber B16;
CARD32 authenticated B32; CARD32 length B32;
CARD32 pad2 B32; CARD32 authenticated B32;
CARD32 pad3 B32; CARD32 pad2 B32;
CARD32 pad4 B32; CARD32 pad3 B32;
CARD32 pad5 B32; CARD32 pad4 B32;
CARD32 pad6 B32; CARD32 pad5 B32;
CARD32 pad6 B32;
} xAppleDRIAuthConnectionReply; } xAppleDRIAuthConnectionReply;
#define zx_xAppleDRIAuthConnectionReply 32 #define zx_xAppleDRIAuthConnectionReply 32
typedef struct _AppleDRICreateSurface { typedef struct _AppleDRICreateSurface
CARD8 reqType; /* always DRIReqCode */ {
CARD8 driReqType; /* always X_DRICreateSurface */ CARD8 reqType; /* always DRIReqCode */
CARD16 length B16; CARD8 driReqType; /* always X_DRICreateSurface */
CARD32 screen B32; CARD16 length B16;
CARD32 drawable B32; CARD32 screen B32;
CARD32 client_id B32; CARD32 drawable B32;
CARD32 client_id B32;
} xAppleDRICreateSurfaceReq; } xAppleDRICreateSurfaceReq;
#define sz_xAppleDRICreateSurfaceReq 16 #define sz_xAppleDRICreateSurfaceReq 16
typedef struct { typedef struct
BYTE type; /* X_Reply */ {
BOOL pad1; BYTE type; /* X_Reply */
CARD16 sequenceNumber B16; BOOL pad1;
CARD32 length B32; CARD16 sequenceNumber B16;
CARD32 key_0 B32; CARD32 length B32;
CARD32 key_1 B32; CARD32 key_0 B32;
CARD32 uid B32; CARD32 key_1 B32;
CARD32 pad4 B32; CARD32 uid B32;
CARD32 pad5 B32; CARD32 pad4 B32;
CARD32 pad6 B32; CARD32 pad5 B32;
CARD32 pad6 B32;
} xAppleDRICreateSurfaceReply; } xAppleDRICreateSurfaceReply;
#define sz_xAppleDRICreateSurfaceReply 32 #define sz_xAppleDRICreateSurfaceReply 32
typedef struct _AppleDRIDestroySurface { typedef struct _AppleDRIDestroySurface
CARD8 reqType; /* always DRIReqCode */ {
CARD8 driReqType; /* always X_DRIDestroySurface */ CARD8 reqType; /* always DRIReqCode */
CARD16 length B16; CARD8 driReqType; /* always X_DRIDestroySurface */
CARD32 screen B32; CARD16 length B16;
CARD32 drawable B32; CARD32 screen B32;
CARD32 drawable B32;
} xAppleDRIDestroySurfaceReq; } xAppleDRIDestroySurfaceReq;
#define sz_xAppleDRIDestroySurfaceReq 12 #define sz_xAppleDRIDestroySurfaceReq 12
typedef struct _AppleDRINotify { typedef struct _AppleDRINotify
BYTE type; /* always eventBase + event type */ {
BYTE kind; BYTE type; /* always eventBase + event type */
CARD16 sequenceNumber B16; BYTE kind;
CARD32 time B32; /* time of change */ CARD16 sequenceNumber B16;
CARD32 pad1 B32; CARD32 time B32; /* time of change */
CARD32 arg B32; CARD32 pad1 B32;
CARD32 pad3 B32; CARD32 arg B32;
CARD32 pad4 B32; CARD32 pad3 B32;
CARD32 pad5 B32; CARD32 pad4 B32;
CARD32 pad6 B32; CARD32 pad5 B32;
CARD32 pad6 B32;
} xAppleDRINotifyEvent; } xAppleDRINotifyEvent;
#define sz_xAppleDRINotifyEvent 32 #define sz_xAppleDRINotifyEvent 32
typedef struct { typedef struct
CARD8 reqType; {
CARD8 driReqType; CARD8 reqType;
CARD16 length B16; CARD8 driReqType;
CARD32 screen B32; CARD16 length B16;
CARD32 drawable B32; CARD32 screen B32;
BOOL doubleSwap; CARD32 drawable B32;
CARD8 pad1, pad2, pad3; BOOL doubleSwap;
CARD8 pad1, pad2, pad3;
} xAppleDRICreateSharedBufferReq; } xAppleDRICreateSharedBufferReq;
#define sz_xAppleDRICreateSharedBufferReq 16 #define sz_xAppleDRICreateSharedBufferReq 16
typedef struct { typedef struct
BYTE type; {
BYTE data1; BYTE type;
CARD16 sequenceNumber B16; BYTE data1;
CARD32 length B32; CARD16 sequenceNumber B16;
CARD32 stringLength B32; /* 0 on error */ CARD32 length B32;
CARD32 width B32; CARD32 stringLength B32; /* 0 on error */
CARD32 height B32; CARD32 width B32;
CARD32 pad1 B32; CARD32 height B32;
CARD32 pad2 B32; CARD32 pad1 B32;
CARD32 pad3 B32; CARD32 pad2 B32;
CARD32 pad3 B32;
} xAppleDRICreateSharedBufferReply; } xAppleDRICreateSharedBufferReply;
#define sz_xAppleDRICreateSharedBufferReply 32 #define sz_xAppleDRICreateSharedBufferReply 32
typedef struct { typedef struct
CARD8 reqType; {
CARD8 driReqType; CARD8 reqType;
CARD16 length B16; CARD8 driReqType;
CARD32 screen B32; CARD16 length B16;
CARD32 drawable B32; CARD32 screen B32;
CARD32 drawable B32;
} xAppleDRISwapBuffersReq; } xAppleDRISwapBuffersReq;
#define sz_xAppleDRISwapBuffersReq 12 #define sz_xAppleDRISwapBuffersReq 12
typedef struct { typedef struct
CARD8 reqType; /*1*/ {
CARD8 driReqType; /*2*/ CARD8 reqType; /*1 */
CARD16 length B16; /*4*/ CARD8 driReqType; /*2 */
CARD32 screen B32; /*8*/ CARD16 length B16; /*4 */
CARD32 drawable B32; /*12*/ CARD32 screen B32; /*8 */
CARD32 drawable B32; /*12 */
} xAppleDRICreatePixmapReq; } xAppleDRICreatePixmapReq;
#define sz_xAppleDRICreatePixmapReq 12 #define sz_xAppleDRICreatePixmapReq 12
typedef struct { typedef struct
BYTE type; /*1*/ {
BOOL pad1; /*2*/ BYTE type; /*1 */
CARD16 sequenceNumber B16; /*4*/ BOOL pad1; /*2 */
CARD32 length B32; /*8*/ CARD16 sequenceNumber B16; /*4 */
CARD32 width B32; /*12*/ CARD32 length B32; /*8 */
CARD32 height B32; /*16*/ CARD32 width B32; /*12 */
CARD32 pitch B32; /*20*/ CARD32 height B32; /*16 */
CARD32 bpp B32; /*24*/ CARD32 pitch B32; /*20 */
CARD32 size B32; /*28*/ CARD32 bpp B32; /*24 */
CARD32 stringLength B32; /*32*/ CARD32 size B32; /*28 */
CARD32 stringLength B32; /*32 */
} xAppleDRICreatePixmapReply; } xAppleDRICreatePixmapReply;
#define sz_xAppleDRICreatePixmapReply 32 #define sz_xAppleDRICreatePixmapReply 32
typedef struct { typedef struct
CARD8 reqType; /*1*/ {
CARD8 driReqType; /*2*/ CARD8 reqType; /*1 */
CARD16 length B16; /*4*/ CARD8 driReqType; /*2 */
CARD32 drawable B32; /*8*/ CARD16 length B16; /*4 */
CARD32 drawable B32; /*8 */
} xAppleDRIDestroyPixmapReq; } xAppleDRIDestroyPixmapReq;
#define sz_xAppleDRIDestroyPixmapReq 8 #define sz_xAppleDRIDestroyPixmapReq 8
#ifdef _APPLEDRI_SERVER_ #ifdef _APPLEDRI_SERVER_
void AppleDRISendEvent ( void AppleDRISendEvent(
#if NeedFunctionPrototypes #if NeedFunctionPrototypes
int /* type */, int /* type */ ,
unsigned int /* mask */, unsigned int /* mask */ ,
int /* which */, int /* which */ ,
int /* arg */ int /* arg */
#endif #endif
); );
#endif /* _APPLEDRI_SERVER_ */ #endif /* _APPLEDRI_SERVER_ */
#endif /* _APPLEDRISTR_H_ */ #endif /* _APPLEDRISTR_H_ */

190
mi/mieq.c
View File

@ -59,7 +59,12 @@ in this Software without prior written authorization from The Open Group.
# include <X11/extensions/dpmsconst.h> # include <X11/extensions/dpmsconst.h>
#endif #endif
#define QUEUE_SIZE 512 /* Maximum size should be initial size multiplied by a power of 2 */
#define QUEUE_INITIAL_SIZE 256
#define QUEUE_RESERVED_SIZE 64
#define QUEUE_MAXIMUM_SIZE 4096
#define QUEUE_DROP_BACKTRACE_FREQUENCY 100
#define QUEUE_DROP_BACKTRACE_MAX 10
#define EnqueueScreen(dev) dev->spriteInfo->sprite->pEnqueueScreen #define EnqueueScreen(dev) dev->spriteInfo->sprite->pEnqueueScreen
#define DequeueScreen(dev) dev->spriteInfo->sprite->pDequeueScreen #define DequeueScreen(dev) dev->spriteInfo->sprite->pDequeueScreen
@ -74,7 +79,9 @@ typedef struct _EventQueue {
HWEventQueueType head, tail; /* long for SetInputCheck */ HWEventQueueType head, tail; /* long for SetInputCheck */
CARD32 lastEventTime; /* to avoid time running backwards */ CARD32 lastEventTime; /* to avoid time running backwards */
int lastMotion; /* device ID if last event motion? */ int lastMotion; /* device ID if last event motion? */
EventRec events[QUEUE_SIZE]; /* static allocation for signals */ EventRec *events; /* our queue as an array */
size_t nevents; /* the number of buckets in our queue */
size_t dropped; /* counter for number of consecutive dropped events */
mieqHandler handlers[128]; /* custom event handler */ mieqHandler handlers[128]; /* custom event handler */
} EventQueueRec, *EventQueuePtr; } EventQueueRec, *EventQueuePtr;
@ -99,25 +106,87 @@ static inline void wait_for_server_init(void) {
} }
#endif #endif
static size_t
mieqNumEnqueued(EventQueuePtr eventQueue) {
size_t n_enqueued = 0;
if (eventQueue->nevents) {
/* % is not well-defined with negative numbers... sigh */
n_enqueued = eventQueue->tail - eventQueue->head + eventQueue->nevents;
if (n_enqueued >= eventQueue->nevents)
n_enqueued -= eventQueue->nevents;
}
return n_enqueued;
}
/* Pre-condition: Called with miEventQueueMutex held */
static Bool
mieqGrowQueue(EventQueuePtr eventQueue, size_t new_nevents) {
size_t i, n_enqueued, first_hunk;
EventRec *new_events;
if (!eventQueue) {
ErrorF("[mi] mieqGrowQueue called with a NULL eventQueue\n");
return FALSE;
}
if (new_nevents <= eventQueue->nevents)
return FALSE;
new_events = calloc(new_nevents, sizeof(EventRec));
if (new_events == NULL) {
ErrorF("[mi] mieqGrowQueue memory allocation error.\n");
return FALSE;
}
n_enqueued = mieqNumEnqueued(eventQueue);
/* We block signals, so an mieqEnqueue triggered by SIGIO does not
* write to our queue as we are modifying it.
*/
OsBlockSignals();
/* First copy the existing events */
first_hunk = eventQueue->nevents - eventQueue->head;
memcpy(new_events,
&eventQueue->events[eventQueue->head],
first_hunk * sizeof(EventRec));
memcpy(&new_events[first_hunk],
eventQueue->events,
eventQueue->head * sizeof(EventRec));
/* Initialize the new portion */
for (i = eventQueue->nevents; i < new_nevents; i++) {
InternalEvent* evlist = InitEventList(1);
if (!evlist) {
size_t j;
for (j = 0; j < i; j++)
FreeEventList(new_events[j].events, 1);
free(new_events);
OsReleaseSignals();
return FALSE;
}
new_events[i].events = evlist;
}
/* And update our record */
eventQueue->tail = n_enqueued;
eventQueue->head = 0;
eventQueue->nevents = new_nevents;
free(eventQueue->events);
eventQueue->events = new_events;
OsReleaseSignals();
return TRUE;
}
Bool Bool
mieqInit(void) mieqInit(void)
{ {
int i; memset(&miEventQueue, 0, sizeof(miEventQueue));
miEventQueue.head = miEventQueue.tail = 0;
miEventQueue.lastEventTime = GetTimeInMillis (); miEventQueue.lastEventTime = GetTimeInMillis ();
miEventQueue.lastMotion = FALSE;
for (i = 0; i < 128; i++) if(!mieqGrowQueue(&miEventQueue, QUEUE_INITIAL_SIZE))
miEventQueue.handlers[i] = NULL; FatalError("Could not allocate event queue.\n");
for (i = 0; i < QUEUE_SIZE; i++)
{
if (miEventQueue.events[i].events == NULL) {
InternalEvent* evlist = InitEventList(1);
if (!evlist)
FatalError("Could not allocate event queue.\n");
miEventQueue.events[i].events = evlist;
}
}
SetInputCheck(&miEventQueue.head, &miEventQueue.tail); SetInputCheck(&miEventQueue.head, &miEventQueue.tail);
return TRUE; return TRUE;
@ -127,13 +196,34 @@ void
mieqFini(void) mieqFini(void)
{ {
int i; int i;
for (i = 0; i < QUEUE_SIZE; i++) for (i = 0; i < miEventQueue.nevents; i++)
{ {
if (miEventQueue.events[i].events != NULL) { if (miEventQueue.events[i].events != NULL) {
FreeEventList(miEventQueue.events[i].events, 1); FreeEventList(miEventQueue.events[i].events, 1);
miEventQueue.events[i].events = NULL; miEventQueue.events[i].events = NULL;
} }
} }
free(miEventQueue.events);
}
/* This function will determine if the given event is allowed to used the reserved
* queue space.
*/
static Bool
mieqReservedCandidate(InternalEvent *e) {
switch(e->any.type) {
case ET_KeyRelease:
case ET_ButtonRelease:
#if XFreeXDGA
case ET_DGAEvent:
#endif
case ET_RawKeyRelease:
case ET_RawButtonRelease:
case ET_XQuartz:
return TRUE;
default:
return FALSE;
}
} }
/* /*
@ -151,6 +241,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
int isMotion = 0; int isMotion = 0;
int evlen; int evlen;
Time time; Time time;
size_t n_enqueued;
#ifdef XQUARTZ #ifdef XQUARTZ
wait_for_server_init(); wait_for_server_init();
@ -159,32 +250,40 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
verify_internal_event(e); verify_internal_event(e);
n_enqueued = mieqNumEnqueued(&miEventQueue);
/* avoid merging events from different devices */ /* avoid merging events from different devices */
if (e->any.type == ET_Motion) if (e->any.type == ET_Motion)
isMotion = pDev->id; isMotion = pDev->id;
if (isMotion && isMotion == miEventQueue.lastMotion && if (isMotion && isMotion == miEventQueue.lastMotion &&
oldtail != miEventQueue.head) { oldtail != miEventQueue.head) {
oldtail = (oldtail - 1) % QUEUE_SIZE; oldtail = (oldtail - 1) % miEventQueue.nevents;
} } else if ((n_enqueued + 1 == miEventQueue.nevents) ||
else { ((n_enqueued + 1 >= miEventQueue.nevents - QUEUE_RESERVED_SIZE) && !mieqReservedCandidate(e))) {
static int stuck = 0;
/* Toss events which come in late. Usually this means your server's /* Toss events which come in late. Usually this means your server's
* stuck in an infinite loop somewhere, but SIGIO is still getting * stuck in an infinite loop somewhere, but SIGIO is still getting
* handled. */ * handled.
if (((oldtail + 1) % QUEUE_SIZE) == miEventQueue.head) { */
if (!stuck) { miEventQueue.dropped++;
ErrorF("[mi] EQ overflowing. The server is probably stuck " if (miEventQueue.dropped == 1) {
"in an infinite loop.\n"); ErrorF("[mi] EQ overflowing. Additional events will be discarded until existing events are processed.\n");
xorg_backtrace(); xorg_backtrace();
stuck = 1; ErrorF("[mi] These backtraces from mieqEnqueue may point to a culprit higher up the stack.\n");
ErrorF("[mi] mieq is *NOT* the cause. It is a victim.\n");
} else if (miEventQueue.dropped % QUEUE_DROP_BACKTRACE_FREQUENCY == 0 &&
miEventQueue.dropped / QUEUE_DROP_BACKTRACE_FREQUENCY <= QUEUE_DROP_BACKTRACE_MAX) {
ErrorF("[mi] EQ overflow continuing. %lu events have been dropped.\n", miEventQueue.dropped);
if (miEventQueue.dropped / QUEUE_DROP_BACKTRACE_FREQUENCY == QUEUE_DROP_BACKTRACE_MAX) {
ErrorF("[mi] No further overflow reports will be reported until the clog is cleared.\n");
} }
#ifdef XQUARTZ xorg_backtrace();
pthread_mutex_unlock(&miEventQueueMutex);
#endif
return;
} }
stuck = 0;
#ifdef XQUARTZ
pthread_mutex_unlock(&miEventQueueMutex);
#endif
return;
} }
evlen = e->any.length; evlen = e->any.length;
@ -203,7 +302,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
miEventQueue.events[oldtail].pDev = pDev; miEventQueue.events[oldtail].pDev = pDev;
miEventQueue.lastMotion = isMotion; miEventQueue.lastMotion = isMotion;
miEventQueue.tail = (oldtail + 1) % QUEUE_SIZE; miEventQueue.tail = (oldtail + 1) % miEventQueue.nevents;
#ifdef XQUARTZ #ifdef XQUARTZ
pthread_mutex_unlock(&miEventQueueMutex); pthread_mutex_unlock(&miEventQueueMutex);
#endif #endif
@ -437,11 +536,28 @@ mieqProcessInputEvents(void)
static InternalEvent event; static InternalEvent event;
DeviceIntPtr dev = NULL, DeviceIntPtr dev = NULL,
master = NULL; master = NULL;
size_t n_enqueued;
#ifdef XQUARTZ #ifdef XQUARTZ
pthread_mutex_lock(&miEventQueueMutex); pthread_mutex_lock(&miEventQueueMutex);
#endif #endif
/* Grow our queue if we are reaching capacity: < 2 * QUEUE_RESERVED_SIZE remaining */
n_enqueued = mieqNumEnqueued(&miEventQueue);
if (n_enqueued >= (miEventQueue.nevents - (2 * QUEUE_RESERVED_SIZE)) &&
miEventQueue.nevents < QUEUE_MAXIMUM_SIZE) {
ErrorF("[mi] Increasing EQ size to %lu to prevent dropped events.\n", miEventQueue.nevents << 1);
if (!mieqGrowQueue(&miEventQueue, miEventQueue.nevents << 1)) {
ErrorF("[mi] Increasing the size of EQ failed.\n");
}
}
if (miEventQueue.dropped) {
ErrorF("[mi] EQ processing has resumed after %lu dropped events.\n", miEventQueue.dropped);
ErrorF("[mi] This may be caused my a misbehaving driver monopolizing the server's resources.\n");
miEventQueue.dropped = 0;
}
while (miEventQueue.head != miEventQueue.tail) { while (miEventQueue.head != miEventQueue.tail) {
e = &miEventQueue.events[miEventQueue.head]; e = &miEventQueue.events[miEventQueue.head];
@ -449,7 +565,7 @@ mieqProcessInputEvents(void)
dev = e->pDev; dev = e->pDev;
screen = e->pScreen; screen = e->pScreen;
miEventQueue.head = (miEventQueue.head + 1) % QUEUE_SIZE; miEventQueue.head = (miEventQueue.head + 1) % miEventQueue.nevents;
#ifdef XQUARTZ #ifdef XQUARTZ
pthread_mutex_unlock(&miEventQueueMutex); pthread_mutex_unlock(&miEventQueueMutex);

View File

@ -40,6 +40,7 @@
#include "dixgrabs.h" #include "dixgrabs.h"
#include "eventstr.h" #include "eventstr.h"
#include "inpututils.h" #include "inpututils.h"
#include "mi.h"
#include "assert.h" #include "assert.h"
/** /**
@ -1480,8 +1481,6 @@ _test_double_fp16_values(double orig_d)
{ {
FP1616 first_fp16, final_fp16; FP1616 first_fp16, final_fp16;
double final_d; double final_d;
char first_fp16_s[64];
char final_fp16_s[64];
if (orig_d > 0x7FFF) { if (orig_d > 0x7FFF) {
printf("Test out of range\n"); printf("Test out of range\n");
@ -1492,10 +1491,15 @@ _test_double_fp16_values(double orig_d)
final_d = fp1616_to_double(first_fp16); final_d = fp1616_to_double(first_fp16);
final_fp16 = double_to_fp1616(final_d); final_fp16 = double_to_fp1616(final_d);
snprintf(first_fp16_s, sizeof(first_fp16_s), "%d + %u * 2^-16", (first_fp16 & 0xffff0000) >> 16, first_fp16 & 0xffff); /* {
snprintf(final_fp16_s, sizeof(final_fp16_s), "%d + %u * 2^-16", (final_fp16 & 0xffff0000) >> 16, final_fp16 & 0xffff); * char first_fp16_s[64];
* char final_fp16_s[64];
printf("FP16: original double: %f first fp16: %s, re-encoded double: %f, final fp16: %s\n", orig_d, first_fp16_s, final_d, final_fp16_s); * snprintf(first_fp16_s, sizeof(first_fp16_s), "%d + %u * 2^-16", (first_fp16 & 0xffff0000) >> 16, first_fp16 & 0xffff);
* snprintf(final_fp16_s, sizeof(final_fp16_s), "%d + %u * 2^-16", (final_fp16 & 0xffff0000) >> 16, final_fp16 & 0xffff);
*
* printf("FP16: original double: %f first fp16: %s, re-encoded double: %f, final fp16: %s\n", orig_d, first_fp16_s, final_d, final_fp16_s);
* }
*/
/* since we lose precision, we only do rough range testing */ /* since we lose precision, we only do rough range testing */
assert(final_d > orig_d - 0.1); assert(final_d > orig_d - 0.1);
@ -1603,6 +1607,73 @@ dix_double_fp_conversion(void)
} }
} }
/* The mieq test verifies that events added to the queue come out in the same
* order that they went in.
*/
static uint32_t mieq_test_event_last_processed;
static void
mieq_test_event_handler(int screenNum, InternalEvent *ie, DeviceIntPtr dev) {
RawDeviceEvent *e = (RawDeviceEvent *)ie;
assert(e->type == ET_RawMotion);
assert(e->flags > mieq_test_event_last_processed);
mieq_test_event_last_processed = e->flags;
}
static void _mieq_test_generate_events(uint32_t start, uint32_t count) {
count += start;
while (start < count) {
RawDeviceEvent e = {0};
e.header = ET_Internal;
e.type = ET_RawMotion;
e.length = sizeof(e);
e.time = GetTimeInMillis();
e.flags = start;
mieqEnqueue(NULL, (InternalEvent*)&e);
start++;
}
}
#define mieq_test_generate_events(c) { _mieq_test_generate_events(next, c); next += c; }
static void
mieq_test(void) {
uint32_t next = 1;
mieq_test_event_last_processed = 0;
mieqInit();
mieqSetHandler(ET_RawMotion, mieq_test_event_handler);
/* Enough to fit the buffer but trigger a grow */
mieq_test_generate_events(180);
/* We should resize to 512 now */
mieqProcessInputEvents();
/* Some should now get dropped */
mieq_test_generate_events(500);
/* Tell us how many got dropped, 1024 now */
mieqProcessInputEvents();
/* Now make it 2048 */
mieq_test_generate_events(900);
mieqProcessInputEvents();
/* Now make it 4096 (max) */
mieq_test_generate_events(1950);
mieqProcessInputEvents();
/* Now overflow one last time with the maximal queue and reach the verbosity limit */
mieq_test_generate_events(10000);
mieqProcessInputEvents();
mieqFini();
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
dix_double_fp_conversion(); dix_double_fp_conversion();
@ -1621,6 +1692,7 @@ int main(int argc, char** argv)
dix_valuator_alloc(); dix_valuator_alloc();
dix_get_master(); dix_get_master();
input_option_test(); input_option_test();
mieq_test();
return 0; return 0;
} }