mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-01-04 19:10:14 +01:00
762 lines
19 KiB
C
762 lines
19 KiB
C
/************************************************************
|
|
|
|
Copyright (c) 2004, Sun Microsystems, Inc.
|
|
|
|
Permission to use, copy, modify, distribute, and sell this software and its
|
|
documentation for any purpose is hereby granted without fee, provided that
|
|
the above copyright notice appear in all copies and that both that
|
|
copyright notice and this permission notice appear in supporting
|
|
documentation.
|
|
|
|
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
|
|
OPEN GROUP 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 of The Open Group shall not be
|
|
used in advertising or otherwise to promote the sale, use or other dealings
|
|
in this Software without prior written authorization from The Open Group.
|
|
|
|
********************************************************/
|
|
|
|
#ifdef LG3D
|
|
|
|
#define NEED_REPLIES
|
|
#define NEED_EVENTS
|
|
#include <unistd.h>
|
|
#include "X.h"
|
|
#include "Xproto.h"
|
|
#include "misc.h"
|
|
#include "dixstruct.h"
|
|
#include "extnsionst.h"
|
|
#include "windowstr.h"
|
|
#include "scrnintstr.h"
|
|
#include "cursorstr.h"
|
|
#include "inputstr.h"
|
|
#include "lgewire.h"
|
|
#include "lgeint.h"
|
|
|
|
int lgeDisplayServerIsAlive = 0;
|
|
|
|
ClientPtr lgePickerClient = NULL;
|
|
ClientPtr lgeEventDelivererClient = NULL;
|
|
int lgeEventComesFromDS = 0;
|
|
|
|
/*
|
|
** If sendEventDirect == true we will call the core process event
|
|
** routine directly. The event will not be subject to queue freezing.
|
|
** If sendEventDirect == false we will reinsert the event via the
|
|
** device's processInputProc routine. This means that the event will
|
|
** be subject to queue freezing. That is to say, if the queue is currently
|
|
** frozen due to a synchronous grab the event will be enqueued and not
|
|
** sent further up the event pipeline until the queue is unfrozen.
|
|
*/
|
|
|
|
Bool lgeSendEventDirect = FALSE;
|
|
|
|
DeviceIntPtr lgekb = NULL;
|
|
DeviceIntPtr lgems = NULL;
|
|
|
|
/* The pseudo-root window of first screen */
|
|
Window lgeDisplayServerPRW = INVALID;
|
|
WindowPtr pLgeDisplayServerPRWWin = NULL;
|
|
|
|
Window lgeDisplayServerPRWsList[MAXSCREENS];
|
|
WindowPtr pLgeDisplayServerPRWWinsList[MAXSCREENS];
|
|
WindowPtr pLgeDisplayServerPRWWinRoots[MAXSCREENS];
|
|
|
|
static int numRegisteredScr = 0;
|
|
|
|
static int LgeReqCode;
|
|
|
|
void LgeExtensionInit (void);
|
|
int LgeShutdownDisplayServer (pointer data, XID id);
|
|
int ProcLgeDispatch (ClientPtr client);
|
|
int SProcLgeDispatch (ClientPtr client);
|
|
|
|
static RESTYPE lgeClientResourceType;
|
|
|
|
#ifdef PERF
|
|
/* For performance analysis */
|
|
#include "../dix/statbuf.h"
|
|
static StatBuf *sbPerf = NULL;
|
|
static struct timeval tvStart, tvStop;
|
|
#endif /* PERF */
|
|
|
|
extern void XkbProcessKeyboardEvent(xEvent *xE, DeviceIntPtr keybd, int count);
|
|
|
|
extern WindowPtr *WindowTable;
|
|
|
|
static void lgeDisableIncompatibleExtensions ();
|
|
static void lgeReenableIncompatibleExtensions ();
|
|
|
|
/* This must be the same as in dix/extension.c */
|
|
#define EXTENSION_BASE 128
|
|
|
|
extern unsigned int NumExtensions;
|
|
extern ExtensionEntry **extensions;
|
|
|
|
static int
|
|
ProcLgeQueryVersion (ClientPtr client)
|
|
{
|
|
REQUEST(xLgeQueryVersionReq);
|
|
xLgeQueryVersionReply rep;
|
|
int n;
|
|
|
|
REQUEST_SIZE_MATCH(xLgeQueryVersionReq);
|
|
rep.type = X_Reply;
|
|
rep.length = 0;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.majorVersion = LGE_MAJOR_VERSION;
|
|
rep.minorVersion = LGE_MINOR_VERSION;
|
|
rep.implementation = LG3D_IMPLEMENTATION;
|
|
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber, n);
|
|
swapl(&rep.majorVersion, n);
|
|
swapl(&rep.minorVersion, n);
|
|
swapl(&rep.implementation, n);
|
|
}
|
|
WriteToClient(client, sizeof(xLgeQueryVersionReply), (char *) &rep);
|
|
return (client->noClientException);
|
|
}
|
|
|
|
/* For debug
|
|
|
|
static void
|
|
printEventMask (unsigned int mask)
|
|
{
|
|
int i;
|
|
unsigned int bit;
|
|
|
|
for (i = 0, bit = 0x1; i < 32; i++, bit <<= 1) {
|
|
if ((mask & bit) != 0) {
|
|
switch (mask & bit) {
|
|
case KeyPressMask:
|
|
ErrorF("KeyPressMask ");
|
|
break;
|
|
case KeyReleaseMask:
|
|
ErrorF("KeyReleaseMask ");
|
|
break;
|
|
case ButtonPressMask:
|
|
ErrorF("ButtonPressMask ");
|
|
break;
|
|
case ButtonReleaseMask:
|
|
ErrorF("ButtonReleaseMask ");
|
|
break;
|
|
case EnterWindowMask:
|
|
ErrorF("EnterWindowMask ");
|
|
break;
|
|
case LeaveWindowMask:
|
|
ErrorF("LeaveWindowMask ");
|
|
break;
|
|
case PointerMotionMask:
|
|
ErrorF("PointerMotionMask ");
|
|
break;
|
|
case PointerMotionHintMask:
|
|
ErrorF("PointerMotionHintMask ");
|
|
break;
|
|
case Button1MotionMask:
|
|
ErrorF("Button1MotionMask ");
|
|
break;
|
|
case Button2MotionMask:
|
|
ErrorF("Button2MotionMask ");
|
|
break;
|
|
case Button3MotionMask:
|
|
ErrorF("Button3MotionMask ");
|
|
break;
|
|
case Button4MotionMask:
|
|
ErrorF("Button4MotionMask ");
|
|
break;
|
|
case Button5MotionMask:
|
|
ErrorF("Button5MotionMask ");
|
|
break;
|
|
case ButtonMotionMask:
|
|
ErrorF("ButtonMotionMask ");
|
|
break;
|
|
case KeymapStateMask:
|
|
ErrorF("KeymapStateMask ");
|
|
break;
|
|
case ExposureMask:
|
|
ErrorF("ExposureMask ");
|
|
break;
|
|
case VisibilityChangeMask:
|
|
ErrorF("VisibilityChangeMask ");
|
|
break;
|
|
case StructureNotifyMask:
|
|
ErrorF("StructureNotifyMask ");
|
|
break;
|
|
case ResizeRedirectMask:
|
|
ErrorF("ResizeRedirectMask ");
|
|
break;
|
|
case SubstructureNotifyMask:
|
|
ErrorF("SubstructureNotifyMask ");
|
|
break;
|
|
case SubstructureRedirectMask:
|
|
ErrorF("SubstructureRedirectMask ");
|
|
break;
|
|
case FocusChangeMask:
|
|
ErrorF("FocusChangeMask ");
|
|
break;
|
|
case PropertyChangeMask:
|
|
ErrorF("PropertyChangeMask ");
|
|
break;
|
|
case ColormapChangeMask:
|
|
ErrorF("ColormapChangeMask ");
|
|
break;
|
|
case OwnerGrabButtonMask:
|
|
ErrorF("OwnerGrabButtonMask ");
|
|
break;
|
|
}
|
|
ErrorF("\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
printEventInterest (WindowPtr pWin)
|
|
{
|
|
OtherClients * others;
|
|
|
|
ErrorF("Owner client = %d\n", wClient(pWin)->index);
|
|
ErrorF("Client event interest for prw %d\n", pWin->drawable.id);
|
|
ErrorF("Owner interest: eventMask = 0x%x\n", pWin->eventMask);
|
|
printEventMask(pWin->eventMask);
|
|
ErrorF("\n");
|
|
ErrorF("Non-owner interest:\n");
|
|
for (others = wOtherClients(pWin); others; others = others->next) {
|
|
ErrorF("Other client mask = 0x%x\n", others->mask);
|
|
printEventMask(others->mask);
|
|
ErrorF("\n");
|
|
}
|
|
}
|
|
*/
|
|
|
|
static int
|
|
ProcLgeRegisterClient (ClientPtr client)
|
|
{
|
|
REQUEST(xLgeRegisterClientReq);
|
|
|
|
REQUEST_SIZE_MATCH(xLgeRegisterClientReq);
|
|
|
|
switch (stuff->clientType) {
|
|
|
|
case LGE_CLIENT_PICKER:
|
|
if (lgePickerClient != NULL) {
|
|
return BadAccess;
|
|
}
|
|
lgePickerClient = client;
|
|
lgeSendEventDirect = stuff->sendEventDirect;
|
|
break;
|
|
|
|
case LGE_CLIENT_EVENT_DELIVERER:
|
|
if (lgeEventDelivererClient != NULL) {
|
|
return BadAccess;
|
|
}
|
|
lgeEventDelivererClient = client;
|
|
break;
|
|
}
|
|
|
|
/* The first client to close down tells the server that the DS has shut down */
|
|
if (!AddResource (FakeClientID(client->index), lgeClientResourceType, NULL)) {
|
|
return BadAlloc;
|
|
}
|
|
|
|
return client->noClientException;
|
|
}
|
|
|
|
static int
|
|
ProcLgeRegisterScreen (ClientPtr client)
|
|
{
|
|
REQUEST(xLgeRegisterScreenReq);
|
|
ScreenPtr pScreen;
|
|
WindowPtr pWin;
|
|
int scrNum;
|
|
|
|
REQUEST_SIZE_MATCH(xLgeRegisterScreenReq);
|
|
|
|
/* Only the picker client can make this request */
|
|
if (client != lgePickerClient) {
|
|
return BadAccess;
|
|
}
|
|
|
|
pWin = (WindowPtr) LookupIDByType (stuff->prw, RT_WINDOW);
|
|
if (pWin == NULL) {
|
|
return BadMatch;
|
|
}
|
|
scrNum = pWin->drawable.pScreen->myNum;
|
|
lgeDisplayServerPRWsList[scrNum] = stuff->prw;
|
|
pLgeDisplayServerPRWWinsList[scrNum] = pWin;
|
|
pLgeDisplayServerPRWWinRoots[scrNum] = WindowTable[scrNum];
|
|
|
|
if (numRegisteredScr == 0) {
|
|
lgeDisplayServerPRW = stuff->prw;
|
|
pLgeDisplayServerPRWWin = pWin;
|
|
}
|
|
else if (numRegisteredScr >= MAXSCREENS) {
|
|
return BadAlloc;
|
|
}
|
|
|
|
pScreen = pWin->drawable.pScreen;
|
|
numRegisteredScr++;
|
|
|
|
/* Prevent events from being sent to the PRW owner, which is AWT */
|
|
pWin->eventMask = 0;
|
|
|
|
#ifdef PERF
|
|
/* For performance analysis */
|
|
sbPerf = statBufCreate();
|
|
if (sbPerf == NULL) {
|
|
return BadAlloc;
|
|
}
|
|
#endif /* PERF */
|
|
|
|
return client->noClientException;
|
|
}
|
|
|
|
static int
|
|
ProcLgeControlLgMode (ClientPtr client)
|
|
{
|
|
REQUEST (xLgeControlLgModeReq);
|
|
|
|
REQUEST_SIZE_MATCH(xLgeControlLgModeReq);
|
|
|
|
/* Only the picker client can make this request */
|
|
if (client != lgePickerClient) {
|
|
return BadAccess;
|
|
}
|
|
|
|
if (stuff->enable == TRUE) {
|
|
lgeDisplayServerIsAlive = 1;
|
|
lgeDisableIncompatibleExtensions();
|
|
} else {
|
|
lgeReenableIncompatibleExtensions();
|
|
LgeShutdownDisplayServer(NULL, INVALID);
|
|
}
|
|
|
|
return client->noClientException;
|
|
}
|
|
|
|
static int
|
|
ProcLgeSendEvent (ClientPtr client)
|
|
{
|
|
REQUEST (xLgeSendEventReq);
|
|
xEvent *xE = (xEvent *)&stuff->event;
|
|
|
|
REQUEST_SIZE_MATCH(xLgeSendEventReq);
|
|
|
|
/* Only the picker client can make this request */
|
|
if (client != lgePickerClient) {
|
|
return BadAccess;
|
|
}
|
|
|
|
/*
|
|
ErrorF("ProcLgeSendEvent, event type = %d, pickSeq = %d\n",
|
|
xE->u.u.type, xE->u.u.sequenceNumber);
|
|
ErrorF("detail = %d\n", xE->u.u.detail);
|
|
ErrorF("time = %d\n", xE->u.keyButtonPointer.time);
|
|
ErrorF("root = %d\n", xE->u.keyButtonPointer.root);
|
|
ErrorF("event = %d\n", xE->u.keyButtonPointer.event);
|
|
ErrorF("child = %d\n", xE->u.keyButtonPointer.child);
|
|
ErrorF("rootX = %d\n", xE->u.keyButtonPointer.rootX);
|
|
ErrorF("rootY = %d\n", xE->u.keyButtonPointer.rootY);
|
|
ErrorF("eventX = %d\n", xE->u.keyButtonPointer.eventX);
|
|
ErrorF("eventY = %d\n", xE->u.keyButtonPointer.eventY);
|
|
ErrorF("state = %d\n", xE->u.keyButtonPointer.state);
|
|
*/
|
|
|
|
lgeEventComesFromDS = 1;
|
|
if (xE->u.u.type == KeyPress || xE->u.u.type == KeyRelease) {
|
|
|
|
if (lgeSendEventDirect) {
|
|
XkbProcessKeyboardEvent(xE, inputInfo.keyboard, 1);
|
|
} else {
|
|
(*inputInfo.keyboard->public.processInputProc)(xE, inputInfo.keyboard, 1);
|
|
}
|
|
|
|
} else {
|
|
|
|
#ifdef PERF
|
|
/* For performance analysis */
|
|
float usStart, usStop, msDelta;
|
|
gettimeofday(&tvStart, 0);
|
|
#endif /* PERF */
|
|
|
|
if (lgeSendEventDirect) {
|
|
CoreProcessPointerEvent(xE, inputInfo.pointer, 1);
|
|
} else {
|
|
(*inputInfo.pointer->public.processInputProc)(xE, inputInfo.pointer, 1);
|
|
}
|
|
|
|
#ifdef PERF
|
|
/* For performance analysis */
|
|
gettimeofday(&tvStop, 0);
|
|
usStart = 1000000.0f * tvStart.tv_sec + tvStart.tv_usec;
|
|
usStop = 1000000.0f * tvStop.tv_sec + tvStop.tv_usec;
|
|
msDelta = (usStop - usStart) / 1000.0f;
|
|
statBufAdd(sbPerf, msDelta);
|
|
#endif /* PERF */
|
|
}
|
|
lgeEventComesFromDS = 0;
|
|
|
|
return client->noClientException;
|
|
}
|
|
|
|
static int
|
|
SProcLgeQueryVersion (ClientPtr client)
|
|
{
|
|
int n;
|
|
REQUEST(xLgeQueryVersionReq);
|
|
|
|
swaps(&stuff->length, n);
|
|
REQUEST_SIZE_MATCH(xLgeQueryVersionReq);
|
|
|
|
return ProcLgeQueryVersion(client);
|
|
}
|
|
|
|
static int
|
|
SProcLgeRegisterClient (ClientPtr client)
|
|
{
|
|
int n;
|
|
REQUEST(xLgeRegisterClientReq);
|
|
|
|
swaps(&stuff->length, n);
|
|
REQUEST_SIZE_MATCH(xLgeRegisterClientReq);
|
|
return ProcLgeRegisterClient(client);
|
|
}
|
|
|
|
static int
|
|
SProcLgeRegisterScreen (ClientPtr client)
|
|
{
|
|
int n;
|
|
REQUEST(xLgeRegisterScreenReq);
|
|
|
|
swaps(&stuff->length, n);
|
|
REQUEST_SIZE_MATCH(xLgeRegisterScreenReq);
|
|
swapl(&stuff->prw, n);
|
|
return ProcLgeRegisterScreen(client);
|
|
}
|
|
|
|
static int
|
|
SProcLgeControlLgMode (ClientPtr client)
|
|
{
|
|
int n;
|
|
REQUEST(xLgeControlLgModeReq);
|
|
|
|
swaps(&stuff->length, n);
|
|
REQUEST_SIZE_MATCH(xLgeControlLgModeReq);
|
|
return ProcLgeControlLgMode(client);
|
|
}
|
|
|
|
static int
|
|
SProcLgeSendEvent (ClientPtr client)
|
|
{
|
|
int n;
|
|
EventSwapPtr proc;
|
|
xEvent eventT;
|
|
|
|
REQUEST(xLgeSendEventReq);
|
|
swaps (&stuff->length, n);
|
|
REQUEST_AT_LEAST_SIZE (xLgeSendEventReq);
|
|
|
|
/* Swap event */
|
|
proc = EventSwapVector[stuff->event.u.u.type & 0177];
|
|
if (!proc || proc == NotImplemented) /* no swapping proc; invalid event type? */
|
|
return (BadValue);
|
|
(*proc)(&stuff->event, &eventT);
|
|
stuff->event = eventT;
|
|
|
|
return ProcLgeSendEvent (client);
|
|
}
|
|
|
|
int
|
|
ProcLgeDispatch (ClientPtr client)
|
|
{
|
|
REQUEST(xReq);
|
|
|
|
switch (stuff->data) {
|
|
case X_LgeQueryVersion:
|
|
return ProcLgeQueryVersion(client);
|
|
case X_LgeRegisterClient:
|
|
return ProcLgeRegisterClient(client);
|
|
case X_LgeRegisterScreen:
|
|
return ProcLgeRegisterScreen(client);
|
|
case X_LgeControlLgMode:
|
|
return ProcLgeControlLgMode(client);
|
|
case X_LgeSendEvent:
|
|
return ProcLgeSendEvent(client);
|
|
default:
|
|
return BadRequest;
|
|
}
|
|
}
|
|
|
|
int
|
|
SProcLgeDispatch (ClientPtr client)
|
|
{
|
|
REQUEST(xReq);
|
|
|
|
switch (stuff->data) {
|
|
|
|
case X_LgeQueryVersion:
|
|
return SProcLgeQueryVersion(client);
|
|
|
|
case X_LgeRegisterClient:
|
|
return SProcLgeRegisterClient(client);
|
|
|
|
case X_LgeRegisterScreen:
|
|
return SProcLgeRegisterScreen(client);
|
|
|
|
case X_LgeControlLgMode:
|
|
return SProcLgeControlLgMode(client);
|
|
|
|
case X_LgeSendEvent:
|
|
return SProcLgeSendEvent(client);
|
|
|
|
default:
|
|
return BadRequest;
|
|
}
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
int
|
|
LgeShutdownDisplayServer (pointer data, XID id)
|
|
{
|
|
int i;
|
|
|
|
if (!lgeDisplayServerIsAlive) {
|
|
return 1;
|
|
}
|
|
|
|
/*ErrorF("LG Display Server has shut down\n");*/
|
|
|
|
lgeDisplayServerIsAlive = 0;
|
|
lgeEventComesFromDS = 0;
|
|
lgekb = NULL;
|
|
lgems = NULL;
|
|
|
|
lgePickerClient = NULL;
|
|
lgeEventDelivererClient = NULL;
|
|
|
|
lgeDisplayServerPRW = INVALID;
|
|
pLgeDisplayServerPRWWin = NULL;
|
|
|
|
for (i = 0; i < MAXSCREENS; i++) {
|
|
lgeDisplayServerPRWsList[i] = INVALID;
|
|
pLgeDisplayServerPRWWinsList[i] = NULL;
|
|
pLgeDisplayServerPRWWinRoots[i] = NULL;
|
|
}
|
|
numRegisteredScr = 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static void
|
|
LgeReset (ExtensionEntry *extEntry)
|
|
{
|
|
(void) LgeShutdownDisplayServer(NULL, INVALID);
|
|
}
|
|
|
|
void
|
|
LgeExtensionInit (void)
|
|
{
|
|
ExtensionEntry *extEntry;
|
|
int i;
|
|
|
|
lgeClientResourceType = CreateNewResourceType(LgeShutdownDisplayServer);
|
|
if (lgeClientResourceType == 0) {
|
|
FatalError("LgeExtensionInit: Cannot create display server resource type\n");
|
|
exit(1);
|
|
}
|
|
|
|
extEntry = AddExtension(LGE_NAME, 0, 0, ProcLgeDispatch,
|
|
SProcLgeDispatch, LgeReset, StandardMinorOpcode);
|
|
if (extEntry == NULL) {
|
|
FatalError("LgeExtensionInit: AddExtension(%s) failed\n", LGE_NAME);
|
|
exit(1);
|
|
}
|
|
|
|
LgeReqCode = extEntry->base;
|
|
|
|
for (i = 0; i < MAXSCREENS; i++) {
|
|
lgeDisplayServerPRWsList[i] = INVALID;
|
|
pLgeDisplayServerPRWWinsList[i] = NULL;
|
|
pLgeDisplayServerPRWWinRoots[i] = NULL;
|
|
}
|
|
}
|
|
|
|
int
|
|
IsWinLgePRWOne(int win)
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i < numRegisteredScr; i++)
|
|
{
|
|
if(lgeDisplayServerPRWsList[i] == win)
|
|
return win;
|
|
}
|
|
return INVALID;
|
|
}
|
|
|
|
WindowPtr
|
|
GetLgePRWWinFor(int win)
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i < numRegisteredScr; i++)
|
|
{
|
|
if(lgeDisplayServerPRWsList[i] == win)
|
|
return pLgeDisplayServerPRWWinsList[i];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
** Returns True if the given extension is compatible with LG mode.
|
|
** Returns false if the given extension is incompatible.
|
|
** Specifically, XVideo is incompatible because it not redirectable
|
|
** by the composite extension. And XINPUT is incompatible because it
|
|
** is not yet supported by the LG-modified Xorg event subsystem.
|
|
**
|
|
** TODO: GLX and NV-GLX are not compatible with LG either. But
|
|
** disabling these extensions has no effect; OpenGL apps run anyway
|
|
** event without these extensions defined. I have not yet found
|
|
** a way to gracefully keep OpenGL programs from running while
|
|
** LG mode is abled.
|
|
*/
|
|
|
|
Bool
|
|
lgeCompatibleExtension (ExtensionEntry *pExt)
|
|
{
|
|
if (strcmp(pExt->name, "XVideo") == 0) {
|
|
return FALSE;
|
|
}
|
|
if (strcmp(pExt->name, "XVideo-MotionCompensation") == 0) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (strcmp(pExt->name, "XInputExtension") == 0) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
** Shuts the given extension off by replacing its MainProc and SwappedMainProc
|
|
** with a routine which prints out an error message and returns BadAccess,
|
|
** or enables the given extension by replacing its original MainProc and
|
|
** SwappedMainProc routines.
|
|
*/
|
|
|
|
#define WARNING_MESSAGE "WARNING: client attempt to access the %s extension, which has been disabled because it is incompatible with LG3D"
|
|
|
|
static int (*XVideoSavedMainProc)(ClientPtr);
|
|
static int (*XVideoSavedSwappedMainProc)(ClientPtr);
|
|
static int (*XVideoMCSavedMainProc)(ClientPtr);
|
|
static int (*XVideoMCSavedSwappedMainProc)(ClientPtr);
|
|
static int (*XINPUTSavedMainProc)(ClientPtr);
|
|
static int (*XINPUTSavedSwappedMainProc)(ClientPtr);
|
|
|
|
static int
|
|
lgeXVideoError (ClientPtr client)
|
|
{
|
|
ErrorF(WARNING_MESSAGE, "XVideo");
|
|
return BadAccess;
|
|
}
|
|
|
|
static int
|
|
lgeXVideoMCError (ClientPtr client)
|
|
{
|
|
ErrorF(WARNING_MESSAGE, "XVideo-MotionCompensation");
|
|
return BadAccess;
|
|
}
|
|
|
|
static int
|
|
lgeXINPUTError (ClientPtr client)
|
|
{
|
|
ErrorF(WARNING_MESSAGE, "XInputExtension");
|
|
return BadAccess;
|
|
}
|
|
|
|
static void
|
|
lgeControlIncompatibleExtension (ExtensionEntry *pExt, Bool enable)
|
|
{
|
|
int idx = pExt->index;
|
|
|
|
if (strcmp(pExt->name, "XVideo") == 0) {
|
|
if (enable) {
|
|
ProcVector[idx + EXTENSION_BASE] = XVideoSavedMainProc;
|
|
SwappedProcVector[idx + EXTENSION_BASE] = XVideoSavedSwappedMainProc;
|
|
} else {
|
|
XVideoSavedMainProc = ProcVector[idx + EXTENSION_BASE];
|
|
ProcVector[idx + EXTENSION_BASE] = lgeXVideoError;
|
|
XVideoSavedSwappedMainProc = SwappedProcVector[idx + EXTENSION_BASE];
|
|
SwappedProcVector[idx + EXTENSION_BASE] = lgeXVideoError;
|
|
}
|
|
}
|
|
if (strcmp(pExt->name, "XVideo-MotionCompensation") == 0) {
|
|
if (enable) {
|
|
ProcVector[idx + EXTENSION_BASE] = XVideoMCSavedMainProc;
|
|
SwappedProcVector[idx + EXTENSION_BASE] = XVideoMCSavedSwappedMainProc;
|
|
} else {
|
|
XVideoMCSavedMainProc = ProcVector[idx + EXTENSION_BASE];
|
|
ProcVector[idx + EXTENSION_BASE] = lgeXVideoMCError;
|
|
XVideoMCSavedSwappedMainProc = SwappedProcVector[idx + EXTENSION_BASE];
|
|
SwappedProcVector[idx + EXTENSION_BASE] = lgeXVideoMCError;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* In order to fix LG bug 665 we must not disable XINPUT here, because
|
|
* realplay requires it. But we will still not advertise the extension
|
|
* in the list of supported extensions.
|
|
*
|
|
* This seems to be a linux-only issue. So right now were only
|
|
* reenabling it on linux.
|
|
|
|
if (strcmp(pExt->name, "XInputExtension") == 0) {
|
|
if (enable) {
|
|
ProcVector[idx + EXTENSION_BASE] = XINPUTSavedMainProc;
|
|
SwappedProcVector[idx + EXTENSION_BASE] = XINPUTSavedSwappedMainProc;
|
|
} else {
|
|
XINPUTSavedMainProc = ProcVector[idx + EXTENSION_BASE];
|
|
ProcVector[idx + EXTENSION_BASE] = lgeXINPUTError;
|
|
XINPUTSavedSwappedMainProc = SwappedProcVector[idx + EXTENSION_BASE];
|
|
SwappedProcVector[idx + EXTENSION_BASE] = lgeXINPUTError;
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
static void
|
|
lgeDisableIncompatibleExtensions ()
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < NumExtensions; i++) {
|
|
if (!lgeCompatibleExtension(extensions[i])) {
|
|
lgeControlIncompatibleExtension(extensions[i], FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
lgeReenableIncompatibleExtensions ()
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < NumExtensions; i++) {
|
|
if (!lgeCompatibleExtension(extensions[i])) {
|
|
lgeControlIncompatibleExtension(extensions[i], TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif /* LG3D */
|
|
|
|
|