Add cursor support to Xglx
This commit is contained in:
parent
7109ae147c
commit
226c0907d4
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include "xgl.h"
|
#include "xgl.h"
|
||||||
#include "inputstr.h"
|
#include "inputstr.h"
|
||||||
|
#include "cursorstr.h"
|
||||||
#include "mipointer.h"
|
#include "mipointer.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -58,12 +59,26 @@ int xglxScreenPrivateIndex;
|
||||||
#define XGLX_SCREEN_PRIV(pScreen) \
|
#define XGLX_SCREEN_PRIV(pScreen) \
|
||||||
xglxScreenPtr pScreenPriv = XGLX_GET_SCREEN_PRIV (pScreen)
|
xglxScreenPtr pScreenPriv = XGLX_GET_SCREEN_PRIV (pScreen)
|
||||||
|
|
||||||
|
typedef struct _xglxCursor {
|
||||||
|
Cursor cursor;
|
||||||
|
} xglxCursorRec, *xglxCursorPtr;
|
||||||
|
|
||||||
|
#define XGLX_GET_CURSOR_PRIV(pCursor, pScreen) \
|
||||||
|
((xglxCursorPtr) (pCursor)->devPriv[(pScreen)->myNum])
|
||||||
|
|
||||||
|
#define XGLX_SET_CURSOR_PRIV(pCursor, pScreen, v) \
|
||||||
|
((pCursor)->devPriv[(pScreen)->myNum] = (pointer) v)
|
||||||
|
|
||||||
|
#define XGLX_CURSOR_PRIV(pCursor, pScreen) \
|
||||||
|
xglxCursorPtr pCursorPriv = XGLX_GET_CURSOR_PRIV (pCursor, pScreen)
|
||||||
|
|
||||||
char *xDisplayName = NULL;
|
char *xDisplayName = NULL;
|
||||||
Display *xdisplay = NULL;
|
Display *xdisplay = NULL;
|
||||||
int xscreen;
|
int xscreen;
|
||||||
glitz_format_t *xglxCurrentFormat;
|
glitz_format_t *xglxCurrentFormat;
|
||||||
CARD32 lastEventTime = 0;
|
CARD32 lastEventTime = 0;
|
||||||
ScreenPtr currentScreen = NULL;
|
ScreenPtr currentScreen = NULL;
|
||||||
|
Bool softCursor = FALSE;
|
||||||
xglScreenInfoRec xglScreenInfo = {
|
xglScreenInfoRec xglScreenInfo = {
|
||||||
NULL, 0, 0, 0, 0, FALSE,
|
NULL, 0, 0, 0, 0, FALSE,
|
||||||
DEFAULT_GEOMETRY_DATA_TYPE,
|
DEFAULT_GEOMETRY_DATA_TYPE,
|
||||||
|
@ -114,13 +129,115 @@ static Bool
|
||||||
xglxDisplayCursor (ScreenPtr pScreen,
|
xglxDisplayCursor (ScreenPtr pScreen,
|
||||||
CursorPtr pCursor)
|
CursorPtr pCursor)
|
||||||
{
|
{
|
||||||
|
XGLX_SCREEN_PRIV (pScreen);
|
||||||
|
XGLX_CURSOR_PRIV (pCursor, pScreen);
|
||||||
|
|
||||||
|
XDefineCursor (xdisplay, pScreenPriv->win, pCursorPriv->cursor);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ARGB_CURSOR
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
xglxARGBCursorSupport (void);
|
||||||
|
|
||||||
|
static Cursor
|
||||||
|
xglxCreateARGBCursor (ScreenPtr pScreen,
|
||||||
|
CursorPtr pCursor);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
xglxRealizeCursor (ScreenPtr pScreen,
|
xglxRealizeCursor (ScreenPtr pScreen,
|
||||||
CursorPtr pCursor)
|
CursorPtr pCursor)
|
||||||
{
|
{
|
||||||
|
xglxCursorPtr pCursorPriv;
|
||||||
|
XImage *ximage;
|
||||||
|
Pixmap source, mask;
|
||||||
|
XColor fgColor, bgColor;
|
||||||
|
GC xgc;
|
||||||
|
unsigned long valuemask;
|
||||||
|
XGCValues values;
|
||||||
|
|
||||||
|
XGLX_SCREEN_PRIV (pScreen);
|
||||||
|
|
||||||
|
valuemask = GCForeground | GCBackground;
|
||||||
|
|
||||||
|
values.foreground = 1L;
|
||||||
|
values.background = 0L;
|
||||||
|
|
||||||
|
pCursorPriv = xalloc (sizeof (xglxCursorRec));
|
||||||
|
if (!pCursorPriv)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
XGLX_SET_CURSOR_PRIV (pCursor, pScreen, pCursorPriv);
|
||||||
|
|
||||||
|
#ifdef ARGB_CURSOR
|
||||||
|
if (pCursor->bits->argb)
|
||||||
|
{
|
||||||
|
pCursorPriv->cursor = xglxCreateARGBCursor (pScreen, pCursor);
|
||||||
|
if (pCursorPriv->cursor)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
source = XCreatePixmap (xdisplay,
|
||||||
|
pScreenPriv->win,
|
||||||
|
pCursor->bits->width,
|
||||||
|
pCursor->bits->height,
|
||||||
|
1);
|
||||||
|
|
||||||
|
mask = XCreatePixmap (xdisplay,
|
||||||
|
pScreenPriv->win,
|
||||||
|
pCursor->bits->width,
|
||||||
|
pCursor->bits->height,
|
||||||
|
1);
|
||||||
|
|
||||||
|
xgc = XCreateGC (xdisplay, source, valuemask, &values);
|
||||||
|
|
||||||
|
ximage = XCreateImage (xdisplay,
|
||||||
|
DefaultVisual (xdisplay, xscreen),
|
||||||
|
1, XYBitmap, 0,
|
||||||
|
(char *) pCursor->bits->source,
|
||||||
|
pCursor->bits->width,
|
||||||
|
pCursor->bits->height,
|
||||||
|
BitmapPad (xdisplay), 0);
|
||||||
|
|
||||||
|
XPutImage (xdisplay, source, xgc, ximage,
|
||||||
|
0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
|
||||||
|
|
||||||
|
XFree (ximage);
|
||||||
|
|
||||||
|
ximage = XCreateImage (xdisplay,
|
||||||
|
DefaultVisual (xdisplay, xscreen),
|
||||||
|
1, XYBitmap, 0,
|
||||||
|
(char *) pCursor->bits->mask,
|
||||||
|
pCursor->bits->width,
|
||||||
|
pCursor->bits->height,
|
||||||
|
BitmapPad (xdisplay), 0);
|
||||||
|
|
||||||
|
XPutImage (xdisplay, mask, xgc, ximage,
|
||||||
|
0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
|
||||||
|
|
||||||
|
XFree (ximage);
|
||||||
|
XFreeGC (xdisplay, xgc);
|
||||||
|
|
||||||
|
fgColor.red = pCursor->foreRed;
|
||||||
|
fgColor.green = pCursor->foreGreen;
|
||||||
|
fgColor.blue = pCursor->foreBlue;
|
||||||
|
|
||||||
|
bgColor.red = pCursor->backRed;
|
||||||
|
bgColor.green = pCursor->backGreen;
|
||||||
|
bgColor.blue = pCursor->backBlue;
|
||||||
|
|
||||||
|
pCursorPriv->cursor =
|
||||||
|
XCreatePixmapCursor (xdisplay, source, mask, &fgColor, &bgColor,
|
||||||
|
pCursor->bits->xhot, pCursor->bits->yhot);
|
||||||
|
|
||||||
|
XFreePixmap (xdisplay, mask);
|
||||||
|
XFreePixmap (xdisplay, source);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,6 +245,11 @@ static Bool
|
||||||
xglxUnrealizeCursor (ScreenPtr pScreen,
|
xglxUnrealizeCursor (ScreenPtr pScreen,
|
||||||
CursorPtr pCursor)
|
CursorPtr pCursor)
|
||||||
{
|
{
|
||||||
|
XGLX_CURSOR_PRIV (pCursor, pScreen);
|
||||||
|
|
||||||
|
XFreeCursor (xdisplay, pCursorPriv->cursor);
|
||||||
|
xfree (pCursorPriv);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,6 +258,19 @@ xglxRecolorCursor (ScreenPtr pScreen,
|
||||||
CursorPtr pCursor,
|
CursorPtr pCursor,
|
||||||
Bool displayed)
|
Bool displayed)
|
||||||
{
|
{
|
||||||
|
XColor fgColor, bgColor;
|
||||||
|
|
||||||
|
XGLX_CURSOR_PRIV (pCursor, pScreen);
|
||||||
|
|
||||||
|
fgColor.red = pCursor->foreRed;
|
||||||
|
fgColor.green = pCursor->foreGreen;
|
||||||
|
fgColor.blue = pCursor->foreBlue;
|
||||||
|
|
||||||
|
bgColor.red = pCursor->backRed;
|
||||||
|
bgColor.green = pCursor->backGreen;
|
||||||
|
bgColor.blue = pCursor->backBlue;
|
||||||
|
|
||||||
|
XRecolorCursor (xdisplay, pCursorPriv->cursor, &fgColor, &bgColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
|
@ -178,6 +313,29 @@ xglxCloseScreen (int index,
|
||||||
return (*pScreen->CloseScreen) (index, pScreen);
|
return (*pScreen->CloseScreen) (index, pScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
xglxCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xglxCrossScreen (ScreenPtr pScreen, Bool entering)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xglxWarpCursor (ScreenPtr pScreen, int x, int y)
|
||||||
|
{
|
||||||
|
miPointerWarpCursor (pScreen, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
miPointerScreenFuncRec xglxPointerScreenFuncs = {
|
||||||
|
xglxCursorOffScreen,
|
||||||
|
xglxCrossScreen,
|
||||||
|
xglxWarpCursor
|
||||||
|
};
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
xglxScreenInit (int index,
|
xglxScreenInit (int index,
|
||||||
ScreenPtr pScreen,
|
ScreenPtr pScreen,
|
||||||
|
@ -305,6 +463,44 @@ xglxScreenInit (int index,
|
||||||
if (!xglScreenInit (pScreen, &xglScreenInfo))
|
if (!xglScreenInit (pScreen, &xglScreenInfo))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
XGL_SCREEN_WRAP (CloseScreen, xglxCloseScreen);
|
||||||
|
|
||||||
|
#ifdef ARGB_CURSOR
|
||||||
|
if (!xglxARGBCursorSupport ())
|
||||||
|
softCursor = TRUE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (softCursor)
|
||||||
|
{
|
||||||
|
static char data = 0;
|
||||||
|
XColor black, dummy;
|
||||||
|
Pixmap bitmap;
|
||||||
|
Cursor cursor;
|
||||||
|
|
||||||
|
if (!XAllocNamedColor (xdisplay, pScreenPriv->colormap,
|
||||||
|
"black", &black, &dummy))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
bitmap = XCreateBitmapFromData (xdisplay, pScreenPriv->win, &data,
|
||||||
|
1, 1);
|
||||||
|
if (!bitmap)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
cursor = XCreatePixmapCursor (xdisplay, bitmap, bitmap, &black, &black,
|
||||||
|
0, 0);
|
||||||
|
if (!cursor)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
XDefineCursor (xdisplay, pScreenPriv->win, cursor);
|
||||||
|
|
||||||
|
XFreeCursor (xdisplay, cursor);
|
||||||
|
XFreePixmap (xdisplay, bitmap);
|
||||||
|
XFreeColors (xdisplay, pScreenPriv->colormap, &black.pixel, 1, 0);
|
||||||
|
|
||||||
|
miDCInitialize (pScreen, &xglxPointerScreenFuncs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
pScreen->ConstrainCursor = xglxConstrainCursor;
|
pScreen->ConstrainCursor = xglxConstrainCursor;
|
||||||
pScreen->CursorLimits = xglxCursorLimits;
|
pScreen->CursorLimits = xglxCursorLimits;
|
||||||
pScreen->DisplayCursor = xglxDisplayCursor;
|
pScreen->DisplayCursor = xglxDisplayCursor;
|
||||||
|
@ -312,8 +508,7 @@ xglxScreenInit (int index,
|
||||||
pScreen->UnrealizeCursor = xglxUnrealizeCursor;
|
pScreen->UnrealizeCursor = xglxUnrealizeCursor;
|
||||||
pScreen->RecolorCursor = xglxRecolorCursor;
|
pScreen->RecolorCursor = xglxRecolorCursor;
|
||||||
pScreen->SetCursorPosition = xglxSetCursorPosition;
|
pScreen->SetCursorPosition = xglxSetCursorPosition;
|
||||||
|
}
|
||||||
XGL_SCREEN_WRAP (CloseScreen, xglxCloseScreen);
|
|
||||||
|
|
||||||
if (!xglFinishScreenInit (pScreen))
|
if (!xglFinishScreenInit (pScreen))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -442,6 +637,7 @@ xglxWakeupHandler (pointer blockData,
|
||||||
x.u.keyButtonPointer.rootX = X.xmotion.x;
|
x.u.keyButtonPointer.rootX = X.xmotion.x;
|
||||||
x.u.keyButtonPointer.rootY = X.xmotion.y;
|
x.u.keyButtonPointer.rootY = X.xmotion.y;
|
||||||
x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis ();
|
x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis ();
|
||||||
|
miPointerAbsoluteCursor (X.xmotion.x, X.xmotion.y, lastEventTime);
|
||||||
mieqEnqueue (&x);
|
mieqEnqueue (&x);
|
||||||
break;
|
break;
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
|
@ -561,6 +757,7 @@ void
|
||||||
ProcessInputEvents ()
|
ProcessInputEvents ()
|
||||||
{
|
{
|
||||||
mieqProcessInputEvents ();
|
mieqProcessInputEvents ();
|
||||||
|
miPointerUpdate ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -589,6 +786,7 @@ ddxUseMsg (void)
|
||||||
{
|
{
|
||||||
ErrorF ("\nXglx usage:\n");
|
ErrorF ("\nXglx usage:\n");
|
||||||
ErrorF ("-display string display name of the real server\n");
|
ErrorF ("-display string display name of the real server\n");
|
||||||
|
ErrorF ("-softcursor force software cursor\n");
|
||||||
|
|
||||||
xglUseMsg ();
|
xglUseMsg ();
|
||||||
}
|
}
|
||||||
|
@ -596,13 +794,19 @@ ddxUseMsg (void)
|
||||||
int
|
int
|
||||||
ddxProcessArgument (int argc, char **argv, int i)
|
ddxProcessArgument (int argc, char **argv, int i)
|
||||||
{
|
{
|
||||||
if (!strcmp (argv[i], "-display")) {
|
if (!strcmp (argv[i], "-display"))
|
||||||
|
{
|
||||||
if (++i < argc) {
|
if (++i < argc) {
|
||||||
xDisplayName = argv[i];
|
xDisplayName = argv[i];
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp (argv[i], "-softcursor"))
|
||||||
|
{
|
||||||
|
softCursor = TRUE;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return xglProcessArgument (&xglScreenInfo, argc, argv, i);
|
return xglProcessArgument (&xglScreenInfo, argc, argv, i);
|
||||||
}
|
}
|
||||||
|
@ -622,3 +826,68 @@ void
|
||||||
OsVendorInit (void)
|
OsVendorInit (void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ARGB_CURSOR
|
||||||
|
|
||||||
|
#include <X11/extensions/Xrender.h>
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
xglxARGBCursorSupport (void)
|
||||||
|
{
|
||||||
|
int renderMajor, renderMinor;
|
||||||
|
|
||||||
|
if (!XRenderQueryVersion (xdisplay, &renderMajor, &renderMinor))
|
||||||
|
renderMajor = renderMinor = -1;
|
||||||
|
|
||||||
|
return (renderMajor > 0 || renderMinor > 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Cursor
|
||||||
|
xglxCreateARGBCursor (ScreenPtr pScreen,
|
||||||
|
CursorPtr pCursor)
|
||||||
|
{
|
||||||
|
Pixmap xpixmap;
|
||||||
|
GC xgc;
|
||||||
|
XImage *ximage;
|
||||||
|
XRenderPictFormat *xformat;
|
||||||
|
Picture xpicture;
|
||||||
|
Cursor cursor;
|
||||||
|
|
||||||
|
XGLX_SCREEN_PRIV (pScreen);
|
||||||
|
|
||||||
|
xpixmap = XCreatePixmap (xdisplay,
|
||||||
|
pScreenPriv->win,
|
||||||
|
pCursor->bits->width,
|
||||||
|
pCursor->bits->height,
|
||||||
|
32);
|
||||||
|
|
||||||
|
xgc = XCreateGC (xdisplay, xpixmap, 0, NULL);
|
||||||
|
|
||||||
|
ximage = XCreateImage (xdisplay,
|
||||||
|
DefaultVisual (xdisplay, xscreen),
|
||||||
|
32, ZPixmap, 0,
|
||||||
|
(char *) pCursor->bits->argb,
|
||||||
|
pCursor->bits->width,
|
||||||
|
pCursor->bits->height,
|
||||||
|
32, pCursor->bits->width * 4);
|
||||||
|
|
||||||
|
XPutImage (xdisplay, xpixmap, xgc, ximage,
|
||||||
|
0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
|
||||||
|
|
||||||
|
XFree (ximage);
|
||||||
|
XFreeGC (xdisplay, xgc);
|
||||||
|
|
||||||
|
xformat = XRenderFindStandardFormat (xdisplay, PictStandardARGB32);
|
||||||
|
xpicture = XRenderCreatePicture (xdisplay, xpixmap, xformat, 0, 0);
|
||||||
|
|
||||||
|
cursor = XRenderCreateCursor (xdisplay, xpicture,
|
||||||
|
pCursor->bits->xhot,
|
||||||
|
pCursor->bits->yhot);
|
||||||
|
|
||||||
|
XRenderFreePicture (xdisplay, xpicture);
|
||||||
|
XFreePixmap (xdisplay, xpixmap);
|
||||||
|
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue