mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-05-07 05:08:02 +02:00
Enable hardware (==windows) cursor for all display modes
This commit is contained in:
parent
01bdcc8530
commit
e6bbc8bcc4
2 changed files with 333 additions and 1 deletions
|
|
@ -348,6 +348,20 @@ typedef struct
|
||||||
PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES];
|
PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES];
|
||||||
} winPrivCmapRec, *winPrivCmapPtr;
|
} winPrivCmapRec, *winPrivCmapPtr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows Cursor handling.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/* from GetSystemMetrics */
|
||||||
|
int sm_cx;
|
||||||
|
int sm_cy;
|
||||||
|
|
||||||
|
BOOL visible;
|
||||||
|
HCURSOR handle;
|
||||||
|
QueryBestSizeProcPtr QueryBestSize;
|
||||||
|
miPointerSpriteFuncPtr spriteFuncs;
|
||||||
|
} winCursorRec;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Screen information structure that we need before privates are available
|
* Screen information structure that we need before privates are available
|
||||||
|
|
@ -565,6 +579,8 @@ typedef struct _winPrivScreenRec
|
||||||
#ifdef SHAPE
|
#ifdef SHAPE
|
||||||
SetShapeProcPtr SetShape;
|
SetShapeProcPtr SetShape;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
winCursorRec cursor;
|
||||||
} winPrivScreenRec;
|
} winPrivScreenRec;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1399,6 +1415,12 @@ winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg,
|
||||||
void
|
void
|
||||||
winWindowsWMExtensionInit (void);
|
winWindowsWMExtensionInit (void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wincursor.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
Bool
|
||||||
|
winInitCursor (ScreenPtr pScreen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* END DDX and DIX Function Prototypes
|
* END DDX and DIX Function Prototypes
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,21 @@
|
||||||
/* $XFree86: xc/programs/Xserver/hw/xwin/wincursor.c,v 1.5 2002/07/05 09:19:26 alanh Exp $ */
|
/* $XFree86: xc/programs/Xserver/hw/xwin/wincursor.c,v 1.5 2002/07/05 09:19:26 alanh Exp $ */
|
||||||
|
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
|
#include "winmsg.h"
|
||||||
|
#include <cursorstr.h>
|
||||||
|
#include <mipointrst.h>
|
||||||
|
#include <servermd.h>
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BYTE_COUNT(x) (((x) + 7) / 8)
|
||||||
|
#if 1
|
||||||
|
# define WIN_DEBUG_MSG winDebug
|
||||||
|
#else
|
||||||
|
# define WIN_DEBUG_MSG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local function prototypes
|
* Local function prototypes
|
||||||
|
|
@ -70,7 +85,7 @@ winPointerWarpCursor (ScreenPtr pScreen, int x, int y)
|
||||||
/* Don't ignore subsequent warps */
|
/* Don't ignore subsequent warps */
|
||||||
s_fInitialWarp = FALSE;
|
s_fInitialWarp = FALSE;
|
||||||
|
|
||||||
ErrorF ("winPointerWarpCursor - Discarding first warp: %d %d\n",
|
winErrorFVerb (2, "winPointerWarpCursor - Discarding first warp: %d %d\n",
|
||||||
x, y);
|
x, y);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
@ -110,3 +125,298 @@ winCrossScreen (ScreenPtr pScreen, Bool fEntering)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned char
|
||||||
|
reverse(unsigned char c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char ret = 0;
|
||||||
|
for (i = 0; i < 8; ++i)
|
||||||
|
{
|
||||||
|
ret |= ((c >> i)&1) << (7 - i);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Convert X cursor to Windows cursor
|
||||||
|
* FIXME: Perhaps there are more smart code
|
||||||
|
*/
|
||||||
|
static HCURSOR
|
||||||
|
winLoadCursor (ScreenPtr pScreen, CursorPtr pCursor, int screen)
|
||||||
|
{
|
||||||
|
winScreenPriv(pScreen);
|
||||||
|
HCURSOR hCursor = NULL;
|
||||||
|
unsigned char *pAnd;
|
||||||
|
unsigned char *pXor;
|
||||||
|
int nCX, nCY;
|
||||||
|
int nBytes;
|
||||||
|
double dForeY;
|
||||||
|
double dBackY;
|
||||||
|
BOOL fReverse;
|
||||||
|
|
||||||
|
/* We can use only White and Black, so calc brightness of color */
|
||||||
|
dForeY = pCursor->foreRed*0.299 + pCursor->foreGreen*.587 + pCursor->foreBlue*.114;
|
||||||
|
dBackY = pCursor->backRed*0.299 + pCursor->backGreen*.587 + pCursor->backBlue*.114;
|
||||||
|
fReverse = dForeY < dBackY;
|
||||||
|
|
||||||
|
if (pScreenPriv->cursor.sm_cx < pCursor->bits->width ||
|
||||||
|
pScreenPriv->cursor.sm_cy < pCursor->bits->height)
|
||||||
|
{
|
||||||
|
winErrorFVerb (2, "winLoadCursor - Windows requires %dx%d cursor\n"
|
||||||
|
"\tbut X requires %dx%d\n",
|
||||||
|
pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy,
|
||||||
|
pCursor->bits->width, pCursor->bits->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* round up to 8 pixel boundary so we can convert whole bytes */
|
||||||
|
nBytes = BYTE_COUNT(pScreenPriv->cursor.sm_cx) * pScreenPriv->cursor.sm_cy;
|
||||||
|
|
||||||
|
nCX = MIN(pScreenPriv->cursor.sm_cx, pCursor->bits->width);
|
||||||
|
nCY = MIN(pScreenPriv->cursor.sm_cy, pCursor->bits->height);
|
||||||
|
|
||||||
|
WIN_DEBUG_MSG("winLoadCursor: Win32: %dx%d X11: %dx%d\n",
|
||||||
|
pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy,
|
||||||
|
pCursor->bits->width, pCursor->bits->height);
|
||||||
|
|
||||||
|
pAnd = malloc (nBytes);
|
||||||
|
memset (pAnd, 0xFF, nBytes);
|
||||||
|
pXor = malloc (nBytes);
|
||||||
|
memset (pXor, 0x00, nBytes);
|
||||||
|
|
||||||
|
if (pCursor->bits->emptyMask)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
for (y = 0; y < nCY; ++y)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int xmax = BYTE_COUNT(nCX);
|
||||||
|
for (x = 0; x < xmax; ++x)
|
||||||
|
{
|
||||||
|
int nWinPix = BYTE_COUNT(pScreenPriv->cursor.sm_cx) * y + x;
|
||||||
|
int nXPix = BYTE_COUNT(pCursor->bits->width) * y + x;
|
||||||
|
pAnd[nWinPix] = 0;
|
||||||
|
if (fReverse)
|
||||||
|
{
|
||||||
|
pXor[nWinPix] = reverse (~pCursor->bits->source[nXPix]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pXor[nWinPix] = reverse (pCursor->bits->source[nXPix]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
for (y = 0; y < nCY; ++y)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int xmax = BYTE_COUNT(nCX);
|
||||||
|
for (x = 0; x < xmax; ++x)
|
||||||
|
{
|
||||||
|
int nWinPix = BYTE_COUNT(pScreenPriv->cursor.sm_cx) * y + x;
|
||||||
|
int nXPix = BitmapBytePad(pCursor->bits->width) * y + x;
|
||||||
|
|
||||||
|
pAnd[nWinPix] = reverse (~pCursor->bits->mask[nXPix]);
|
||||||
|
if (fReverse)
|
||||||
|
{
|
||||||
|
pXor[nWinPix] = reverse (~pCursor->bits->source[nXPix] & pCursor->bits->mask[nXPix]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pXor[nWinPix] = reverse (pCursor->bits->source[nXPix] & pCursor->bits->mask[nXPix]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hCursor = CreateCursor (g_hInstance,
|
||||||
|
pCursor->bits->xhot, pCursor->bits->yhot,
|
||||||
|
pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy,
|
||||||
|
pAnd, pXor);
|
||||||
|
|
||||||
|
free (pAnd);
|
||||||
|
free (pXor);
|
||||||
|
|
||||||
|
if (hCursor == NULL)
|
||||||
|
{
|
||||||
|
LPVOID lpMsgBuf;
|
||||||
|
|
||||||
|
/* Display a fancy error message */
|
||||||
|
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
NULL,
|
||||||
|
GetLastError (),
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
(LPTSTR) &lpMsgBuf,
|
||||||
|
0, NULL);
|
||||||
|
|
||||||
|
winErrorFVerb (2, "winLoadCursor - CreateCursor failed\n"
|
||||||
|
"\t%s\n", (LPSTR)lpMsgBuf);
|
||||||
|
LocalFree (lpMsgBuf);
|
||||||
|
}
|
||||||
|
return hCursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Pointer sprite functions
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* winMWExtWMRealizeCursor
|
||||||
|
* Convert the X cursor representation to native format if possible.
|
||||||
|
*/
|
||||||
|
static Bool
|
||||||
|
winRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
|
||||||
|
{
|
||||||
|
WIN_DEBUG_MSG("winRealizeCursor: cursor=%p\n", pCursor);
|
||||||
|
|
||||||
|
if(pCursor == NULL || pCursor->bits == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* FIXME: cache ARGB8888 representation? */
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* winMWExtWMUnrealizeCursor
|
||||||
|
* Free the storage space associated with a realized cursor.
|
||||||
|
*/
|
||||||
|
static Bool
|
||||||
|
winUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
|
||||||
|
{
|
||||||
|
WIN_DEBUG_MSG("winUnrealizeCursor: cursor=%p\n", pCursor);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* winMWExtWMSetCursor
|
||||||
|
* Set the cursor sprite and position.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
winSetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
|
||||||
|
{
|
||||||
|
winScreenPriv(pScreen);
|
||||||
|
WIN_DEBUG_MSG("winSetCursor: cursor=%p\n", pCursor);
|
||||||
|
|
||||||
|
if (pCursor == NULL)
|
||||||
|
{
|
||||||
|
if (pScreenPriv->cursor.visible)
|
||||||
|
{
|
||||||
|
ShowCursor (FALSE);
|
||||||
|
pScreenPriv->cursor.visible = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pScreenPriv->cursor.handle)
|
||||||
|
{
|
||||||
|
SetCursor (NULL);
|
||||||
|
DestroyCursor (pScreenPriv->cursor.handle);
|
||||||
|
pScreenPriv->cursor.handle = NULL;
|
||||||
|
}
|
||||||
|
pScreenPriv->cursor.handle = winLoadCursor (pScreen, pCursor, pScreen->myNum);
|
||||||
|
WIN_DEBUG_MSG("winSetCursor: handle=%p\n", pScreenPriv->cursor.handle);
|
||||||
|
SetCursor (pScreenPriv->cursor.handle);
|
||||||
|
|
||||||
|
if (!pScreenPriv->cursor.visible)
|
||||||
|
{
|
||||||
|
ShowCursor (TRUE);
|
||||||
|
pScreenPriv->cursor.visible = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* winMWExtWMReallySetCursor
|
||||||
|
* Not needed for xpr. Cursor is set from the X server thread.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
winReallySetCursor ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* QuartzMoveCursor
|
||||||
|
* Move the cursor. This is a noop for us.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
winMoveCursor (ScreenPtr pScreen, int x, int y)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static miPointerSpriteFuncRec winSpriteFuncsRec = {
|
||||||
|
winRealizeCursor,
|
||||||
|
winUnrealizeCursor,
|
||||||
|
winSetCursor,
|
||||||
|
winMoveCursor
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Other screen functions
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* winMWExtWMCursorQueryBestSize
|
||||||
|
* Handle queries for best cursor size
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
winCursorQueryBestSize (int class, unsigned short *width,
|
||||||
|
unsigned short *height, ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
winScreenPriv(pScreen);
|
||||||
|
|
||||||
|
if (class == CursorShape)
|
||||||
|
{
|
||||||
|
*width = pScreenPriv->cursor.sm_cx;
|
||||||
|
*height = pScreenPriv->cursor.sm_cy;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pScreenPriv->cursor.QueryBestSize)
|
||||||
|
(*pScreenPriv->cursor.QueryBestSize)(class, width, height, pScreen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* winInitCursor
|
||||||
|
* Initialize cursor support
|
||||||
|
*/
|
||||||
|
Bool
|
||||||
|
winInitCursor (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
winScreenPriv(pScreen);
|
||||||
|
miPointerScreenPtr pPointPriv;
|
||||||
|
/* override some screen procedures */
|
||||||
|
pScreenPriv->cursor.QueryBestSize = pScreen->QueryBestSize;
|
||||||
|
pScreen->QueryBestSize = winCursorQueryBestSize;
|
||||||
|
|
||||||
|
pPointPriv = (miPointerScreenPtr) pScreen->devPrivates[miPointerScreenIndex].ptr;
|
||||||
|
|
||||||
|
pScreenPriv->cursor.spriteFuncs = pPointPriv->spriteFuncs;
|
||||||
|
pPointPriv->spriteFuncs = &winSpriteFuncsRec;
|
||||||
|
|
||||||
|
pScreenPriv->cursor.handle = NULL;
|
||||||
|
pScreenPriv->cursor.visible = FALSE;
|
||||||
|
|
||||||
|
pScreenPriv->cursor.sm_cx = GetSystemMetrics (SM_CXCURSOR);
|
||||||
|
pScreenPriv->cursor.sm_cy = GetSystemMetrics (SM_CYCURSOR);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue