Alloc sprite memory in devices' devPrivates, allow undisplaying cursors.

Improve memory usage by allocating the sprite's memory only to devices that
actually have a sprite and provide means to remove a device's cursor from the
screen (more hotplugging, yay!).
This commit breaks ScreenRec's ABI.
This commit is contained in:
Peter Hutterer 2007-04-09 19:31:59 +09:30
parent 7cef789fa1
commit f1f8b562aa
12 changed files with 444 additions and 293 deletions

View File

@ -225,18 +225,29 @@ DisableDevice(DeviceIntPtr dev)
return TRUE; return TRUE;
} }
/**
* Initialize device through driver, allocate memory for cursor sprite (if
* applicable) and send a PresenceNotify event to all clients.
*
* Must be called before EnableDevice.
*/
int int
ActivateDevice(DeviceIntPtr dev) ActivateDevice(DeviceIntPtr dev)
{ {
int ret = Success; int ret = Success;
devicePresenceNotify ev; devicePresenceNotify ev;
DeviceIntRec dummyDev; DeviceIntRec dummyDev;
ScreenPtr pScreen = screenInfo.screens[0];
if (!dev || !dev->deviceProc) if (!dev || !dev->deviceProc)
return BadImplementation; return BadImplementation;
ret = (*dev->deviceProc) (dev, DEVICE_INIT); ret = (*dev->deviceProc) (dev, DEVICE_INIT);
dev->inited = (ret == Success); dev->inited = (ret == Success);
/* Initialize memory for sprites. */
if (IsPointerDevice(dev))
pScreen->DeviceCursorInitialize(dev, pScreen);
ev.type = DevicePresenceNotify; ev.type = DevicePresenceNotify;
ev.time = currentTime.milliseconds; ev.time = currentTime.milliseconds;
@ -497,11 +508,16 @@ CloseDevice(DeviceIntPtr dev)
StringFeedbackPtr s, snext; StringFeedbackPtr s, snext;
BellFeedbackPtr b, bnext; BellFeedbackPtr b, bnext;
LedFeedbackPtr l, lnext; LedFeedbackPtr l, lnext;
ScreenPtr screen = screenInfo.screens[0];
int j; int j;
if (dev->inited) if (dev->inited)
(void)(*dev->deviceProc)(dev, DEVICE_CLOSE); (void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
/* free sprite memory */
if (IsPointerDevice(dev))
screen->DeviceCursorCleanup(dev, screen);
xfree(dev->name); xfree(dev->name);
if (dev->key) { if (dev->key) {
@ -624,6 +640,22 @@ CloseDownDevices()
inputInfo.pointer = NULL; inputInfo.pointer = NULL;
} }
/**
* Remove the cursor sprite for all devices. This needs to be done before any
* resources are freed or any device is deleted.
*/
void
UndisplayDevices()
{
DeviceIntPtr dev;
ScreenPtr screen = screenInfo.screens[0];
for (dev = inputInfo.devices; dev; dev = dev->next)
{
screen->UndisplayCursor(dev, screen);
}
}
int int
RemoveDevice(DeviceIntPtr dev) RemoveDevice(DeviceIntPtr dev)
{ {
@ -631,23 +663,26 @@ RemoveDevice(DeviceIntPtr dev)
int ret = BadMatch; int ret = BadMatch;
devicePresenceNotify ev; devicePresenceNotify ev;
DeviceIntRec dummyDev; DeviceIntRec dummyDev;
ScreenPtr screen = screenInfo.screens[0];
DebugF("(dix) removing device %d\n", dev->id); DebugF("(dix) removing device %d\n", dev->id);
if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer) if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
return BadImplementation; return BadImplementation;
screen->UndisplayCursor(dev, screen);
prev = NULL; prev = NULL;
for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) { for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
next = tmp->next; next = tmp->next;
if (tmp == dev) { if (tmp == dev) {
CloseDevice(tmp);
if (prev==NULL) if (prev==NULL)
inputInfo.devices = next; inputInfo.devices = next;
else else
prev->next = next; prev->next = next;
CloseDevice(tmp);
ret = Success; ret = Success;
} }
} }

View File

@ -466,6 +466,8 @@ main(int argc, char *argv[], char *envp[])
Dispatch(); Dispatch();
UndisplayDevices();
/* Now free up whatever must be freed */ /* Now free up whatever must be freed */
if (screenIsSaved == SCREEN_SAVER_ON) if (screenIsSaved == SCREEN_SAVER_ON)
SaveScreens(SCREEN_SAVER_OFF, ScreenSaverReset); SaveScreens(SCREEN_SAVER_OFF, ScreenSaverReset);

View File

@ -247,9 +247,13 @@ ProcessInputEvents ()
mieqProcessInputEvents(); mieqProcessInputEvents();
/* FIXME: This is a problem if we have multiple pointers */ /* PIE can be called after devices have been shut down. Blame DGA. */
miPointerGetPosition(inputInfo.pointer, &x, &y); if (inputInfo.pointer)
xf86SetViewport(xf86Info.currentScreen, x, y); {
/* FIXME: This is a problem if we have multiple pointers */
miPointerGetPosition(inputInfo.pointer, &x, &y);
xf86SetViewport(xf86Info.currentScreen, x, y);
}
} }
void void

View File

