e4d11e58ce
This was an attempt to avoid scratch gc creation and validation for paintwin because that was expensive. This is not the case in current servers, and the danger of failure to implement it correctly (as seen in all previous implementations) is high enough to justify removing it. No performance difference detected with x11perf -create -move -resize -circulate on Xvfb. Leave the screen hooks for PaintWindow* in for now to avoid ABI change.
1455 lines
32 KiB
C
1455 lines
32 KiB
C
/*
|
|
* Copyright © 2004 David Reveman
|
|
*
|
|
* 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, and that the name of
|
|
* David Reveman not be used in advertising or publicity pertaining to
|
|
* distribution of the software without specific, written prior permission.
|
|
* David Reveman makes no representations about the suitability of this
|
|
* software for any purpose. It is provided "as is" without express or
|
|
* implied warranty.
|
|
*
|
|
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
|
* NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
|
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
|
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
* Author: David Reveman <davidr@novell.com>
|
|
*/
|
|
|
|
#include "xglx.h"
|
|
|
|
#include <X11/extensions/Xrandr.h>
|
|
#include <X11/cursorfont.h>
|
|
|
|
#include <glitz-glx.h>
|
|
|
|
#ifdef GLXEXT
|
|
#include "xglglxext.h"
|
|
#endif
|
|
|
|
#include "inputstr.h"
|
|
#include "cursorstr.h"
|
|
#include "mipointer.h"
|
|
|
|
#ifdef RANDR
|
|
#include "randrstr.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
#include <math.h>
|
|
|
|
#ifdef XKB
|
|
#include <X11/extensions/XKB.h>
|
|
#include <xkbsrv.h>
|
|
#include <X11/extensions/XKBconfig.h>
|
|
|
|
extern Bool
|
|
XkbQueryExtension (Display *dpy,
|
|
int *opcodeReturn,
|
|
int *eventBaseReturn,
|
|
int *errorBaseReturn,
|
|
int *majorRtrn,
|
|
int *minorRtrn);
|
|
|
|
extern XkbDescPtr
|
|
XkbGetKeyboard (Display *dpy,
|
|
unsigned int which,
|
|
unsigned int deviceSpec);
|
|
|
|
extern Status
|
|
XkbGetControls (Display *dpy,
|
|
unsigned long which,
|
|
XkbDescPtr desc);
|
|
|
|
#ifndef XKB_BASE_DIRECTORY
|
|
#define XKB_BASE_DIRECTORY "/usr/lib/X11/xkb/"
|
|
#endif
|
|
#ifndef XKB_CONFIG_FILE
|
|
#define XKB_CONFIG_FILE "X0-config.keyboard"
|
|
#endif
|
|
#ifndef XKB_DFLT_RULES_FILE
|
|
#define XKB_DFLT_RULES_FILE "xorg"
|
|
#endif
|
|
#ifndef XKB_DFLT_KB_LAYOUT
|
|
#define XKB_DFLT_KB_LAYOUT "us"
|
|
#endif
|
|
#ifndef XKB_DFLT_KB_MODEL
|
|
#define XKB_DFLT_KB_MODEL "pc101"
|
|
#endif
|
|
#ifndef XKB_DFLT_KB_VARIANT
|
|
#define XKB_DFLT_KB_VARIANT NULL
|
|
#endif
|
|
#ifndef XKB_DFLT_KB_OPTIONS
|
|
#define XKB_DFLT_KB_OPTIONS NULL
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#define XGLX_DEFAULT_SCREEN_WIDTH 800
|
|
#define XGLX_DEFAULT_SCREEN_HEIGHT 600
|
|
|
|
typedef struct _xglxScreen {
|
|
Window win, root;
|
|
Colormap colormap;
|
|
Bool fullscreen;
|
|
CloseScreenProcPtr CloseScreen;
|
|
} xglxScreenRec, *xglxScreenPtr;
|
|
|
|
int xglxScreenGeneration = -1;
|
|
int xglxScreenPrivateIndex;
|
|
|
|
#define XGLX_GET_SCREEN_PRIV(pScreen) \
|
|
((xglxScreenPtr) (pScreen)->devPrivates[xglxScreenPrivateIndex].ptr)
|
|
|
|
#define XGLX_SET_SCREEN_PRIV(pScreen, v) \
|
|
((pScreen)->devPrivates[xglxScreenPrivateIndex].ptr = (pointer) v)
|
|
|
|
#define XGLX_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)
|
|
|
|
static char *xDisplayName = 0;
|
|
static Display *xdisplay = 0;
|
|
static int xscreen;
|
|
static CARD32 lastEventTime = 0;
|
|
static ScreenPtr currentScreen = 0;
|
|
static Bool softCursor = FALSE;
|
|
static Bool fullscreen = TRUE;
|
|
|
|
static Bool randrExtension = FALSE;
|
|
static int randrEvent, randrError;
|
|
|
|
static glitz_drawable_format_t *xglxScreenFormat = 0;
|
|
|
|
static Bool
|
|
xglxAllocatePrivates (ScreenPtr pScreen)
|
|
{
|
|
xglxScreenPtr pScreenPriv;
|
|
|
|
if (xglxScreenGeneration != serverGeneration)
|
|
{
|
|
xglxScreenPrivateIndex = AllocateScreenPrivateIndex ();
|
|
if (xglxScreenPrivateIndex < 0)
|
|
return FALSE;
|
|
|
|
xglxScreenGeneration = serverGeneration;
|
|
}
|
|
|
|
pScreenPriv = xalloc (sizeof (xglxScreenRec));
|
|
if (!pScreenPriv)
|
|
return FALSE;
|
|
|
|
XGLX_SET_SCREEN_PRIV (pScreen, pScreenPriv);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#ifdef RANDR
|
|
|
|
#define DEFAULT_REFRESH_RATE 50
|
|
|
|
static Bool
|
|
xglxRandRGetInfo (ScreenPtr pScreen,
|
|
Rotation *rotations)
|
|
{
|
|
RRScreenSizePtr pSize;
|
|
|
|
*rotations = RR_Rotate_0;
|
|
|
|
if (randrExtension)
|
|
{
|
|
XRRScreenConfiguration *xconfig;
|
|
XRRScreenSize *sizes;
|
|
int nSizes, currentSize = 0;
|
|
short *rates, currentRate;
|
|
int nRates, i, j;
|
|
|
|
XGLX_SCREEN_PRIV (pScreen);
|
|
|
|
xconfig = XRRGetScreenInfo (xdisplay, pScreenPriv->root);
|
|
sizes = XRRConfigSizes (xconfig, &nSizes);
|
|
currentRate = XRRConfigCurrentRate (xconfig);
|
|
|
|
if (pScreenPriv->fullscreen)
|
|
{
|
|
Rotation rotation;
|
|
|
|
currentSize = XRRConfigCurrentConfiguration (xconfig, &rotation);
|
|
|
|
for (i = 0; i < nSizes; i++)
|
|
{
|
|
pSize = RRRegisterSize (pScreen,
|
|
sizes[i].width,
|
|
sizes[i].height,
|
|
sizes[i].mwidth,
|
|
sizes[i].mheight);
|
|
|
|
rates = XRRConfigRates (xconfig, i, &nRates);
|
|
|
|
for (j = 0; j < nRates; j++)
|
|
{
|
|
RRRegisterRate (pScreen, pSize, rates[j]);
|
|
|
|
if (i == currentSize && rates[j] == currentRate)
|
|
RRSetCurrentConfig (pScreen, RR_Rotate_0, currentRate,
|
|
pSize);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pSize = RRRegisterSize (pScreen,
|
|
pScreen->width,
|
|
pScreen->height,
|
|
pScreen->mmWidth,
|
|
pScreen->mmHeight);
|
|
|
|
for (i = 0; i < nSizes; i++)
|
|
{
|
|
rates = XRRConfigRates (xconfig, i, &nRates);
|
|
|
|
for (j = 0; j < nRates; j++)
|
|
{
|
|
RRRegisterRate (pScreen, pSize, rates[j]);
|
|
|
|
if (rates[j] == currentRate)
|
|
RRSetCurrentConfig (pScreen, RR_Rotate_0, currentRate,
|
|
pSize);
|
|
}
|
|
}
|
|
}
|
|
|
|
XRRFreeScreenConfigInfo (xconfig);
|
|
}
|
|
else
|
|
{
|
|
pSize = RRRegisterSize (pScreen,
|
|
pScreen->width,
|
|
pScreen->height,
|
|
pScreen->mmWidth,
|
|
pScreen->mmHeight);
|
|
|
|
RRRegisterRate (pScreen, pSize, DEFAULT_REFRESH_RATE);
|
|
RRSetCurrentConfig (pScreen, RR_Rotate_0, DEFAULT_REFRESH_RATE, pSize);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static Bool
|
|
xglxRandRSetConfig (ScreenPtr pScreen,
|
|
Rotation rotations,
|
|
int rate,
|
|
RRScreenSizePtr pSize)
|
|
{
|
|
if (randrExtension)
|
|
{
|
|
XRRScreenConfiguration *xconfig;
|
|
XRRScreenSize *sizes;
|
|
int nSizes, currentSize;
|
|
int i, size = -1;
|
|
int status = RRSetConfigFailed;
|
|
Rotation rotation;
|
|
|
|
XGLX_SCREEN_PRIV (pScreen);
|
|
|
|
xconfig = XRRGetScreenInfo (xdisplay, pScreenPriv->root);
|
|
sizes = XRRConfigSizes (xconfig, &nSizes);
|
|
currentSize = XRRConfigCurrentConfiguration (xconfig, &rotation);
|
|
|
|
for (i = 0; i < nSizes; i++)
|
|
{
|
|
if (pScreenPriv->fullscreen)
|
|
{
|
|
if (sizes[i].width == pSize->width &&
|
|
sizes[i].height == pSize->height &&
|
|
sizes[i].mwidth == pSize->mmWidth &&
|
|
sizes[i].mheight == pSize->mmHeight)
|
|
{
|
|
size = i;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
short *rates;
|
|
int nRates, j;
|
|
|
|
rates = XRRConfigRates (xconfig, i, &nRates);
|
|
|
|
for (j = 0; j < nRates; j++)
|
|
{
|
|
if (rates[j] == rate)
|
|
{
|
|
size = i;
|
|
if (i >= currentSize)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (size >= 0)
|
|
status = XRRSetScreenConfigAndRate (xdisplay,
|
|
xconfig,
|
|
pScreenPriv->root,
|
|
size,
|
|
RR_Rotate_0,
|
|
rate,
|
|
CurrentTime);
|
|
|
|
XRRFreeScreenConfigInfo (xconfig);
|
|
|
|
if (status == RRSetConfigSuccess)
|
|
{
|
|
PixmapPtr pPixmap;
|
|
|
|
pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
|
|
|
|
if (pScreenPriv->fullscreen)
|
|
{
|
|
XGL_PIXMAP_PRIV (pPixmap);
|
|
|
|
xglSetRootClip (pScreen, FALSE);
|
|
|
|
XResizeWindow (xdisplay, pScreenPriv->win,
|
|
pSize->width, pSize->height);
|
|
|
|
glitz_drawable_update_size (pPixmapPriv->drawable,
|
|
pSize->width, pSize->height);
|
|
|
|
pScreen->width = pSize->width;
|
|
pScreen->height = pSize->height;
|
|
pScreen->mmWidth = pSize->mmWidth;
|
|
pScreen->mmHeight = pSize->mmHeight;
|
|
|
|
(*pScreen->ModifyPixmapHeader) (pPixmap,
|
|
pScreen->width,
|
|
pScreen->height,
|
|
pPixmap->drawable.depth,
|
|
pPixmap->drawable.bitsPerPixel,
|
|
0, 0);
|
|
|
|
xglSetRootClip (pScreen, TRUE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static Bool
|
|
xglxRandRInit (ScreenPtr pScreen)
|
|
{
|
|
rrScrPrivPtr pScrPriv;
|
|
|
|
if (!RRScreenInit (pScreen))
|
|
return FALSE;
|
|
|
|
pScrPriv = rrGetScrPriv (pScreen);
|
|
pScrPriv->rrGetInfo = xglxRandRGetInfo;
|
|
pScrPriv->rrSetConfig = xglxRandRSetConfig;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#endif
|
|
|
|
static void
|
|
xglxConstrainCursor (ScreenPtr pScreen,
|
|
BoxPtr pBox)
|
|
{
|
|
}
|
|
|
|
static void
|
|
xglxCursorLimits (ScreenPtr pScreen,
|
|
CursorPtr pCursor,
|
|
BoxPtr pHotBox,
|
|
BoxPtr pTopLeftBox)
|
|
{
|
|
*pTopLeftBox = *pHotBox;
|
|
}
|
|
|
|
static Bool
|
|
xglxDisplayCursor (ScreenPtr pScreen,
|
|
CursorPtr pCursor)
|
|
{
|
|
XGLX_SCREEN_PRIV (pScreen);
|
|
XGLX_CURSOR_PRIV (pCursor, pScreen);
|
|
|
|
XDefineCursor (xdisplay, pScreenPriv->win, pCursorPriv->cursor);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#ifdef ARGB_CURSOR
|
|
|
|
static Bool
|
|
xglxARGBCursorSupport (void);
|
|
|
|
static Cursor
|
|
xglxCreateARGBCursor (ScreenPtr pScreen,
|
|
CursorPtr pCursor);
|
|
|
|
#endif
|
|
|
|
static Bool
|
|
xglxRealizeCursor (ScreenPtr pScreen,
|
|
CursorPtr pCursor)
|
|
{
|
|
xglxCursorPtr pCursorPriv;
|
|
XImage *ximage;
|
|
Pixmap source, mask;
|
|
XColor fgColor, bgColor;
|
|
XlibGC 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;
|
|
}
|
|
|
|
static Bool
|
|
xglxUnrealizeCursor (ScreenPtr pScreen,
|
|
CursorPtr pCursor)
|
|
{
|
|
XGLX_CURSOR_PRIV (pCursor, pScreen);
|
|
|
|
XFreeCursor (xdisplay, pCursorPriv->cursor);
|
|
xfree (pCursorPriv);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
xglxRecolorCursor (ScreenPtr pScreen,
|
|
CursorPtr pCursor,
|
|
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
|
|
xglxSetCursorPosition (ScreenPtr pScreen,
|
|
int x,
|
|
int y,
|
|
Bool generateEvent)
|
|
{
|
|
XGLX_SCREEN_PRIV (pScreen);
|
|
|
|
XWarpPointer (xdisplay, pScreenPriv->win, pScreenPriv->win,
|
|
0, 0, 0, 0, x, y);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static Bool
|
|
xglxCloseScreen (int index,
|
|
ScreenPtr pScreen)
|
|
{
|
|
glitz_drawable_t *drawable;
|
|
|
|
XGLX_SCREEN_PRIV (pScreen);
|
|
|
|
drawable = XGL_GET_SCREEN_PRIV (pScreen)->drawable;
|
|
if (drawable)
|
|
glitz_drawable_destroy (drawable);
|
|
|
|
xglClearVisualTypes ();
|
|
|
|
if (pScreenPriv->win)
|
|
XDestroyWindow (xdisplay, pScreenPriv->win);
|
|
|
|
if (pScreenPriv->colormap)
|
|
XFreeColormap (xdisplay, pScreenPriv->colormap);
|
|
|
|
XGL_SCREEN_UNWRAP (CloseScreen);
|
|
xfree (pScreenPriv);
|
|
|
|
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
|
|
xglxScreenInit (int index,
|
|
ScreenPtr pScreen,
|
|
int argc,
|
|
char **argv)
|
|
{
|
|
XSetWindowAttributes xswa;
|
|
XWMHints *wmHints;
|
|
XSizeHints *normalHints;
|
|
XClassHint *classHint;
|
|
xglxScreenPtr pScreenPriv;
|
|
XVisualInfo *vinfo;
|
|
XEvent xevent;
|
|
glitz_drawable_format_t *format;
|
|
glitz_drawable_t *drawable;
|
|
|
|
format = xglxScreenFormat;
|
|
|
|
if (!xglxAllocatePrivates (pScreen))
|
|
return FALSE;
|
|
|
|
currentScreen = pScreen;
|
|
|
|
pScreenPriv = XGLX_GET_SCREEN_PRIV (pScreen);
|
|
|
|
pScreenPriv->root = RootWindow (xdisplay, xscreen);
|
|
pScreenPriv->fullscreen = fullscreen;
|
|
|
|
vinfo = glitz_glx_get_visual_info_from_format (xdisplay, xscreen, format);
|
|
if (!vinfo)
|
|
{
|
|
ErrorF ("[%d] no visual info from format\n", index);
|
|
return FALSE;
|
|
}
|
|
|
|
pScreenPriv->colormap =
|
|
XCreateColormap (xdisplay, pScreenPriv->root, vinfo->visual,
|
|
AllocNone);
|
|
|
|
if (XRRQueryExtension (xdisplay, &randrEvent, &randrError))
|
|
randrExtension = TRUE;
|
|
|
|
if (fullscreen)
|
|
{
|
|
xglScreenInfo.width = DisplayWidth (xdisplay, xscreen);
|
|
xglScreenInfo.height = DisplayHeight (xdisplay, xscreen);
|
|
xglScreenInfo.widthMm = DisplayWidthMM (xdisplay, xscreen);
|
|
xglScreenInfo.heightMm = DisplayHeightMM (xdisplay, xscreen);
|
|
|
|
if (randrExtension)
|
|
{
|
|
XRRScreenConfiguration *xconfig;
|
|
Rotation rotation;
|
|
XRRScreenSize *sizes;
|
|
int nSizes, currentSize;
|
|
|
|
xconfig = XRRGetScreenInfo (xdisplay, pScreenPriv->root);
|
|
currentSize = XRRConfigCurrentConfiguration (xconfig, &rotation);
|
|
sizes = XRRConfigSizes (xconfig, &nSizes);
|
|
|
|
xglScreenInfo.width = sizes[currentSize].width;
|
|
xglScreenInfo.height = sizes[currentSize].height;
|
|
xglScreenInfo.widthMm = sizes[currentSize].mwidth;
|
|
xglScreenInfo.heightMm = sizes[currentSize].mheight;
|
|
|
|
XRRFreeScreenConfigInfo (xconfig);
|
|
}
|
|
}
|
|
else if (xglScreenInfo.width == 0 || xglScreenInfo.height == 0)
|
|
{
|
|
xglScreenInfo.width = XGLX_DEFAULT_SCREEN_WIDTH;
|
|
xglScreenInfo.height = XGLX_DEFAULT_SCREEN_HEIGHT;
|
|
}
|
|
|
|
xswa.colormap = pScreenPriv->colormap;
|
|
|
|
pScreenPriv->win =
|
|
XCreateWindow (xdisplay, pScreenPriv->root, 0, 0,
|
|
xglScreenInfo.width, xglScreenInfo.height, 0,
|
|
vinfo->depth, InputOutput, vinfo->visual,
|
|
CWColormap, &xswa);
|
|
|
|
XFree (vinfo);
|
|
|
|
normalHints = XAllocSizeHints ();
|
|
normalHints->flags = PMinSize | PMaxSize | PSize;
|
|
normalHints->min_width = xglScreenInfo.width;
|
|
normalHints->min_height = xglScreenInfo.height;
|
|
normalHints->max_width = xglScreenInfo.width;
|
|
normalHints->max_height = xglScreenInfo.height;
|
|
|
|
if (fullscreen)
|
|
{
|
|
normalHints->x = 0;
|
|
normalHints->y = 0;
|
|
normalHints->flags |= PPosition;
|
|
}
|
|
|
|
classHint = XAllocClassHint ();
|
|
classHint->res_name = "xglx";
|
|
classHint->res_class = "Xglx";
|
|
|
|
wmHints = XAllocWMHints ();
|
|
wmHints->flags = InputHint;
|
|
wmHints->input = TRUE;
|
|
|
|
Xutf8SetWMProperties (xdisplay, pScreenPriv->win, "Xglx", "Xglx", 0, 0,
|
|
normalHints, wmHints, classHint);
|
|
|
|
XFree (wmHints);
|
|
XFree (classHint);
|
|
XFree (normalHints);
|
|
|
|
drawable = glitz_glx_create_drawable_for_window (xdisplay, xscreen,
|
|
format, pScreenPriv->win,
|
|
xglScreenInfo.width,
|
|
xglScreenInfo.height);
|
|
if (!drawable)
|
|
{
|
|
ErrorF ("[%d] couldn't create glitz drawable for window\n", index);
|
|
return FALSE;
|
|
}
|
|
|
|
XSelectInput (xdisplay, pScreenPriv->win,
|
|
ButtonPressMask | ButtonReleaseMask |
|
|
KeyPressMask | KeyReleaseMask | EnterWindowMask |
|
|
PointerMotionMask | ExposureMask);
|
|
|
|
XMapWindow (xdisplay, pScreenPriv->win);
|
|
|
|
if (fullscreen)
|
|
{
|
|
XClientMessageEvent xev;
|
|
|
|
memset (&xev, 0, sizeof (xev));
|
|
|
|
xev.type = ClientMessage;
|
|
xev.message_type = XInternAtom (xdisplay, "_NET_WM_STATE", FALSE);
|
|
xev.display = xdisplay;
|
|
xev.window = pScreenPriv->win;
|
|
xev.format = 32;
|
|
xev.data.l[0] = 1;
|
|
xev.data.l[1] =
|
|
XInternAtom (xdisplay, "_NET_WM_STATE_FULLSCREEN", FALSE);
|
|
|
|
XSendEvent (xdisplay, pScreenPriv->root, FALSE,
|
|
SubstructureRedirectMask, (XEvent *) &xev);
|
|
}
|
|
|
|
xglScreenInfo.drawable = drawable;
|
|
|
|
if (!xglScreenInit (pScreen))
|
|
return FALSE;
|
|
|
|
#ifdef GLXEXT
|
|
if (!xglInitVisualConfigs (pScreen))
|
|
return FALSE;
|
|
#endif
|
|
|
|
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->CursorLimits = xglxCursorLimits;
|
|
pScreen->DisplayCursor = xglxDisplayCursor;
|
|
pScreen->RealizeCursor = xglxRealizeCursor;
|
|
pScreen->UnrealizeCursor = xglxUnrealizeCursor;
|
|
pScreen->RecolorCursor = xglxRecolorCursor;
|
|
pScreen->SetCursorPosition = xglxSetCursorPosition;
|
|
}
|
|
|
|
if (!xglFinishScreenInit (pScreen))
|
|
return FALSE;
|
|
|
|
#ifdef RANDR
|
|
if (!xglxRandRInit (pScreen))
|
|
return FALSE;
|
|
#endif
|
|
|
|
while (XNextEvent (xdisplay, &xevent))
|
|
if (xevent.type == Expose)
|
|
break;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
xglxInitOutput (ScreenInfo *pScreenInfo,
|
|
int argc,
|
|
char **argv)
|
|
{
|
|
glitz_drawable_format_t *format, templ;
|
|
int i;
|
|
unsigned long mask;
|
|
unsigned long extraMask[] = {
|
|
GLITZ_FORMAT_DOUBLEBUFFER_MASK | GLITZ_FORMAT_ALPHA_SIZE_MASK,
|
|
GLITZ_FORMAT_DOUBLEBUFFER_MASK,
|
|
GLITZ_FORMAT_ALPHA_SIZE_MASK,
|
|
0
|
|
};
|
|
|
|
xglClearVisualTypes ();
|
|
|
|
xglSetPixmapFormats (pScreenInfo);
|
|
|
|
if (!xdisplay)
|
|
{
|
|
char *name = xDisplayName;
|
|
|
|
if (!name)
|
|
name = xglxInitXorg ();
|
|
|
|
xdisplay = XOpenDisplay (name);
|
|
if (!xdisplay)
|
|
FatalError ("can't open display: %s\n", name ? name : "NULL");
|
|
|
|
xscreen = DefaultScreen (xdisplay);
|
|
|
|
if (!xDisplayName)
|
|
XDefineCursor (xdisplay, RootWindow (xdisplay, xscreen),
|
|
XCreateFontCursor (xdisplay, XC_watch));
|
|
}
|
|
|
|
templ.samples = 1;
|
|
templ.doublebuffer = 1;
|
|
templ.color.fourcc = GLITZ_FOURCC_RGB;
|
|
templ.color.alpha_size = 8;
|
|
|
|
mask = GLITZ_FORMAT_SAMPLES_MASK | GLITZ_FORMAT_FOURCC_MASK;
|
|
|
|
for (i = 0; i < sizeof (extraMask) / sizeof (extraMask[0]); i++)
|
|
{
|
|
format = glitz_glx_find_window_format (xdisplay, xscreen,
|
|
mask | extraMask[i],
|
|
&templ, 0);
|
|
if (format)
|
|
break;
|
|
}
|
|
|
|
if (!format)
|
|
FatalError ("no visual format found");
|
|
|
|
xglScreenInfo.depth =
|
|
format->color.red_size +
|
|
format->color.green_size +
|
|
format->color.blue_size;
|
|
|
|
xglSetVisualTypes (xglScreenInfo.depth,
|
|
(1 << TrueColor),
|
|
format->color.red_size,
|
|
format->color.green_size,
|
|
format->color.blue_size);
|
|
|
|
xglxScreenFormat = format;
|
|
|
|
AddScreen (xglxScreenInit, argc, argv);
|
|
}
|
|
|
|
static Bool
|
|
xglxExposurePredicate (Display *xdisplay,
|
|
XEvent *xevent,
|
|
char *args)
|
|
{
|
|
return (xevent->type == Expose);
|
|
}
|
|
|
|
static Bool
|
|
xglxNotExposurePredicate (Display *xdisplay,
|
|
XEvent *xevent,
|
|
char *args)
|
|
{
|
|
return (xevent->type != Expose);
|
|
}
|
|
|
|
static int
|
|
xglxWindowExposures (WindowPtr pWin,
|
|
pointer pReg)
|
|
{
|
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
|
RegionRec ClipList;
|
|
|
|
if (HasBorder (pWin))
|
|
{
|
|
REGION_INIT (pScreen, &ClipList, NullBox, 0);
|
|
REGION_SUBTRACT (pScreen, &ClipList, &pWin->borderClip,
|
|
&pWin->winSize);
|
|
REGION_INTERSECT (pScreen, &ClipList, &ClipList, (RegionPtr) pReg);
|
|
miPaintWindow(pWin, &ClipList, PW_BORDER);
|
|
REGION_UNINIT (pScreen, &ClipList);
|
|
}
|
|
|
|
REGION_INIT (pScreen, &ClipList, NullBox, 0);
|
|
REGION_INTERSECT (pScreen, &ClipList, &pWin->clipList, (RegionPtr) pReg);
|
|
(*pScreen->WindowExposures) (pWin, &ClipList, NullRegion);
|
|
REGION_UNINIT (pScreen, &ClipList);
|
|
|
|
return WT_WALKCHILDREN;
|
|
}
|
|
|
|
static void
|
|
xglxBlockHandler (pointer blockData,
|
|
OSTimePtr pTimeout,
|
|
pointer pReadMask)
|
|
{
|
|
XEvent X;
|
|
RegionRec region;
|
|
BoxRec box;
|
|
|
|
XGL_SCREEN_PRIV (currentScreen);
|
|
|
|
while (XCheckIfEvent (xdisplay, &X, xglxExposurePredicate, NULL))
|
|
{
|
|
ScreenPtr pScreen = currentScreen;
|
|
|
|
box.x1 = X.xexpose.x;
|
|
box.y1 = X.xexpose.y;
|
|
box.x2 = box.x1 + X.xexpose.width;
|
|
box.y2 = box.y1 + X.xexpose.height;
|
|
|
|
REGION_INIT (currentScreen, ®ion, &box, 1);
|
|
|
|
WalkTree (pScreen, xglxWindowExposures, ®ion);
|
|
|
|
REGION_UNINIT (pScreen, ®ion);
|
|
}
|
|
|
|
if (!xglSyncSurface (&pScreenPriv->pScreenPixmap->drawable))
|
|
FatalError (XGL_SW_FAILURE_STRING);
|
|
|
|
glitz_surface_flush (pScreenPriv->surface);
|
|
glitz_drawable_flush (pScreenPriv->drawable);
|
|
|
|
XFlush (xdisplay);
|
|
}
|
|
|
|
static void
|
|
xglxWakeupHandler (pointer blockData,
|
|
int result,
|
|
pointer pReadMask)
|
|
{
|
|
ScreenPtr pScreen = currentScreen;
|
|
XEvent X;
|
|
xEvent x;
|
|
|
|
while (XCheckIfEvent (xdisplay, &X, xglxNotExposurePredicate, NULL))
|
|
{
|
|
switch (X.type) {
|
|
case KeyPress:
|
|
x.u.u.type = KeyPress;
|
|
x.u.u.detail = X.xkey.keycode;
|
|
x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis ();
|
|
mieqEnqueue (&x);
|
|
break;
|
|
case KeyRelease:
|
|
x.u.u.type = KeyRelease;
|
|
x.u.u.detail = X.xkey.keycode;
|
|
x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis ();
|
|
mieqEnqueue (&x);
|
|
break;
|
|
case ButtonPress:
|
|
x.u.u.type = ButtonPress;
|
|
x.u.u.detail = X.xbutton.button;
|
|
x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis ();
|
|
mieqEnqueue (&x);
|
|
break;
|
|
case ButtonRelease:
|
|
x.u.u.type = ButtonRelease;
|
|
x.u.u.detail = X.xbutton.button;
|
|
x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis ();
|
|
mieqEnqueue (&x);
|
|
break;
|
|
case MotionNotify:
|
|
x.u.u.type = MotionNotify;
|
|
x.u.u.detail = 0;
|
|
x.u.keyButtonPointer.rootX = X.xmotion.x;
|
|
x.u.keyButtonPointer.rootY = X.xmotion.y;
|
|
x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis ();
|
|
miPointerAbsoluteCursor (X.xmotion.x, X.xmotion.y, lastEventTime);
|
|
mieqEnqueue (&x);
|
|
break;
|
|
case EnterNotify:
|
|
if (X.xcrossing.detail != NotifyInferior) {
|
|
if (pScreen) {
|
|
NewCurrentScreen (pScreen, X.xcrossing.x, X.xcrossing.y);
|
|
x.u.u.type = MotionNotify;
|
|
x.u.u.detail = 0;
|
|
x.u.keyButtonPointer.rootX = X.xcrossing.x;
|
|
x.u.keyButtonPointer.rootY = X.xcrossing.y;
|
|
x.u.keyButtonPointer.time = lastEventTime =
|
|
GetTimeInMillis ();
|
|
mieqEnqueue (&x);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
xglxBell (int volume,
|
|
DeviceIntPtr pDev,
|
|
pointer ctrl,
|
|
int cls)
|
|
{
|
|
XBell (xdisplay, volume);
|
|
}
|
|
|
|
static void
|
|
xglxKbdCtrl (DeviceIntPtr pDev,
|
|
KeybdCtrl *ctrl)
|
|
{
|
|
unsigned long valueMask;
|
|
XKeyboardControl values;
|
|
int i;
|
|
|
|
valueMask = KBKeyClickPercent | KBBellPercent | KBBellPitch |
|
|
KBBellDuration | KBAutoRepeatMode;
|
|
|
|
values.key_click_percent = ctrl->click;
|
|
values.bell_percent = ctrl->bell;
|
|
values.bell_pitch = ctrl->bell_pitch;
|
|
values.bell_duration = ctrl->bell_duration;
|
|
values.auto_repeat_mode = (ctrl->autoRepeat) ? AutoRepeatModeOn :
|
|
AutoRepeatModeOff;
|
|
|
|
XChangeKeyboardControl (xdisplay, valueMask, &values);
|
|
|
|
valueMask = KBLed | KBLedMode;
|
|
|
|
for (i = 1; i <= 32; i++)
|
|
{
|
|
values.led = i;
|
|
values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn :
|
|
LedModeOff;
|
|
|
|
XChangeKeyboardControl (xdisplay, valueMask, &values);
|
|
}
|
|
}
|
|
|
|
static int
|
|
xglxKeybdProc (DeviceIntPtr pDevice,
|
|
int onoff)
|
|
{
|
|
Bool ret = FALSE;
|
|
DevicePtr pDev = (DevicePtr) pDevice;
|
|
|
|
if (!pDev)
|
|
return BadImplementation;
|
|
|
|
switch (onoff) {
|
|
case DEVICE_INIT: {
|
|
XModifierKeymap *xmodMap;
|
|
KeySym *xkeyMap;
|
|
int minKeyCode, maxKeyCode, mapWidth, i, j;
|
|
KeySymsRec xglxKeySyms;
|
|
CARD8 xglxModMap[256];
|
|
XKeyboardState values;
|
|
|
|
#ifdef _XSERVER64
|
|
KeySym64 *xkeyMap64;
|
|
int len;
|
|
#endif
|
|
|
|
#ifdef XKB
|
|
Bool xkbExtension = FALSE;
|
|
int xkbOp, xkbEvent, xkbError, xkbMajor, xkbMinor;
|
|
#endif
|
|
|
|
if (pDev != LookupKeyboardDevice ())
|
|
return !Success;
|
|
|
|
xmodMap = XGetModifierMapping (xdisplay);
|
|
|
|
XDisplayKeycodes (xdisplay, &minKeyCode, &maxKeyCode);
|
|
|
|
#ifdef _XSERVER64
|
|
xkeyMap64 = XGetKeyboardMapping (xdisplay,
|
|
minKeyCode,
|
|
maxKeyCode - minKeyCode + 1,
|
|
&mapWidth);
|
|
|
|
len = (maxKeyCode - minKeyCode + 1) * mapWidth;
|
|
xkeyMap = (KeySym *) xalloc (len * sizeof (KeySym));
|
|
for (i = 0; i < len; ++i)
|
|
xkeyMap[i] = xkeyMap64[i];
|
|
|
|
XFree (xkeyMap64);
|
|
#else
|
|
xkeyMap = XGetKeyboardMapping (xdisplay,
|
|
minKeyCode,
|
|
maxKeyCode - minKeyCode + 1,
|
|
&mapWidth);
|
|
#endif
|
|
|
|
memset (xglxModMap, 0, 256);
|
|
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
for (i = 0; i < xmodMap->max_keypermod; i++)
|
|
{
|
|
CARD8 keyCode;
|
|
|
|
keyCode = xmodMap->modifiermap[j * xmodMap->max_keypermod + i];
|
|
if (keyCode)
|
|
xglxModMap[keyCode] |= 1 << j;
|
|
}
|
|
}
|
|
|
|
XFreeModifiermap (xmodMap);
|
|
|
|
xglxKeySyms.minKeyCode = minKeyCode;
|
|
xglxKeySyms.maxKeyCode = maxKeyCode;
|
|
xglxKeySyms.mapWidth = mapWidth;
|
|
xglxKeySyms.map = xkeyMap;
|
|
|
|
#ifdef XKB
|
|
if (!noXkbExtension)
|
|
xkbExtension = XkbQueryExtension (xdisplay,
|
|
&xkbOp, &xkbEvent, &xkbError,
|
|
&xkbMajor, &xkbMinor);
|
|
|
|
if (xkbExtension)
|
|
{
|
|
XkbDescPtr desc;
|
|
char *rules, *model, *layout, *variants, *options;
|
|
|
|
desc = XkbGetKeyboard (xdisplay,
|
|
XkbGBN_AllComponentsMask,
|
|
XkbUseCoreKbd);
|
|
|
|
if (desc && desc->geom)
|
|
{
|
|
XkbComponentNamesRec names;
|
|
FILE *file;
|
|
|
|
rules = XKB_DFLT_RULES_FILE;
|
|
model = XKB_DFLT_KB_MODEL;
|
|
layout = XKB_DFLT_KB_LAYOUT;
|
|
variants = XKB_DFLT_KB_VARIANT;
|
|
options = XKB_DFLT_KB_OPTIONS;
|
|
|
|
XkbGetControls (xdisplay, XkbAllControlsMask, desc);
|
|
|
|
memset (&names, 0, sizeof (XkbComponentNamesRec));
|
|
|
|
XkbSetRulesDflts (rules, model, layout, variants, options);
|
|
|
|
ret = XkbInitKeyboardDeviceStruct ((pointer) pDev,
|
|
&names,
|
|
&xglxKeySyms,
|
|
xglxModMap,
|
|
xglxBell,
|
|
xglxKbdCtrl);
|
|
|
|
if (ret)
|
|
XkbDDXChangeControls ((pointer) pDev, desc->ctrls,
|
|
desc->ctrls);
|
|
|
|
XkbFreeKeyboard (desc, 0, False);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (!ret)
|
|
{
|
|
XGetKeyboardControl (xdisplay, &values);
|
|
|
|
memmove (defaultKeyboardControl.autoRepeats,
|
|
values.auto_repeats, sizeof (values.auto_repeats));
|
|
|
|
ret = InitKeyboardDeviceStruct (pDev,
|
|
&xglxKeySyms,
|
|
xglxModMap,
|
|
xglxBell,
|
|
xglxKbdCtrl);
|
|
}
|
|
|
|
#ifdef _XSERVER64
|
|
xfree (xkeyMap);
|
|
#else
|
|
XFree (xkeyMap);
|
|
#endif
|
|
|
|
if (!ret)
|
|
return BadImplementation;
|
|
|
|
} break;
|
|
case DEVICE_ON:
|
|
pDev->on = TRUE;
|
|
break;
|
|
case DEVICE_OFF:
|
|
case DEVICE_CLOSE:
|
|
pDev->on = FALSE;
|
|
break;
|
|
}
|
|
|
|
return Success;
|
|
}
|
|
|
|
Bool
|
|
xglxLegalModifier (unsigned int key,
|
|
DeviceIntPtr pDev)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
xglxProcessInputEvents (void)
|
|
{
|
|
mieqProcessInputEvents ();
|
|
miPointerUpdate ();
|
|
}
|
|
|
|
void
|
|
xglxInitInput (int argc,
|
|
char **argv)
|
|
{
|
|
DeviceIntPtr pKeyboard, pPointer;
|
|
|
|
pPointer = AddInputDevice (xglMouseProc, TRUE);
|
|
pKeyboard = AddInputDevice (xglxKeybdProc, TRUE);
|
|
|
|
RegisterPointerDevice (pPointer);
|
|
RegisterKeyboardDevice (pKeyboard);
|
|
|
|
miRegisterPointerDevice (screenInfo.screens[0], pPointer);
|
|
mieqInit (&pKeyboard->public, &pPointer->public);
|
|
|
|
AddEnabledDevice (XConnectionNumber (xdisplay));
|
|
|
|
RegisterBlockAndWakeupHandlers (xglxBlockHandler,
|
|
xglxWakeupHandler,
|
|
NULL);
|
|
}
|
|
|
|
void
|
|
xglxUseMsg (void)
|
|
{
|
|
ErrorF ("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM] "
|
|
"specify screen characteristics\n");
|
|
ErrorF ("-fullscreen run fullscreen\n");
|
|
ErrorF ("-display string display name of the real server\n");
|
|
ErrorF ("-softcursor force software cursor\n");
|
|
|
|
if (!xDisplayName)
|
|
xglxUseXorgMsg ();
|
|
}
|
|
|
|
int
|
|
xglxProcessArgument (int argc,
|
|
char **argv,
|
|
int i)
|
|
{
|
|
static Bool checkDisplayName = FALSE;
|
|
|
|
if (!checkDisplayName)
|
|
{
|
|
char *display = ":0";
|
|
int j;
|
|
|
|
for (j = i; j < argc; j++)
|
|
{
|
|
if (!strcmp (argv[j], "-display"))
|
|
{
|
|
if (++j < argc)
|
|
xDisplayName = argv[j];
|
|
|
|
break;
|
|
}
|
|
else if (argv[j][0] == ':')
|
|
{
|
|
display = argv[j];
|
|
}
|
|
}
|
|
|
|
if (!xDisplayName)
|
|
xDisplayName = getenv ("DISPLAY");
|
|
|
|
if (xDisplayName)
|
|
{
|
|
int n;
|
|
|
|
n = strspn (xDisplayName, ":0123456789");
|
|
if (strncmp (xDisplayName, display, n) == 0)
|
|
xDisplayName = 0;
|
|
}
|
|
|
|
if (xDisplayName)
|
|
fullscreen = FALSE;
|
|
|
|
checkDisplayName = TRUE;
|
|
}
|
|
|
|
if (!strcmp (argv[i], "-screen"))
|
|
{
|
|
if ((i + 1) < argc)
|
|
{
|
|
xglParseScreen (argv[i + 1]);
|
|
}
|
|
else
|
|
return 1;
|
|
|
|
return 2;
|
|
}
|
|
else if (!strcmp (argv[i], "-fullscreen"))
|
|
{
|
|
fullscreen = TRUE;
|
|
return 1;
|
|
}
|
|
else if (!strcmp (argv[i], "-display"))
|
|
{
|
|
if (++i < argc)
|
|
return 2;
|
|
|
|
return 0;
|
|
}
|
|
else if (!strcmp (argv[i], "-softcursor"))
|
|
{
|
|
softCursor = TRUE;
|
|
return 1;
|
|
}
|
|
else if (!xDisplayName)
|
|
{
|
|
return xglxProcessXorgArgument (argc, argv, i);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
xglxAbort (void)
|
|
{
|
|
xglxAbortXorg ();
|
|
}
|
|
|
|
void
|
|
xglxGiveUp (void)
|
|
{
|
|
AbortDDX ();
|
|
}
|
|
|
|
void
|
|
xglxOsVendorInit (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;
|
|
XlibGC 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
|