@ -424,6 +424,10 @@ extern int DeliverDeviceEvents(
extern void DefineInitialRootWindow( extern void DefineInitialRootWindow(
WindowPtr /* win */); WindowPtr /* win */);
extern void SetupSprite(
DeviceIntPtr /* pDev */,
ScreenPtr /* pScreen */);
extern void InitializeSprite( extern void InitializeSprite(
DeviceIntPtr /* pDev */, DeviceIntPtr /* pDev */,
WindowPtr /* pWin */); WindowPtr /* pWin */);

View File

@ -190,6 +190,8 @@ extern int InitAndStartDevices(void);
extern void CloseDownDevices(void); extern void CloseDownDevices(void);
extern void UndisplayDevices(void);
extern int RemoveDevice( extern int RemoveDevice(
DeviceIntPtr /*dev*/); DeviceIntPtr /*dev*/);

View File

@ -431,6 +431,18 @@ typedef void (* MarkUnrealizedWindowProcPtr)(
WindowPtr /*pWin*/, WindowPtr /*pWin*/,
Bool /*fromConfigure*/); Bool /*fromConfigure*/);
typedef void (* UndisplayCursorProcPtr)(
DeviceIntPtr /* pDev */,
ScreenPtr /* pScreen */);
typedef Bool (* DeviceCursorInitializeProcPtr)(
DeviceIntPtr /* pDev */,
ScreenPtr /* pScreen */);
typedef void (* DeviceCursorCleanupProcPtr)(
DeviceIntPtr /* pDev */,
ScreenPtr /* pScreen */);
typedef struct _Screen { typedef struct _Screen {
int myNum; /* index of this instance in Screens[] */ int myNum; /* index of this instance in Screens[] */
ATOM id; ATOM id;
@ -587,6 +599,10 @@ typedef struct _Screen {
ChangeBorderWidthProcPtr ChangeBorderWidth; ChangeBorderWidthProcPtr ChangeBorderWidth;
MarkUnrealizedWindowProcPtr MarkUnrealizedWindow; MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
/* Device cursor procedures */
UndisplayCursorProcPtr UndisplayCursor;
DeviceCursorInitializeProcPtr DeviceCursorInitialize;
DeviceCursorCleanupProcPtr DeviceCursorCleanup;
} ScreenRec; } ScreenRec;
typedef struct _ScreenInfo { typedef struct _ScreenInfo {

View File

@ -67,6 +67,9 @@ static unsigned long miDCGeneration = 0;
static Bool miDCCloseScreen(int index, ScreenPtr pScreen); static Bool miDCCloseScreen(int index, ScreenPtr pScreen);
/* per device private data */
static int miDCSpriteIndex;
typedef struct { typedef struct {
GCPtr pSourceGC, pMaskGC; GCPtr pSourceGC, pMaskGC;
GCPtr pSaveGC, pRestoreGC; GCPtr pSaveGC, pRestoreGC;
@ -79,13 +82,16 @@ typedef struct {
#endif #endif
} miDCBufferRec, *miDCBufferPtr; } miDCBufferRec, *miDCBufferPtr;
#define MIDCBUFFER(dev) \
((DevHasCursor(dev)) ? \
(miDCBufferPtr)dev->devPrivates[miDCSpriteIndex].ptr :\
(miDCBufferPtr)inputInfo.pointer->devPrivates[miDCSpriteIndex].ptr)
/* /*
* The core pointer buffer will point to the index of the virtual core pointer * The core pointer buffer will point to the index of the virtual core pointer
* in the pCursorBuffers array. * in the pCursorBuffers array.
*/ */
typedef struct { typedef struct {
miDCBufferPtr pCoreBuffer; /* for core pointer */
miDCBufferPtr pCursorBuffers; /* one for each device */
CloseScreenProcPtr CloseScreen; CloseScreenProcPtr CloseScreen;
} miDCScreenRec, *miDCScreenPtr; } miDCScreenRec, *miDCScreenPtr;
@ -121,6 +127,9 @@ static Bool miDCChangeSave(DeviceIntPtr pDev, ScreenPtr pScreen,
int x, int y, int w, int h, int x, int y, int w, int h,
int dx, int dy); int dx, int dy);
static Bool miDCDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen);
static void miDCDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen);
static miSpriteCursorFuncRec miDCFuncs = { static miSpriteCursorFuncRec miDCFuncs = {
miDCRealizeCursor, miDCRealizeCursor,
miDCUnrealizeCursor, miDCUnrealizeCursor,
@ -129,6 +138,8 @@ static miSpriteCursorFuncRec miDCFuncs = {
miDCRestoreUnderCursor, miDCRestoreUnderCursor,
miDCMoveCursor, miDCMoveCursor,
miDCChangeSave, miDCChangeSave,
miDCDeviceInitialize,
miDCDeviceCleanup
}; };
_X_EXPORT Bool _X_EXPORT Bool
@ -137,8 +148,6 @@ miDCInitialize (pScreen, screenFuncs)
miPointerScreenFuncPtr screenFuncs; miPointerScreenFuncPtr screenFuncs;
{ {
miDCScreenPtr pScreenPriv; miDCScreenPtr pScreenPriv;
miDCBufferPtr pBuffer;
int mpBufferIdx;
if (miDCGeneration != serverGeneration) if (miDCGeneration != serverGeneration)
{ {
@ -151,41 +160,8 @@ miDCInitialize (pScreen, screenFuncs)
if (!pScreenPriv) if (!pScreenPriv)
return FALSE; return FALSE;
/*
* initialize the entire private structure to zeros
*/
pScreenPriv->pCursorBuffers = (miDCBufferPtr)xalloc(MAX_DEVICES *
sizeof(miDCBufferRec));
if (!pScreenPriv->pCursorBuffers)
{
xfree((pointer)pScreenPriv);
return FALSE;
}
/* virtual core pointer ID is 1 */
pScreenPriv->pCoreBuffer = &pScreenPriv->pCursorBuffers[1];
mpBufferIdx = 0;
while(mpBufferIdx < MAX_DEVICES)
{
pBuffer = &pScreenPriv->pCursorBuffers[mpBufferIdx];
pBuffer->pSourceGC =
pBuffer->pMaskGC =
pBuffer->pSaveGC =
pBuffer->pRestoreGC =
pBuffer->pMoveGC =
pBuffer->pPixSourceGC =
pBuffer->pPixMaskGC = NULL;
#ifdef ARGB_CURSOR
pBuffer->pRootPicture = NULL;
pBuffer->pTempPicture = NULL;
#endif
pBuffer->pSave = pBuffer->pTemp = NULL;
mpBufferIdx++;
}
miDCSpriteIndex = AllocateDevicePrivateIndex();
pScreenPriv->CloseScreen = pScreen->CloseScreen; pScreenPriv->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = miDCCloseScreen; pScreen->CloseScreen = miDCCloseScreen;
@ -194,7 +170,6 @@ miDCInitialize (pScreen, screenFuncs)
if (!miSpriteInitialize (pScreen, &miDCFuncs, screenFuncs)) if (!miSpriteInitialize (pScreen, &miDCFuncs, screenFuncs))
{ {
xfree ((pointer) pScreenPriv->pCursorBuffers);
xfree ((pointer) pScreenPriv); xfree ((pointer) pScreenPriv);
return FALSE; return FALSE;
} }
@ -211,38 +186,10 @@ miDCCloseScreen (index, pScreen)
ScreenPtr pScreen; ScreenPtr pScreen;
{ {
miDCScreenPtr pScreenPriv; miDCScreenPtr pScreenPriv;
miDCBufferPtr pBuffer;
int mpBufferIdx;
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
pScreen->CloseScreen = pScreenPriv->CloseScreen; pScreen->CloseScreen = pScreenPriv->CloseScreen;
mpBufferIdx = 0;
while (mpBufferIdx < MAX_DEVICES)
{
pBuffer = &pScreenPriv->pCursorBuffers[mpBufferIdx];
tossGC (pBuffer->pSourceGC);
tossGC (pBuffer->pMaskGC);
tossGC (pBuffer->pSaveGC);
tossGC (pBuffer->pRestoreGC);
tossGC (pBuffer->pMoveGC);
tossGC (pBuffer->pPixSourceGC);
tossGC (pBuffer->pPixMaskGC);
tossPix (pBuffer->pSave);
tossPix (pBuffer->pTemp);
#ifdef ARGB_CURSOR
#if 0 /* This has been free()d before */
tossPict (pScreenPriv->pRootPicture);
#endif
tossPict (pBuffer->pTempPicture);
#endif
mpBufferIdx++;
}
xfree((pointer) pScreenPriv->pCursorBuffers);
xfree ((pointer) pScreenPriv); xfree ((pointer) pScreenPriv);
return (*pScreen->CloseScreen) (index, pScreen); return (*pScreen->CloseScreen) (index, pScreen);
} }
@ -536,10 +483,7 @@ miDCPutUpCursor (pDev, pScreen, pCursor, x, y, source, mask)
} }
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
pWin = WindowTable[pScreen->myNum]; pWin = WindowTable[pScreen->myNum];
pBuffer = pScreenPriv->pCoreBuffer; pBuffer = MIDCBUFFER(pDev);
if (DevHasCursor(pDev))
pBuffer = &pScreenPriv->pCursorBuffers[pDev->id];
#ifdef ARGB_CURSOR #ifdef ARGB_CURSOR
if (pPriv->pPicture) if (pPriv->pPicture)
@ -587,10 +531,7 @@ miDCSaveUnderCursor (pDev, pScreen, x, y, w, h)
GCPtr pGC; GCPtr pGC;
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
pBuffer = pScreenPriv->pCoreBuffer; pBuffer = MIDCBUFFER(pDev);
if (DevHasCursor(pDev))
pBuffer = &pScreenPriv->pCursorBuffers[pDev->id];
pSave = pBuffer->pSave; pSave = pBuffer->pSave;
pWin = WindowTable[pScreen->myNum]; pWin = WindowTable[pScreen->myNum];
@ -626,10 +567,7 @@ miDCRestoreUnderCursor (pDev, pScreen, x, y, w, h)
GCPtr pGC; GCPtr pGC;
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
pBuffer = pScreenPriv->pCoreBuffer; pBuffer = MIDCBUFFER(pDev);
if (DevHasCursor(pDev))
pBuffer = &pScreenPriv->pCursorBuffers[pDev->id];
pSave = pBuffer->pSave; pSave = pBuffer->pSave;
pWin = WindowTable[pScreen->myNum]; pWin = WindowTable[pScreen->myNum];
@ -659,10 +597,7 @@ miDCChangeSave (pDev, pScreen, x, y, w, h, dx, dy)
int sourcex, sourcey, destx, desty, copyw, copyh; int sourcex, sourcey, destx, desty, copyw, copyh;
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
pBuffer = pScreenPriv->pCoreBuffer; pBuffer = MIDCBUFFER(pDev);
if (DevHasCursor(pDev))
pBuffer = &pScreenPriv->pCursorBuffers[pDev->id];
pSave = pBuffer->pSave; pSave = pBuffer->pSave;
pWin = WindowTable[pScreen->myNum]; pWin = WindowTable[pScreen->myNum];
@ -810,10 +745,7 @@ miDCMoveCursor (pDev, pScreen, pCursor, x, y, w, h, dx, dy, source, mask)
} }
pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr; pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
pWin = WindowTable[pScreen->myNum]; pWin = WindowTable[pScreen->myNum];
pBuffer = pScreenPriv->pCoreBuffer; pBuffer = MIDCBUFFER(pDev);
if (DevHasCursor(pDev))
pBuffer = &pScreenPriv->pCursorBuffers[pDev->id];
pTemp = pBuffer->pTemp; pTemp = pBuffer->pTemp;
if (!pTemp || if (!pTemp ||
@ -905,3 +837,62 @@ miDCMoveCursor (pDev, pScreen, pCursor, x, y, w, h, dx, dy, source, mask)
0, 0, w, h, x, y); 0, 0, w, h, x, y);
return TRUE; return TRUE;
} }
static Bool
miDCDeviceInitialize(pDev, pScreen)
DeviceIntPtr pDev;
ScreenPtr pScreen;
{
miDCBufferPtr pBuffer;
if (!AllocateDevicePrivate(pDev, miDCSpriteIndex))
return FALSE;
pBuffer =
pDev->devPrivates[miDCSpriteIndex].ptr = xalloc(sizeof(miDCBufferRec));
pBuffer->pSourceGC =
pBuffer->pMaskGC =
pBuffer->pSaveGC =
pBuffer->pRestoreGC =
pBuffer->pMoveGC =
pBuffer->pPixSourceGC =
pBuffer->pPixMaskGC = NULL;
#ifdef ARGB_CURSOR
pBuffer->pRootPicture = NULL;
pBuffer->pTempPicture = NULL;
#endif
pBuffer->pSave = pBuffer->pTemp = NULL;
return TRUE;
}
static void
miDCDeviceCleanup(pDev, pScreen)
DeviceIntPtr pDev;
ScreenPtr pScreen;
{
miDCBufferPtr pBuffer;
if (DevHasCursor(pDev))
{
pBuffer = MIDCBUFFER(pDev);
tossGC (pBuffer->pSourceGC);
tossGC (pBuffer->pMaskGC);
tossGC (pBuffer->pSaveGC);
tossGC (pBuffer->pRestoreGC);
tossGC (pBuffer->pMoveGC);
tossGC (pBuffer->pPixSourceGC);
tossGC (pBuffer->pPixMaskGC);
tossPix (pBuffer->pSave);
tossPix (pBuffer->pTemp);
#ifdef ARGB_CURSOR
#if 0 /* This has been free()d before */
tossPict (pScreenPriv->pRootPicture);
#endif
tossPict (pBuffer->pTempPicture);
#endif
xfree(pDev->devPrivates[miDCSpriteIndex].ptr);
pDev->devPrivates[miDCSpriteIndex].ptr = NULL;
}
}

View File

@ -54,18 +54,12 @@ static unsigned long miPointerGeneration = 0;
#define GetScreenPrivate(s) ((miPointerScreenPtr) ((s)->devPrivates[miPointerScreenIndex].ptr)) #define GetScreenPrivate(s) ((miPointerScreenPtr) ((s)->devPrivates[miPointerScreenIndex].ptr))
#define SetupScreen(s) miPointerScreenPtr pScreenPriv = GetScreenPrivate(s) #define SetupScreen(s) miPointerScreenPtr pScreenPriv = GetScreenPrivate(s)
/* static int miPointerPrivatesIndex = 0;
* until more than one pointer device exists.
*/
static miPointerPtr miCorePointer;
/* Multipointers
* ID of a device == index in this array.
*/
static miPointerRec miPointers[MAX_DEVICES];
#define MIPOINTER(dev) \ #define MIPOINTER(dev) \
(DevHasCursor((dev))) ? &miPointers[(dev)->id] : miCorePointer ((DevHasCursor((dev))) ? \
(miPointerPtr) dev->devPrivates[miPointerPrivatesIndex].ptr : \
(miPointerPtr) inputInfo.pointer->devPrivates[miPointerPrivatesIndex].ptr)
static Bool miPointerRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, static Bool miPointerRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
CursorPtr pCursor); CursorPtr pCursor);
@ -73,6 +67,7 @@ static Bool miPointerUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
CursorPtr pCursor); CursorPtr pCursor);
static Bool miPointerDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, static Bool miPointerDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
CursorPtr pCursor); CursorPtr pCursor);
static void miPointerUndisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen);
static void miPointerConstrainCursor(DeviceIntPtr pDev, ScreenPtr pScreen, static void miPointerConstrainCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
BoxPtr pBox); BoxPtr pBox);
static void miPointerPointerNonInterestBox(DeviceIntPtr pDev, static void miPointerPointerNonInterestBox(DeviceIntPtr pDev,
@ -87,6 +82,9 @@ static Bool miPointerCloseScreen(int index, ScreenPtr pScreen);
static void miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, static void miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen,
int x, int y, int x, int y,
unsigned long time); unsigned long time);
static Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen);
static void miPointerDeviceCleanup(DeviceIntPtr pDev,
ScreenPtr pScreen);
static xEvent* events; /* for WarpPointer MotionNotifies */ static xEvent* events; /* for WarpPointer MotionNotifies */
@ -98,8 +96,6 @@ miPointerInitialize (pScreen, spriteFuncs, screenFuncs, waitForUpdate)
Bool waitForUpdate; Bool waitForUpdate;
{ {
miPointerScreenPtr pScreenPriv; miPointerScreenPtr pScreenPriv;
miPointerPtr pPointer;
int ptrIdx;
if (miPointerGeneration != serverGeneration) if (miPointerGeneration != serverGeneration)
{ {
@ -131,33 +127,17 @@ miPointerInitialize (pScreen, spriteFuncs, screenFuncs, waitForUpdate)
pScreen->ConstrainCursor = miPointerConstrainCursor; pScreen->ConstrainCursor = miPointerConstrainCursor;
pScreen->CursorLimits = miPointerCursorLimits; pScreen->CursorLimits = miPointerCursorLimits;
pScreen->DisplayCursor = miPointerDisplayCursor; pScreen->DisplayCursor = miPointerDisplayCursor;
pScreen->UndisplayCursor = miPointerUndisplayCursor;
pScreen->UndisplayCursor = miPointerUndisplayCursor;
pScreen->RealizeCursor = miPointerRealizeCursor; pScreen->RealizeCursor = miPointerRealizeCursor;
pScreen->UnrealizeCursor = miPointerUnrealizeCursor; pScreen->UnrealizeCursor = miPointerUnrealizeCursor;
pScreen->SetCursorPosition = miPointerSetCursorPosition; pScreen->SetCursorPosition = miPointerSetCursorPosition;
pScreen->RecolorCursor = miRecolorCursor; pScreen->RecolorCursor = miRecolorCursor;
pScreen->PointerNonInterestBox = miPointerPointerNonInterestBox; pScreen->PointerNonInterestBox = miPointerPointerNonInterestBox;
pScreen->DeviceCursorInitialize = miPointerDeviceInitialize;
pScreen->DeviceCursorCleanup = miPointerDeviceCleanup;
/* miPointerPrivatesIndex = AllocateDevicePrivateIndex();
* set up the pointer object
* virtual core pointer ID is always 1, so we let it point to the matching
* index in the array.
*/
miCorePointer = &miPointers[1];
for(ptrIdx = 0; ptrIdx < MAX_DEVICES; ptrIdx++)
{
pPointer = &miPointers[ptrIdx];
pPointer->pScreen = NULL;
pPointer->pSpriteScreen = NULL;
pPointer->pCursor = NULL;
pPointer->pSpriteCursor = NULL;
pPointer->limits.x1 = 0;
pPointer->limits.x2 = 32767;
pPointer->limits.y1 = 0;
pPointer->limits.y2 = 32767;
pPointer->confined = FALSE;
pPointer->x = 0;
pPointer->y = 0;
}
events = NULL; events = NULL;
return TRUE; return TRUE;
@ -169,20 +149,30 @@ miPointerCloseScreen (index, pScreen)
ScreenPtr pScreen; ScreenPtr pScreen;
{ {
miPointerPtr pPointer; miPointerPtr pPointer;
int ptrIdx; DeviceIntPtr pDev;
SetupScreen(pScreen); SetupScreen(pScreen);
for(ptrIdx = 0; ptrIdx < MAX_DEVICES; ptrIdx++) #if 0
for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
{ {
pPointer = &miPointers[ptrIdx]; if (DevHasCursor(pDev))
{
pPointer = MIPOINTER(pDev);
if (pScreen == pPointer->pScreen) if (pScreen == pPointer->pScreen)
pPointer->pScreen = 0; pPointer->pScreen = 0;
if (pScreen == pPointer->pSpriteScreen) if (pScreen == pPointer->pSpriteScreen)
pPointer->pSpriteScreen = 0; pPointer->pSpriteScreen = 0;
}
} }
if (MIPOINTER(inputInfo.pointer)->pScreen == pScreen)
MIPOINTER(inputInfo.pointer)->pScreen = 0;
if (MIPOINTER(inputInfo.pointer)->pSpriteScreen == pScreen)
MIPOINTER(inputInfo.pointer)->pSpriteScreen = 0;
#endif
pScreen->CloseScreen = pScreenPriv->CloseScreen; pScreen->CloseScreen = pScreenPriv->CloseScreen;
xfree ((pointer) pScreenPriv); xfree ((pointer) pScreenPriv);
xfree ((pointer) events); xfree ((pointer) events);
@ -228,6 +218,15 @@ miPointerDisplayCursor (pDev, pScreen, pCursor)
return TRUE; return TRUE;
} }
static void
miPointerUndisplayCursor(pDev, pScreen)
DeviceIntPtr pDev;
ScreenPtr pScreen;
{
SetupScreen(pScreen);
(*pScreenPriv->spriteFuncs->UndisplayCursor)(pDev, pScreen);
}
static void static void
miPointerConstrainCursor (pDev, pScreen, pBox) miPointerConstrainCursor (pDev, pScreen, pBox)
DeviceIntPtr pDev; DeviceIntPtr pDev;
@ -281,6 +280,65 @@ miPointerSetCursorPosition(pDev, pScreen, x, y, generateEvent)
return TRUE; return TRUE;
} }
/* Set up sprite information for the device.
This function will be called once for each device after it is initialized
in the DIX.
*/
static Bool
miPointerDeviceInitialize(pDev, pScreen)
DeviceIntPtr pDev;
ScreenPtr pScreen;
{
miPointerPtr pPointer;
SetupScreen (pScreen);
if (!AllocateDevicePrivate(pDev, miPointerPrivatesIndex))
return FALSE;
pPointer = xalloc(sizeof(miPointerRec));
if (!pPointer)
return FALSE;
pPointer->pScreen = NULL;
pPointer->pSpriteScreen = NULL;
pPointer->pCursor = NULL;
pPointer->pSpriteCursor = NULL;
pPointer->limits.x1 = 0;
pPointer->limits.x2 = 32767;
pPointer->limits.y1 = 0;
pPointer->limits.y2 = 32767;
pPointer->confined = FALSE;
pPointer->x = 0;
pPointer->y = 0;
if (!((*pScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen)))
{
xfree(pPointer);
return FALSE;
}
pDev->devPrivates[miPointerPrivatesIndex].ptr = pPointer;
return TRUE;
}
/* Clean up after device.
This function will be called once before the device is freed in the DIX
*/
static void
miPointerDeviceCleanup(pDev, pScreen)
DeviceIntPtr pDev;
ScreenPtr pScreen;
{
if (DevHasCursor(pDev))
{
SetupScreen(pScreen);
(*pScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
xfree(pDev->devPrivates[miPointerPrivatesIndex].ptr);
pDev->devPrivates[miPointerPrivatesIndex].ptr = NULL;
}
}
/* Once signals are ignored, the WarpCursor function can call this */ /* Once signals are ignored, the WarpCursor function can call this */
_X_EXPORT void _X_EXPORT void
@ -413,7 +471,8 @@ miPointerUpdateSprite (DeviceIntPtr pDev)
void void
miPointerDeltaCursor (int dx, int dy, unsigned long time) miPointerDeltaCursor (int dx, int dy, unsigned long time)
{ {
int x = miCorePointer->x + dx, y = miCorePointer->y + dy; int x = MIPOINTER(inputInfo.pointer)->x = dx;
int y = MIPOINTER(inputInfo.pointer)->y = dy;
miPointerSetPosition(inputInfo.pointer, &x, &y, time); miPointerSetPosition(inputInfo.pointer, &x, &y, time);
} }

View File

@ -53,6 +53,18 @@ typedef struct _miPointerSpriteFuncRec {
int /* x */, int /* x */,
int /* y */ int /* y */
); );
Bool (*DeviceCursorInitialize)(
DeviceIntPtr /* pDev */,
ScreenPtr /* pScr */
);
void (*DeviceCursorCleanup)(
DeviceIntPtr /* pDev */,
ScreenPtr /* pScr */
);
void (*UndisplayCursor)(
DeviceIntPtr /* pDev */,
ScreenPtr /* pScr */
);
} miPointerSpriteFuncRec, *miPointerSpriteFuncPtr; } miPointerSpriteFuncRec, *miPointerSpriteFuncPtr;
typedef struct _miPointerScreenFuncRec { typedef struct _miPointerScreenFuncRec {

View File

@ -72,6 +72,13 @@ in this Software without prior written authorization from The Open Group.
#define SPRITE_DEBUG(x) #define SPRITE_DEBUG(x)
#endif #endif
static int miSpriteDevPrivatesIndex;
#define MISPRITE(dev) \
((DevHasCursor(dev)) ? \
(miCursorInfoPtr) dev->devPrivates[miSpriteDevPrivatesIndex].ptr : \
(miCursorInfoPtr) inputInfo.pointer->devPrivates[miSpriteDevPrivatesIndex].ptr)
/* /*
* screen wrappers * screen wrappers
*/ */
@ -104,6 +111,11 @@ static void miSpriteSaveDoomedAreas(WindowPtr pWin,
static void miSpriteComputeSaved(DeviceIntPtr pDev, static void miSpriteComputeSaved(DeviceIntPtr pDev,
ScreenPtr pScreen); ScreenPtr pScreen);
static Bool miSpriteDeviceCursorInitialize(DeviceIntPtr pDev,
ScreenPtr pScreen);
static void miSpriteDeviceCursorCleanup(DeviceIntPtr pDev,
ScreenPtr pScreen);
#define SCREEN_PROLOGUE(pScreen, field)\ #define SCREEN_PROLOGUE(pScreen, field)\
((pScreen)->field = \ ((pScreen)->field = \
((miSpriteScreenPtr) (pScreen)->devPrivates[miSpriteScreenIndex].ptr)->field) ((miSpriteScreenPtr) (pScreen)->devPrivates[miSpriteScreenIndex].ptr)->field)
@ -123,12 +135,16 @@ static void miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
CursorPtr pCursor, int x, int y); CursorPtr pCursor, int x, int y);
static void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, static void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
int x, int y); int x, int y);
static void miSpriteUndisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen);
_X_EXPORT miPointerSpriteFuncRec miSpritePointerFuncs = { _X_EXPORT miPointerSpriteFuncRec miSpritePointerFuncs = {
miSpriteRealizeCursor, miSpriteRealizeCursor,
miSpriteUnrealizeCursor, miSpriteUnrealizeCursor,
miSpriteSetCursor, miSpriteSetCursor,
miSpriteMoveCursor, miSpriteMoveCursor,
miSpriteDeviceCursorInitialize,
miSpriteDeviceCursorCleanup,
miSpriteUndisplayCursor
}; };
/* /*
@ -156,7 +172,7 @@ miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
{ {
if (DevHasCursor(pDev)) if (DevHasCursor(pDev))
{ {
pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; pCursorInfo = MISPRITE(pDev);
if (pCursorInfo->isUp && if (pCursorInfo->isUp &&
RECT_IN_REGION (pScreen, pRegion, &pCursorInfo->saved) RECT_IN_REGION (pScreen, pRegion, &pCursorInfo->saved)
@ -183,8 +199,6 @@ miSpriteInitialize (pScreen, cursorFuncs, screenFuncs)
{ {
miSpriteScreenPtr pScreenPriv; miSpriteScreenPtr pScreenPriv;
VisualPtr pVisual; VisualPtr pVisual;
miCursorInfoPtr pCursorInfo;
int cursorIdx;
if (!DamageSetup (pScreen)) if (!DamageSetup (pScreen))
return FALSE; return FALSE;
@ -231,44 +245,19 @@ miSpriteInitialize (pScreen, cursorFuncs, screenFuncs)
pScreenPriv->StoreColors = pScreen->StoreColors; pScreenPriv->StoreColors = pScreen->StoreColors;
pScreenPriv->BlockHandler = pScreen->BlockHandler; pScreenPriv->BlockHandler = pScreen->BlockHandler;
/* alloc and zero memory for all cursors */
pScreenPriv->pDevCursors =
(miCursorInfoPtr)xalloc(MAX_DEVICES * sizeof(miCursorInfoRec));
if (!pScreenPriv->pDevCursors) pScreenPriv->DeviceCursorInitialize = pScreen->DeviceCursorInitialize;
{ pScreenPriv->DeviceCursorCleanup = pScreen->DeviceCursorCleanup;
xfree((pointer)pScreenPriv);
return FALSE;
}
/* virtual core pointer's ID is 1 */
pScreenPriv->cp = &(pScreenPriv->pDevCursors[1]);
cursorIdx = 0;
while (cursorIdx < MAX_DEVICES)
{
pCursorInfo = &(pScreenPriv->pDevCursors[cursorIdx]);
pCursorInfo->pCursor = NULL;
pCursorInfo->x = 0;
pCursorInfo->y = 0;
pCursorInfo->isUp = FALSE;
pCursorInfo->shouldBeUp = FALSE;
pCursorInfo->pCacheWin = NullWindow;
pCursorInfo->isInCacheWin = FALSE;
pCursorInfo->checkPixels = TRUE;
pCursorInfo->pInstalledMap = NULL;
pCursorInfo->pColormap = NULL;
pCursorInfo->colors[SOURCE_COLOR].red = 0;
pCursorInfo->colors[SOURCE_COLOR].green = 0;
pCursorInfo->colors[SOURCE_COLOR].blue = 0;
pCursorInfo->colors[MASK_COLOR].red = 0;
pCursorInfo->colors[MASK_COLOR].green = 0;
pCursorInfo->colors[MASK_COLOR].blue = 0;
cursorIdx++;
}
pScreenPriv->pInstalledMap = NULL;
pScreenPriv->pColormap = NULL;
pScreenPriv->funcs = cursorFuncs; pScreenPriv->funcs = cursorFuncs;
pScreenPriv->colors[SOURCE_COLOR].red = 0;
pScreenPriv->colors[SOURCE_COLOR].green = 0;
pScreenPriv->colors[SOURCE_COLOR].blue = 0;
pScreenPriv->colors[MASK_COLOR].red = 0;
pScreenPriv->colors[MASK_COLOR].green = 0;
pScreenPriv->colors[MASK_COLOR].blue = 0;
pScreen->devPrivates[miSpriteScreenIndex].ptr = (pointer) pScreenPriv; pScreen->devPrivates[miSpriteScreenIndex].ptr = (pointer) pScreenPriv;
pScreen->CloseScreen = miSpriteCloseScreen; pScreen->CloseScreen = miSpriteCloseScreen;
@ -286,6 +275,8 @@ miSpriteInitialize (pScreen, cursorFuncs, screenFuncs)
pScreen->BlockHandler = miSpriteBlockHandler; pScreen->BlockHandler = miSpriteBlockHandler;
damageRegister = 0; damageRegister = 0;
miSpriteDevPrivatesIndex = AllocateDevicePrivateIndex();
return TRUE; return TRUE;
} }
@ -318,18 +309,8 @@ miSpriteCloseScreen (i, pScreen)
pScreen->StoreColors = pScreenPriv->StoreColors; pScreen->StoreColors = pScreenPriv->StoreColors;
pScreen->SaveDoomedAreas = pScreenPriv->SaveDoomedAreas; pScreen->SaveDoomedAreas = pScreenPriv->SaveDoomedAreas;
for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
{
if (DevHasCursor(pDev))
{
miCursorInfoPtr pCursor;
pCursor = &pScreenPriv->pDevCursors[pDev->id];
miSpriteIsUpFALSE (pCursor, pScreen, pScreenPriv);
}
}
DamageDestroy (pScreenPriv->pDamage); DamageDestroy (pScreenPriv->pDamage);
xfree ((pointer)(pScreenPriv->pDevCursors));
xfree ((pointer) pScreenPriv); xfree ((pointer) pScreenPriv);
return (*pScreen->CloseScreen) (i, pScreen); return (*pScreen->CloseScreen) (i, pScreen);
@ -356,7 +337,7 @@ miSpriteGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
{ {
if (DevHasCursor(pDev)) if (DevHasCursor(pDev))
{ {
pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; pCursorInfo = MISPRITE(pDev);
if (pDrawable->type == DRAWABLE_WINDOW && if (pDrawable->type == DRAWABLE_WINDOW &&
pCursorInfo->isUp && pCursorInfo->isUp &&
ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y, ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y,
@ -396,7 +377,7 @@ miSpriteGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
{ {
if (DevHasCursor(pDev)) if (DevHasCursor(pDev))
{ {
pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; pCursorInfo = MISPRITE(pDev);
if (pDrawable->type == DRAWABLE_WINDOW && pCursorInfo->isUp) if (pDrawable->type == DRAWABLE_WINDOW && pCursorInfo->isUp)
{ {
@ -448,7 +429,7 @@ miSpriteSourceValidate (pDrawable, x, y, width, height)
{ {
if (DevHasCursor(pDev)) if (DevHasCursor(pDev))
{ {
pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; pCursorInfo = MISPRITE(pDev);
if (pDrawable->type == DRAWABLE_WINDOW && pCursorInfo->isUp && if (pDrawable->type == DRAWABLE_WINDOW && pCursorInfo->isUp &&
ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y,
x, y, width, height)) x, y, width, height))
@ -481,7 +462,7 @@ miSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{ {
if (DevHasCursor(pDev)) if (DevHasCursor(pDev))
{ {
pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; pCursorInfo = MISPRITE(pDev);
/* /*
* Damage will take care of destination check * Damage will take care of destination check
*/ */
@ -522,7 +503,7 @@ miSpriteBlockHandler (i, blockData, pTimeout, pReadmask)
{ {
if (DevHasCursor(pDev)) if (DevHasCursor(pDev))
{ {
pCursorInfo = &pPriv->pDevCursors[pDev->id]; pCursorInfo = MISPRITE(pDev);
if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp) if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp)
{ {
SPRITE_DEBUG (("BlockHandler restore\n")); SPRITE_DEBUG (("BlockHandler restore\n"));
@ -534,7 +515,7 @@ miSpriteBlockHandler (i, blockData, pTimeout, pReadmask)
{ {
if (DevHasCursor(pDev)) if (DevHasCursor(pDev))
{ {
pCursorInfo = &pPriv->pDevCursors[pDev->id]; pCursorInfo = MISPRITE(pDev);
if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp) if (!pCursorInfo->isUp && pCursorInfo->shouldBeUp)
{ {
SPRITE_DEBUG (("BlockHandler restore\n")); SPRITE_DEBUG (("BlockHandler restore\n"));
@ -550,9 +531,6 @@ miSpriteInstallColormap (pMap)
{ {
ScreenPtr pScreen = pMap->pScreen; ScreenPtr pScreen = pMap->pScreen;
miSpriteScreenPtr pPriv; miSpriteScreenPtr pPriv;
DeviceIntPtr pDev = inputInfo.pointer;
miCursorInfoPtr pCursorInfo;
int cursorIdx;
pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
@ -562,29 +540,23 @@ miSpriteInstallColormap (pMap)
SCREEN_EPILOGUE(pScreen, InstallColormap); SCREEN_EPILOGUE(pScreen, InstallColormap);
/* InstallColormap is called before devices are initialized. We cannot /* InstallColormap can be called before devices are initialized. */
* just run through the device list, we need to go through all possible pPriv->pInstalledMap = pMap;
* sprite structs.*/ if (pPriv->pColormap != pMap)
for (cursorIdx = 0; cursorIdx < MAX_DEVICES; cursorIdx++)
{ {
pCursorInfo = &pPriv->pDevCursors[cursorIdx]; DeviceIntPtr pDev;
pCursorInfo->pInstalledMap = pMap; miCursorInfoPtr pCursorInfo;
if (pCursorInfo->pColormap != pMap) for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
{ {
pCursorInfo->checkPixels = TRUE; if (DevHasCursor(pDev))
if (pCursorInfo->isUp)
{ {
/* find matching device */ pCursorInfo = MISPRITE(pDev);
for(pDev = inputInfo.devices; pDev; pDev = pDev->next) pCursorInfo->checkPixels = TRUE;
{ if (pCursorInfo->isUp)
if (pDev->id == cursorIdx) miSpriteRemoveCursor(pDev, pScreen);
{ }
miSpriteRemoveCursor(pDev, pScreen); }
break;
}
}
}
}
} }
} }
@ -599,8 +571,8 @@ miSpriteStoreColors (pMap, ndef, pdef)
int i; int i;
int updated; int updated;
VisualPtr pVisual; VisualPtr pVisual;
DeviceIntPtr pDev = inputInfo.pointer; DeviceIntPtr pDev = inputInfo.pointer;
miCursorInfoPtr pCursorInfo; miCursorInfoPtr pCursorInfo;
pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
@ -610,6 +582,14 @@ miSpriteStoreColors (pMap, ndef, pdef)
SCREEN_EPILOGUE(pScreen, StoreColors); SCREEN_EPILOGUE(pScreen, StoreColors);
if (pPriv->pColormap == pMap)
{
updated = 0;
pVisual = pMap->pVisual;
if (pVisual->class == DirectColor)
{
/* Direct color - match on any of the subfields */
#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask))) #define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask)))
#define UpdateDAC(dev, plane,dac,mask) {\ #define UpdateDAC(dev, plane,dac,mask) {\
@ -624,48 +604,40 @@ miSpriteStoreColors (pMap, ndef, pdef)
UpdateDAC(dev, plane,green,greenMask) \ UpdateDAC(dev, plane,green,greenMask) \
UpdateDAC(dev, plane,blue,blueMask) UpdateDAC(dev, plane,blue,blueMask)
for(pDev = inputInfo.devices; pDev; pDev = pDev->next) for (i = 0; i < ndef; i++)
{
if (DevHasCursor(pDev))
{
pCursorInfo = &pPriv->pDevCursors[pDev->id];
if (pCursorInfo->pColormap == pMap)
{ {
updated = 0; CheckDirect (pPriv, SOURCE_COLOR)
pVisual = pMap->pVisual; CheckDirect (pPriv, MASK_COLOR)
if (pVisual->class == DirectColor) }
}
else
{
/* PseudoColor/GrayScale - match on exact pixel */
for (i = 0; i < ndef; i++)
{
if (pdef[i].pixel ==
pPriv->colors[SOURCE_COLOR].pixel)
{ {
/* Direct color - match on any of the subfields */ pPriv->colors[SOURCE_COLOR] = pdef[i];
if (++updated == 2)
for (i = 0; i < ndef; i++) break;
{
CheckDirect (pCursorInfo, SOURCE_COLOR)
CheckDirect (pCursorInfo, MASK_COLOR)
}
} }
else if (pdef[i].pixel ==
pPriv->colors[MASK_COLOR].pixel)
{ {
/* PseudoColor/GrayScale - match on exact pixel */ pPriv->colors[MASK_COLOR] = pdef[i];
for (i = 0; i < ndef; i++) if (++updated == 2)
{ break;
if (pdef[i].pixel ==
pCursorInfo->colors[SOURCE_COLOR].pixel)
{
pCursorInfo->colors[SOURCE_COLOR] = pdef[i];
if (++updated == 2)
break;
}
if (pdef[i].pixel ==
pCursorInfo->colors[MASK_COLOR].pixel)
{
pCursorInfo->colors[MASK_COLOR] = pdef[i];
if (++updated == 2)
break;
}
}
} }
if (updated) }
}
if (updated)
{
for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
{
if (DevHasCursor(pDev))
{ {
pCursorInfo = MISPRITE(pDev);
pCursorInfo->checkPixels = TRUE; pCursorInfo->checkPixels = TRUE;
if (pCursorInfo->isUp) if (pCursorInfo->isUp)
miSpriteRemoveCursor (pDev, pScreen); miSpriteRemoveCursor (pDev, pScreen);
@ -673,19 +645,20 @@ miSpriteStoreColors (pMap, ndef, pdef)
} }
} }
} }
} }
static void static void
miSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen) miSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen)
{ {
miSpriteScreenPtr pScreenPriv = (miSpriteScreenPtr)
pScreen->devPrivates[miSpriteScreenIndex].ptr;
CursorPtr pCursor; CursorPtr pCursor;
xColorItem *sourceColor, *maskColor; xColorItem *sourceColor, *maskColor;
pCursor = pDevCursor->pCursor; pCursor = pDevCursor->pCursor;
sourceColor = &pDevCursor->colors[SOURCE_COLOR]; sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
maskColor = &pDevCursor->colors[MASK_COLOR]; maskColor = &pScreenPriv->colors[MASK_COLOR];
if (pDevCursor->pColormap != pDevCursor->pInstalledMap || if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
!(pCursor->foreRed == sourceColor->red && !(pCursor->foreRed == sourceColor->red &&
pCursor->foreGreen == sourceColor->green && pCursor->foreGreen == sourceColor->green &&
pCursor->foreBlue == sourceColor->blue && pCursor->foreBlue == sourceColor->blue &&
@ -693,18 +666,18 @@ miSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen)
pCursor->backGreen == maskColor->green && pCursor->backGreen == maskColor->green &&
pCursor->backBlue == maskColor->blue)) pCursor->backBlue == maskColor->blue))
{ {
pDevCursor->pColormap = pDevCursor->pInstalledMap; pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
sourceColor->red = pCursor->foreRed; sourceColor->red = pCursor->foreRed;
sourceColor->green = pCursor->foreGreen; sourceColor->green = pCursor->foreGreen;
sourceColor->blue = pCursor->foreBlue; sourceColor->blue = pCursor->foreBlue;
FakeAllocColor (pDevCursor->pColormap, sourceColor); FakeAllocColor (pScreenPriv->pColormap, sourceColor);
maskColor->red = pCursor->backRed; maskColor->red = pCursor->backRed;
maskColor->green = pCursor->backGreen; maskColor->green = pCursor->backGreen;
maskColor->blue = pCursor->backBlue; maskColor->blue = pCursor->backBlue;
FakeAllocColor (pDevCursor->pColormap, maskColor); FakeAllocColor (pScreenPriv->pColormap, maskColor);
/* "free" the pixels right away, don't let this confuse you */ /* "free" the pixels right away, don't let this confuse you */
FakeFreeColor(pDevCursor->pColormap, sourceColor->pixel); FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
FakeFreeColor(pDevCursor->pColormap, maskColor->pixel); FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
} }
pDevCursor->checkPixels = FALSE; pDevCursor->checkPixels = FALSE;
@ -737,7 +710,7 @@ miSpriteSaveDoomedAreas (pWin, pObscured, dx, dy)
{ {
if(DevHasCursor(pDev)) if(DevHasCursor(pDev))
{ {
pCursorInfo = &pScreenPriv->pDevCursors[pDev->id]; pCursorInfo = MISPRITE(pDev);
if (pCursorInfo->isUp) if (pCursorInfo->isUp)
{ {
cursorBox = pCursorInfo->saved; cursorBox = pCursorInfo->saved;
@ -777,10 +750,7 @@ miSpriteRealizeCursor (pDev, pScreen, pCursor)
miCursorInfoPtr pCursorInfo; miCursorInfoPtr pCursorInfo;
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
pCursorInfo = pScreenPriv->cp; pCursorInfo = MISPRITE(pDev);
if (DevHasCursor(pDev))
pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
if (pCursor == pCursorInfo->pCursor) if (pCursor == pCursorInfo->pCursor)
pCursorInfo->checkPixels = TRUE; pCursorInfo->checkPixels = TRUE;
@ -811,10 +781,7 @@ miSpriteSetCursor (pDev, pScreen, pCursor, x, y)
miSpriteScreenPtr pScreenPriv; miSpriteScreenPtr pScreenPriv;
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
miCursorInfoPtr pPointer = pScreenPriv->cp; miCursorInfoPtr pPointer = MISPRITE(pDev);
if (DevHasCursor(pDev))
pPointer = &pScreenPriv->pDevCursors[pDev->id];
if (!pCursor) if (!pCursor)
{ {
@ -929,14 +896,76 @@ miSpriteMoveCursor (pDev, pScreen, x, y)
CursorPtr pCursor; CursorPtr pCursor;
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
pCursor = pScreenPriv->cp->pCursor; pCursor = MISPRITE(pDev)->pCursor;
if (DevHasCursor(pDev))
pCursor = pScreenPriv->pDevCursors[pDev->id].pCursor;
miSpriteSetCursor (pDev, pScreen, pCursor, x, y); miSpriteSetCursor (pDev, pScreen, pCursor, x, y);
} }
static Bool
miSpriteDeviceCursorInitialize(pDev, pScreen)
DeviceIntPtr pDev;
ScreenPtr pScreen;
{
miSpriteScreenPtr pScreenPriv;
miCursorInfoPtr pCursorInfo;
int ret = FALSE;
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
if (!AllocateDevicePrivate(pDev, miSpriteDevPrivatesIndex))
return FALSE;
pCursorInfo =
pDev->devPrivates[miSpriteDevPrivatesIndex].ptr =
xalloc(sizeof(miCursorInfoRec));
if (!pCursorInfo)
return FALSE;
pCursorInfo->pCursor = NULL;
pCursorInfo->x = 0;
pCursorInfo->y = 0;
pCursorInfo->isUp = FALSE;
pCursorInfo->shouldBeUp = FALSE;
pCursorInfo->pCacheWin = NullWindow;
pCursorInfo->isInCacheWin = FALSE;
pCursorInfo->checkPixels = TRUE;
ret = (*pScreenPriv->funcs->DeviceCursorInitialize)(pDev, pScreen);
if (!ret)
{
xfree(pCursorInfo);
pDev->devPrivates[miSpriteDevPrivatesIndex].ptr = NULL;
}
return ret;
}
static void
miSpriteDeviceCursorCleanup(pDev, pScreen)
DeviceIntPtr pDev;
ScreenPtr pScreen;
{
if (DevHasCursor(pDev))
{
miSpriteScreenPtr pScreenPriv;
pScreenPriv =
(miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
(*pScreenPriv->funcs->DeviceCursorCleanup)(pDev, pScreen);
pDev->devPrivates[miSpriteDevPrivatesIndex].ptr = NULL;
xfree(MISPRITE(pDev));
}
}
static void
miSpriteUndisplayCursor(pDev, pScreen)
DeviceIntPtr pDev;
ScreenPtr pScreen;
{
if (MISPRITE(pDev)->isUp)
miSpriteRemoveCursor(pDev, pScreen);
}
/* /*
* undraw/draw cursor * undraw/draw cursor
*/ */
@ -952,10 +981,7 @@ miSpriteRemoveCursor (pDev, pScreen)
DamageDrawInternal (pScreen, TRUE); DamageDrawInternal (pScreen, TRUE);
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
pCursorInfo = pScreenPriv->cp; pCursorInfo = MISPRITE(pDev);
if (DevHasCursor(pDev))
pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
miSpriteIsUpFALSE (pCursorInfo, pScreen, pScreenPriv); miSpriteIsUpFALSE (pCursorInfo, pScreen, pScreenPriv);
pCursorInfo->pCacheWin = NullWindow; pCursorInfo->pCacheWin = NullWindow;
@ -992,10 +1018,7 @@ miSpriteSaveUnderCursor(pDev, pScreen)
DamageDrawInternal (pScreen, TRUE); DamageDrawInternal (pScreen, TRUE);
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
pCursorInfo = pScreenPriv->cp; pCursorInfo = MISPRITE(pDev);
if (DevHasCursor(pDev))
pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
miSpriteComputeSaved (pDev, pScreen); miSpriteComputeSaved (pDev, pScreen);
pCursor = pCursorInfo->pCursor; pCursor = pCursorInfo->pCursor;
@ -1035,10 +1058,7 @@ miSpriteRestoreCursor (pDev, pScreen)
DamageDrawInternal (pScreen, TRUE); DamageDrawInternal (pScreen, TRUE);
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
pCursorInfo = pScreenPriv->cp; pCursorInfo = MISPRITE(pDev);
if (DevHasCursor(pDev))
pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
miSpriteComputeSaved (pDev, pScreen); miSpriteComputeSaved (pDev, pScreen);
pCursor = pCursorInfo->pCursor; pCursor = pCursorInfo->pCursor;
@ -1051,8 +1071,8 @@ miSpriteRestoreCursor (pDev, pScreen)
miSpriteFindColors (pCursorInfo, pScreen); miSpriteFindColors (pCursorInfo, pScreen);
if ((*pScreenPriv->funcs->PutUpCursor) (pDev, pScreen, if ((*pScreenPriv->funcs->PutUpCursor) (pDev, pScreen,
pCursor, x, y, pCursor, x, y,
pCursorInfo->colors[SOURCE_COLOR].pixel, pScreenPriv->colors[SOURCE_COLOR].pixel,
pCursorInfo->colors[MASK_COLOR].pixel)) pScreenPriv->colors[MASK_COLOR].pixel))
{ {
miSpriteIsUpTRUE (pCursorInfo, pScreen, pScreenPriv); miSpriteIsUpTRUE (pCursorInfo, pScreen, pScreenPriv);
} }
@ -1076,10 +1096,7 @@ miSpriteComputeSaved (pDev, pScreen)
miCursorInfoPtr pCursorInfo; miCursorInfoPtr pCursorInfo;
pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
pCursorInfo = pScreenPriv->cp; pCursorInfo = MISPRITE(pDev);
if (DevHasCursor(pDev))
pCursorInfo = &pScreenPriv->pDevCursors[pDev->id];
pCursor = pCursorInfo->pCursor; pCursor = pCursorInfo->pCursor;
x = pCursorInfo->x - (int)pCursor->bits->xhot; x = pCursorInfo->x - (int)pCursor->bits->xhot;

View File

@ -89,6 +89,14 @@ typedef struct {
int /*dx*/, int /*dx*/,
int /*dy*/ int /*dy*/
); );
Bool (*DeviceCursorInitialize)(
DeviceIntPtr /*pDev*/,
ScreenPtr /*pScreen*/
);
void (*DeviceCursorCleanup)(
DeviceIntPtr /*pDev*/,
ScreenPtr /*pScreen*/
);
} miSpriteCursorFuncRec, *miSpriteCursorFuncPtr; } miSpriteCursorFuncRec, *miSpriteCursorFuncPtr;

View File

@ -53,9 +53,6 @@ typedef struct {
WindowPtr pCacheWin; /* window the cursor last seen in */ WindowPtr pCacheWin; /* window the cursor last seen in */
Bool isInCacheWin; Bool isInCacheWin;
Bool checkPixels; /* check colormap collision */ Bool checkPixels; /* check colormap collision */
xColorItem colors[2];
ColormapPtr pInstalledMap;
ColormapPtr pColormap;
} miCursorInfoRec, *miCursorInfoPtr; } miCursorInfoRec, *miCursorInfoPtr;
/* /*
@ -81,13 +78,17 @@ typedef struct {
/* os layer procedures */ /* os layer procedures */
ScreenBlockHandlerProcPtr BlockHandler; ScreenBlockHandlerProcPtr BlockHandler;
/* device cursor procedures */
DeviceCursorInitializeProcPtr DeviceCursorInitialize;
DeviceCursorCleanupProcPtr DeviceCursorCleanup;
miCursorInfoPtr cp; /* core pointer */ xColorItem colors[2];
ColormapPtr pInstalledMap;
ColormapPtr pColormap;
VisualPtr pVisual; VisualPtr pVisual;
miSpriteCursorFuncPtr funcs; miSpriteCursorFuncPtr funcs;
DamagePtr pDamage; /* damage tracking structure */ DamagePtr pDamage; /* damage tracking structure */
miCursorInfoPtr pDevCursors; /* all cursors' info */
} miSpriteScreenRec, *miSpriteScreenPtr; } miSpriteScreenRec, *miSpriteScreenPtr;
#define SOURCE_COLOR 0 #define SOURCE_COLOR 0