mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-06-19 12:28:26 +02:00
Merge branch 'master' into glucose-2
Conflicts: fb/fb.h fb/fbcompose.c fb/fbmmx.c fb/fbmmx.h fb/fbpict.c fb/fbtile.c hw/xfree86/Makefile.am hw/xfree86/dri/dri.c hw/xgl/xglcompose.c render/picture.c render/picture.h render/picturestr.h
This commit is contained in:
commit
c13e2a941d
969 changed files with 13565 additions and 193939 deletions
31
.gitignore
vendored
31
.gitignore
vendored
|
|
@ -16,11 +16,13 @@ config.log
|
|||
config.status
|
||||
config.sub
|
||||
configure
|
||||
configure.lineno
|
||||
depcomp
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
ylwrap
|
||||
xorg-server.pc
|
||||
stamp-h?
|
||||
do-not-use-config.h
|
||||
|
|
@ -90,6 +92,8 @@ cfb32/cfbzerarcG.c
|
|||
cfb32/cfbzerarcX.c
|
||||
doc/Xserver.1x
|
||||
doc/Xserver.man
|
||||
doc/SecurityPolicy.5
|
||||
doc/SecurityPolicy.man
|
||||
hw/dmx/Xdmx
|
||||
hw/dmx/Xdmx.1x
|
||||
hw/dmx/config/dmxtodmx
|
||||
|
|
@ -205,31 +209,58 @@ hw/xfree86/xaa/mf3-xaaBitmap.c
|
|||
hw/xfree86/xaa/mf3-xaaStipple.c
|
||||
hw/xfree86/xaa/s-xaaDashLine.c
|
||||
hw/xfree86/xaa/s-xaaLine.c
|
||||
hw/xfree86/xf1bpp/maskbits.c
|
||||
hw/xfree86/xf1bpp/mfbbitblt.c
|
||||
hw/xfree86/xf1bpp/mfbbltC.c
|
||||
hw/xfree86/xf1bpp/mfbbltCI.c
|
||||
hw/xfree86/xf1bpp/mfbbltG.c
|
||||
hw/xfree86/xf1bpp/mfbbltO.c
|
||||
hw/xfree86/xf1bpp/mfbbltX.c
|
||||
hw/xfree86/xf1bpp/mfbbres.c
|
||||
hw/xfree86/xf1bpp/mfbbresd.c
|
||||
hw/xfree86/xf1bpp/mfbclip.c
|
||||
hw/xfree86/xf1bpp/mfbcmap.c
|
||||
hw/xfree86/xf1bpp/mfbfillarc.c
|
||||
hw/xfree86/xf1bpp/mfbfillrct.c
|
||||
hw/xfree86/xf1bpp/mfbfillsp.c
|
||||
hw/xfree86/xf1bpp/mfbfont.c
|
||||
hw/xfree86/xf1bpp/mfbgc.c
|
||||
hw/xfree86/xf1bpp/mfbgetsp.c
|
||||
hw/xfree86/xf1bpp/mfbigbblak.c
|
||||
hw/xfree86/xf1bpp/mfbigbwht.c
|
||||
hw/xfree86/xf1bpp/mfbhrzvert.c
|
||||
hw/xfree86/xf1bpp/mfbimage.c
|
||||
hw/xfree86/xf1bpp/mfbline.c
|
||||
hw/xfree86/xf1bpp/mfbmisc.c
|
||||
hw/xfree86/xf1bpp/mfbpablack.c
|
||||
hw/xfree86/xf1bpp/mfbpainv.c
|
||||
hw/xfree86/xf1bpp/mfbpawhite.c
|
||||
hw/xfree86/xf1bpp/mfbpgbblak.c
|
||||
hw/xfree86/xf1bpp/mfbpgbinv.c
|
||||
hw/xfree86/xf1bpp/mfbpgbwht.c
|
||||
hw/xfree86/xf1bpp/mfbpixmap.c
|
||||
hw/xfree86/xf1bpp/mfbplyblack.c
|
||||
hw/xfree86/xf1bpp/mfbplyinv.c
|
||||
hw/xfree86/xf1bpp/mfbplywhite.c
|
||||
hw/xfree86/xf1bpp/mfbpntwin.c
|
||||
hw/xfree86/xf1bpp/mfbpolypnt.c
|
||||
hw/xfree86/xf1bpp/mfbpushpxl.c
|
||||
hw/xfree86/xf1bpp/mfbscrclse.c
|
||||
hw/xfree86/xf1bpp/mfbscrinit.c
|
||||
hw/xfree86/xf1bpp/mfbseg.c
|
||||
hw/xfree86/xf1bpp/mfbsetsp.c
|
||||
hw/xfree86/xf1bpp/mfbteblack.c
|
||||
hw/xfree86/xf1bpp/mfbtewhite.c
|
||||
hw/xfree86/xf1bpp/mfbtileC.c
|
||||
hw/xfree86/xf1bpp/mfbtileG.c
|
||||
hw/xfree86/xf1bpp/mfbwindow.c
|
||||
hw/xfree86/xf1bpp/mfbzerarc.c
|
||||
hw/xfree86/xf4bpp/mfbseg.c
|
||||
hw/xfree86/xf8_32bpp/cfbgc32.c
|
||||
hw/xfree86/xf8_32bpp/cfbgc8.c
|
||||
hw/xfree86/xorg.c
|
||||
hw/xfree86/xorg.conf.example
|
||||
hw/xfree86/xorg.conf.example.pre
|
||||
hw/xnest/Xnest
|
||||
hw/xnest/Xnest.1x
|
||||
hw/xnest/Xnest.man
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
# someone could get really crazy someday and add support for the SI...
|
||||
|
||||
# xwin/darwin/xfree86 have their accel support under the DDX
|
||||
|
||||
if BUILD_DARWIN
|
||||
if XDARWIN
|
||||
DARWIN_SUBDIRS = apple
|
||||
endif
|
||||
SUBDIRS = glx mesa $(DARWIN_SUBDIRS)
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ libglxdri_la_SOURCES = \
|
|||
|
||||
libglx_la_SOURCES = \
|
||||
g_disptab.h \
|
||||
glxbyteorder.h \
|
||||
glxcmds.c \
|
||||
glxcmdsswap.c \
|
||||
glxcontext.h \
|
||||
|
|
|
|||
|
|
@ -1019,6 +1019,7 @@ __glXCreateARGBConfig(__GLXscreen *screen)
|
|||
VisualPtr visual;
|
||||
int i;
|
||||
|
||||
/* search for a 32-bit visual */
|
||||
visual = NULL;
|
||||
for (i = 0; i < screen->pScreen->numVisuals; i++)
|
||||
if (screen->pScreen->visuals[i].nplanes == 32) {
|
||||
|
|
@ -1037,8 +1038,22 @@ __glXCreateARGBConfig(__GLXscreen *screen)
|
|||
if (modes == NULL)
|
||||
return;
|
||||
|
||||
modes->next = screen->modes;
|
||||
screen->modes = modes;
|
||||
/* Insert this new mode at the TAIL of the linked list.
|
||||
* Previously, the mode was incorrectly inserted at the head of the
|
||||
* list, causing find_mesa_visual() to be off by one. This would
|
||||
* GLX clients to blow up if they attempted to use the last mode
|
||||
* in the list!
|
||||
*/
|
||||
{
|
||||
__GLcontextModes *prev = NULL, *m;
|
||||
for (m = screen->modes; m; m = m->next)
|
||||
prev = m;
|
||||
if (prev)
|
||||
prev->next = modes;
|
||||
else
|
||||
screen->modes = modes;
|
||||
}
|
||||
|
||||
screen->numUsableVisuals++;
|
||||
screen->numVisuals++;
|
||||
|
||||
|
|
@ -1104,6 +1119,9 @@ int DoGetFBConfigs(__GLXclientState *cl, unsigned screen, GLboolean do_swap)
|
|||
}
|
||||
pGlxScreen = __glXActiveScreens[screen];
|
||||
|
||||
/* Create the "extra" 32bpp ARGB visual, if not already added.
|
||||
* XXX This is questionable place to do so! Re-examine this someday.
|
||||
*/
|
||||
__glXCreateARGBConfig(pGlxScreen);
|
||||
|
||||
reply.numFBConfigs = pGlxScreen->numUsableVisuals;
|
||||
|
|
@ -1242,13 +1260,15 @@ static int ValidateCreateDrawable(ClientPtr client,
|
|||
** Create a GLX Pixmap from an X Pixmap.
|
||||
*/
|
||||
int DoCreateGLXPixmap(__GLXclientState *cl, XID fbconfigId,
|
||||
GLuint screenNum, XID pixmapId, XID glxPixmapId)
|
||||
GLuint screenNum, XID pixmapId, XID glxPixmapId,
|
||||
CARD32 *attribs, CARD32 numAttribs)
|
||||
{
|
||||
ClientPtr client = cl->client;
|
||||
DrawablePtr pDraw;
|
||||
__GLXpixmap *pGlxPixmap;
|
||||
__GLcontextModes *modes;
|
||||
int retval;
|
||||
GLenum target = 0;
|
||||
int retval, i;
|
||||
|
||||
retval = ValidateCreateDrawable (client, screenNum, fbconfigId,
|
||||
pixmapId, glxPixmapId,
|
||||
|
|
@ -1267,11 +1287,37 @@ int DoCreateGLXPixmap(__GLXclientState *cl, XID fbconfigId,
|
|||
pGlxPixmap->pGlxScreen = __glXgetActiveScreen(screenNum);
|
||||
pGlxPixmap->pScreen = pDraw->pScreen;
|
||||
pGlxPixmap->idExists = True;
|
||||
#ifdef XF86DRI
|
||||
pGlxPixmap->pDamage = NULL;
|
||||
#endif
|
||||
pGlxPixmap->refcnt = 0;
|
||||
|
||||
pGlxPixmap->modes = modes;
|
||||
|
||||
for (i = 0; i < numAttribs; i++) {
|
||||
if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
|
||||
switch (attribs[2 * i + 1]) {
|
||||
case GLX_TEXTURE_2D_EXT:
|
||||
target = GL_TEXTURE_2D;
|
||||
break;
|
||||
case GLX_TEXTURE_RECTANGLE_EXT:
|
||||
target = GL_TEXTURE_RECTANGLE_ARB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
int w = pDraw->width, h = pDraw->height;
|
||||
|
||||
if (h & (h - 1) || w & (w - 1))
|
||||
target = GL_TEXTURE_RECTANGLE_ARB;
|
||||
else
|
||||
target = GL_TEXTURE_2D;
|
||||
}
|
||||
|
||||
pGlxPixmap->target = target;
|
||||
|
||||
/*
|
||||
** Bump the ref count on the X pixmap so it won't disappear.
|
||||
*/
|
||||
|
|
@ -1284,14 +1330,16 @@ int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
|
|||
{
|
||||
xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
|
||||
return DoCreateGLXPixmap( cl, req->visual, req->screen,
|
||||
req->pixmap, req->glxpixmap );
|
||||
req->pixmap, req->glxpixmap, NULL, 0 );
|
||||
}
|
||||
|
||||
int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
|
||||
{
|
||||
xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
|
||||
return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
|
||||
req->pixmap, req->glxpixmap );
|
||||
req->pixmap, req->glxpixmap,
|
||||
(CARD32*)(req + 1),
|
||||
req->numAttribs );
|
||||
}
|
||||
|
||||
int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
|
||||
|
|
@ -1299,7 +1347,7 @@ int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
|
|||
xGLXCreateGLXPixmapWithConfigSGIXReq *req =
|
||||
(xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
|
||||
return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
|
||||
req->pixmap, req->glxpixmap );
|
||||
req->pixmap, req->glxpixmap, NULL, 0 );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1675,7 +1723,8 @@ DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
|
|||
reply.numAttribs = numAttribs;
|
||||
|
||||
attributes[0] = GLX_TEXTURE_TARGET_EXT;
|
||||
attributes[1] = GLX_TEXTURE_RECTANGLE_EXT;
|
||||
attributes[1] = glxPixmap->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT :
|
||||
GLX_TEXTURE_RECTANGLE_EXT;
|
||||
attributes[2] = GLX_Y_INVERTED_EXT;
|
||||
attributes[3] = GL_FALSE;
|
||||
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ int __glXDispSwap_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
|
|||
__GLX_SWAP_INT(&req->glxpixmap);
|
||||
|
||||
return DoCreateGLXPixmap( cl, req->visual, req->screen,
|
||||
req->pixmap, req->glxpixmap );
|
||||
req->pixmap, req->glxpixmap, NULL, 0 );
|
||||
}
|
||||
|
||||
int __glXDispSwap_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
|
||||
|
|
@ -279,9 +279,12 @@ int __glXDispSwap_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
|
|||
__GLX_SWAP_INT(&req->fbconfig);
|
||||
__GLX_SWAP_INT(&req->pixmap);
|
||||
__GLX_SWAP_INT(&req->glxpixmap);
|
||||
__GLX_SWAP_INT(&req->numAttribs);
|
||||
|
||||
return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
|
||||
req->pixmap, req->glxpixmap );
|
||||
req->pixmap, req->glxpixmap,
|
||||
(CARD32*)(req + 1),
|
||||
req->numAttribs );
|
||||
}
|
||||
|
||||
int __glXDispSwap_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
|
||||
|
|
@ -297,7 +300,7 @@ int __glXDispSwap_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc
|
|||
__GLX_SWAP_INT(&req->glxpixmap);
|
||||
|
||||
return DoCreateGLXPixmap( cl, req->fbconfig, req->screen,
|
||||
req->pixmap, req->glxpixmap );
|
||||
req->pixmap, req->glxpixmap, NULL, 0 );
|
||||
}
|
||||
|
||||
int __glXDispSwap_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@
|
|||
|
||||
#include <damage.h>
|
||||
|
||||
#ifdef XF86DRI
|
||||
#include <GL/internal/dri_interface.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
|
||||
DrawablePtr pDraw;
|
||||
|
|
@ -50,7 +54,13 @@ typedef struct {
|
|||
ScreenPtr pScreen;
|
||||
Bool idExists;
|
||||
int refcnt;
|
||||
GLenum target;
|
||||
#ifdef XF86DRI
|
||||
DamagePtr pDamage;
|
||||
__DRIcontext *pDRICtx;
|
||||
GLint texname;
|
||||
unsigned long offset;
|
||||
#endif
|
||||
} __GLXpixmap;
|
||||
|
||||
struct __GLXdrawable {
|
||||
|
|
|
|||
319
GL/glx/glxdri.c
319
GL/glx/glxdri.c
|
|
@ -76,6 +76,11 @@ struct __GLXDRIscreen {
|
|||
xf86EnterVTProc *enterVT;
|
||||
xf86LeaveVTProc *leaveVT;
|
||||
|
||||
DRITexOffsetStartProcPtr texOffsetStart;
|
||||
DRITexOffsetFinishProcPtr texOffsetFinish;
|
||||
__GLXpixmap* texOffsetOverride[16];
|
||||
GLuint lastTexOffsetOverride;
|
||||
|
||||
unsigned char glx_enable_bits[__GLX_EXT_BYTES];
|
||||
};
|
||||
|
||||
|
|
@ -125,30 +130,75 @@ struct __GLXDRIdrawable {
|
|||
static const char CREATE_NEW_SCREEN_FUNC[] =
|
||||
"__driCreateNewScreen_" STRINGIFY (INTERNAL_VERSION);
|
||||
|
||||
/* The DRI driver entry point version wasn't bumped when the
|
||||
* copySubBuffer functionality was added to the DRI drivers, but the
|
||||
* functionality is still conditional on the value of the
|
||||
* internal_api_version passed to __driCreateNewScreen. However, the
|
||||
* screen constructor doesn't fail for a DRI driver that's older than
|
||||
* the passed in version number, so there's no way we can know for
|
||||
* sure that we can actually use the copySubBuffer functionality. But
|
||||
* since the earliest (and at this point only) released mesa version
|
||||
* (6.5) that uses the 20050727 entry point does have copySubBuffer,
|
||||
* we'll just settle for that. We still have to pass in a higher to
|
||||
* the screen constructor to enable the functionality.
|
||||
*/
|
||||
#define COPY_SUB_BUFFER_INTERNAL_VERSION 20060314
|
||||
|
||||
static void
|
||||
__glXDRIleaveServer(void)
|
||||
__glXDRIleaveServer(GLboolean rendering)
|
||||
{
|
||||
DRIBlockHandler(NULL, NULL, NULL);
|
||||
int i;
|
||||
|
||||
for (i = 0; rendering && i < screenInfo.numScreens; i++) {
|
||||
__GLXDRIscreen * const screen =
|
||||
(__GLXDRIscreen *) __glXgetActiveScreen(i);
|
||||
GLuint lastOverride = screen->lastTexOffsetOverride;
|
||||
|
||||
if (lastOverride) {
|
||||
__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < lastOverride; j++) {
|
||||
__GLXpixmap *pGlxPix = texOffsetOverride[j];
|
||||
|
||||
if (pGlxPix && pGlxPix->texname) {
|
||||
pGlxPix->offset =
|
||||
screen->texOffsetStart((PixmapPtr)pGlxPix->pDraw);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DRIBlockHandler(NULL, NULL, NULL);
|
||||
|
||||
for (i = 0; rendering && i < screenInfo.numScreens; i++) {
|
||||
__GLXDRIscreen * const screen =
|
||||
(__GLXDRIscreen *) __glXgetActiveScreen(i);
|
||||
GLuint lastOverride = screen->lastTexOffsetOverride;
|
||||
|
||||
if (lastOverride) {
|
||||
__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < lastOverride; j++) {
|
||||
__GLXpixmap *pGlxPix = texOffsetOverride[j];
|
||||
|
||||
if (pGlxPix && pGlxPix->texname) {
|
||||
screen->driScreen.setTexOffset(pGlxPix->pDRICtx,
|
||||
pGlxPix->texname,
|
||||
pGlxPix->offset,
|
||||
pGlxPix->pDraw->depth,
|
||||
((PixmapPtr)pGlxPix->pDraw)->
|
||||
devKind);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
__glXDRIenterServer(void)
|
||||
__glXDRIenterServer(GLboolean rendering)
|
||||
{
|
||||
DRIWakeupHandler(NULL, 0, NULL);
|
||||
int i;
|
||||
|
||||
for (i = 0; rendering && i < screenInfo.numScreens; i++) {
|
||||
__GLXDRIscreen * const screen =
|
||||
(__GLXDRIscreen *) __glXgetActiveScreen(i);
|
||||
|
||||
if (screen->lastTexOffsetOverride) {
|
||||
CALL_Flush(GET_DISPATCH(), ());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DRIWakeupHandler(NULL, 0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -289,19 +339,6 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext)
|
|||
&context->driContext);
|
||||
}
|
||||
|
||||
static int
|
||||
glxCountBits(int word)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
while (word) {
|
||||
ret += (word & 1);
|
||||
word >>= 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
glxFillAlphaChannel (PixmapPtr pixmap, int x, int y, int width, int height)
|
||||
{
|
||||
|
|
@ -335,19 +372,71 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
|
|||
int buffer,
|
||||
__GLXpixmap *glxPixmap)
|
||||
{
|
||||
RegionPtr pRegion;
|
||||
RegionPtr pRegion = NULL;
|
||||
PixmapPtr pixmap;
|
||||
int bpp;
|
||||
GLenum target, format, type;
|
||||
int bpp, override = 0, texname;
|
||||
GLenum format, type;
|
||||
ScreenPtr pScreen = glxPixmap->pScreen;
|
||||
__GLXDRIscreen * const screen =
|
||||
(__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum);
|
||||
|
||||
CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ?
|
||||
GL_TEXTURE_BINDING_2D :
|
||||
GL_TEXTURE_BINDING_RECTANGLE_NV,
|
||||
&texname));
|
||||
|
||||
if (!texname)
|
||||
return __glXError(GLXBadContextState);
|
||||
|
||||
pixmap = (PixmapPtr) glxPixmap->pDraw;
|
||||
if (!glxPixmap->pDamage) {
|
||||
glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
|
||||
TRUE, glxPixmap->pScreen, NULL);
|
||||
if (!glxPixmap->pDamage)
|
||||
return BadAlloc;
|
||||
|
||||
DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage);
|
||||
if (screen->texOffsetStart && screen->driScreen.setTexOffset) {
|
||||
__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
|
||||
int i, firstEmpty = 16;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (texOffsetOverride[i] == glxPixmap)
|
||||
goto alreadyin;
|
||||
|
||||
if (firstEmpty == 16 && !texOffsetOverride[i])
|
||||
firstEmpty = i;
|
||||
}
|
||||
|
||||
if (firstEmpty == 16) {
|
||||
ErrorF("%s: Failed to register texture offset override\n", __func__);
|
||||
goto nooverride;
|
||||
}
|
||||
|
||||
if (firstEmpty >= screen->lastTexOffsetOverride)
|
||||
screen->lastTexOffsetOverride = firstEmpty + 1;
|
||||
|
||||
texOffsetOverride[firstEmpty] = glxPixmap;
|
||||
|
||||
alreadyin:
|
||||
override = 1;
|
||||
|
||||
glxPixmap->pDRICtx = &((__GLXDRIcontext*)baseContext)->driContext;
|
||||
|
||||
if (texname == glxPixmap->texname)
|
||||
return Success;
|
||||
|
||||
glxPixmap->texname = texname;
|
||||
|
||||
screen->driScreen.setTexOffset(glxPixmap->pDRICtx, texname, 0,
|
||||
pixmap->drawable.depth, pixmap->devKind);
|
||||
}
|
||||
nooverride:
|
||||
|
||||
if (!glxPixmap->pDamage) {
|
||||
if (!override) {
|
||||
glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
|
||||
TRUE, pScreen, NULL);
|
||||
if (!glxPixmap->pDamage)
|
||||
return BadAlloc;
|
||||
|
||||
DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage);
|
||||
}
|
||||
|
||||
pRegion = NULL;
|
||||
} else {
|
||||
pRegion = DamageRegion(glxPixmap->pDamage);
|
||||
|
|
@ -360,30 +449,22 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
|
|||
bpp = 4;
|
||||
format = GL_BGRA;
|
||||
type =
|
||||
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
|
||||
GL_UNSIGNED_BYTE;
|
||||
#else
|
||||
GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
#if X_BYTE_ORDER == X_BIG_ENDIAN
|
||||
!override ? GL_UNSIGNED_INT_8_8_8_8_REV :
|
||||
#endif
|
||||
GL_UNSIGNED_BYTE;
|
||||
} else {
|
||||
bpp = 2;
|
||||
format = GL_RGB;
|
||||
type = GL_UNSIGNED_SHORT_5_6_5;
|
||||
}
|
||||
|
||||
if (!(glxCountBits(pixmap->drawable.width) == 1 &&
|
||||
glxCountBits(pixmap->drawable.height) == 1)
|
||||
/* || strstr(CALL_GetString(GL_EXTENSIONS,
|
||||
"GL_ARB_texture_non_power_of_two")) */)
|
||||
target = GL_TEXTURE_RECTANGLE_ARB;
|
||||
else
|
||||
target = GL_TEXTURE_2D;
|
||||
|
||||
CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH,
|
||||
pixmap->devKind / bpp) );
|
||||
|
||||
if (pRegion == NULL)
|
||||
{
|
||||
if (pixmap->drawable.depth == 24)
|
||||
if (!override && pixmap->drawable.depth == 24)
|
||||
glxFillAlphaChannel(pixmap,
|
||||
pixmap->drawable.x,
|
||||
pixmap->drawable.y,
|
||||
|
|
@ -396,7 +477,7 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
|
|||
pixmap->drawable.y) );
|
||||
|
||||
CALL_TexImage2D( GET_DISPATCH(),
|
||||
(target,
|
||||
(glxPixmap->target,
|
||||
0,
|
||||
bpp == 4 ? 4 : 3,
|
||||
pixmap->drawable.width,
|
||||
|
|
@ -404,8 +485,8 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
|
|||
0,
|
||||
format,
|
||||
type,
|
||||
pixmap->devPrivate.ptr) );
|
||||
} else {
|
||||
override ? NULL : pixmap->devPrivate.ptr) );
|
||||
} else if (!override) {
|
||||
int i, numRects;
|
||||
BoxPtr p;
|
||||
|
||||
|
|
@ -426,7 +507,7 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
|
|||
pixmap->drawable.y + p[i].y1) );
|
||||
|
||||
CALL_TexSubImage2D( GET_DISPATCH(),
|
||||
(target,
|
||||
(glxPixmap->target,
|
||||
0,
|
||||
p[i].x1, p[i].y1,
|
||||
p[i].x2 - p[i].x1, p[i].y2 - p[i].y1,
|
||||
|
|
@ -436,7 +517,8 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
|
|||
}
|
||||
}
|
||||
|
||||
DamageEmpty(glxPixmap->pDamage);
|
||||
if (!override)
|
||||
DamageEmpty(glxPixmap->pDamage);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
|
@ -446,6 +528,40 @@ __glXDRIreleaseTexImage(__GLXcontext *baseContext,
|
|||
int buffer,
|
||||
__GLXpixmap *pixmap)
|
||||
{
|
||||
ScreenPtr pScreen = pixmap->pScreen;
|
||||
__GLXDRIscreen * const screen =
|
||||
(__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum);
|
||||
GLuint lastOverride = screen->lastTexOffsetOverride;
|
||||
|
||||
if (lastOverride) {
|
||||
__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lastOverride; i++) {
|
||||
if (texOffsetOverride[i] == pixmap) {
|
||||
if (screen->texOffsetFinish)
|
||||
screen->texOffsetFinish((PixmapPtr)pixmap->pDraw);
|
||||
|
||||
texOffsetOverride[i] = NULL;
|
||||
|
||||
if (i + 1 == lastOverride) {
|
||||
lastOverride = 0;
|
||||
|
||||
while (i--) {
|
||||
if (texOffsetOverride[i]) {
|
||||
lastOverride = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
screen->lastTexOffsetOverride = lastOverride;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
|
@ -638,9 +754,16 @@ static __DRIscreen *findScreen(__DRInativeDisplay *dpy, int scrn)
|
|||
|
||||
static GLboolean windowExists(__DRInativeDisplay *dpy, __DRIid draw)
|
||||
{
|
||||
WindowPtr pWin = (WindowPtr) LookupIDByType(draw, RT_WINDOW);
|
||||
DrawablePtr pDrawable = (DrawablePtr) LookupIDByType(draw, RT_WINDOW);
|
||||
int unused;
|
||||
drm_clip_rect_t *pRects;
|
||||
|
||||
return pWin == NULL ? GL_FALSE : GL_TRUE;
|
||||
return pDrawable ? DRIGetDrawableInfo(pDrawable->pScreen, pDrawable,
|
||||
(unsigned*)&unused, (unsigned*)&unused,
|
||||
&unused, &unused, &unused, &unused,
|
||||
&unused, &pRects, &unused, &unused,
|
||||
&unused, &pRects)
|
||||
: GL_FALSE;
|
||||
}
|
||||
|
||||
static GLboolean createContext(__DRInativeDisplay *dpy, int screen,
|
||||
|
|
@ -666,9 +789,9 @@ static GLboolean createContext(__DRInativeDisplay *dpy, int screen,
|
|||
fakeID = FakeClientID(0);
|
||||
*(XID *) contextID = fakeID;
|
||||
|
||||
__glXDRIenterServer();
|
||||
__glXDRIenterServer(GL_FALSE);
|
||||
retval = DRICreateContext(pScreen, visual, fakeID, hw_context);
|
||||
__glXDRIleaveServer();
|
||||
__glXDRIleaveServer(GL_FALSE);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -677,9 +800,9 @@ static GLboolean destroyContext(__DRInativeDisplay *dpy, int screen,
|
|||
{
|
||||
GLboolean retval;
|
||||
|
||||
__glXDRIenterServer();
|
||||
__glXDRIenterServer(GL_FALSE);
|
||||
retval = DRIDestroyContext(screenInfo.screens[screen], context);
|
||||
__glXDRIleaveServer();
|
||||
__glXDRIleaveServer(GL_FALSE);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -694,12 +817,10 @@ createDrawable(__DRInativeDisplay *dpy, int screen,
|
|||
if (!pDrawable)
|
||||
return GL_FALSE;
|
||||
|
||||
__glXDRIenterServer();
|
||||
retval = DRICreateDrawable(screenInfo.screens[screen],
|
||||
drawable,
|
||||
pDrawable,
|
||||
hHWDrawable);
|
||||
__glXDRIleaveServer();
|
||||
__glXDRIenterServer(GL_FALSE);
|
||||
retval = DRICreateDrawable(screenInfo.screens[screen], __pGlxClient,
|
||||
pDrawable, hHWDrawable);
|
||||
__glXDRIleaveServer(GL_FALSE);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -713,11 +834,10 @@ destroyDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable)
|
|||
if (!pDrawable)
|
||||
return GL_FALSE;
|
||||
|
||||
__glXDRIenterServer();
|
||||
retval = DRIDestroyDrawable(screenInfo.screens[screen],
|
||||
drawable,
|
||||
pDrawable);
|
||||
__glXDRIleaveServer();
|
||||
__glXDRIenterServer(GL_FALSE);
|
||||
retval = DRIDestroyDrawable(screenInfo.screens[screen], __pGlxClient,
|
||||
pDrawable);
|
||||
__glXDRIleaveServer(GL_FALSE);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -754,20 +874,44 @@ getDrawableInfo(__DRInativeDisplay *dpy, int screen,
|
|||
return GL_FALSE;
|
||||
}
|
||||
|
||||
__glXDRIenterServer();
|
||||
__glXDRIenterServer(GL_FALSE);
|
||||
retval = DRIGetDrawableInfo(screenInfo.screens[screen],
|
||||
pDrawable, index, stamp,
|
||||
x, y, width, height,
|
||||
numClipRects, &pClipRects,
|
||||
backX, backY,
|
||||
numBackClipRects, &pBackClipRects);
|
||||
__glXDRIleaveServer();
|
||||
__glXDRIleaveServer(GL_FALSE);
|
||||
|
||||
if (*numClipRects > 0) {
|
||||
size = sizeof (drm_clip_rect_t) * *numClipRects;
|
||||
*ppClipRects = xalloc (size);
|
||||
if (*ppClipRects != NULL)
|
||||
memcpy (*ppClipRects, pClipRects, size);
|
||||
|
||||
/* Clip cliprects to screen dimensions (redirected windows) */
|
||||
if (*ppClipRects != NULL) {
|
||||
ScreenPtr pScreen = screenInfo.screens[screen];
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = 0; i < *numClipRects; i++) {
|
||||
(*ppClipRects)[j].x1 = max(pClipRects[i].x1, 0);
|
||||
(*ppClipRects)[j].y1 = max(pClipRects[i].y1, 0);
|
||||
(*ppClipRects)[j].x2 = min(pClipRects[i].x2, pScreen->width);
|
||||
(*ppClipRects)[j].y2 = min(pClipRects[i].y2, pScreen->height);
|
||||
|
||||
if ((*ppClipRects)[j].x1 < (*ppClipRects)[j].x2 &&
|
||||
(*ppClipRects)[j].y1 < (*ppClipRects)[j].y2) {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if (*numClipRects != j) {
|
||||
*numClipRects = j;
|
||||
*ppClipRects = xrealloc (*ppClipRects,
|
||||
sizeof (drm_clip_rect_t) *
|
||||
*numClipRects);
|
||||
}
|
||||
} else
|
||||
*numClipRects = 0;
|
||||
}
|
||||
else {
|
||||
*ppClipRects = NULL;
|
||||
|
|
@ -783,7 +927,7 @@ getDrawableInfo(__DRInativeDisplay *dpy, int screen,
|
|||
*ppBackClipRects = NULL;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -829,7 +973,6 @@ static Bool
|
|||
glxDRIEnterVT (int index, int flags)
|
||||
{
|
||||
__GLXDRIscreen *screen = (__GLXDRIscreen *) __glXgetActiveScreen(index);
|
||||
Bool ret;
|
||||
|
||||
LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n");
|
||||
|
||||
|
|
@ -866,7 +1009,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
|
|||
__DRIframebuffer framebuffer;
|
||||
int fd = -1;
|
||||
int status;
|
||||
int api_ver = COPY_SUB_BUFFER_INTERNAL_VERSION;
|
||||
int api_ver = 20070121;
|
||||
drm_magic_t magic;
|
||||
drmVersionPtr version;
|
||||
int newlyopened;
|
||||
|
|
@ -881,13 +1024,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
|
|||
size_t buffer_size;
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
|
||||
if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable")) {
|
||||
LogMessage(X_ERROR, "AIGLX: DRI module not loaded\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!DRIQueryDirectRenderingCapable(pScreen, &isCapable) || !isCapable) {
|
||||
LogMessage(X_ERROR,
|
||||
if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") ||
|
||||
!DRIQueryDirectRenderingCapable(pScreen, &isCapable) ||
|
||||
!isCapable) {
|
||||
LogMessage(X_INFO,
|
||||
"AIGLX: Screen %d is not DRI capable\n", pScreen->myNum);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1048,6 +1188,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
|
|||
goto handle_error;
|
||||
}
|
||||
|
||||
DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart,
|
||||
&screen->texOffsetFinish);
|
||||
|
||||
__glXScreenInit(&screen->base, pScreen);
|
||||
|
||||
buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
|
||||
|
|
|
|||
|
|
@ -61,6 +61,11 @@ xGLXSingleReply __glXReply;
|
|||
*/
|
||||
static __GLXclientState *__glXClients[MAXCLIENTS + 1];
|
||||
|
||||
/*
|
||||
** Client that called into GLX dispatch.
|
||||
*/
|
||||
ClientPtr __pGlxClient;
|
||||
|
||||
/*
|
||||
** Forward declarations.
|
||||
*/
|
||||
|
|
@ -169,10 +174,12 @@ static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
|
|||
|
||||
pGlxPixmap->idExists = False;
|
||||
if (!pGlxPixmap->refcnt) {
|
||||
#ifdef XF86DRI
|
||||
if (pGlxPixmap->pDamage) {
|
||||
DamageUnregister (pGlxPixmap->pDraw, pGlxPixmap->pDamage);
|
||||
DamageDestroy(pGlxPixmap->pDamage);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
** The DestroyPixmap routine should decrement the refcount and free
|
||||
** only if it's zero.
|
||||
|
|
@ -240,9 +247,9 @@ GLboolean __glXFreeContext(__GLXcontext *cx)
|
|||
* the latter case we need to lift the DRI lock manually. */
|
||||
|
||||
if (!glxBlockClients) {
|
||||
__glXleaveServer();
|
||||
__glXleaveServer(GL_FALSE);
|
||||
cx->destroy(cx);
|
||||
__glXenterServer();
|
||||
__glXenterServer(GL_FALSE);
|
||||
} else {
|
||||
cx->next = glxPendingDestroyContexts;
|
||||
glxPendingDestroyContexts = cx;
|
||||
|
|
@ -441,49 +448,49 @@ void glxResumeClients(void)
|
|||
AttendClient(__glXClients[i]->client);
|
||||
}
|
||||
|
||||
__glXleaveServer();
|
||||
__glXleaveServer(GL_FALSE);
|
||||
for (cx = glxPendingDestroyContexts; cx != NULL; cx = next) {
|
||||
next = cx->next;
|
||||
|
||||
cx->destroy(cx);
|
||||
}
|
||||
glxPendingDestroyContexts = NULL;
|
||||
__glXenterServer();
|
||||
__glXenterServer(GL_FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
__glXnopEnterServer(void)
|
||||
__glXnopEnterServer(GLboolean rendering)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
__glXnopLeaveServer(void)
|
||||
__glXnopLeaveServer(GLboolean rendering)
|
||||
{
|
||||
}
|
||||
|
||||
static void (*__glXenterServerFunc)(void) = __glXnopEnterServer;
|
||||
static void (*__glXleaveServerFunc)(void) = __glXnopLeaveServer;
|
||||
static void (*__glXenterServerFunc)(GLboolean) = __glXnopEnterServer;
|
||||
static void (*__glXleaveServerFunc)(GLboolean) = __glXnopLeaveServer;
|
||||
|
||||
void __glXsetEnterLeaveServerFuncs(void (*enter)(void),
|
||||
void (*leave)(void))
|
||||
void __glXsetEnterLeaveServerFuncs(void (*enter)(GLboolean),
|
||||
void (*leave)(GLboolean))
|
||||
{
|
||||
__glXenterServerFunc = enter;
|
||||
__glXleaveServerFunc = leave;
|
||||
}
|
||||
|
||||
|
||||
void __glXenterServer(void)
|
||||
void __glXenterServer(GLboolean rendering)
|
||||
{
|
||||
glxServerLeaveCount--;
|
||||
|
||||
if (glxServerLeaveCount == 0)
|
||||
(*__glXenterServerFunc)();
|
||||
(*__glXenterServerFunc)(rendering);
|
||||
}
|
||||
|
||||
void __glXleaveServer(void)
|
||||
void __glXleaveServer(GLboolean rendering)
|
||||
{
|
||||
if (glxServerLeaveCount == 0)
|
||||
(*__glXleaveServerFunc)();
|
||||
(*__glXleaveServerFunc)(rendering);
|
||||
|
||||
glxServerLeaveCount++;
|
||||
}
|
||||
|
|
@ -548,11 +555,14 @@ static int __glXDispatch(ClientPtr client)
|
|||
opcode,
|
||||
client->swapped);
|
||||
if (proc != NULL) {
|
||||
__glXleaveServer();
|
||||
GLboolean rendering = opcode <= X_GLXRenderLarge;
|
||||
__glXleaveServer(rendering);
|
||||
|
||||
__pGlxClient = client;
|
||||
|
||||
retval = (*proc)(cl, (GLbyte *) stuff);
|
||||
|
||||
__glXenterServer();
|
||||
__glXenterServer(rendering);
|
||||
}
|
||||
else {
|
||||
retval = BadRequest;
|
||||
|
|
|
|||
|
|
@ -80,7 +80,8 @@ extern int DoGetFBConfigs(__GLXclientState *cl, unsigned screen,
|
|||
extern int DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
|
||||
GLXContextID shareList, VisualID visual, GLuint screen, GLboolean isDirect);
|
||||
extern int DoCreateGLXPixmap(__GLXclientState *cl, XID fbconfigId,
|
||||
GLuint screenNum, XID pixmapId, XID glxpixmapId);
|
||||
GLuint screenNum, XID pixmapId, XID glxpixmapId, CARD32 *attribs,
|
||||
CARD32 numAttribs);
|
||||
extern int DoDestroyPixmap(__GLXclientState *cl, XID glxpixmapId);
|
||||
|
||||
extern int DoQueryContext(__GLXclientState *cl, GLXContextID gcId);
|
||||
|
|
|
|||
|
|
@ -106,11 +106,11 @@ __glXMesaDrawableSwapBuffers(__GLXdrawable *base)
|
|||
* why we need to re-take the lock and swap in the server context
|
||||
* before calling XMesaSwapBuffers() here. /me shakes head. */
|
||||
|
||||
__glXenterServer();
|
||||
__glXenterServer(GL_FALSE);
|
||||
|
||||
XMesaSwapBuffers(glxPriv->xm_buf);
|
||||
|
||||
__glXleaveServer();
|
||||
__glXleaveServer(GL_FALSE);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
|
@ -258,12 +258,14 @@ __glXMesaScreenDestroy(__GLXscreen *screen)
|
|||
__GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mesaScreen->num_vis; i++) {
|
||||
if (mesaScreen->xm_vis[i])
|
||||
XMesaDestroyVisual(mesaScreen->xm_vis[i]);
|
||||
}
|
||||
if (mesaScreen->xm_vis) {
|
||||
for (i = 0; i < mesaScreen->num_vis; i++) {
|
||||
if (mesaScreen->xm_vis[i])
|
||||
XMesaDestroyVisual(mesaScreen->xm_vis[i]);
|
||||
}
|
||||
|
||||
xfree(mesaScreen->xm_vis);
|
||||
xfree(mesaScreen->xm_vis);
|
||||
}
|
||||
|
||||
__glXScreenDestroy(screen);
|
||||
|
||||
|
|
@ -294,7 +296,7 @@ static void init_screen_visuals(__GLXMESAscreen *screen)
|
|||
__GLcontextModes *modes;
|
||||
XMesaVisual *pXMesaVisual;
|
||||
int *used;
|
||||
int i, j, size;
|
||||
int num_vis, j, size;
|
||||
|
||||
/* Alloc space for the list of XMesa visuals */
|
||||
size = screen->base.numVisuals * sizeof(XMesaVisual);
|
||||
|
|
@ -310,7 +312,7 @@ static void init_screen_visuals(__GLXMESAscreen *screen)
|
|||
used = (int *) xalloc(pScreen->numVisuals * sizeof(int));
|
||||
memset(used, 0, pScreen->numVisuals * sizeof(int));
|
||||
|
||||
i = 0;
|
||||
num_vis = 0;
|
||||
for ( modes = screen->base.modes; modes != NULL; modes = modes->next ) {
|
||||
const int vis_class = _gl_convert_to_x_visual_type( modes->visualType );
|
||||
const int nplanes = (modes->rgbBits - modes->alphaBits);
|
||||
|
|
@ -325,7 +327,8 @@ static void init_screen_visuals(__GLXMESAscreen *screen)
|
|||
!used[j]) {
|
||||
|
||||
/* Create the XMesa visual */
|
||||
pXMesaVisual[i] =
|
||||
assert(num_vis < screen->base.numVisuals);
|
||||
pXMesaVisual[num_vis] =
|
||||
XMesaCreateVisual(pScreen,
|
||||
&pVis[j],
|
||||
modes->rgbMode,
|
||||
|
|
@ -362,13 +365,15 @@ static void init_screen_visuals(__GLXMESAscreen *screen)
|
|||
FatalError( "Matching visual found, but visualID still -1!\n" );
|
||||
}
|
||||
|
||||
i++;
|
||||
num_vis++;
|
||||
}
|
||||
|
||||
xfree(used);
|
||||
|
||||
screen->num_vis = pScreen->numVisuals;
|
||||
screen->num_vis = num_vis;
|
||||
screen->xm_vis = pXMesaVisual;
|
||||
|
||||
assert(screen->num_vis <= screen->base.numVisuals);
|
||||
}
|
||||
|
||||
static __GLXscreen *
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ void __glXScreenInitVisuals(__GLXscreen *screen);
|
|||
extern __GLXcontext *__glXLastContext;
|
||||
extern __GLXcontext *__glXForceCurrent(__GLXclientState*, GLXContextTag, int*);
|
||||
|
||||
extern ClientPtr __pGlxClient;
|
||||
|
||||
int __glXError(int error);
|
||||
|
||||
/*
|
||||
|
|
@ -131,10 +133,10 @@ struct __GLXprovider {
|
|||
|
||||
void GlxPushProvider(__GLXprovider *provider);
|
||||
|
||||
void __glXsetEnterLeaveServerFuncs(void (*enter)(void),
|
||||
void (*leave)(void));
|
||||
void __glXenterServer(void);
|
||||
void __glXleaveServer(void);
|
||||
void __glXsetEnterLeaveServerFuncs(void (*enter)(GLboolean),
|
||||
void (*leave)(GLboolean));
|
||||
void __glXenterServer(GLboolean rendering);
|
||||
void __glXleaveServer(GLboolean rendering);
|
||||
|
||||
void glxSuspendClients(void);
|
||||
void glxResumeClients(void);
|
||||
|
|
|
|||
|
|
@ -211,8 +211,6 @@ extern HIDDEN int __glXDisp_ReadPixels(struct __GLXclientStateRec *, GLbyte *);
|
|||
extern HIDDEN int __glXDispSwap_ReadPixels(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN void __glXDisp_EdgeFlagv(GLbyte * pc);
|
||||
extern HIDDEN void __glXDispSwap_EdgeFlagv(GLbyte * pc);
|
||||
extern HIDDEN void __glXDisp_Rotatef(GLbyte * pc);
|
||||
extern HIDDEN void __glXDispSwap_Rotatef(GLbyte * pc);
|
||||
extern HIDDEN void __glXDisp_TexParameterf(GLbyte * pc);
|
||||
extern HIDDEN void __glXDispSwap_TexParameterf(GLbyte * pc);
|
||||
extern HIDDEN void __glXDisp_TexParameteri(GLbyte * pc);
|
||||
|
|
@ -519,6 +517,8 @@ extern HIDDEN void __glXDisp_SecondaryColor3ivEXT(GLbyte * pc);
|
|||
extern HIDDEN void __glXDispSwap_SecondaryColor3ivEXT(GLbyte * pc);
|
||||
extern HIDDEN void __glXDisp_TexCoord4iv(GLbyte * pc);
|
||||
extern HIDDEN void __glXDispSwap_TexCoord4iv(GLbyte * pc);
|
||||
extern HIDDEN int __glXDisp_GetDrawableAttributesSGIX(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDispSwap_GetDrawableAttributesSGIX(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN void __glXDisp_SampleMaskSGIS(GLbyte * pc);
|
||||
extern HIDDEN void __glXDispSwap_SampleMaskSGIS(GLbyte * pc);
|
||||
extern HIDDEN void __glXDisp_ColorTableParameteriv(GLbyte * pc);
|
||||
|
|
@ -849,10 +849,8 @@ extern HIDDEN int __glXDisp_GetHistogramParameteriv(struct __GLXclientStateRec *
|
|||
extern HIDDEN int __glXDispSwap_GetHistogramParameteriv(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDisp_GetHistogramParameterivEXT(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDispSwap_GetHistogramParameterivEXT(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDisp_GetConvolutionFilter(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDispSwap_GetConvolutionFilter(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDisp_GetConvolutionFilterEXT(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDispSwap_GetConvolutionFilterEXT(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN void __glXDisp_Rotatef(GLbyte * pc);
|
||||
extern HIDDEN void __glXDispSwap_Rotatef(GLbyte * pc);
|
||||
extern HIDDEN int __glXDisp_GetProgramivARB(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDispSwap_GetProgramivARB(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN void __glXDisp_BlendFuncSeparateEXT(GLbyte * pc);
|
||||
|
|
@ -877,6 +875,10 @@ extern HIDDEN void __glXDisp_Map2f(GLbyte * pc);
|
|||
extern HIDDEN void __glXDispSwap_Map2f(GLbyte * pc);
|
||||
extern HIDDEN void __glXDisp_ProgramStringARB(GLbyte * pc);
|
||||
extern HIDDEN void __glXDispSwap_ProgramStringARB(GLbyte * pc);
|
||||
extern HIDDEN int __glXDisp_GetConvolutionFilter(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDispSwap_GetConvolutionFilter(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDisp_GetConvolutionFilterEXT(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDispSwap_GetConvolutionFilterEXT(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDisp_GetCompressedTexImageARB(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDispSwap_GetCompressedTexImageARB(struct __GLXclientStateRec *, GLbyte *);
|
||||
extern HIDDEN int __glXDisp_GetTexGenfv(struct __GLXclientStateRec *, GLbyte *);
|
||||
|
|
|
|||
|
|
@ -370,6 +370,7 @@ __glGetBooleanv_size(GLenum e)
|
|||
case GL_PROJECTION_STACK_DEPTH:
|
||||
case GL_TEXTURE_STACK_DEPTH:
|
||||
case GL_ATTRIB_STACK_DEPTH:
|
||||
case GL_CLIENT_ATTRIB_STACK_DEPTH:
|
||||
case GL_ALPHA_TEST:
|
||||
case GL_ALPHA_TEST_FUNC:
|
||||
case GL_ALPHA_TEST_REF:
|
||||
|
|
@ -448,6 +449,7 @@ __glGetBooleanv_size(GLenum e)
|
|||
case GL_MAX_NAME_STACK_DEPTH:
|
||||
case GL_MAX_PROJECTION_STACK_DEPTH:
|
||||
case GL_MAX_TEXTURE_STACK_DEPTH:
|
||||
case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
|
||||
case GL_SUBPIXEL_BITS:
|
||||
case GL_INDEX_BITS:
|
||||
case GL_RED_BITS:
|
||||
|
|
|
|||
|
|
@ -1231,8 +1231,8 @@ const struct __glXDispatchInfo Render_dispatch_info = {
|
|||
};
|
||||
|
||||
/*****************************************************************/
|
||||
/* tree depth = 13 */
|
||||
static const int_fast16_t VendorPriv_dispatch_tree[155] = {
|
||||
/* tree depth = 12 */
|
||||
static const int_fast16_t VendorPriv_dispatch_tree[152] = {
|
||||
/* [0] -> opcode range [0, 131072], node depth 1 */
|
||||
2,
|
||||
5,
|
||||
|
|
@ -1474,17 +1474,12 @@ static const int_fast16_t VendorPriv_dispatch_tree[155] = {
|
|||
|
||||
/* [149] -> opcode range [65536, 65568], node depth 12 */
|
||||
1,
|
||||
152,
|
||||
EMPTY_LEAF,
|
||||
|
||||
/* [152] -> opcode range [65536, 65552], node depth 13 */
|
||||
1,
|
||||
LEAF(88),
|
||||
EMPTY_LEAF,
|
||||
|
||||
};
|
||||
|
||||
static const void *VendorPriv_function_table[96][2] = {
|
||||
static const void *VendorPriv_function_table[104][2] = {
|
||||
/* [ 0] = 0 */ {NULL, NULL},
|
||||
/* [ 1] = 1 */ {__glXDisp_GetConvolutionFilterEXT, __glXDispSwap_GetConvolutionFilterEXT},
|
||||
/* [ 2] = 2 */ {__glXDisp_GetConvolutionParameterfvEXT, __glXDispSwap_GetConvolutionParameterfvEXT},
|
||||
|
|
@ -1581,6 +1576,14 @@ static const void *VendorPriv_function_table[96][2] = {
|
|||
/* [ 93] = 65541 */ {__glXDisp_CreateContextWithConfigSGIX, __glXDispSwap_CreateContextWithConfigSGIX},
|
||||
/* [ 94] = 65542 */ {__glXDisp_CreateGLXPixmapWithConfigSGIX, __glXDispSwap_CreateGLXPixmapWithConfigSGIX},
|
||||
/* [ 95] = 65543 */ {NULL, NULL},
|
||||
/* [ 96] = 65544 */ {NULL, NULL},
|
||||
/* [ 97] = 65545 */ {NULL, NULL},
|
||||
/* [ 98] = 65546 */ {__glXDisp_GetDrawableAttributesSGIX, __glXDispSwap_GetDrawableAttributesSGIX},
|
||||
/* [ 99] = 65547 */ {NULL, NULL},
|
||||
/* [ 100] = 65548 */ {NULL, NULL},
|
||||
/* [ 101] = 65549 */ {NULL, NULL},
|
||||
/* [ 102] = 65550 */ {NULL, NULL},
|
||||
/* [ 103] = 65551 */ {NULL, NULL},
|
||||
};
|
||||
|
||||
const struct __glXDispatchInfo VendorPriv_dispatch_info = {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
/*
|
||||
** License Applicability. Except to the extent portions of this file are
|
||||
** made subject to an alternative license as permitted in the SGI Free
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
/*
|
||||
** License Applicability. Except to the extent portions of this file are
|
||||
** made subject to an alternative license as permitted in the SGI Free
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
/*
|
||||
** License Applicability. Except to the extent portions of this file are
|
||||
** made subject to an alternative license as permitted in the SGI Free
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
/*
|
||||
** License Applicability. Except to the extent portions of this file are
|
||||
** made subject to an alternative license as permitted in the SGI Free
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ nodist_libmain_la_SOURCES = accum.c \
|
|||
matrix.c \
|
||||
mipmap.c \
|
||||
mm.c \
|
||||
occlude.c \
|
||||
pixel.c \
|
||||
points.c \
|
||||
polygon.c \
|
||||
queryobj.c \
|
||||
rastpos.c \
|
||||
rbadaptors.c \
|
||||
renderbuffer.c \
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ nodist_libslang_la_SOURCES = slang_builtin.c \
|
|||
slang_library_noise.c \
|
||||
slang_link.c \
|
||||
slang_log.c \
|
||||
slang_mem.c \
|
||||
slang_preprocess.c \
|
||||
slang_print.c \
|
||||
slang_simplify.c \
|
||||
|
|
|
|||
12
Makefile.am
12
Makefile.am
|
|
@ -69,7 +69,17 @@ aclocal_DATA = xorg-server.m4
|
|||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = xorg-server.pc
|
||||
|
||||
EXTRA_DIST = xorg-server.pc.in xorg-server.m4
|
||||
EXTRA_DIST = xorg-server.pc.in xorg-server.m4 ChangeLog autogen.sh
|
||||
|
||||
MAINTAINERCLEANFILES=ChangeLog
|
||||
|
||||
.PHONY: ChangeLog
|
||||
|
||||
ChangeLog:
|
||||
(GIT_DIR=$(top_srcdir)/.git git-log > .changelog.tmp && mv .changelog.tmp ChangeLog; rm -f .changelog.tmp) || \
|
||||
(touch ChangeLog; echo 'git directory not found: installing possibly empty changelog.' >&2)
|
||||
|
||||
dist-hook: ChangeLog
|
||||
|
||||
DIST_SUBDIRS = \
|
||||
doc \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
/****************************************************************************
|
||||
Copyright 1987, 1988, 1989, 1990, 1991, 1992 by
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
/****************************************************************************
|
||||
Copyright 1987, 1988, 1989, 1990, 1991 by Digital Equipment Corp., Maynard, MA
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ MODULE_SRCS = \
|
|||
xcmisc.c
|
||||
|
||||
# Extra configuration files ship with some extensions
|
||||
SERVERCONFIGdir = $(libdir)/xserver
|
||||
SERVERCONFIG_DATA =
|
||||
|
||||
# Optional sources included if extension enabled by configure.ac rules
|
||||
|
|
@ -88,7 +87,7 @@ endif
|
|||
XCALIBRATE_SRCS = xcalibrate.c
|
||||
if XCALIBRATE
|
||||
BUILTIN_SRCS += $(XCALIBRATE_SRCS)
|
||||
# XCalibrare needs tslib
|
||||
# XCalibrate needs tslib
|
||||
endif
|
||||
|
||||
# X EVent Interception Extension: allows accessibility helpers & composite
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@
|
|||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Id: fontcache.c,v 1.12 1999/01/31 13:47:45 akiyama Exp $
|
||||
*/
|
||||
|
||||
/* THIS IS NOT AN X CONSORTIUM STANDARD */
|
||||
|
|
|
|||
|
|
@ -329,10 +329,6 @@ bufCreateBuffer(pScreen, pWin, bufferNum)
|
|||
pBuffer->firstChild = NULL;
|
||||
pBuffer->lastChild = NULL;
|
||||
|
||||
/* XXX - Worry about backingstore later */
|
||||
pBuffer->backStorage = NULL;
|
||||
pBuffer->backingStore = NotUseful;
|
||||
|
||||
/* XXX - Need to call pScreen->CreateWindow for tile/stipples
|
||||
* or should I just copy the devPrivates?
|
||||
*/
|
||||
|
|
@ -505,18 +501,6 @@ bufClearImageBufferArea(pMBBuffer, x,y, w,h, generateExposures)
|
|||
|
||||
pScreen = pBuffer->drawable.pScreen;
|
||||
REGION_INIT(pScreen, ®, &box, 1);
|
||||
if (pBuffer->backStorage)
|
||||
{
|
||||
/*
|
||||
* If the window has backing-store on, call through the
|
||||
* ClearToBackground vector to handle the special semantics
|
||||
* (i.e. things backing store is to be cleared out and
|
||||
* an Expose event is to be generated for those areas in backing
|
||||
* store if generateExposures is TRUE).
|
||||
*/
|
||||
pBSReg = (* pScreen->ClearBackingStore)(pBuffer, x, y, w, h,
|
||||
generateExposures);
|
||||
}
|
||||
|
||||
REGION_INTERSECT(pScreen, ®, ®, &pBuffer->clipList);
|
||||
if (pBuffer->backgroundState != None)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* $TOG: panoramiX.h /main/4 1998/03/17 06:51:02 kaleb $ */
|
||||
/*****************************************************************
|
||||
|
||||
Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ 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.
|
||||
********************************************************/
|
||||
/* $XFree86$ */
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
|
|
|
|||
|
|
@ -1285,11 +1285,7 @@ SecurityFreePropertyAccessList(void)
|
|||
}
|
||||
} /* SecurityFreePropertyAccessList */
|
||||
|
||||
#ifndef __UNIXOS2__
|
||||
#define SecurityIsWhitespace(c) ( (c == ' ') || (c == '\t') || (c == '\n') )
|
||||
#else
|
||||
#define SecurityIsWhitespace(c) ( (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') )
|
||||
#endif
|
||||
|
||||
static char *
|
||||
SecuritySkipWhitespace(
|
||||
|
|
@ -1567,11 +1563,7 @@ SecurityLoadPropertyAccessList(void)
|
|||
if (!SecurityPolicyFile)
|
||||
return;
|
||||
|
||||
#ifndef __UNIXOS2__
|
||||
f = fopen(SecurityPolicyFile, "r");
|
||||
#else
|
||||
f = fopen((char*)__XOS2RedirRoot(SecurityPolicyFile), "r");
|
||||
#endif
|
||||
if (!f)
|
||||
{
|
||||
ErrorF("error opening security policy file %s\n",
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ in this Software without prior written authorization from The Open Group.
|
|||
#include "gcstruct.h"
|
||||
#include "extnsionst.h"
|
||||
#include "servermd.h"
|
||||
#include "shmint.h"
|
||||
#define _XSHM_SERVER_
|
||||
#include <X11/extensions/shmstr.h>
|
||||
#include <X11/Xfuncproto.h>
|
||||
|
|
@ -78,7 +79,6 @@ typedef struct _ShmDesc {
|
|||
} ShmDescRec, *ShmDescPtr;
|
||||
|
||||
static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
|
||||
static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
|
||||
static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
|
||||
static int ShmDetachSegment(
|
||||
pointer /* value */,
|
||||
|
|
@ -154,7 +154,7 @@ static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
|
|||
}
|
||||
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__)
|
||||
#include <sys/signal.h>
|
||||
|
||||
static Bool badSysCall = FALSE;
|
||||
|
|
@ -510,7 +510,7 @@ miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
|
|||
(*pmap->drawable.pScreen->DestroyPixmap)(pmap);
|
||||
}
|
||||
|
||||
static void
|
||||
_X_EXPORT void
|
||||
fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
|
||||
DrawablePtr dst;
|
||||
GCPtr pGC;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright © 2003 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
@ -38,6 +36,9 @@ ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs);
|
|||
void
|
||||
ShmSetPixmapFormat(ScreenPtr pScreen, int format);
|
||||
|
||||
void
|
||||
fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
|
||||
|
||||
void
|
||||
ShmRegisterFbFuncs(ScreenPtr pScreen);
|
||||
|
||||
|
|
|
|||
120
Xext/sync.c
120
Xext/sync.c
|
|
@ -243,6 +243,11 @@ SyncInitServerTime(
|
|||
void
|
||||
);
|
||||
|
||||
static void
|
||||
SyncInitIdleTime(
|
||||
void
|
||||
);
|
||||
|
||||
static void
|
||||
SyncResetProc(
|
||||
ExtensionEntry * /* extEntry */
|
||||
|
|
@ -2400,6 +2405,7 @@ SyncExtensionInit(INITARGS)
|
|||
* because there is always a servertime counter.
|
||||
*/
|
||||
SyncInitServerTime();
|
||||
SyncInitIdleTime();
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Sync Extension %d.%d\n",
|
||||
|
|
@ -2520,3 +2526,117 @@ SyncInitServerTime(void)
|
|||
ServertimeQueryValue, ServertimeBracketValues);
|
||||
pnext_time = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* IDLETIME implementation
|
||||
*/
|
||||
|
||||
static pointer IdleTimeCounter;
|
||||
static XSyncValue *pIdleTimeValueLess;
|
||||
static XSyncValue *pIdleTimeValueGreater;
|
||||
|
||||
static void
|
||||
IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return)
|
||||
{
|
||||
CARD32 idle = GetTimeInMillis() - lastDeviceEventTime.milliseconds;
|
||||
XSyncIntsToValue (pValue_return, idle, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
IdleTimeBlockHandler (pointer env,
|
||||
struct timeval **wt,
|
||||
pointer LastSelectMask)
|
||||
{
|
||||
XSyncValue idle;
|
||||
|
||||
if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
|
||||
return;
|
||||
|
||||
IdleTimeQueryValue (NULL, &idle);
|
||||
|
||||
if (pIdleTimeValueLess &&
|
||||
XSyncValueLessOrEqual (idle, *pIdleTimeValueLess))
|
||||
{
|
||||
AdjustWaitForDelay (wt, 0);
|
||||
}
|
||||
else if (pIdleTimeValueGreater)
|
||||
{
|
||||
unsigned long timeout = 0;
|
||||
|
||||
if (XSyncValueLessThan (idle, *pIdleTimeValueGreater))
|
||||
{
|
||||
XSyncValue value;
|
||||
Bool overflow;
|
||||
|
||||
XSyncValueSubtract (&value, *pIdleTimeValueGreater,
|
||||
idle, &overflow);
|
||||
timeout = XSyncValueLow32 (value);
|
||||
}
|
||||
|
||||
AdjustWaitForDelay (wt, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
IdleTimeWakeupHandler (pointer env,
|
||||
int rc,
|
||||
pointer LastSelectMask)
|
||||
{
|
||||
XSyncValue idle;
|
||||
|
||||
if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
|
||||
return;
|
||||
|
||||
IdleTimeQueryValue (NULL, &idle);
|
||||
|
||||
if ((pIdleTimeValueGreater &&
|
||||
XSyncValueGreaterOrEqual (idle, *pIdleTimeValueGreater)) ||
|
||||
(pIdleTimeValueLess &&
|
||||
XSyncValueLessOrEqual (idle, *pIdleTimeValueLess)))
|
||||
{
|
||||
SyncChangeCounter (IdleTimeCounter, idle);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
IdleTimeBracketValues (pointer pCounter,
|
||||
CARD64 *pbracket_less,
|
||||
CARD64 *pbracket_greater)
|
||||
{
|
||||
Bool registered = (pIdleTimeValueLess || pIdleTimeValueGreater);
|
||||
|
||||
if (registered && !pbracket_less && !pbracket_greater)
|
||||
{
|
||||
RemoveBlockAndWakeupHandlers(IdleTimeBlockHandler,
|
||||
IdleTimeWakeupHandler,
|
||||
NULL);
|
||||
}
|
||||
else if (!registered && (pbracket_less || pbracket_greater))
|
||||
{
|
||||
RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler,
|
||||
IdleTimeWakeupHandler,
|
||||
NULL);
|
||||
}
|
||||
|
||||
pIdleTimeValueGreater = pbracket_greater;
|
||||
pIdleTimeValueLess = pbracket_less;
|
||||
}
|
||||
|
||||
static void
|
||||
SyncInitIdleTime (void)
|
||||
{
|
||||
CARD64 resolution;
|
||||
XSyncValue idle;
|
||||
|
||||
IdleTimeQueryValue (NULL, &idle);
|
||||
XSyncIntToValue (&resolution, 4);
|
||||
|
||||
IdleTimeCounter = SyncCreateSystemCounter ("IDLETIME", idle, resolution,
|
||||
XSyncCounterUnrestricted,
|
||||
IdleTimeQueryValue,
|
||||
IdleTimeBracketValues);
|
||||
|
||||
pIdleTimeValueLess = pIdleTimeValueGreater = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id: xcalibrate.c,v 3.1 2004/06/02 20:49:50 pb Exp $
|
||||
*
|
||||
* Copyright © 2003 Philip Blundell
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ static unsigned int pagesize;
|
|||
|
||||
static Bool badSysCall = FALSE;
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__)
|
||||
|
||||
#include <sys/signal.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1 @@
|
|||
/* $XFree86$ */
|
||||
|
||||
extern void XineramifyXv(void);
|
||||
|
|
|
|||
|
|
@ -248,7 +248,9 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr other, int count)
|
|||
SetMaskForEvent(Motion_Filter(b), DeviceMotionNotify);
|
||||
if (!grab)
|
||||
if (CheckDeviceGrabs(other, xE, 0, count))
|
||||
return;
|
||||
/* if a passive grab was activated, the event has been sent
|
||||
* already */
|
||||
return;
|
||||
|
||||
} else if (xE->u.u.type == DeviceButtonRelease) {
|
||||
if (!b)
|
||||
|
|
@ -258,7 +260,7 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr other, int count)
|
|||
*kptr &= ~bit;
|
||||
if (other->valuator)
|
||||
other->valuator->motionHintWindow = NullWindow;
|
||||
if (!--b->buttonsDown)
|
||||
if (b->buttonsDown >= 1 && !--b->buttonsDown)
|
||||
b->motionMask = 0;
|
||||
xE->u.u.detail = b->map[key];
|
||||
if (xE->u.u.detail == 0)
|
||||
|
|
|
|||
|
|
@ -98,7 +98,6 @@ int
|
|||
ProcXOpenDevice(ClientPtr client)
|
||||
{
|
||||
xInputClassInfo evbase[numInputClasses];
|
||||
Bool enableit = FALSE;
|
||||
int j = 0;
|
||||
int status = Success;
|
||||
xOpenDeviceReply rep;
|
||||
|
|
@ -121,7 +120,6 @@ ProcXOpenDevice(ClientPtr client)
|
|||
SendErrorToClient(client, IReqCode, X_OpenDevice, 0, BadDevice);
|
||||
return Success;
|
||||
}
|
||||
enableit = TRUE;
|
||||
}
|
||||
|
||||
OpenInputDevice(dev, client, &status);
|
||||
|
|
@ -129,8 +127,6 @@ ProcXOpenDevice(ClientPtr client)
|
|||
SendErrorToClient(client, IReqCode, X_OpenDevice, 0, status);
|
||||
return Success;
|
||||
}
|
||||
if (enableit && dev->inited && dev->startup)
|
||||
(void)EnableDevice(dev);
|
||||
|
||||
rep.repType = X_Reply;
|
||||
rep.RepType = X_OpenDevice;
|
||||
|
|
|
|||
33
acinclude.m4
33
acinclude.m4
|
|
@ -1,3 +1,36 @@
|
|||
##### http://autoconf-archive.cryp.to/ac_define_dir.html
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AC_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro sets VARNAME to the expansion of the DIR variable,
|
||||
# taking care of fixing up ${prefix} and such.
|
||||
#
|
||||
# VARNAME is then offered as both an output variable and a C
|
||||
# preprocessor symbol.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# AC_DEFINE_DIR([DATADIR], [datadir], [Where data are placed to.])
|
||||
#
|
||||
# LAST MODIFICATION
|
||||
#
|
||||
# 2006-10-13
|
||||
#
|
||||
# COPYLEFT
|
||||
#
|
||||
# Copyright (c) 2006 Stepan Kasal <kasal@ucw.cz>
|
||||
# Copyright (c) 2006 Andreas Schwab <schwab@suse.de>
|
||||
# Copyright (c) 2006 Guido U. Draheim <guidod@gmx.de>
|
||||
# Copyright (c) 2006 Alexandre Oliva
|
||||
#
|
||||
# Copying and distribution of this file, with or without
|
||||
# modification, are permitted in any medium without royalty provided
|
||||
# the copyright notice and this notice are preserved.
|
||||
|
||||
AC_DEFUN([AC_DEFINE_DIR], [
|
||||
prefix_NONE=
|
||||
exec_prefix_NONE=
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ libafb_la_SOURCES = afbgc.c afbwindow.c afbfont.c afbfillrct.c afbpntwin.c afbpi
|
|||
afbimage.c afbline.c afbbres.c afbhrzvert.c afbbresd.c afbpushpxl.c afbply1rct.c \
|
||||
afbzerarc.c afbfillarc.c afbfillsp.c afbsetsp.c afbscrinit.c afbplygblt.c \
|
||||
afbclip.c afbgetsp.c afbpolypnt.c afbbitblt.c afbcmap.c afbimggblt.c afbpntarea.c \
|
||||
afbmisc.c afbbstore.c afbtegblt.c $(libafb_gen_sources)
|
||||
afbmisc.c afbtegblt.c $(libafb_gen_sources)
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/mfb -I$(top_srcdir)/hw/xfree86/os-support
|
||||
|
||||
|
|
|
|||
16
afb/afb.h
16
afb/afb.h
|
|
@ -182,23 +182,7 @@ extern void afbBresD(
|
|||
unsigned char * /*rrops*/,
|
||||
unsigned char * /*bgrrops*/
|
||||
);
|
||||
/* afbbstore.c */
|
||||
|
||||
extern void afbSaveAreas(
|
||||
PixmapPtr /*pPixmap*/,
|
||||
RegionPtr /*prgnSave*/,
|
||||
int /*xorg*/,
|
||||
int /*yorg*/,
|
||||
WindowPtr /*pWin*/
|
||||
);
|
||||
|
||||
extern void afbRestoreAreas(
|
||||
PixmapPtr /*pPixmap*/,
|
||||
RegionPtr /*prgnRestore*/,
|
||||
int /*xorg*/,
|
||||
int /*yorg*/,
|
||||
WindowPtr /*pWin*/
|
||||
);
|
||||
/* afbclip.c */
|
||||
|
||||
extern RegionPtr afbPixmapToRegion(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
|
||||
/***********************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
/***********************************************************
|
||||
|
||||
Copyright (c) 1987 X Consortium
|
||||
|
|
|
|||
155
afb/afbbstore.c
155
afb/afbbstore.c
|
|
@ -1,155 +0,0 @@
|
|||
/* $XFree86$ */
|
||||
/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
|
||||
/*
|
||||
|
||||
Copyright (c) 1987 X Consortium
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the X Consortium shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the X Consortium.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "afb.h"
|
||||
#include <X11/X.h>
|
||||
#include "mibstore.h"
|
||||
#include "regionstr.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "windowstr.h"
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* afbSaveAreas --
|
||||
* Function called by miSaveAreas to actually fetch the areas to be
|
||||
* saved into the backing pixmap. This is very simple to do, since
|
||||
* afbDoBitblt is designed for this very thing. The region to save is
|
||||
* already destination-relative and we're given the offset to the
|
||||
* window origin, so we have only to create an array of points of the
|
||||
* u.l. corners of the boxes in the region translated to the screen
|
||||
* coordinate system and fetch the screen pixmap out of its devPrivate
|
||||
* field....
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side Effects:
|
||||
* Data are copied from the screen into the pixmap.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
afbSaveAreas(pPixmap, prgnSave, xorg, yorg, pWin)
|
||||
PixmapPtr pPixmap; /* Backing pixmap */
|
||||
RegionPtr prgnSave; /* Region to save (pixmap-relative) */
|
||||
int xorg; /* X origin of region */
|
||||
int yorg; /* Y origin of region */
|
||||
WindowPtr pWin;
|
||||
{
|
||||
register DDXPointPtr pPt;
|
||||
DDXPointPtr pPtsInit;
|
||||
register BoxPtr pBox;
|
||||
register int numRects;
|
||||
|
||||
numRects = REGION_NUM_RECTS(prgnSave);
|
||||
pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(numRects * sizeof(DDXPointRec));
|
||||
if (!pPtsInit)
|
||||
return;
|
||||
|
||||
pBox = REGION_RECTS(prgnSave);
|
||||
pPt = pPtsInit;
|
||||
while (numRects--) {
|
||||
pPt->x = pBox->x1 + xorg;
|
||||
pPt->y = pBox->y1 + yorg;
|
||||
pPt++;
|
||||
pBox++;
|
||||
}
|
||||
|
||||
afbDoBitblt((DrawablePtr)pPixmap->drawable.pScreen->devPrivates[afbScreenPrivateIndex].ptr,
|
||||
(DrawablePtr)pPixmap,
|
||||
GXcopy,
|
||||
prgnSave,
|
||||
pPtsInit, wBackingBitPlanes (pWin));
|
||||
|
||||
DEALLOCATE_LOCAL(pPtsInit);
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* afbRestoreAreas --
|
||||
* Function called by miRestoreAreas to actually fetch the areas to be
|
||||
* restored from the backing pixmap. This is very simple to do, since
|
||||
* afbDoBitblt is designed for this very thing. The region to restore is
|
||||
* already destination-relative and we're given the offset to the
|
||||
* window origin, so we have only to create an array of points of the
|
||||
* u.l. corners of the boxes in the region translated to the pixmap
|
||||
* coordinate system and fetch the screen pixmap out of its devPrivate
|
||||
* field....
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side Effects:
|
||||
* Data are copied from the pixmap into the screen.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
afbRestoreAreas(pPixmap, prgnRestore, xorg, yorg, pWin)
|
||||
PixmapPtr pPixmap; /* Backing pixmap */
|
||||
RegionPtr prgnRestore; /* Region to restore (screen-relative)*/
|
||||
int xorg; /* X origin of window */
|
||||
int yorg; /* Y origin of window */
|
||||
WindowPtr pWin;
|
||||
{
|
||||
register DDXPointPtr pPt;
|
||||
DDXPointPtr pPtsInit;
|
||||
register BoxPtr pBox;
|
||||
register int numRects;
|
||||
|
||||
numRects = REGION_NUM_RECTS(prgnRestore);
|
||||
pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(numRects*sizeof(DDXPointRec));
|
||||
if (!pPtsInit)
|
||||
return;
|
||||
|
||||
pBox = REGION_RECTS(prgnRestore);
|
||||
pPt = pPtsInit;
|
||||
while (numRects--) {
|
||||
pPt->x = pBox->x1 - xorg;
|
||||
pPt->y = pBox->y1 - yorg;
|
||||
pPt++;
|
||||
pBox++;
|
||||
}
|
||||
|
||||
afbDoBitblt((DrawablePtr)pPixmap,
|
||||
(DrawablePtr)pPixmap->drawable.pScreen->devPrivates[afbScreenPrivateIndex].ptr,
|
||||
GXcopy,
|
||||
prgnRestore,
|
||||
pPtsInit, wBackingBitPlanes (pWin));
|
||||
|
||||
DEALLOCATE_LOCAL(pPtsInit);
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
/*
|
||||
|
||||
Copyright (c) 1987 X Consortium
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
/***********************************************************
|
||||
|
||||
Copyright (c) 1987 X Consortium
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
|
||||
/***********************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -77,14 +77,6 @@ int afbScreenPrivateIndex;
|
|||
|
||||
static unsigned long afbGeneration = 0;
|
||||
|
||||
static BSFuncRec afbBSFuncRec = {
|
||||
afbSaveAreas,
|
||||
afbRestoreAreas,
|
||||
(BackingStoreSetClipmaskRgnProcPtr) 0,
|
||||
(BackingStoreGetImagePixmapProcPtr) 0,
|
||||
(BackingStoreGetSpansPixmapProcPtr) 0,
|
||||
};
|
||||
|
||||
static Bool
|
||||
afbCloseScreen(int index, ScreenPtr pScreen)
|
||||
{
|
||||
|
|
@ -231,7 +223,6 @@ afbScreenInit(register ScreenPtr pScreen, pointer pbits, int xsize, int ysize, i
|
|||
|
||||
pScreen->CloseScreen = afbCloseScreen;
|
||||
pScreen->CreateScreenResources = afbCreateScreenResources;
|
||||
pScreen->BackingStoreFuncs = afbBSFuncRec;
|
||||
|
||||
pScreen->devPrivates[afbScreenPrivateIndex].ptr = pScreen->devPrivate;
|
||||
pScreen->devPrivate = oldDevPrivate;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ libcfb_common_sources = $(top_srcdir)/cfb/cfbgc.c $(top_srcdir)/cfb/cfbrrop.c \
|
|||
$(top_srcdir)/cfb/cfballpriv.c $(top_srcdir)/cfb/cfbgetsp.c \
|
||||
$(top_srcdir)/cfb/cfbfillrct.c $(top_srcdir)/cfb/cfbigblt8.c \
|
||||
$(top_srcdir)/cfb/cfbglblt8.c $(top_srcdir)/cfb/cfbtegblt.c \
|
||||
$(top_srcdir)/cfb/cfbbstore.c $(top_srcdir)/cfb/cfbpolypnt.c \
|
||||
$(top_srcdir)/cfb/cfbpolypnt.c \
|
||||
$(top_srcdir)/cfb/cfbbres.c $(top_srcdir)/cfb/cfbline.c \
|
||||
$(top_srcdir)/cfb/cfbhrzvert.c $(top_srcdir)/cfb/cfbbresd.c \
|
||||
$(top_srcdir)/cfb/cfbimage.c $(top_srcdir)/cfb/cfbcppl.c \
|
||||
|
|
|
|||
16
cfb/cfb.h
16
cfb/cfb.h
|
|
@ -486,23 +486,7 @@ extern void cfbBresD(
|
|||
int /*e2*/,
|
||||
int /*len*/
|
||||
);
|
||||
/* cfbbstore.c */
|
||||
|
||||
extern void cfbSaveAreas(
|
||||
PixmapPtr /*pPixmap*/,
|
||||
RegionPtr /*prgnSave*/,
|
||||
int /*xorg*/,
|
||||
int /*yorg*/,
|
||||
WindowPtr /*pWin*/
|
||||
);
|
||||
|
||||
extern void cfbRestoreAreas(
|
||||
PixmapPtr /*pPixmap*/,
|
||||
RegionPtr /*prgnRestore*/,
|
||||
int /*xorg*/,
|
||||
int /*yorg*/,
|
||||
WindowPtr /*pWin*/
|
||||
);
|
||||
/* cfbcmap.c */
|
||||
|
||||
#ifndef CFB_PROTOTYPES_ONLY
|
||||
|
|
|
|||
143
cfb/cfbbstore.c
143
cfb/cfbbstore.c
|
|
@ -1,143 +0,0 @@
|
|||
/*-
|
||||
* cfbbstore.c --
|
||||
* Functions required by the backing-store implementation in MI.
|
||||
*
|
||||
* Copyright (c) 1987 by the Regents of the University of California
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies. The University of California
|
||||
* makes no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without
|
||||
* express or implied warranty.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "cfb.h"
|
||||
#include <X11/X.h>
|
||||
#include "mibstore.h"
|
||||
#include "regionstr.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "windowstr.h"
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* cfbSaveAreas --
|
||||
* Function called by miSaveAreas to actually fetch the areas to be
|
||||
* saved into the backing pixmap. This is very simple to do, since
|
||||
* cfbDoBitblt is designed for this very thing. The region to save is
|
||||
* already destination-relative and we're given the offset to the
|
||||
* window origin, so we have only to create an array of points of the
|
||||
* u.l. corners of the boxes in the region translated to the screen
|
||||
* coordinate system and fetch the screen pixmap out of its devPrivate
|
||||
* field....
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side Effects:
|
||||
* Data are copied from the screen into the pixmap.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
cfbSaveAreas(pPixmap, prgnSave, xorg, yorg, pWin)
|
||||
PixmapPtr pPixmap; /* Backing pixmap */
|
||||
RegionPtr prgnSave; /* Region to save (pixmap-relative) */
|
||||
int xorg; /* X origin of region */
|
||||
int yorg; /* Y origin of region */
|
||||
WindowPtr pWin;
|
||||
{
|
||||
register DDXPointPtr pPt;
|
||||
DDXPointPtr pPtsInit;
|
||||
register BoxPtr pBox;
|
||||
register int i;
|
||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||
PixmapPtr pScrPix;
|
||||
|
||||
i = REGION_NUM_RECTS(prgnSave);
|
||||
pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i * sizeof(DDXPointRec));
|
||||
if (!pPtsInit)
|
||||
return;
|
||||
|
||||
pBox = REGION_RECTS(prgnSave);
|
||||
pPt = pPtsInit;
|
||||
while (--i >= 0) {
|
||||
pPt->x = pBox->x1 + xorg;
|
||||
pPt->y = pBox->y1 + yorg;
|
||||
pPt++;
|
||||
pBox++;
|
||||
}
|
||||
|
||||
pScrPix = (*pScreen->GetWindowPixmap)(pWin);
|
||||
|
||||
|
||||
cfbDoBitbltCopy((DrawablePtr) pScrPix, (DrawablePtr)pPixmap,
|
||||
GXcopy, prgnSave, pPtsInit, ~0L);
|
||||
|
||||
DEALLOCATE_LOCAL (pPtsInit);
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* cfbRestoreAreas --
|
||||
* Function called by miRestoreAreas to actually fetch the areas to be
|
||||
* restored from the backing pixmap. This is very simple to do, since
|
||||
* cfbDoBitblt is designed for this very thing. The region to restore is
|
||||
* already destination-relative and we're given the offset to the
|
||||
* window origin, so we have only to create an array of points of the
|
||||
* u.l. corners of the boxes in the region translated to the pixmap
|
||||
* coordinate system and fetch the screen pixmap out of its devPrivate
|
||||
* field....
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side Effects:
|
||||
* Data are copied from the pixmap into the screen.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
cfbRestoreAreas(pPixmap, prgnRestore, xorg, yorg, pWin)
|
||||
PixmapPtr pPixmap; /* Backing pixmap */
|
||||
RegionPtr prgnRestore; /* Region to restore (screen-relative)*/
|
||||
int xorg; /* X origin of window */
|
||||
int yorg; /* Y origin of window */
|
||||
WindowPtr pWin;
|
||||
{
|
||||
register DDXPointPtr pPt;
|
||||
DDXPointPtr pPtsInit;
|
||||
register BoxPtr pBox;
|
||||
register int i;
|
||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||
PixmapPtr pScrPix;
|
||||
|
||||
i = REGION_NUM_RECTS(prgnRestore);
|
||||
pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i*sizeof(DDXPointRec));
|
||||
if (!pPtsInit)
|
||||
return;
|
||||
|
||||
pBox = REGION_RECTS(prgnRestore);
|
||||
pPt = pPtsInit;
|
||||
while (--i >= 0) {
|
||||
pPt->x = pBox->x1 - xorg;
|
||||
pPt->y = pBox->y1 - yorg;
|
||||
pPt++;
|
||||
pBox++;
|
||||
}
|
||||
|
||||
pScrPix = (*pScreen->GetWindowPixmap)(pWin);
|
||||
|
||||
cfbDoBitbltCopy((DrawablePtr)pPixmap, (DrawablePtr) pScrPix,
|
||||
GXcopy, prgnRestore, pPtsInit, ~0L);
|
||||
|
||||
DEALLOCATE_LOCAL (pPtsInit);
|
||||
}
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $TOG: cfb8cppl.c /main/16 1998/02/09 14:04:13 kaleb $
|
||||
*
|
||||
Copyright 1990, 1998 The Open Group
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
|
|||
|
|
@ -46,14 +46,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "cfbmskbits.h"
|
||||
#include "mibstore.h"
|
||||
|
||||
BSFuncRec cfbBSFuncRec = {
|
||||
cfbSaveAreas,
|
||||
cfbRestoreAreas,
|
||||
(BackingStoreSetClipmaskRgnProcPtr) 0,
|
||||
(BackingStoreGetImagePixmapProcPtr) 0,
|
||||
(BackingStoreGetSpansPixmapProcPtr) 0,
|
||||
};
|
||||
|
||||
Bool
|
||||
cfbCloseScreen (index, pScreen)
|
||||
int index;
|
||||
|
|
@ -184,7 +176,6 @@ cfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width)
|
|||
pScreen->devPrivates[cfbScreenPrivateIndex].ptr = pScreen->devPrivate;
|
||||
pScreen->devPrivate = oldDevPrivate;
|
||||
#endif
|
||||
pScreen->BackingStoreFuncs = cfbBSFuncRec;
|
||||
pScreen->GetScreenPixmap = cfbGetScreenPixmap;
|
||||
pScreen->SetScreenPixmap = cfbSetScreenPixmap;
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright © 2006 Sun Microsystems
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
@ -206,7 +204,7 @@ compFreeClientWindow (WindowPtr pWin, XID id)
|
|||
EnableMapUnmapEvents (pWin);
|
||||
}
|
||||
|
||||
if (pWin->redirectDraw)
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
compFreePixmap (pWin);
|
||||
|
||||
if (cw->damage)
|
||||
|
|
@ -218,10 +216,11 @@ compFreeClientWindow (WindowPtr pWin, XID id)
|
|||
xfree (cw);
|
||||
}
|
||||
else if (cw->update == CompositeRedirectAutomatic &&
|
||||
!cw->damageRegistered && pWin->redirectDraw)
|
||||
!cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
DamageRegister (&pWin->drawable, cw->damage);
|
||||
cw->damageRegistered = TRUE;
|
||||
pWin->redirectDraw = RedirectDrawAutomatic;
|
||||
DamageDamageRegion (&pWin->drawable, &pWin->borderSize);
|
||||
}
|
||||
if (wasMapped && !pWin->mapped)
|
||||
|
|
@ -462,7 +461,6 @@ compNewPixmap (WindowPtr pWin, int x, int y, int w, int h)
|
|||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
WindowPtr pParent = pWin->parent;
|
||||
PixmapPtr pPixmap;
|
||||
GCPtr pGC;
|
||||
|
||||
pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth);
|
||||
|
||||
|
|
@ -472,25 +470,63 @@ compNewPixmap (WindowPtr pWin, int x, int y, int w, int h)
|
|||
pPixmap->screen_x = x;
|
||||
pPixmap->screen_y = y;
|
||||
|
||||
pGC = GetScratchGC (pWin->drawable.depth, pScreen);
|
||||
|
||||
/*
|
||||
* Copy bits from the parent into the new pixmap so that it will
|
||||
* have "reasonable" contents in case for background None areas.
|
||||
*/
|
||||
if (pGC)
|
||||
if (pParent->drawable.depth == pWin->drawable.depth)
|
||||
{
|
||||
XID val = IncludeInferiors;
|
||||
GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen);
|
||||
|
||||
ValidateGC(&pPixmap->drawable, pGC);
|
||||
dixChangeGC (serverClient, pGC, GCSubwindowMode, &val, NULL);
|
||||
(*pGC->ops->CopyArea) (&pParent->drawable,
|
||||
&pPixmap->drawable,
|
||||
pGC,
|
||||
x - pParent->drawable.x,
|
||||
y - pParent->drawable.y,
|
||||
w, h, 0, 0);
|
||||
FreeScratchGC (pGC);
|
||||
/*
|
||||
* Copy bits from the parent into the new pixmap so that it will
|
||||
* have "reasonable" contents in case for background None areas.
|
||||
*/
|
||||
if (pGC)
|
||||
{
|
||||
XID val = IncludeInferiors;
|
||||
|
||||
ValidateGC(&pPixmap->drawable, pGC);
|
||||
dixChangeGC (serverClient, pGC, GCSubwindowMode, &val, NULL);
|
||||
(*pGC->ops->CopyArea) (&pParent->drawable,
|
||||
&pPixmap->drawable,
|
||||
pGC,
|
||||
x - pParent->drawable.x,
|
||||
y - pParent->drawable.y,
|
||||
w, h, 0, 0);
|
||||
FreeScratchGC (pGC);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PictFormatPtr pSrcFormat = compWindowFormat (pParent);
|
||||
PictFormatPtr pDstFormat = compWindowFormat (pWin);
|
||||
XID inferiors = IncludeInferiors;
|
||||
int error;
|
||||
|
||||
PicturePtr pSrcPicture = CreatePicture (None,
|
||||
&pParent->drawable,
|
||||
pSrcFormat,
|
||||
CPSubwindowMode,
|
||||
&inferiors,
|
||||
serverClient, &error);
|
||||
|
||||
PicturePtr pDstPicture = CreatePicture (None,
|
||||
&pPixmap->drawable,
|
||||
pDstFormat,
|
||||
0, 0,
|
||||
serverClient, &error);
|
||||
|
||||
if (pSrcPicture && pDstPicture)
|
||||
{
|
||||
CompositePicture (PictOpSrc,
|
||||
pSrcPicture,
|
||||
NULL,
|
||||
pDstPicture,
|
||||
x - pParent->drawable.x,
|
||||
y - pParent->drawable.y,
|
||||
0, 0, 0, 0, w, h);
|
||||
}
|
||||
if (pSrcPicture)
|
||||
FreePicture (pSrcPicture, 0);
|
||||
if (pDstPicture)
|
||||
FreePicture (pDstPicture, 0);
|
||||
}
|
||||
return pPixmap;
|
||||
}
|
||||
|
|
@ -508,7 +544,11 @@ compAllocPixmap (WindowPtr pWin)
|
|||
|
||||
if (!pPixmap)
|
||||
return FALSE;
|
||||
pWin->redirectDraw = TRUE;
|
||||
if (cw->update == CompositeRedirectAutomatic)
|
||||
pWin->redirectDraw = RedirectDrawAutomatic;
|
||||
else
|
||||
pWin->redirectDraw = RedirectDrawManual;
|
||||
|
||||
compSetPixmap (pWin, pPixmap);
|
||||
cw->oldx = COMP_ORIGIN_INVALID;
|
||||
cw->oldy = COMP_ORIGIN_INVALID;
|
||||
|
|
@ -543,7 +583,7 @@ compFreePixmap (WindowPtr pWin)
|
|||
REGION_COPY (pScreen, &pWin->borderClip, &cw->borderClip);
|
||||
pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||
pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
|
||||
pWin->redirectDraw = FALSE;
|
||||
pWin->redirectDraw = RedirectDrawNone;
|
||||
compSetPixmap (pWin, pParentPixmap);
|
||||
(*pScreen->DestroyPixmap) (pRedirectPixmap);
|
||||
}
|
||||
|
|
@ -564,7 +604,7 @@ compReallocPixmap (WindowPtr pWin, int draw_x, int draw_y,
|
|||
int pix_x, pix_y;
|
||||
int pix_w, pix_h;
|
||||
|
||||
assert (cw && pWin->redirectDraw);
|
||||
assert (cw && pWin->redirectDraw != RedirectDrawNone);
|
||||
cw->oldx = pOld->screen_x;
|
||||
cw->oldy = pOld->screen_y;
|
||||
pix_x = draw_x - bw;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
*
|
||||
* Copyright © 2006 Sun Microsystems
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
@ -49,6 +46,9 @@
|
|||
|
||||
#include "compint.h"
|
||||
|
||||
#define SERVER_COMPOSITE_MAJOR 0
|
||||
#define SERVER_COMPOSITE_MINOR 4
|
||||
|
||||
static CARD8 CompositeReqCode;
|
||||
static int CompositeClientPrivateIndex;
|
||||
RESTYPE CompositeClientWindowType;
|
||||
|
|
@ -133,16 +133,12 @@ ProcCompositeQueryVersion (ClientPtr client)
|
|||
rep.type = X_Reply;
|
||||
rep.length = 0;
|
||||
rep.sequenceNumber = client->sequence;
|
||||
if (stuff->majorVersion < COMPOSITE_MAJOR) {
|
||||
if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR) {
|
||||
rep.majorVersion = stuff->majorVersion;
|
||||
rep.minorVersion = stuff->minorVersion;
|
||||
} else {
|
||||
rep.majorVersion = COMPOSITE_MAJOR;
|
||||
if (stuff->majorVersion == COMPOSITE_MAJOR &&
|
||||
stuff->minorVersion < COMPOSITE_MINOR)
|
||||
rep.minorVersion = stuff->minorVersion;
|
||||
else
|
||||
rep.minorVersion = COMPOSITE_MINOR;
|
||||
rep.majorVersion = SERVER_COMPOSITE_MAJOR;
|
||||
rep.minorVersion = SERVER_COMPOSITE_MINOR;
|
||||
}
|
||||
pCompositeClient->major_version = rep.majorVersion;
|
||||
pCompositeClient->minor_version = rep.minorVersion;
|
||||
|
|
@ -696,11 +692,13 @@ CompositeExtensionInit (void)
|
|||
if (GetPictureScreenIfSet(pScreen) == NULL)
|
||||
return;
|
||||
}
|
||||
#ifdef PANORAMIX
|
||||
/* Xinerama's rewriting of window drawing before Composite gets to it
|
||||
* breaks Composite.
|
||||
*/
|
||||
if (!noPanoramiXExtension)
|
||||
return;
|
||||
#endif
|
||||
|
||||
CompositeClientWindowType = CreateNewResourceType (FreeCompositeClientWindow);
|
||||
if (!CompositeClientWindowType)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright © 2006 Sun Microsystems
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
@ -65,6 +63,7 @@ compCloseScreen (int index, ScreenPtr pScreen)
|
|||
pScreen->CloseScreen = cs->CloseScreen;
|
||||
pScreen->BlockHandler = cs->BlockHandler;
|
||||
pScreen->InstallColormap = cs->InstallColormap;
|
||||
pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
|
||||
pScreen->ReparentWindow = cs->ReparentWindow;
|
||||
pScreen->MoveWindow = cs->MoveWindow;
|
||||
pScreen->ResizeWindow = cs->ResizeWindow;
|
||||
|
|
@ -111,6 +110,33 @@ compInstallColormap (ColormapPtr pColormap)
|
|||
pScreen->InstallColormap = compInstallColormap;
|
||||
}
|
||||
|
||||
/* Fake backing store via automatic redirection */
|
||||
static Bool
|
||||
compChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
Bool ret;
|
||||
|
||||
pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
|
||||
ret = pScreen->ChangeWindowAttributes(pWin, mask);
|
||||
|
||||
if (ret && (mask & CWBackingStore)) {
|
||||
if (pWin->backingStore != NotUseful) {
|
||||
compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
|
||||
pWin->backStorage = TRUE;
|
||||
} else {
|
||||
compUnredirectWindow(serverClient, pWin,
|
||||
CompositeRedirectAutomatic);
|
||||
pWin->backStorage = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
compScreenUpdate (ScreenPtr pScreen)
|
||||
{
|
||||
|
|
@ -201,106 +227,84 @@ Bool CompositeRegisterAlternateVisuals (ScreenPtr pScreen, VisualID *vids,
|
|||
return compRegisterAlternateVisuals(cs, vids, nVisuals);
|
||||
}
|
||||
|
||||
#if COMP_INCLUDE_RGB24_VISUAL
|
||||
#define NUM_COMP_ALTERNATE_VISUALS 2
|
||||
#else
|
||||
#define NUM_COMP_ALTERNATE_VISUALS 1
|
||||
#endif
|
||||
|
||||
typedef struct _alternateVisual {
|
||||
int depth;
|
||||
CARD32 format;
|
||||
} CompAlternateVisual;
|
||||
|
||||
static CompAlternateVisual altVisuals[NUM_COMP_ALTERNATE_VISUALS] = {
|
||||
static CompAlternateVisual altVisuals[] = {
|
||||
#if COMP_INCLUDE_RGB24_VISUAL
|
||||
{ 24, PICT_r8g8b8 },
|
||||
#endif
|
||||
{ 32, PICT_a8r8g8b8 },
|
||||
};
|
||||
|
||||
static const int NUM_COMP_ALTERNATE_VISUALS = sizeof(altVisuals) /
|
||||
sizeof(CompAlternateVisual);
|
||||
|
||||
static Bool
|
||||
compAddAlternateVisuals (ScreenPtr pScreen, CompScreenPtr cs)
|
||||
compAddAlternateVisual(ScreenPtr pScreen, CompScreenPtr cs,
|
||||
CompAlternateVisual *alt)
|
||||
{
|
||||
VisualPtr visuals;
|
||||
DepthPtr depths[NUM_COMP_ALTERNATE_VISUALS];
|
||||
PictFormatPtr pPictFormats[NUM_COMP_ALTERNATE_VISUALS];
|
||||
VisualPtr visual, visuals;
|
||||
int i;
|
||||
int numVisuals;
|
||||
VisualID *vids[NUM_COMP_ALTERNATE_VISUALS];
|
||||
XID *installedCmaps;
|
||||
ColormapPtr installedCmap;
|
||||
int numInstalledCmaps;
|
||||
int numAlternate = 0;
|
||||
int alt;
|
||||
|
||||
for (alt = 0; alt < NUM_COMP_ALTERNATE_VISUALS; alt++)
|
||||
{
|
||||
DepthPtr depth;
|
||||
PictFormatPtr pPictFormat;
|
||||
|
||||
depth = compFindVisuallessDepth (pScreen, altVisuals[alt].depth);
|
||||
if (!depth)
|
||||
continue;
|
||||
/*
|
||||
* Find the right picture format
|
||||
*/
|
||||
pPictFormat = PictureMatchFormat (pScreen, altVisuals[alt].depth,
|
||||
altVisuals[alt].format);
|
||||
if (!pPictFormat)
|
||||
continue;
|
||||
DepthPtr depth;
|
||||
PictFormatPtr pPictFormat;
|
||||
VisualID *vid;
|
||||
unsigned long alphaMask;
|
||||
|
||||
/*
|
||||
* Allocate vid list for this depth
|
||||
*/
|
||||
vids[numAlternate] = xalloc (sizeof (VisualID));
|
||||
if (!vids[numAlternate])
|
||||
continue;
|
||||
depths[numAlternate] = depth;
|
||||
pPictFormats[numAlternate] = pPictFormat;
|
||||
numAlternate++;
|
||||
}
|
||||
|
||||
if (!numAlternate)
|
||||
/*
|
||||
* The ARGB32 visual is always available. Other alternate depth visuals
|
||||
* are only provided if their depth is less than the root window depth.
|
||||
* There's no deep reason for this.
|
||||
*/
|
||||
if (alt->depth >= pScreen->rootDepth && alt->depth != 32)
|
||||
return FALSE;
|
||||
|
||||
depth = compFindVisuallessDepth (pScreen, alt->depth);
|
||||
if (!depth)
|
||||
/* alt->depth doesn't exist or already has alternate visuals. */
|
||||
return TRUE;
|
||||
|
||||
/*
|
||||
* Find the installed colormaps
|
||||
*/
|
||||
pPictFormat = PictureMatchFormat (pScreen, alt->depth, alt->format);
|
||||
if (!pPictFormat)
|
||||
return FALSE;
|
||||
|
||||
vid = xalloc(sizeof(VisualID));
|
||||
if (!vid)
|
||||
return FALSE;
|
||||
|
||||
/* Find the installed colormaps */
|
||||
installedCmaps = xalloc (pScreen->maxInstalledCmaps * sizeof (XID));
|
||||
if (!installedCmaps)
|
||||
{
|
||||
for (alt = 0; alt < numAlternate; alt++)
|
||||
xfree (vids[alt]);
|
||||
if (!installedCmaps) {
|
||||
xfree(vid);
|
||||
return FALSE;
|
||||
}
|
||||
numInstalledCmaps = (*pScreen->ListInstalledColormaps) (pScreen,
|
||||
installedCmaps);
|
||||
|
||||
/*
|
||||
* realloc the visual array to fit the new one in place
|
||||
*/
|
||||
numInstalledCmaps = pScreen->ListInstalledColormaps(pScreen,
|
||||
installedCmaps);
|
||||
|
||||
/* realloc the visual array to fit the new one in place */
|
||||
numVisuals = pScreen->numVisuals;
|
||||
visuals = xrealloc (pScreen->visuals,
|
||||
(numVisuals + numAlternate) * sizeof (VisualRec));
|
||||
if (!visuals)
|
||||
{
|
||||
for (alt = 0; alt < numAlternate; alt++)
|
||||
xfree (vids[alt]);
|
||||
xfree (installedCmaps);
|
||||
visuals = xrealloc(pScreen->visuals, (numVisuals + 1) * sizeof(VisualRec));
|
||||
if (!visuals) {
|
||||
xfree(vid);
|
||||
xfree(installedCmaps);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fix up any existing installed colormaps -- we'll assume that
|
||||
* the only ones created so far have been installed. If this
|
||||
* isn't true, we'll have to walk the resource database looking
|
||||
* for all colormaps.
|
||||
*/
|
||||
for (i = 0; i < numInstalledCmaps; i++)
|
||||
{
|
||||
for (i = 0; i < numInstalledCmaps; i++) {
|
||||
int j;
|
||||
|
||||
|
||||
installedCmap = LookupIDByType (installedCmaps[i], RT_COLORMAP);
|
||||
if (!installedCmap)
|
||||
continue;
|
||||
|
|
@ -308,66 +312,64 @@ compAddAlternateVisuals (ScreenPtr pScreen, CompScreenPtr cs)
|
|||
installedCmap->pVisual = &visuals[j];
|
||||
}
|
||||
|
||||
xfree (installedCmaps);
|
||||
xfree(installedCmaps);
|
||||
|
||||
pScreen->visuals = visuals;
|
||||
pScreen->numVisuals = numVisuals + numAlternate;
|
||||
visual = visuals + pScreen->numVisuals; /* the new one */
|
||||
pScreen->numVisuals++;
|
||||
|
||||
for (alt = 0; alt < numAlternate; alt++)
|
||||
{
|
||||
DepthPtr depth = depths[alt];
|
||||
PictFormatPtr pPictFormat = pPictFormats[alt];
|
||||
VisualPtr visual = &visuals[numVisuals + alt];
|
||||
unsigned long alphaMask;
|
||||
|
||||
/*
|
||||
* Initialize the visual
|
||||
*/
|
||||
/* Initialize the visual */
|
||||
visual->vid = FakeClientID (0);
|
||||
visual->bitsPerRGBValue = 8;
|
||||
if (PICT_FORMAT_TYPE(alt->format) == PICT_TYPE_COLOR) {
|
||||
visual->class = PseudoColor;
|
||||
visual->nplanes = PICT_FORMAT_BPP(alt->format);
|
||||
visual->ColormapEntries = 1 << visual->nplanes;
|
||||
} else {
|
||||
DirectFormatRec *direct = &pPictFormat->direct;
|
||||
visual->class = TrueColor;
|
||||
visual->bitsPerRGBValue = 8;
|
||||
|
||||
visual->vid = FakeClientID (0);
|
||||
visual->redMask = (((unsigned long) pPictFormat->direct.redMask) <<
|
||||
pPictFormat->direct.red);
|
||||
visual->greenMask = (((unsigned long) pPictFormat->direct.greenMask) <<
|
||||
pPictFormat->direct.green);
|
||||
visual->blueMask = (((unsigned long) pPictFormat->direct.blueMask) <<
|
||||
pPictFormat->direct.blue);
|
||||
alphaMask = (((unsigned long) pPictFormat->direct.alphaMask) <<
|
||||
pPictFormat->direct.alpha);
|
||||
visual->offsetRed = pPictFormat->direct.red;
|
||||
visual->offsetGreen = pPictFormat->direct.green;
|
||||
visual->offsetBlue = pPictFormat->direct.blue;
|
||||
visual->redMask = ((unsigned long)direct->redMask) << direct->red;
|
||||
visual->greenMask = ((unsigned long)direct->greenMask) << direct->green;
|
||||
visual->blueMask = ((unsigned long)direct->blueMask) << direct->blue;
|
||||
alphaMask = ((unsigned long)direct->alphaMask) << direct->alpha;
|
||||
visual->offsetRed = direct->red;
|
||||
visual->offsetGreen = direct->green;
|
||||
visual->offsetBlue = direct->blue;
|
||||
/*
|
||||
* Include A bits in this (unlike GLX which includes only RGB)
|
||||
* This lets DIX compute suitable masks for colormap allocations
|
||||
*/
|
||||
visual->nplanes = Ones (visual->redMask |
|
||||
visual->greenMask |
|
||||
visual->blueMask |
|
||||
alphaMask);
|
||||
/*
|
||||
* find widest component
|
||||
*/
|
||||
visual->greenMask |
|
||||
visual->blueMask |
|
||||
alphaMask);
|
||||
/* find widest component */
|
||||
visual->ColormapEntries = (1 << max (Ones (visual->redMask),
|
||||
max (Ones (visual->greenMask),
|
||||
Ones (visual->blueMask))));
|
||||
|
||||
/*
|
||||
* remember the visual ID to detect auto-update windows
|
||||
*/
|
||||
compRegisterAlternateVisuals(cs, &visual->vid, 1);
|
||||
|
||||
/*
|
||||
* Fix up the depth
|
||||
*/
|
||||
vids[alt][0] = visual->vid;
|
||||
depth->numVids = 1;
|
||||
depth->vids = vids[alt];
|
||||
max (Ones (visual->greenMask),
|
||||
Ones (visual->blueMask))));
|
||||
}
|
||||
|
||||
/* remember the visual ID to detect auto-update windows */
|
||||
compRegisterAlternateVisuals(cs, &visual->vid, 1);
|
||||
|
||||
/* Fix up the depth */
|
||||
*vid = visual->vid;
|
||||
depth->numVids = 1;
|
||||
depth->vids = vid;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
compAddAlternateVisuals (ScreenPtr pScreen, CompScreenPtr cs)
|
||||
{
|
||||
int alt, ret = 0;
|
||||
|
||||
for (alt = 0; alt < NUM_COMP_ALTERNATE_VISUALS; alt++)
|
||||
ret |= compAddAlternateVisual(pScreen, cs, altVisuals + alt);
|
||||
|
||||
return !!ret;
|
||||
}
|
||||
|
||||
Bool
|
||||
compScreenInit (ScreenPtr pScreen)
|
||||
{
|
||||
|
|
@ -450,6 +452,9 @@ compScreenInit (ScreenPtr pScreen)
|
|||
cs->InstallColormap = pScreen->InstallColormap;
|
||||
pScreen->InstallColormap = compInstallColormap;
|
||||
|
||||
cs->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
|
||||
pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
|
||||
|
||||
cs->BlockHandler = pScreen->BlockHandler;
|
||||
pScreen->BlockHandler = compBlockHandler;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright © 2006 Sun Microsystems
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
@ -145,6 +143,11 @@ typedef struct _CompScreen {
|
|||
*/
|
||||
InstallColormapProcPtr InstallColormap;
|
||||
|
||||
/*
|
||||
* Fake backing store via automatic redirection
|
||||
*/
|
||||
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
|
||||
|
||||
ScreenBlockHandlerProcPtr BlockHandler;
|
||||
CloseScreenProcPtr CloseScreen;
|
||||
Bool damaged;
|
||||
|
|
@ -234,6 +237,9 @@ compCheckTree (ScreenPtr pScreen);
|
|||
#define compCheckTree(s)
|
||||
#endif
|
||||
|
||||
PictFormatPtr
|
||||
compWindowFormat (WindowPtr pWin);
|
||||
|
||||
void
|
||||
compSetPixmap (WindowPtr pWin, PixmapPtr pPixmap);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright © 2006 Sun Microsystems
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
@ -59,10 +57,10 @@ compCheckWindow (WindowPtr pWin, pointer data)
|
|||
|
||||
if (!pWin->parent)
|
||||
{
|
||||
assert (!pWin->redirectDraw);
|
||||
assert (pWin->redirectDraw == RedirectDrawNone);
|
||||
assert (pWinPixmap == pScreenPixmap);
|
||||
}
|
||||
else if (pWin->redirectDraw)
|
||||
else if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
assert (pWinPixmap != pParentPixmap);
|
||||
assert (pWinPixmap != pScreenPixmap);
|
||||
|
|
@ -113,7 +111,7 @@ compSetPixmapVisitWindow (WindowPtr pWindow, pointer data)
|
|||
CompPixmapVisitPtr pVisit = (CompPixmapVisitPtr) data;
|
||||
ScreenPtr pScreen = pWindow->drawable.pScreen;
|
||||
|
||||
if (pWindow != pVisit->pWindow && pWindow->redirectDraw)
|
||||
if (pWindow != pVisit->pWindow && pWindow->redirectDraw != RedirectDrawNone)
|
||||
return WT_DONTWALKCHILDREN;
|
||||
(*pScreen->SetWindowPixmap) (pWindow, pVisit->pPixmap);
|
||||
/*
|
||||
|
|
@ -157,7 +155,7 @@ compCheckRedirect (WindowPtr pWin)
|
|||
}
|
||||
}
|
||||
|
||||
if (should != pWin->redirectDraw)
|
||||
if (should != (pWin->redirectDraw != RedirectDrawNone))
|
||||
{
|
||||
if (should)
|
||||
return compAllocPixmap (pWin);
|
||||
|
|
@ -181,10 +179,11 @@ compPositionWindow (WindowPtr pWin, int x, int y)
|
|||
compCheckRedirect (pWin);
|
||||
*/
|
||||
#ifdef COMPOSITE_DEBUG
|
||||
if (pWin->redirectDraw != (pWin->viewable && (GetCompWindow(pWin) != NULL)))
|
||||
if ((pWin->redirectDraw != RedirectDrawNone) !=
|
||||
(pWin->viewable && (GetCompWindow(pWin) != NULL)))
|
||||
abort ();
|
||||
#endif
|
||||
if (pWin->redirectDraw)
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||
int bw = wBorderWidth (pWin);
|
||||
|
|
@ -331,7 +330,7 @@ compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
|
|||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
|
||||
compCheckTree (pScreen);
|
||||
if (pWin->redirectDraw)
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
WindowPtr pParent;
|
||||
int draw_x, draw_y;
|
||||
|
|
@ -355,7 +354,7 @@ compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
|
|||
cs->MoveWindow = pScreen->MoveWindow;
|
||||
pScreen->MoveWindow = compMoveWindow;
|
||||
|
||||
if (pWin->redirectDraw)
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
if (cw->pOldPixmap)
|
||||
|
|
@ -376,7 +375,7 @@ compResizeWindow (WindowPtr pWin, int x, int y,
|
|||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
|
||||
compCheckTree (pScreen);
|
||||
if (pWin->redirectDraw)
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
WindowPtr pParent;
|
||||
int draw_x, draw_y;
|
||||
|
|
@ -397,7 +396,7 @@ compResizeWindow (WindowPtr pWin, int x, int y,
|
|||
(*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
|
||||
cs->ResizeWindow = pScreen->ResizeWindow;
|
||||
pScreen->ResizeWindow = compResizeWindow;
|
||||
if (pWin->redirectDraw)
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
if (cw->pOldPixmap)
|
||||
|
|
@ -416,7 +415,7 @@ compChangeBorderWidth (WindowPtr pWin, unsigned int bw)
|
|||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
|
||||
compCheckTree (pScreen);
|
||||
if (pWin->redirectDraw)
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
WindowPtr pParent;
|
||||
int draw_x, draw_y;
|
||||
|
|
@ -438,7 +437,7 @@ compChangeBorderWidth (WindowPtr pWin, unsigned int bw)
|
|||
(*pScreen->ChangeBorderWidth) (pWin, bw);
|
||||
cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
|
||||
pScreen->ChangeBorderWidth = compChangeBorderWidth;
|
||||
if (pWin->redirectDraw)
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
if (cw->pOldPixmap)
|
||||
|
|
@ -482,7 +481,7 @@ compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent)
|
|||
/*
|
||||
* Reset pixmap pointers as appropriate
|
||||
*/
|
||||
if (pWin->parent && !pWin->redirectDraw)
|
||||
if (pWin->parent && pWin->redirectDraw == RedirectDrawNone)
|
||||
compSetPixmap (pWin, (*pScreen->GetWindowPixmap) (pWin->parent));
|
||||
/*
|
||||
* Call down to next function
|
||||
|
|
@ -501,7 +500,7 @@ compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
|||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
int dx = 0, dy = 0;
|
||||
|
||||
if (pWin->redirectDraw)
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
|
|
@ -626,7 +625,7 @@ compDestroyWindow (WindowPtr pWin)
|
|||
while ((csw = GetCompSubwindows (pWin)))
|
||||
FreeResource (csw->clients->id, RT_NONE);
|
||||
|
||||
if (pWin->redirectDraw)
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
compFreePixmap (pWin);
|
||||
ret = (*pScreen->DestroyWindow) (pWin);
|
||||
cs->DestroyWindow = pScreen->DestroyWindow;
|
||||
|
|
@ -686,7 +685,7 @@ compGetWindowVisual (WindowPtr pWin)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static PictFormatPtr
|
||||
PictFormatPtr
|
||||
compWindowFormat (WindowPtr pWin)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
|
|
@ -770,7 +769,7 @@ compWindowUpdate (WindowPtr pWin)
|
|||
|
||||
for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
|
||||
compWindowUpdate (pChild);
|
||||
if (pWin->redirectDraw)
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
CompWindowPtr cw = GetCompWindow(pWin);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,22 @@
|
|||
AM_CFLAGS = @DIX_CFLAGS@
|
||||
|
||||
noinst_LIBRARIES = libconfig.a
|
||||
libconfig_a_SOURCES = config.c config-backends.h
|
||||
|
||||
if HAVE_DBUS
|
||||
AM_CFLAGS += @DBUS_CFLAGS@
|
||||
libconfig_a_SOURCES += dbus-core.c
|
||||
endif
|
||||
|
||||
if CONFIG_DBUS_API
|
||||
dbusconfigdir = $(sysconfdir)/dbus-1/system.d
|
||||
dbusconfig_DATA = xorg-server.conf
|
||||
|
||||
lib_LIBRARIES = libconfig.a
|
||||
libconfig_a_SOURCES += dbus.c
|
||||
endif
|
||||
|
||||
libconfig_a_SOURCES = config.c
|
||||
if CONFIG_HAL
|
||||
libconfig_a_SOURCES += hal.c
|
||||
endif
|
||||
|
||||
EXTRA_DIST = xorg-server.conf
|
||||
EXTRA_DIST = xorg-server.conf x11-input.fdi
|
||||
|
|
|
|||
59
config/config-backends.h
Normal file
59
config/config-backends.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright © 2006-2007 Daniel Stone
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
typedef void (*config_dbus_core_connect_hook)(DBusConnection *connection,
|
||||
void *data);
|
||||
typedef void (*config_dbus_core_disconnect_hook)(void *data);
|
||||
|
||||
struct config_dbus_core_hook {
|
||||
config_dbus_core_connect_hook connect;
|
||||
config_dbus_core_disconnect_hook disconnect;
|
||||
void *data;
|
||||
|
||||
struct config_dbus_core_hook *next;
|
||||
};
|
||||
|
||||
int config_dbus_core_init(void);
|
||||
void config_dbus_core_fini(void);
|
||||
int config_dbus_core_add_hook(struct config_dbus_core_hook *hook);
|
||||
void config_dbus_core_remove_hook(struct config_dbus_core_hook *hook);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DBUS_API
|
||||
int config_dbus_init(void);
|
||||
void config_dbus_fini(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HAL
|
||||
int config_hal_init(void);
|
||||
void config_hal_fini(void);
|
||||
#endif
|
||||
532
config/config.c
532
config/config.c
|
|
@ -1,504 +1,66 @@
|
|||
/*
|
||||
* Copyright © 2006 Daniel Stone
|
||||
* Copyright © 2006-2007 Daniel Stone
|
||||
*
|
||||
* 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 the copyright holders and/or authors
|
||||
* not be used in advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission. The copyright holders
|
||||
* and/or authors make no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without express or
|
||||
* implied warranty.
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS AND/OR AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD
|
||||
* TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND/OR AUTHORS 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.
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
#define DBUS_API_SUBJECT_TO_CHANGE
|
||||
#include <dbus/dbus.h>
|
||||
#include <string.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include <X11/X.h>
|
||||
|
||||
#include "opaque.h" /* for 'display': there has to be a better way */
|
||||
/* the above comment lies. there is no better way. */
|
||||
#include "input.h"
|
||||
#include "inputstr.h"
|
||||
#include "hotplug.h"
|
||||
#include "os.h"
|
||||
#include "hotplug.h"
|
||||
#include "config-backends.h"
|
||||
|
||||
#define CONFIG_MATCH_RULE "type='method_call',interface='org.x.config.input'"
|
||||
|
||||
#define MALFORMED_MSG "[config] malformed message, dropping"
|
||||
#define MALFORMED_MESSAGE() { DebugF(MALFORMED_MSG "\n"); \
|
||||
ret = BadValue; \
|
||||
goto unwind; }
|
||||
#define MALFORMED_MESSAGE_ERROR() { DebugF(MALFORMED_MSG ": %s, %s", \
|
||||
error->name, error->message); \
|
||||
ret = BadValue; \
|
||||
goto unwind; }
|
||||
|
||||
/* How often to attempt reconnecting when we get booted off the bus. */
|
||||
#define RECONNECT_DELAY 10000 /* in ms */
|
||||
|
||||
struct config_data {
|
||||
int fd;
|
||||
DBusConnection *connection;
|
||||
char busobject[32];
|
||||
char busname[64];
|
||||
};
|
||||
|
||||
static struct config_data *configData;
|
||||
|
||||
static CARD32 configReconnect(OsTimerPtr timer, CARD32 time, pointer arg);
|
||||
|
||||
static void
|
||||
configWakeupHandler(pointer blockData, int err, pointer pReadMask)
|
||||
void
|
||||
config_init()
|
||||
{
|
||||
struct config_data *data = blockData;
|
||||
|
||||
if (data->connection && FD_ISSET(data->fd, (fd_set *) pReadMask))
|
||||
dbus_connection_read_write_dispatch(data->connection, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
configBlockHandler(pointer data, struct timeval **tv, pointer pReadMask)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
configTeardown(void)
|
||||
{
|
||||
if (configData) {
|
||||
RemoveGeneralSocket(configData->fd);
|
||||
RemoveBlockAndWakeupHandlers(configBlockHandler, configWakeupHandler,
|
||||
configData);
|
||||
xfree(configData);
|
||||
configData = NULL;
|
||||
#if defined(CONFIG_DBUS_API) || defined(CONFIG_HAL)
|
||||
if (config_dbus_core_init()) {
|
||||
# ifdef CONFIG_DBUS_API
|
||||
if (!config_dbus_init())
|
||||
ErrorF("[config] failed to initialise D-Bus API\n");
|
||||
# endif
|
||||
# ifdef CONFIG_HAL
|
||||
if (!config_hal_init())
|
||||
ErrorF("[config] failed to initialise HAL\n");
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
configAddDevice(DBusMessage *message, DBusMessageIter *iter,
|
||||
DBusMessage *reply, DBusMessageIter *r_iter,
|
||||
DBusError *error)
|
||||
{
|
||||
DBusMessageIter subiter;
|
||||
InputOption *tmpo = NULL, *options = NULL;
|
||||
char *tmp = NULL;
|
||||
int ret = BadMatch;
|
||||
DeviceIntPtr dev = NULL;
|
||||
|
||||
DebugF("[config] adding device\n");
|
||||
|
||||
/* signature should be [ss][ss]... */
|
||||
options = (InputOption *) xcalloc(sizeof(InputOption), 1);
|
||||
if (!options) {
|
||||
ErrorF("[config] couldn't allocate option\n");
|
||||
return BadAlloc;
|
||||
else {
|
||||
ErrorF("[config] failed to initialise D-Bus core\n");
|
||||
}
|
||||
|
||||
options->key = xstrdup("_source");
|
||||
options->value = xstrdup("client/dbus");
|
||||
if(!options->key || !options->value) {
|
||||
ErrorF("[config] couldn't allocate first key/value pair\n");
|
||||
ret = BadAlloc;
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_ARRAY) {
|
||||
tmpo = (InputOption *) xcalloc(sizeof(InputOption), 1);
|
||||
if (!tmpo) {
|
||||
ErrorF("[config] couldn't allocate option\n");
|
||||
ret = BadAlloc;
|
||||
goto unwind;
|
||||
}
|
||||
tmpo->next = options;
|
||||
options = tmpo;
|
||||
|
||||
dbus_message_iter_recurse(iter, &subiter);
|
||||
|
||||
if (dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_STRING)
|
||||
MALFORMED_MESSAGE();
|
||||
|
||||
dbus_message_iter_get_basic(&subiter, &tmp);
|
||||
if (!tmp)
|
||||
MALFORMED_MESSAGE();
|
||||
if (tmp[0] == '_') {
|
||||
ErrorF("[config] attempted subterfuge: option name %s given\n",
|
||||
tmp);
|
||||
MALFORMED_MESSAGE();
|
||||
}
|
||||
options->key = xstrdup(tmp);
|
||||
if (!options->key) {
|
||||
ErrorF("[config] couldn't duplicate key!\n");
|
||||
ret = BadAlloc;
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
if (!dbus_message_iter_has_next(&subiter))
|
||||
MALFORMED_MESSAGE();
|
||||
dbus_message_iter_next(&subiter);
|
||||
if (dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_STRING)
|
||||
MALFORMED_MESSAGE();
|
||||
|
||||
dbus_message_iter_get_basic(&subiter, &tmp);
|
||||
if (!tmp)
|
||||
MALFORMED_MESSAGE();
|
||||
options->value = xstrdup(tmp);
|
||||
if (!options->value) {
|
||||
ErrorF("[config] couldn't duplicate option!\n");
|
||||
ret = BadAlloc;
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
dbus_message_iter_next(iter);
|
||||
}
|
||||
|
||||
ret = NewInputDeviceRequest(options, &dev);
|
||||
if (ret != Success) {
|
||||
DebugF("[config] NewInputDeviceRequest failed\n");
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
if (!dev) {
|
||||
DebugF("[config] NewInputDeviceRequest succeeded, without device\n");
|
||||
ret = BadMatch;
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
if (!dbus_message_iter_append_basic(r_iter, DBUS_TYPE_INT32, &(dev->id))) {
|
||||
ErrorF("[config] couldn't append to iterator\n");
|
||||
ret = BadAlloc;
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
unwind:
|
||||
if (dev && ret != Success)
|
||||
RemoveDevice(dev);
|
||||
|
||||
while (options) {
|
||||
tmpo = options;
|
||||
options = options->next;
|
||||
if (tmpo->key)
|
||||
xfree(tmpo->key);
|
||||
if (tmpo->value)
|
||||
xfree(tmpo->value);
|
||||
xfree(tmpo);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
configRemoveDevice(DBusMessage *message, DBusMessageIter *iter,
|
||||
DBusError *error)
|
||||
{
|
||||
int deviceid = -1;
|
||||
int ret = BadMatch;
|
||||
DeviceIntPtr pDev = NULL;
|
||||
|
||||
if (!dbus_message_get_args(message, error, DBUS_TYPE_INT32,
|
||||
&deviceid, DBUS_TYPE_INVALID)) {
|
||||
MALFORMED_MESSAGE_ERROR();
|
||||
}
|
||||
|
||||
if (deviceid < 0 || !(pDev = LookupDeviceIntRec(deviceid))) {
|
||||
DebugF("[config] bogus device id %d given\n", deviceid);
|
||||
ret = BadMatch;
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
DebugF("[config] removing device %s (id %d)\n", pDev->name, deviceid);
|
||||
|
||||
/* Call PIE here so we don't try to dereference a device that's
|
||||
* already been removed. */
|
||||
OsBlockSignals();
|
||||
ProcessInputEvents();
|
||||
DeleteInputDeviceRequest(pDev);
|
||||
OsReleaseSignals();
|
||||
|
||||
return Success;
|
||||
|
||||
unwind:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
configListDevices(DBusMessage *message, DBusMessageIter *iter,
|
||||
DBusMessage *reply, DBusMessageIter *r_iter,
|
||||
DBusError *error)
|
||||
{
|
||||
DeviceIntPtr d;
|
||||
int ret = BadMatch;
|
||||
|
||||
for (d = inputInfo.devices; d; d = d->next) {
|
||||
if (!dbus_message_iter_append_basic(r_iter, DBUS_TYPE_INT32,
|
||||
&(d->id))) {
|
||||
ErrorF("[config] couldn't append to iterator\n");
|
||||
ret = BadAlloc;
|
||||
goto unwind;
|
||||
}
|
||||
if (!dbus_message_iter_append_basic(r_iter, DBUS_TYPE_STRING,
|
||||
&(d->name))) {
|
||||
ErrorF("[config] couldn't append to iterator\n");
|
||||
ret = BadAlloc;
|
||||
goto unwind;
|
||||
}
|
||||
}
|
||||
|
||||
unwind:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DBusHandlerResult
|
||||
configMessage(DBusConnection *connection, DBusMessage *message, void *closure)
|
||||
{
|
||||
DBusMessageIter iter;
|
||||
DBusError error;
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter r_iter;
|
||||
DBusConnection *bus = closure;
|
||||
int ret = BadDrawable; /* nonsensical value */
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
DebugF("[config] received a message\n");
|
||||
|
||||
if (strcmp(dbus_message_get_interface(message),
|
||||
"org.x.config.input") == 0) {
|
||||
if (!dbus_message_iter_init(message, &iter)) {
|
||||
ErrorF("[config] failed to init iterator\n");
|
||||
dbus_error_free(&error);
|
||||
return DBUS_HANDLER_RESULT_NEED_MEMORY; /* ?? */
|
||||
}
|
||||
|
||||
if (!(reply = dbus_message_new_method_return(message))) {
|
||||
ErrorF("[config] failed to create the reply message\n");
|
||||
dbus_error_free(&error);
|
||||
return DBUS_HANDLER_RESULT_NEED_MEMORY;
|
||||
}
|
||||
dbus_message_iter_init_append(reply, &r_iter);
|
||||
|
||||
if (strcmp(dbus_message_get_member(message), "add") == 0)
|
||||
ret = configAddDevice(message, &iter, reply, &r_iter, &error);
|
||||
else if (strcmp(dbus_message_get_member(message), "remove") == 0)
|
||||
ret = configRemoveDevice(message, &iter, &error);
|
||||
else if (strcmp(dbus_message_get_member(message), "listDevices") == 0)
|
||||
ret = configListDevices(message, &iter, reply, &r_iter, &error);
|
||||
if (ret != BadDrawable && ret != BadAlloc) {
|
||||
|
||||
if (!strlen(dbus_message_get_signature(reply)))
|
||||
if (!dbus_message_iter_append_basic(&r_iter, DBUS_TYPE_INT32, &ret)) {
|
||||
ErrorF("[config] couldn't append to iterator\n");
|
||||
dbus_error_free(&error);
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
if (!dbus_connection_send(bus, reply, NULL))
|
||||
ErrorF("[config] failed to send reply\n");
|
||||
}
|
||||
dbus_message_unref(reply);
|
||||
dbus_connection_flush(bus);
|
||||
}
|
||||
|
||||
dbus_error_free(&error);
|
||||
|
||||
if (ret == BadAlloc)
|
||||
return DBUS_HANDLER_RESULT_NEED_MEMORY;
|
||||
else if (ret == BadDrawable)
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
else
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a filter, which only handles the disconnected signal, which
|
||||
* doesn't go to the normal message handling function. This takes
|
||||
* precedence over the message handling function, so have have to be
|
||||
* careful to ignore anything we don't want to deal with here.
|
||||
*
|
||||
* Yes, this is brutally stupid.
|
||||
*/
|
||||
static DBusHandlerResult
|
||||
configFilter(DBusConnection *connection, DBusMessage *message, void *closure)
|
||||
{
|
||||
if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL,
|
||||
"Disconnected")) {
|
||||
ErrorF("[dbus] disconnected from bus\n");
|
||||
TimerSet(NULL, 0, RECONNECT_DELAY, configReconnect, NULL);
|
||||
configTeardown();
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
static Bool
|
||||
configSetup(void)
|
||||
{
|
||||
DBusError error;
|
||||
DBusObjectPathVTable vtable = { .message_function = configMessage };
|
||||
|
||||
if (!configData)
|
||||
configData = (struct config_data *) xcalloc(sizeof(struct config_data), 1);
|
||||
if (!configData) {
|
||||
ErrorF("[dbus] failed to allocate data struct\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dbus_error_init(&error);
|
||||
configData->connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
|
||||
if (!configData->connection || dbus_error_is_set(&error)) {
|
||||
DebugF("[dbus] some kind of error occurred while connecting: %s (%s)\n",
|
||||
error.name, error.message);
|
||||
dbus_error_free(&error);
|
||||
xfree(configData);
|
||||
configData = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dbus_connection_set_exit_on_disconnect(configData->connection, FALSE);
|
||||
|
||||
if (!dbus_connection_get_unix_fd(configData->connection, &configData->fd)) {
|
||||
dbus_connection_unref(configData->connection);
|
||||
ErrorF("[dbus] couldn't get fd for bus\n");
|
||||
dbus_error_free(&error);
|
||||
xfree(configData);
|
||||
configData = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
snprintf(configData->busname, sizeof(configData->busname),
|
||||
"org.x.config.display%d", atoi(display));
|
||||
if (!dbus_bus_request_name(configData->connection, configData->busname,
|
||||
0, &error) || dbus_error_is_set(&error)) {
|
||||
ErrorF("[dbus] couldn't take over org.x.config: %s (%s)\n",
|
||||
error.name, error.message);
|
||||
dbus_error_free(&error);
|
||||
dbus_connection_unref(configData->connection);
|
||||
xfree(configData);
|
||||
configData = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* blocks until we get a reply. */
|
||||
dbus_bus_add_match(configData->connection, CONFIG_MATCH_RULE, &error);
|
||||
if (dbus_error_is_set(&error)) {
|
||||
ErrorF("[dbus] couldn't match X.Org rule: %s (%s)\n", error.name,
|
||||
error.message);
|
||||
dbus_error_free(&error);
|
||||
dbus_bus_release_name(configData->connection, configData->busname,
|
||||
&error);
|
||||
dbus_connection_unref(configData->connection);
|
||||
xfree(configData);
|
||||
configData = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dbus_connection_add_filter(configData->connection, configFilter,
|
||||
configData, NULL)) {
|
||||
|
||||
ErrorF("[dbus] couldn't add signal filter: %s (%s)\n", error.name,
|
||||
error.message);
|
||||
dbus_error_free(&error);
|
||||
dbus_bus_release_name(configData->connection, configData->busname,
|
||||
&error);
|
||||
dbus_bus_remove_match(configData->connection, CONFIG_MATCH_RULE,
|
||||
&error);
|
||||
dbus_connection_unref(configData->connection);
|
||||
xfree(configData);
|
||||
configData = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
snprintf(configData->busobject, sizeof(configData->busobject),
|
||||
"/org/x/config/%d", atoi(display));
|
||||
if (!dbus_connection_register_object_path(configData->connection,
|
||||
configData->busobject, &vtable,
|
||||
configData->connection)) {
|
||||
ErrorF("[dbus] couldn't register object path\n");
|
||||
dbus_bus_release_name(configData->connection, configData->busname,
|
||||
&error);
|
||||
dbus_bus_remove_match(configData->connection, CONFIG_MATCH_RULE,
|
||||
&error);
|
||||
dbus_connection_unref(configData->connection);
|
||||
dbus_error_free(&error);
|
||||
xfree(configData);
|
||||
configData = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DebugF("[dbus] registered object path %s\n", configData->busobject);
|
||||
|
||||
dbus_error_free(&error);
|
||||
AddGeneralSocket(configData->fd);
|
||||
|
||||
RegisterBlockAndWakeupHandlers(configBlockHandler, configWakeupHandler,
|
||||
configData);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static CARD32
|
||||
configReconnect(OsTimerPtr timer, CARD32 time, pointer arg)
|
||||
{
|
||||
if (configSetup())
|
||||
return 0;
|
||||
else
|
||||
return RECONNECT_DELAY;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
configInitialise(void)
|
||||
config_fini()
|
||||
{
|
||||
TimerSet(NULL, 0, 1, configReconnect, NULL);
|
||||
#if defined(CONFIG_DBUS_API) || defined(CONFIG_HAL)
|
||||
# ifdef CONFIG_HAL
|
||||
config_hal_fini();
|
||||
# endif
|
||||
# ifdef CONFIG_DBUS_API
|
||||
config_dbus_fini();
|
||||
# endif
|
||||
config_dbus_core_fini();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
configFini(void)
|
||||
{
|
||||
DBusError error;
|
||||
|
||||
if (configData) {
|
||||
dbus_error_init(&error);
|
||||
dbus_connection_unregister_object_path(configData->connection,
|
||||
configData->busobject);
|
||||
dbus_connection_remove_filter(configData->connection, configFilter,
|
||||
configData);
|
||||
dbus_bus_remove_match(configData->connection, CONFIG_MATCH_RULE,
|
||||
&error);
|
||||
dbus_bus_release_name(configData->connection, configData->busname,
|
||||
&error);
|
||||
dbus_connection_unref(configData->connection);
|
||||
dbus_error_free(&error);
|
||||
configTeardown();
|
||||
}
|
||||
}
|
||||
|
||||
#else /* !HAVE_DBUS */
|
||||
|
||||
void
|
||||
configInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
configFini()
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* HAVE_DBUS */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
D-BUS Configuration API v0.1
|
||||
D-BUS Configuration API v2
|
||||
----------------------------
|
||||
|
||||
The X server will register the bus name org.x.config.displayN, and the
|
||||
|
|
@ -7,6 +7,9 @@ object /org/x/config/N, where N is the display number.
|
|||
Currently only hotplugging of input devices is supported.
|
||||
|
||||
org.x.config.input:
|
||||
org.x.config.input.version:
|
||||
Returns one unsigned int32, which is the API version.
|
||||
|
||||
org.x.config.input.add:
|
||||
Takes an argument of key/value option pairs in arrays, e.g.:
|
||||
[ss][ss][ss][ss]
|
||||
|
|
@ -15,21 +18,23 @@ org.x.config.input:
|
|||
Option names beginning with _ are not allowed; they are reserved
|
||||
for internal use.
|
||||
|
||||
Returns one int32, which is an X Status, as defined in X.h. If
|
||||
everything is successful, Success will be returned. BadMatch will
|
||||
be returned if the options given do not match any device. BadValue
|
||||
is returned for a malformed message.
|
||||
Returns a number of signed int32s. Positive integers are the
|
||||
device IDs of new devices; negative numbers are X error codes,
|
||||
as defined in X.h. BadMatch will be returned if the options
|
||||
given do not match any device. BadValue is returned for a malformed
|
||||
message. (Example: 8 is new device ID 8; -8 is BadMatch.)
|
||||
|
||||
Notably, BadAlloc is never returned: the server internally signals
|
||||
to D-BUS that the attempt failed for lack of memory.
|
||||
|
||||
The return does not notify the client of which devices were created
|
||||
or modified as a result of this request: clients are encouraged to
|
||||
listen for the XInput DevicePresenceNotify event to monitor changes
|
||||
in the device list.
|
||||
|
||||
org.x.config.input.remove:
|
||||
Takes one int32 argument, which is the device ID to remove, i.e.:
|
||||
i
|
||||
Takes one uint32 argument, which is the device ID to remove, i.e.:
|
||||
u
|
||||
is the signature.
|
||||
Same return values as org.x.config.input.add.
|
||||
|
||||
Returns one signed int32 which represents an X status as defined in
|
||||
X.h. See org.x.config.input.add. Error codes are negative numbers.
|
||||
|
||||
org.x.config.input.listDevices:
|
||||
Lists the currently active devices. No argument.
|
||||
Return value is sequence of [<id> <name>] [<id> <name>] ..., i.e. [us].
|
||||
|
|
|
|||
243
config/dbus-core.c
Normal file
243
config/dbus-core.c
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* Copyright © 2006-2007 Daniel Stone
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#define DBUS_API_SUBJECT_TO_CHANGE
|
||||
#include <dbus/dbus.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include "config-backends.h"
|
||||
#include "dix.h"
|
||||
#include "os.h"
|
||||
|
||||
/* How often to attempt reconnecting when we get booted off the bus. */
|
||||
#define RECONNECT_DELAY (10 * 1000) /* in ms */
|
||||
|
||||
struct dbus_core_info {
|
||||
int fd;
|
||||
DBusConnection *connection;
|
||||
OsTimerPtr timer;
|
||||
struct config_dbus_core_hook *hooks;
|
||||
};
|
||||
static struct dbus_core_info bus_info;
|
||||
|
||||
static CARD32 reconnect_timer(OsTimerPtr timer, CARD32 time, pointer arg);
|
||||
|
||||
static void
|
||||
wakeup_handler(pointer data, int err, pointer read_mask)
|
||||
{
|
||||
struct dbus_core_info *info = data;
|
||||
|
||||
if (info->connection && FD_ISSET(info->fd, (fd_set *) read_mask)) {
|
||||
do {
|
||||
dbus_connection_read_write_dispatch(info->connection, 0);
|
||||
} while (dbus_connection_get_dispatch_status(info->connection) ==
|
||||
DBUS_DISPATCH_DATA_REMAINS);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
block_handler(pointer data, struct timeval **tv, pointer read_mask)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect (if we haven't already been forcefully disconnected), clean up
|
||||
* after ourselves, and call all registered disconnect hooks.
|
||||
*/
|
||||
static void
|
||||
teardown(void)
|
||||
{
|
||||
struct config_dbus_core_hook *hook;
|
||||
|
||||
if (bus_info.timer) {
|
||||
TimerCancel(bus_info.timer);
|
||||
bus_info.timer = NULL;
|
||||
}
|
||||
|
||||
/* We should really have pre-disconnect hooks and run them here, for
|
||||
* completeness. But then it gets awkward, given that you can't
|
||||
* guarantee that they'll be called ... */
|
||||
if (bus_info.connection)
|
||||
dbus_connection_unref(bus_info.connection);
|
||||
|
||||
RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, &bus_info);
|
||||
RemoveGeneralSocket(bus_info.fd);
|
||||
bus_info.fd = -1;
|
||||
bus_info.connection = NULL;
|
||||
|
||||
for (hook = bus_info.hooks; hook; hook = hook->next) {
|
||||
if (hook->disconnect)
|
||||
hook->disconnect(hook->data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a filter, which only handles the disconnected signal, which
|
||||
* doesn't go to the normal message handling function. This takes
|
||||
* precedence over the message handling function, so have have to be
|
||||
* careful to ignore anything we don't want to deal with here.
|
||||
*/
|
||||
static DBusHandlerResult
|
||||
message_filter(DBusConnection *connection, DBusMessage *message, void *data)
|
||||
{
|
||||
/* If we get disconnected, then take everything down, and attempt to
|
||||
* reconnect immediately (assuming it's just a restart). The
|
||||
* connection isn't valid at this point, so throw it out immediately. */
|
||||
if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL,
|
||||
"Disconnected")) {
|
||||
DebugF("[config/dbus-core] disconnected from bus\n");
|
||||
bus_info.connection = NULL;
|
||||
teardown();
|
||||
|
||||
bus_info.timer = TimerSet(NULL, 0, 1, reconnect_timer, NULL);
|
||||
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to connect to the system bus, and set a filter to deal with
|
||||
* disconnection (see message_filter above).
|
||||
*
|
||||
* @return 1 on success, 0 on failure.
|
||||
*/
|
||||
static int
|
||||
connect_to_bus(void)
|
||||
{
|
||||
DBusError error;
|
||||
struct config_dbus_core_hook *hook;
|
||||
|
||||
dbus_error_init(&error);
|
||||
bus_info.connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
|
||||
if (!bus_info.connection || dbus_error_is_set(&error)) {
|
||||
DebugF("[config/dbus-core] error connecting to system bus: %s (%s)\n",
|
||||
error.name, error.message);
|
||||
goto err_begin;
|
||||
}
|
||||
|
||||
/* Thankyou. Really, thankyou. */
|
||||
dbus_connection_set_exit_on_disconnect(bus_info.connection, FALSE);
|
||||
|
||||
if (!dbus_connection_get_unix_fd(bus_info.connection, &bus_info.fd)) {
|
||||
ErrorF("[config/dbus-core] couldn't get fd for system bus\n");
|
||||
goto err_unref;
|
||||
}
|
||||
|
||||
if (!dbus_connection_add_filter(bus_info.connection, message_filter,
|
||||
&bus_info, NULL)) {
|
||||
ErrorF("[config/dbus-core] couldn't add filter: %s (%s)\n", error.name,
|
||||
error.message);
|
||||
goto err_fd;
|
||||
}
|
||||
|
||||
dbus_error_free(&error);
|
||||
AddGeneralSocket(bus_info.fd);
|
||||
|
||||
RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, &bus_info);
|
||||
|
||||
for (hook = bus_info.hooks; hook; hook = hook->next) {
|
||||
if (hook->connect)
|
||||
hook->connect(bus_info.connection, hook->data);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
err_fd:
|
||||
bus_info.fd = -1;
|
||||
err_unref:
|
||||
dbus_connection_unref(bus_info.connection);
|
||||
bus_info.connection = NULL;
|
||||
err_begin:
|
||||
dbus_error_free(&error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CARD32
|
||||
reconnect_timer(OsTimerPtr timer, CARD32 time, pointer arg)
|
||||
{
|
||||
if (connect_to_bus()) {
|
||||
bus_info.timer = NULL;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return RECONNECT_DELAY;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
config_dbus_core_add_hook(struct config_dbus_core_hook *hook)
|
||||
{
|
||||
struct config_dbus_core_hook **prev;
|
||||
|
||||
for (prev = &bus_info.hooks; *prev; prev = &(*prev)->next)
|
||||
;
|
||||
|
||||
hook->next = NULL;
|
||||
*prev = hook;
|
||||
|
||||
/* If we're already connected, call the connect hook. */
|
||||
if (bus_info.connection)
|
||||
hook->connect(bus_info.connection, hook->data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
config_dbus_core_remove_hook(struct config_dbus_core_hook *hook)
|
||||
{
|
||||
struct config_dbus_core_hook **prev;
|
||||
|
||||
for (prev = &bus_info.hooks; *prev; prev = &(*prev)->next) {
|
||||
if (*prev == hook) {
|
||||
*prev = hook->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
config_dbus_core_init(void)
|
||||
{
|
||||
memset(&bus_info, 0, sizeof(bus_info));
|
||||
bus_info.fd = -1;
|
||||
bus_info.hooks = NULL;
|
||||
bus_info.connection = NULL;
|
||||
bus_info.timer = TimerSet(NULL, 0, 1, reconnect_timer, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
config_dbus_core_fini(void)
|
||||
{
|
||||
teardown();
|
||||
}
|
||||
443
config/dbus.c
Normal file
443
config/dbus.c
Normal file
|
|
@ -0,0 +1,443 @@
|
|||
/*
|
||||
* Copyright © 2006-2007 Daniel Stone
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#define DBUS_API_SUBJECT_TO_CHANGE
|
||||
#include <dbus/dbus.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <X11/X.h>
|
||||
|
||||
#include "config-backends.h"
|
||||
#include "opaque.h" /* for 'display': there should be a better way. */
|
||||
#include "input.h"
|
||||
#include "inputstr.h"
|
||||
|
||||
#define API_VERSION 2
|
||||
|
||||
#define MATCH_RULE "type='method_call',interface='org.x.config.input'"
|
||||
|
||||
#define MALFORMED_MSG "[config/dbus] malformed message, dropping"
|
||||
#define MALFORMED_MESSAGE() { DebugF(MALFORMED_MSG "\n"); \
|
||||
ret = BadValue; \
|
||||
goto unwind; }
|
||||
#define MALFORMED_MESSAGE_ERROR() { DebugF(MALFORMED_MSG ": %s, %s", \
|
||||
error->name, error->message); \
|
||||
ret = BadValue; \
|
||||
goto unwind; }
|
||||
|
||||
struct connection_info {
|
||||
char busobject[32];
|
||||
char busname[64];
|
||||
DBusConnection *connection;
|
||||
};
|
||||
|
||||
static void
|
||||
reset_info(struct connection_info *info)
|
||||
{
|
||||
info->connection = NULL;
|
||||
info->busname[0] = '\0';
|
||||
info->busobject[0] = '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
add_device(DBusMessage *message, DBusMessage *reply, DBusError *error)
|
||||
{
|
||||
DBusMessageIter iter, reply_iter, subiter;
|
||||
InputOption *tmpo = NULL, *options = NULL;
|
||||
char *tmp = NULL;
|
||||
int ret, err;
|
||||
DeviceIntPtr dev = NULL;
|
||||
|
||||
dbus_message_iter_init_append(reply, &reply_iter);
|
||||
|
||||
if (!dbus_message_iter_init(message, &iter)) {
|
||||
ErrorF("[config/dbus] couldn't initialise iterator\n");
|
||||
MALFORMED_MESSAGE();
|
||||
}
|
||||
|
||||
options = xcalloc(sizeof(*options), 1);
|
||||
if (!options) {
|
||||
ErrorF("[config/dbus] couldn't allocate option\n");
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
options->key = xstrdup("_source");
|
||||
options->value = xstrdup("client/dbus");
|
||||
if (!options->key || !options->value) {
|
||||
ErrorF("[config/dbus] couldn't allocate first key/value pair\n");
|
||||
ret = BadAlloc;
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
/* signature should be [ss][ss]... */
|
||||
while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY) {
|
||||
tmpo = xcalloc(sizeof(*tmpo), 1);
|
||||
if (!tmpo) {
|
||||
ErrorF("[config/dbus] couldn't allocate option\n");
|
||||
ret = BadAlloc;
|
||||
goto unwind;
|
||||
}
|
||||
tmpo->next = options;
|
||||
options = tmpo;
|
||||
|
||||
dbus_message_iter_recurse(&iter, &subiter);
|
||||
|
||||
if (dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_STRING)
|
||||
MALFORMED_MESSAGE();
|
||||
|
||||
dbus_message_iter_get_basic(&subiter, &tmp);
|
||||
if (!tmp)
|
||||
MALFORMED_MESSAGE();
|
||||
/* The _ prefix refers to internal settings, and may not be given by
|
||||
* the client. */
|
||||
if (tmp[0] == '_') {
|
||||
ErrorF("[config/dbus] attempted subterfuge: option name %s given\n",
|
||||
tmp);
|
||||
MALFORMED_MESSAGE();
|
||||
}
|
||||
options->key = xstrdup(tmp);
|
||||
if (!options->key) {
|
||||
ErrorF("[config/dbus] couldn't duplicate key!\n");
|
||||
ret = BadAlloc;
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
if (!dbus_message_iter_has_next(&subiter))
|
||||
MALFORMED_MESSAGE();
|
||||
dbus_message_iter_next(&subiter);
|
||||
if (dbus_message_iter_get_arg_type(&subiter) != DBUS_TYPE_STRING)
|
||||
MALFORMED_MESSAGE();
|
||||
|
||||
dbus_message_iter_get_basic(&subiter, &tmp);
|
||||
if (!tmp)
|
||||
MALFORMED_MESSAGE();
|
||||
options->value = xstrdup(tmp);
|
||||
if (!options->value) {
|
||||
ErrorF("[config/dbus] couldn't duplicate option!\n");
|
||||
ret = BadAlloc;
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
dbus_message_iter_next(&iter);
|
||||
}
|
||||
|
||||
ret = NewInputDeviceRequest(options, &dev);
|
||||
if (ret != Success) {
|
||||
DebugF("[config/dbus] NewInputDeviceRequest failed\n");
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
if (!dev) {
|
||||
DebugF("[config/dbus] NewInputDeviceRequest provided no device\n");
|
||||
ret = BadImplementation;
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
/* XXX: If we fail halfway through, we don't seem to have any way to
|
||||
* empty the iterator, so you'll end up with some device IDs,
|
||||
* plus an error. This seems to be a shortcoming in the D-Bus
|
||||
* API. */
|
||||
for (; dev; dev = dev->next) {
|
||||
if (!dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32,
|
||||
&dev->id)) {
|
||||
ErrorF("[config/dbus] couldn't append to iterator\n");
|
||||
ret = BadAlloc;
|
||||
goto unwind;
|
||||
}
|
||||
}
|
||||
|
||||
unwind:
|
||||
if (ret != Success) {
|
||||
if (dev)
|
||||
RemoveDevice(dev);
|
||||
|
||||
err = -ret;
|
||||
dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32, &err);
|
||||
}
|
||||
|
||||
while (options) {
|
||||
tmpo = options;
|
||||
options = options->next;
|
||||
if (tmpo->key)
|
||||
xfree(tmpo->key);
|
||||
if (tmpo->value)
|
||||
xfree(tmpo->value);
|
||||
xfree(tmpo);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
remove_device(DBusMessage *message, DBusMessage *reply, DBusError *error)
|
||||
{
|
||||
int deviceid, ret, err;
|
||||
DeviceIntPtr dev;
|
||||
DBusMessageIter iter, reply_iter;
|
||||
|
||||
dbus_message_iter_init_append(reply, &reply_iter);
|
||||
|
||||
if (!dbus_message_iter_init(message, &iter)) {
|
||||
ErrorF("[config/dbus] failed to init iterator\n");
|
||||
MALFORMED_MESSAGE();
|
||||
}
|
||||
|
||||
if (!dbus_message_get_args(message, error, DBUS_TYPE_UINT32,
|
||||
&deviceid, DBUS_TYPE_INVALID)) {
|
||||
MALFORMED_MESSAGE_ERROR();
|
||||
}
|
||||
|
||||
dev = LookupDeviceIntRec(deviceid);
|
||||
if (!dev) {
|
||||
DebugF("[config/dbus] bogus device id %d given\n", deviceid);
|
||||
ret = BadMatch;
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
DebugF("[config/dbus] removing device %s (id %d)\n", dev->name, deviceid);
|
||||
|
||||
/* Call PIE here so we don't try to dereference a device that's
|
||||
* already been removed. */
|
||||
OsBlockSignals();
|
||||
ProcessInputEvents();
|
||||
DeleteInputDeviceRequest(dev);
|
||||
OsReleaseSignals();
|
||||
|
||||
ret = Success;
|
||||
|
||||
unwind:
|
||||
err = (ret == Success) ? ret : -ret;
|
||||
dbus_message_iter_append_basic(&reply_iter, DBUS_TYPE_INT32, &err);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
list_devices(DBusMessage *message, DBusMessage *reply, DBusError *error)
|
||||
{
|
||||
DeviceIntPtr dev;
|
||||
DBusMessageIter iter, subiter;
|
||||
|
||||
dbus_message_iter_init_append(reply, &iter);
|
||||
|
||||
for (dev = inputInfo.devices; dev; dev = dev->next) {
|
||||
if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_STRUCT, NULL,
|
||||
&subiter)) {
|
||||
ErrorF("[config/dbus] couldn't init container\n");
|
||||
return BadAlloc;
|
||||
}
|
||||
if (!dbus_message_iter_append_basic(&subiter, DBUS_TYPE_UINT32,
|
||||
&dev->id)) {
|
||||
ErrorF("[config/dbus] couldn't append to iterator\n");
|
||||
return BadAlloc;
|
||||
}
|
||||
if (!dbus_message_iter_append_basic(&subiter, DBUS_TYPE_STRING,
|
||||
&dev->name)) {
|
||||
ErrorF("[config/dbus] couldn't append to iterator\n");
|
||||
return BadAlloc;
|
||||
}
|
||||
if (!dbus_message_iter_close_container(&iter, &subiter)) {
|
||||
ErrorF("[config/dbus] couldn't close container\n");
|
||||
return BadAlloc;
|
||||
}
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
get_version(DBusMessage *message, DBusMessage *reply, DBusError *error)
|
||||
{
|
||||
DBusMessageIter iter;
|
||||
unsigned int version = API_VERSION;
|
||||
|
||||
dbus_message_iter_init_append(reply, &iter);
|
||||
if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &version)) {
|
||||
ErrorF("[config/dbus] couldn't append version\n");
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static DBusHandlerResult
|
||||
message_handler(DBusConnection *connection, DBusMessage *message, void *data)
|
||||
{
|
||||
DBusError error;
|
||||
DBusMessage *reply;
|
||||
struct connection_info *info = data;
|
||||
|
||||
/* ret is the overall D-Bus handler result, whereas err is the internal
|
||||
* X error from our individual functions. */
|
||||
int ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
int err;
|
||||
|
||||
DebugF("[config/dbus] received a message for %s\n",
|
||||
dbus_message_get_interface(message));
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
reply = dbus_message_new_method_return(message);
|
||||
if (!reply) {
|
||||
ErrorF("[config/dbus] failed to create reply\n");
|
||||
ret = DBUS_HANDLER_RESULT_NEED_MEMORY;
|
||||
goto err_start;
|
||||
}
|
||||
|
||||
if (strcmp(dbus_message_get_member(message), "add") == 0)
|
||||
err = add_device(message, reply, &error);
|
||||
else if (strcmp(dbus_message_get_member(message), "remove") == 0)
|
||||
err = remove_device(message, reply, &error);
|
||||
else if (strcmp(dbus_message_get_member(message), "listDevices") == 0)
|
||||
err = list_devices(message, reply, &error);
|
||||
else if (strcmp(dbus_message_get_member(message), "version") == 0)
|
||||
err = get_version(message, reply, &error);
|
||||
else
|
||||
goto err_reply;
|
||||
|
||||
/* Failure to allocate is a special case. */
|
||||
if (err == BadAlloc) {
|
||||
ret = DBUS_HANDLER_RESULT_NEED_MEMORY;
|
||||
goto err_reply;
|
||||
}
|
||||
|
||||
/* While failure here is always an OOM, we don't return that,
|
||||
* since that would result in devices being double-added/removed. */
|
||||
if (dbus_connection_send(info->connection, reply, NULL))
|
||||
dbus_connection_flush(info->connection);
|
||||
else
|
||||
ErrorF("[config/dbus] failed to send reply\n");
|
||||
|
||||
ret = DBUS_HANDLER_RESULT_HANDLED;
|
||||
|
||||
err_reply:
|
||||
dbus_message_unref(reply);
|
||||
err_start:
|
||||
dbus_error_free(&error);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
connect_hook(DBusConnection *connection, void *data)
|
||||
{
|
||||
DBusError error;
|
||||
DBusObjectPathVTable vtable = { .message_function = message_handler, };
|
||||
struct connection_info *info = data;
|
||||
|
||||
info->connection = connection;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
if (!dbus_bus_request_name(info->connection, info->busname,
|
||||
0, &error)) {
|
||||
ErrorF("[config/dbus] couldn't take over org.x.config: %s (%s)\n",
|
||||
error.name, error.message);
|
||||
goto err_start;
|
||||
}
|
||||
|
||||
/* blocks until we get a reply. */
|
||||
dbus_bus_add_match(info->connection, MATCH_RULE, &error);
|
||||
if (dbus_error_is_set(&error)) {
|
||||
ErrorF("[config/dbus] couldn't add match: %s (%s)\n", error.name,
|
||||
error.message);
|
||||
goto err_name;
|
||||
}
|
||||
|
||||
if (!dbus_connection_register_object_path(info->connection,
|
||||
info->busobject, &vtable,
|
||||
info)) {
|
||||
ErrorF("[config/dbus] couldn't register object path\n");
|
||||
goto err_match;
|
||||
}
|
||||
|
||||
DebugF("[dbus] registered %s, %s\n", info->busname, info->busobject);
|
||||
|
||||
dbus_error_free(&error);
|
||||
|
||||
return;
|
||||
|
||||
err_match:
|
||||
dbus_bus_remove_match(info->connection, MATCH_RULE, &error);
|
||||
err_name:
|
||||
dbus_bus_release_name(info->connection, info->busname, &error);
|
||||
err_start:
|
||||
dbus_error_free(&error);
|
||||
|
||||
reset_info(info);
|
||||
}
|
||||
|
||||
static void
|
||||
disconnect_hook(void *data)
|
||||
{
|
||||
struct connection_info *info = data;
|
||||
|
||||
reset_info(info);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
pre_disconnect_hook(void)
|
||||
{
|
||||
DBusError error;
|
||||
|
||||
dbus_error_init(&error);
|
||||
dbus_connection_unregister_object_path(connection_data->connection,
|
||||
connection_data->busobject);
|
||||
dbus_bus_remove_match(connection_data->connection, MATCH_RULE,
|
||||
&error);
|
||||
dbus_bus_release_name(connection_data->connection,
|
||||
connection_data->busname, &error);
|
||||
dbus_error_free(&error);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct connection_info connection_data;
|
||||
static struct config_dbus_core_hook core_hook = {
|
||||
.connect = connect_hook,
|
||||
.disconnect = disconnect_hook,
|
||||
.data = &connection_data,
|
||||
};
|
||||
|
||||
int
|
||||
config_dbus_init(void)
|
||||
{
|
||||
snprintf(connection_data.busname, sizeof(connection_data.busname),
|
||||
"org.x.config.display%d", atoi(display));
|
||||
snprintf(connection_data.busobject, sizeof(connection_data.busobject),
|
||||
"/org/x/config/%d", atoi(display));
|
||||
|
||||
return config_dbus_core_add_hook(&core_hook);
|
||||
}
|
||||
|
||||
void
|
||||
config_dbus_fini(void)
|
||||
{
|
||||
config_dbus_core_remove_hook(&core_hook);
|
||||
}
|
||||
370
config/hal.c
Normal file
370
config/hal.c
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
/*
|
||||
* Copyright © 2007 Daniel Stone
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
#include <hal/libhal.h>
|
||||
#include <string.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include "input.h"
|
||||
#include "inputstr.h"
|
||||
#include "hotplug.h"
|
||||
#include "config-backends.h"
|
||||
#include "os.h"
|
||||
|
||||
#define TYPE_NONE 0
|
||||
#define TYPE_KEYS 1
|
||||
#define TYPE_POINTER 2
|
||||
|
||||
struct config_hal_info {
|
||||
DBusConnection *system_bus;
|
||||
LibHalContext *hal_ctx;
|
||||
};
|
||||
|
||||
static void
|
||||
remove_device(DeviceIntPtr dev)
|
||||
{
|
||||
DebugF("[config/hal] removing device %s\n", dev->name);
|
||||
|
||||
/* Call PIE here so we don't try to dereference a device that's
|
||||
* already been removed. */
|
||||
OsBlockSignals();
|
||||
ProcessInputEvents();
|
||||
DeleteInputDeviceRequest(dev);
|
||||
OsReleaseSignals();
|
||||
}
|
||||
|
||||
static void
|
||||
device_removed(LibHalContext *ctx, const char *udi)
|
||||
{
|
||||
DeviceIntPtr dev;
|
||||
char *value;
|
||||
|
||||
value = xalloc(strlen(udi) + 5); /* "hal:" + NULL */
|
||||
if (!value)
|
||||
return;
|
||||
sprintf(value, "hal:%s", udi);
|
||||
|
||||
for (dev = inputInfo.devices; dev; dev = dev->next) {
|
||||
if (dev->config_info && strcmp(dev->config_info, value) == 0)
|
||||
remove_device(dev);
|
||||
}
|
||||
for (dev = inputInfo.off_devices; dev; dev = dev->next) {
|
||||
if (dev->config_info && strcmp(dev->config_info, value) == 0)
|
||||
remove_device(dev);
|
||||
}
|
||||
|
||||
xfree(value);
|
||||
}
|
||||
|
||||
static void
|
||||
add_option(InputOption **options, const char *key, const char *value)
|
||||
{
|
||||
if (!value || *value == '\0')
|
||||
return;
|
||||
|
||||
for (; *options; options = &(*options)->next)
|
||||
;
|
||||
*options = xcalloc(sizeof(**options), 1);
|
||||
(*options)->key = xstrdup(key);
|
||||
(*options)->value = xstrdup(value);
|
||||
(*options)->next = NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_prop_string(LibHalContext *hal_ctx, const char *udi, const char *name)
|
||||
{
|
||||
char *prop, *ret;
|
||||
|
||||
prop = libhal_device_get_property_string(hal_ctx, udi, name, NULL);
|
||||
DebugF(" [config/hal] getting %s on %s returned %s\n", name, udi, prop);
|
||||
if (prop) {
|
||||
ret = xstrdup(prop);
|
||||
libhal_free_string(prop);
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop)
|
||||
{
|
||||
char **props, *ret, *str;
|
||||
int i, len = 0;
|
||||
|
||||
props = libhal_device_get_property_strlist(hal_ctx, udi, prop, NULL);
|
||||
if (props) {
|
||||
for (i = 0; props[i]; i++)
|
||||
len += strlen(props[i]);
|
||||
|
||||
ret = xcalloc(sizeof(char), len + i); /* i - 1 commas, 1 NULL */
|
||||
if (!ret) {
|
||||
libhal_free_string_array(props);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
str = ret;
|
||||
for (i = 0; props[i]; i++) {
|
||||
str = strcpy(str, props[i]);
|
||||
*str++ = ',';
|
||||
}
|
||||
*str = '\0';
|
||||
|
||||
libhal_free_string_array(props);
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
device_added(LibHalContext *hal_ctx, const char *udi)
|
||||
{
|
||||
char **props;
|
||||
char *path = NULL, *driver = NULL, *name = NULL, *xkb_rules = NULL;
|
||||
char *xkb_model = NULL, *xkb_layout = NULL, *xkb_variant = NULL;
|
||||
char *xkb_options = NULL, *config_info = NULL;
|
||||
InputOption *options = NULL;
|
||||
DeviceIntPtr dev;
|
||||
DBusError error;
|
||||
int type = TYPE_NONE;
|
||||
int i;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
props = libhal_device_get_property_strlist(hal_ctx, udi,
|
||||
"info.capabilities", &error);
|
||||
if (!props) {
|
||||
DebugF("[config/hal] couldn't get capabilities for %s: %s (%s)\n",
|
||||
udi, error.name, error.message);
|
||||
goto out_error;
|
||||
}
|
||||
for (i = 0; props[i]; i++) {
|
||||
/* input.keys is the new, of which input.keyboard is a subset, but
|
||||
* input.keyboard is the old 'we have keys', so we have to keep it
|
||||
* around. */
|
||||
if (strcmp(props[i], "input.keys") == 0 ||
|
||||
strcmp(props[i], "input.keyboard") == 0)
|
||||
type |= TYPE_KEYS;
|
||||
if (strcmp(props[i], "input.mouse") == 0)
|
||||
type |= TYPE_POINTER;
|
||||
}
|
||||
libhal_free_string_array(props);
|
||||
|
||||
if (type == TYPE_NONE)
|
||||
goto out_error;
|
||||
|
||||
driver = get_prop_string(hal_ctx, udi, "input.x11_driver");
|
||||
path = get_prop_string(hal_ctx, udi, "input.device");
|
||||
if (!driver || !path) {
|
||||
DebugF("[config/hal] no driver or path specified for %s\n", udi);
|
||||
goto unwind;
|
||||
}
|
||||
name = get_prop_string(hal_ctx, udi, "info.product");
|
||||
if (!name)
|
||||
name = xstrdup("(unnamed)");
|
||||
|
||||
if (type & TYPE_KEYS) {
|
||||
xkb_rules = get_prop_string(hal_ctx, udi, "input.xkb.rules");
|
||||
xkb_model = get_prop_string(hal_ctx, udi, "input.xkb.model");
|
||||
xkb_layout = get_prop_string(hal_ctx, udi, "input.xkb.layout");
|
||||
xkb_variant = get_prop_string(hal_ctx, udi, "input.xkb.variant");
|
||||
xkb_options = get_prop_string_array(hal_ctx, udi, "input.xkb.options");
|
||||
}
|
||||
|
||||
options = xcalloc(sizeof(*options), 1);
|
||||
options->key = xstrdup("_source");
|
||||
options->value = xstrdup("server/hal");
|
||||
if (!options->key || !options->value) {
|
||||
ErrorF("[config] couldn't allocate first key/value pair\n");
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
add_option(&options, "path", path);
|
||||
add_option(&options, "driver", driver);
|
||||
add_option(&options, "name", name);
|
||||
config_info = xalloc(strlen(udi) + 5); /* "hal:" and NULL */
|
||||
if (!config_info)
|
||||
goto unwind;
|
||||
sprintf(config_info, "hal:%s", udi);
|
||||
|
||||
if (xkb_model)
|
||||
add_option(&options, "xkb_model", xkb_model);
|
||||
if (xkb_layout)
|
||||
add_option(&options, "xkb_layout", xkb_layout);
|
||||
if (xkb_variant)
|
||||
add_option(&options, "xkb_variant", xkb_variant);
|
||||
if (xkb_options)
|
||||
add_option(&options, "xkb_options", xkb_options);
|
||||
|
||||
if (NewInputDeviceRequest(options, &dev) != Success) {
|
||||
DebugF("[config/hal] NewInputDeviceRequest failed\n");
|
||||
goto unwind;
|
||||
}
|
||||
|
||||
for (; dev; dev = dev->next)
|
||||
dev->config_info = xstrdup(config_info);
|
||||
|
||||
unwind:
|
||||
if (path)
|
||||
xfree(path);
|
||||
if (driver)
|
||||
xfree(driver);
|
||||
if (name)
|
||||
xfree(name);
|
||||
if (xkb_rules)
|
||||
xfree(xkb_rules);
|
||||
if (xkb_model)
|
||||
xfree(xkb_model);
|
||||
if (xkb_layout)
|
||||
xfree(xkb_layout);
|
||||
if (xkb_options)
|
||||
xfree(xkb_options);
|
||||
if (config_info)
|
||||
xfree(config_info);
|
||||
|
||||
out_error:
|
||||
dbus_error_free(&error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
disconnect_hook(void *data)
|
||||
{
|
||||
DBusError error;
|
||||
struct config_hal_info *info = data;
|
||||
|
||||
if (info->hal_ctx) {
|
||||
dbus_error_init(&error);
|
||||
if (!libhal_ctx_shutdown(info->hal_ctx, &error))
|
||||
DebugF("[config/hal] couldn't shut down context: %s (%s)\n",
|
||||
error.name, error.message);
|
||||
libhal_ctx_free(info->hal_ctx);
|
||||
dbus_error_free(&error);
|
||||
}
|
||||
|
||||
info->hal_ctx = NULL;
|
||||
info->system_bus = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
connect_hook(DBusConnection *connection, void *data)
|
||||
{
|
||||
DBusError error;
|
||||
struct config_hal_info *info = data;
|
||||
char **devices;
|
||||
int num_devices, i;
|
||||
|
||||
info->system_bus = connection;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
if (!info->hal_ctx)
|
||||
info->hal_ctx = libhal_ctx_new();
|
||||
if (!info->hal_ctx) {
|
||||
ErrorF("[config/hal] couldn't create HAL context\n");
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (!libhal_ctx_set_dbus_connection(info->hal_ctx, info->system_bus)) {
|
||||
ErrorF("[config/hal] couldn't associate HAL context with bus\n");
|
||||
goto out_ctx;
|
||||
}
|
||||
if (!libhal_ctx_init(info->hal_ctx, &error)) {
|
||||
ErrorF("[config/hal] couldn't initialise context: %s (%s)\n",
|
||||
error.name, error.message);
|
||||
goto out_ctx;
|
||||
}
|
||||
if (!libhal_device_property_watch_all(info->hal_ctx, &error)) {
|
||||
ErrorF("[config/hal] couldn't watch all properties: %s (%s)\n",
|
||||
error.name, error.message);
|
||||
goto out_ctx2;
|
||||
}
|
||||
libhal_ctx_set_device_added(info->hal_ctx, device_added);
|
||||
libhal_ctx_set_device_removed(info->hal_ctx, device_removed);
|
||||
|
||||
devices = libhal_find_device_by_capability(info->hal_ctx, "input",
|
||||
&num_devices, &error);
|
||||
/* FIXME: Get default devices if error is set. */
|
||||
for (i = 0; i < num_devices; i++)
|
||||
device_added(info->hal_ctx, devices[i]);
|
||||
libhal_free_string_array(devices);
|
||||
|
||||
dbus_error_free(&error);
|
||||
|
||||
return;
|
||||
|
||||
out_ctx2:
|
||||
if (!libhal_ctx_shutdown(info->hal_ctx, &error))
|
||||
DebugF("[config/hal] couldn't shut down context: %s (%s)\n",
|
||||
error.name, error.message);
|
||||
out_ctx:
|
||||
libhal_ctx_free(info->hal_ctx);
|
||||
out_err:
|
||||
dbus_error_free(&error);
|
||||
|
||||
info->hal_ctx = NULL;
|
||||
info->system_bus = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static struct config_hal_info hal_info;
|
||||
static struct config_dbus_core_hook hook = {
|
||||
.connect = connect_hook,
|
||||
.disconnect = disconnect_hook,
|
||||
.data = &hal_info,
|
||||
};
|
||||
|
||||
int
|
||||
config_hal_init(void)
|
||||
{
|
||||
memset(&hal_info, 0, sizeof(hal_info));
|
||||
hal_info.system_bus = NULL;
|
||||
hal_info.hal_ctx = NULL;
|
||||
|
||||
if (!config_dbus_core_add_hook(&hook)) {
|
||||
ErrorF("[config/hal] failed to add D-Bus hook\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
config_hal_fini(void)
|
||||
{
|
||||
config_dbus_core_remove_hook(&hook);
|
||||
}
|
||||
31
config/x11-input.fdi
Normal file
31
config/x11-input.fdi
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<deviceinfo version="0.2">
|
||||
<device>
|
||||
<!-- FIXME: Support tablets too. -->
|
||||
<match key="info.capabilities" contains="input.mouse">
|
||||
<merge key="input.x11_driver" type="string">mouse</merge>
|
||||
<match key="/org/freedesktop/Hal/devices/computer:system.kernel.name"
|
||||
string="Linux">
|
||||
<merge key="input.x11_driver" type="string">evdev</merge>
|
||||
</match>
|
||||
</match>
|
||||
|
||||
<match key="info.capabilities" contains="input.keys">
|
||||
<merge key="input.xkb.rules" type="string">base</merge>
|
||||
|
||||
<!-- If we're using Linux, we use evdev by default (falling back to
|
||||
keyboard otherwise). -->
|
||||
<merge key="input.x11_driver" type="string">keyboard</merge>
|
||||
<merge key="input.xkb.model" type="string">pc105</merge>
|
||||
<match key="/org/freedesktop/Hal/devices/computer:system.kernel.name"
|
||||
string="Linux">
|
||||
<merge key="input.x11_driver" type="string">evdev</merge>
|
||||
<merge key="input.xkb.model" type="string">evdev</merge>
|
||||
</match>
|
||||
|
||||
<merge key="input.xkb.layout" type="string">us</merge>
|
||||
|
||||
<merge key="input.xkb.variant" type="string" />
|
||||
</match>
|
||||
</device>
|
||||
</deviceinfo>
|
||||
633
configure.ac
633
configure.ac
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright © 2002 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright © 2002 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright © 2002 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
* Header file for DIX-related DBE
|
||||
*
|
||||
*****************************************************************************/
|
||||
/* $XFree86$ */
|
||||
|
||||
#ifndef DBE_STRUCT_H
|
||||
#define DBE_STRUCT_H
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (c) 1994, 1995 Hewlett-Packard Company
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
|
|
@ -29,8 +28,6 @@
|
|||
* Header file for users of machine-independent DBE code
|
||||
*
|
||||
*****************************************************************************/
|
||||
/* $XFree86$ */
|
||||
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
noinst_LTLIBRARIES = libdix.la libxpstubs.la
|
||||
|
||||
AM_CFLAGS = $(DIX_CFLAGS) \
|
||||
-DVENDOR_STRING=\""@VENDOR_STRING@"\" \
|
||||
-DVENDOR_NAME=\""@VENDOR_NAME@"\" \
|
||||
-DVENDOR_RELEASE="@VENDOR_RELEASE@"
|
||||
|
||||
libdix_la_SOURCES = \
|
||||
|
|
@ -57,3 +57,8 @@ noinst_PROGRAMS = dix.O
|
|||
dix.O: dtrace-dix.o $(am_libdix_la_OBJECTS)
|
||||
ld -r -o $@ .libs/*.o
|
||||
endif
|
||||
|
||||
dix.c:
|
||||
touch $@
|
||||
|
||||
CLEANFILES = dix.c
|
||||
|
|
|
|||
22
dix/cursor.c
22
dix/cursor.c
|
|
@ -430,25 +430,41 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar,
|
|||
*************************************************************/
|
||||
|
||||
CursorPtr
|
||||
CreateRootCursor(char *pfilename, unsigned glyph)
|
||||
CreateRootCursor(char *unused1, unsigned int unused2)
|
||||
{
|
||||
CursorPtr curs;
|
||||
#ifdef NULL_ROOT_CURSOR
|
||||
CursorMetricRec cm;
|
||||
#else
|
||||
FontPtr cursorfont;
|
||||
int err;
|
||||
XID fontID;
|
||||
#endif
|
||||
|
||||
#ifdef NULL_ROOT_CURSOR
|
||||
cm.width = 0;
|
||||
cm.height = 0;
|
||||
cm.xhot = 0;
|
||||
cm.yhot = 0;
|
||||
|
||||
curs = AllocCursor(NULL, NULL, &cm, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
if (curs == NullCursor)
|
||||
return NullCursor;
|
||||
#else
|
||||
fontID = FakeClientID(0);
|
||||
err = OpenFont(serverClient, fontID, FontLoadAll | FontOpenSync,
|
||||
(unsigned)strlen( pfilename), pfilename);
|
||||
(unsigned)strlen(defaultCursorFont), defaultCursorFont);
|
||||
if (err != Success)
|
||||
return NullCursor;
|
||||
|
||||
cursorfont = (FontPtr)LookupIDByType(fontID, RT_FONT);
|
||||
if (!cursorfont)
|
||||
return NullCursor;
|
||||
if (AllocGlyphCursor(fontID, glyph, fontID, glyph + 1,
|
||||
if (AllocGlyphCursor(fontID, 0, fontID, 1,
|
||||
0, 0, 0, ~0, ~0, ~0, &curs, serverClient) != Success)
|
||||
return NullCursor;
|
||||
#endif
|
||||
|
||||
if (!AddResource(FakeClientID(0), RT_CURSOR, (pointer)curs))
|
||||
return NullCursor;
|
||||
|
|
|
|||
115
dix/devices.c
115
dix/devices.c
|
|
@ -75,13 +75,25 @@ SOFTWARE.
|
|||
#include "swaprep.h"
|
||||
#include "dixevents.h"
|
||||
|
||||
#include <X11/extensions/XI.h>
|
||||
#include <X11/extensions/XIproto.h>
|
||||
#include "exglobals.h"
|
||||
#include "exevents.h"
|
||||
|
||||
/** @file
|
||||
* This file handles input device-related stuff.
|
||||
*/
|
||||
|
||||
int CoreDevicePrivatesIndex = 0;
|
||||
static int CoreDevicePrivatesGeneration = -1;
|
||||
|
||||
/**
|
||||
* Create a new input device and init it to sane values. The device is added
|
||||
* to the server's off_devices list.
|
||||
*
|
||||
* @param deviceProc Callback for device control function (switch dev on/off).
|
||||
* @return The newly created device.
|
||||
*/
|
||||
DeviceIntPtr
|
||||
AddInputDevice(DeviceProc deviceProc, Bool autoStart)
|
||||
{
|
||||
|
|
@ -137,6 +149,7 @@ AddInputDevice(DeviceProc deviceProc, Bool autoStart)
|
|||
#ifdef XKB
|
||||
dev->xkb_interest = NULL;
|
||||
#endif
|
||||
dev->config_info = NULL;
|
||||
dev->nPrivates = 0;
|
||||
dev->devPrivates = NULL;
|
||||
dev->unwrapProc = NULL;
|
||||
|
|
@ -152,11 +165,22 @@ AddInputDevice(DeviceProc deviceProc, Bool autoStart)
|
|||
return dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch device ON through the driver and push it onto the global device
|
||||
* list. All clients are notified about the device being enabled.
|
||||
*
|
||||
* A device will send events once enabled.
|
||||
*
|
||||
* @param The device to be enabled.
|
||||
* @return TRUE on success or FALSE otherwise.
|
||||
*/
|
||||
Bool
|
||||
EnableDevice(DeviceIntPtr dev)
|
||||
{
|
||||
DeviceIntPtr *prev;
|
||||
int ret;
|
||||
DeviceIntRec dummyDev;
|
||||
devicePresenceNotify ev;
|
||||
|
||||
for (prev = &inputInfo.off_devices;
|
||||
*prev && (*prev != dev);
|
||||
|
|
@ -175,13 +199,30 @@ EnableDevice(DeviceIntPtr dev)
|
|||
*prev = dev;
|
||||
dev->next = NULL;
|
||||
|
||||
ev.type = DevicePresenceNotify;
|
||||
ev.time = currentTime.milliseconds;
|
||||
ev.devchange = DeviceEnabled;
|
||||
ev.deviceid = dev->id;
|
||||
dummyDev.id = 0;
|
||||
SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
|
||||
(xEvent *) &ev, 1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch a device off through the driver and push it onto the off_devices
|
||||
* list. A device will not send events while disabled. All clients are
|
||||
* notified about the device being disabled.
|
||||
*
|
||||
* @return TRUE on success or FALSE otherwise.
|
||||
*/
|
||||
Bool
|
||||
DisableDevice(DeviceIntPtr dev)
|
||||
{
|
||||
DeviceIntPtr *prev;
|
||||
DeviceIntRec dummyDev;
|
||||
devicePresenceNotify ev;
|
||||
|
||||
for (prev = &inputInfo.devices;
|
||||
*prev && (*prev != dev);
|
||||
|
|
@ -194,9 +235,26 @@ DisableDevice(DeviceIntPtr dev)
|
|||
*prev = dev->next;
|
||||
dev->next = inputInfo.off_devices;
|
||||
inputInfo.off_devices = dev;
|
||||
|
||||
ev.type = DevicePresenceNotify;
|
||||
ev.time = currentTime.milliseconds;
|
||||
ev.devchange = DeviceDisabled;
|
||||
ev.deviceid = dev->id;
|
||||
dummyDev.id = 0;
|
||||
SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
|
||||
(xEvent *) &ev, 1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise a new device through the driver and tell all clients about the
|
||||
* new device.
|
||||
*
|
||||
* The device will NOT send events until it is enabled!
|
||||
*
|
||||
* @return Success or an error code on failure.
|
||||
*/
|
||||
int
|
||||
ActivateDevice(DeviceIntPtr dev)
|
||||
{
|
||||
|
|
@ -212,8 +270,8 @@ ActivateDevice(DeviceIntPtr dev)
|
|||
|
||||
ev.type = DevicePresenceNotify;
|
||||
ev.time = currentTime.milliseconds;
|
||||
ev.devchange = 0;
|
||||
ev.deviceid = 0;
|
||||
ev.devchange = DeviceAdded;
|
||||
ev.deviceid = dev->id;
|
||||
dummyDev.id = 0;
|
||||
SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
|
||||
(xEvent *) &ev, 1);
|
||||
|
|
@ -221,6 +279,10 @@ ActivateDevice(DeviceIntPtr dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ring the bell.
|
||||
* The actual task of ringing the bell is the job of the DDX.
|
||||
*/
|
||||
static void
|
||||
CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
|
||||
{
|
||||
|
|
@ -235,6 +297,9 @@ CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
|
|||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Device control function for the Virtual Core Keyboard.
|
||||
*/
|
||||
static int
|
||||
CoreKeyboardProc(DeviceIntPtr pDev, int what)
|
||||
{
|
||||
|
|
@ -295,6 +360,9 @@ CoreKeyboardProc(DeviceIntPtr pDev, int what)
|
|||
return Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Device control function for the Virtual Core Pointer.
|
||||
*/
|
||||
static int
|
||||
CorePointerProc(DeviceIntPtr pDev, int what)
|
||||
{
|
||||
|
|
@ -325,6 +393,12 @@ CorePointerProc(DeviceIntPtr pDev, int what)
|
|||
return Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the two core devices, VCP and VCK (see events.c).
|
||||
* The devices are activated but not enabled.
|
||||
* Note that the server MUST have two core devices at all times, even if there
|
||||
* is no physical device connected.
|
||||
*/
|
||||
void
|
||||
InitCoreDevices(void)
|
||||
{
|
||||
|
|
@ -384,6 +458,14 @@ InitCoreDevices(void)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate all switched-off devices and then enable all those devices.
|
||||
*
|
||||
* Will return an error if no core keyboard or core pointer is present.
|
||||
* In theory this should never happen if you call InitCoreDevices() first.
|
||||
*
|
||||
* @return Success or error code on failure.
|
||||
*/
|
||||
int
|
||||
InitAndStartDevices(void)
|
||||
{
|
||||
|
|
@ -403,6 +485,7 @@ InitAndStartDevices(void)
|
|||
for (dev = inputInfo.devices;
|
||||
dev && (dev != inputInfo.keyboard);
|
||||
dev = dev->next)
|
||||
;
|
||||
if (!dev || (dev != inputInfo.keyboard)) {
|
||||
ErrorF("No core keyboard\n");
|
||||
return BadImplementation;
|
||||
|
|
@ -418,6 +501,13 @@ InitAndStartDevices(void)
|
|||
return Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close down a device and free all resources.
|
||||
* Once closed down, the driver will probably not expect you that you'll ever
|
||||
* enable it again and free associated structs. If you want the device to just
|
||||
* be disabled, DisableDevice().
|
||||
* Don't call this function directly, use RemoveDevice() instead.
|
||||
*/
|
||||
static void
|
||||
CloseDevice(DeviceIntPtr dev)
|
||||
{
|
||||
|
|
@ -519,6 +609,10 @@ CloseDevice(DeviceIntPtr dev)
|
|||
xfree(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut down all devices, free all resources, etc.
|
||||
* Only useful if you're shutting down the server!
|
||||
*/
|
||||
void
|
||||
CloseDownDevices(void)
|
||||
{
|
||||
|
|
@ -540,6 +634,12 @@ CloseDownDevices(void)
|
|||
inputInfo.pointer = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a device from the device list, closes it and thus frees all
|
||||
* resources.
|
||||
* Removes both enabled and disabled devices and notifies all devices about
|
||||
* the removal of the device.
|
||||
*/
|
||||
int
|
||||
RemoveDevice(DeviceIntPtr dev)
|
||||
{
|
||||
|
|
@ -547,12 +647,16 @@ RemoveDevice(DeviceIntPtr dev)
|
|||
int ret = BadMatch;
|
||||
devicePresenceNotify ev;
|
||||
DeviceIntRec dummyDev;
|
||||
int deviceid;
|
||||
|
||||
DebugF("(dix) removing device %d\n", dev->id);
|
||||
|
||||
if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
|
||||
return BadImplementation;
|
||||
|
||||
deviceid = dev->id;
|
||||
DisableDevice(dev);
|
||||
|
||||
prev = NULL;
|
||||
for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
|
||||
next = tmp->next;
|
||||
|
|
@ -587,8 +691,8 @@ RemoveDevice(DeviceIntPtr dev)
|
|||
inputInfo.numDevices--;
|
||||
ev.type = DevicePresenceNotify;
|
||||
ev.time = currentTime.milliseconds;
|
||||
ev.devchange = 0;
|
||||
ev.deviceid = 0;
|
||||
ev.devchange = DeviceRemoved;
|
||||
ev.deviceid = deviceid;
|
||||
dummyDev.id = 0;
|
||||
SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
|
||||
(xEvent *) &ev, 1);
|
||||
|
|
@ -764,6 +868,7 @@ InitKeyClassDeviceStruct(DeviceIntPtr dev, KeySymsPtr pKeySyms, CARD8 pModifiers
|
|||
else
|
||||
bzero((char *)keyc->modifierMap, MAP_LENGTH);
|
||||
bzero((char *)keyc->down, DOWN_LENGTH);
|
||||
bzero((char *)keyc->postdown, DOWN_LENGTH);
|
||||
for (i = 0; i < 8; i++)
|
||||
keyc->modifierKeyCount[i] = 0;
|
||||
if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc))
|
||||
|
|
@ -874,6 +979,7 @@ InitAbsoluteClassDeviceStruct(DeviceIntPtr dev)
|
|||
abs->width = -1;
|
||||
abs->height = -1;
|
||||
abs->following = 0;
|
||||
abs->screen = 0;
|
||||
|
||||
dev->absolute = abs;
|
||||
|
||||
|
|
@ -1241,6 +1347,7 @@ DoSetModifierMapping(ClientPtr client, KeyCode *inputMap,
|
|||
}
|
||||
else {
|
||||
pDev->key->modifierKeyMap = NULL;
|
||||
pDev->key->maxKeysPerModifier = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -996,10 +996,6 @@ ProcGetAtomName(ClientPtr client)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef K5AUTH
|
||||
extern int k5_bad();
|
||||
#endif
|
||||
|
||||
int
|
||||
ProcSetSelectionOwner(ClientPtr client)
|
||||
{
|
||||
|
|
@ -3541,12 +3537,6 @@ InitProcVectors(void)
|
|||
ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
|
||||
ReplySwapVector[i] = ReplyNotSwappd;
|
||||
}
|
||||
#ifdef K5AUTH
|
||||
if (!k5_Vector[i])
|
||||
{
|
||||
k5_Vector[i] = k5_bad;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
for(i = LASTEvent; i < 128; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ _X_EXPORT int
|
|||
dixLookupClient(ClientPtr *pClient, XID rid, ClientPtr client, Mask access)
|
||||
{
|
||||
pointer pRes = (pointer)SecurityLookupIDByClass(client, rid, RC_ANY,
|
||||
DixReadAccess);
|
||||
access);
|
||||
int clientIndex = CLIENT_ID(rid);
|
||||
client->errorValue = rid;
|
||||
|
||||
|
|
|
|||
39
dix/events.c
39
dix/events.c
|
|
@ -160,7 +160,6 @@ extern Mask xevieFilters[128];
|
|||
extern int xevieEventSent;
|
||||
extern int xevieKBEventSent;
|
||||
int xeviegrabState = 0;
|
||||
static xEvent *xeviexE;
|
||||
#endif
|
||||
|
||||
#include <X11/extensions/XIproto.h>
|
||||
|
|
@ -695,6 +694,13 @@ XineramaChangeToCursor(CursorPtr cursor)
|
|||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#define SyntheticMotion(x, y) \
|
||||
PostSyntheticMotion(x, y, \
|
||||
0, \
|
||||
syncEvents.playingEvents ? \
|
||||
syncEvents.time.milliseconds : \
|
||||
currentTime.milliseconds);
|
||||
|
||||
#endif /* PANORAMIX */
|
||||
|
||||
|
|
@ -2622,6 +2628,7 @@ BorderSizeNotEmpty(WindowPtr pWin)
|
|||
/**
|
||||
* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
|
||||
* passive grab set on the window to be activated.
|
||||
* If a passive grab is activated, the event will be delivered to the client.
|
||||
*
|
||||
* @param pWin The window that may be subject to a passive grab.
|
||||
* @param device Device that caused the event.
|
||||
|
|
@ -2721,16 +2728,26 @@ CheckPassiveGrabsOnWindow(
|
|||
}
|
||||
|
||||
/**
|
||||
"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
|
||||
a passive grab to be activated. If the event is a keyboard event, the
|
||||
ancestors of the focus window are traced down and tried to see if they have
|
||||
any passive grabs to be activated. If the focus window itself is reached and
|
||||
it's descendants contain they pointer, the ancestors of the window that the
|
||||
pointer is in are then traced down starting at the focus window, otherwise no
|
||||
grabs are activated. If the event is a pointer event, the ancestors of the
|
||||
window that the pointer is in are traced down starting at the root until
|
||||
CheckPassiveGrabs causes a passive grab to activate or all the windows are
|
||||
tried. PRH
|
||||
* CheckDeviceGrabs handles both keyboard and pointer events that may cause
|
||||
* a passive grab to be activated.
|
||||
*
|
||||
* If the event is a keyboard event, the ancestors of the focus window are
|
||||
* traced down and tried to see if they have any passive grabs to be
|
||||
* activated. If the focus window itself is reached and it's descendants
|
||||
* contain the pointer, the ancestors of the window that the pointer is in
|
||||
* are then traced down starting at the focus window, otherwise no grabs are
|
||||
* activated.
|
||||
* If the event is a pointer event, the ancestors of the window that the
|
||||
* pointer is in are traced down starting at the root until CheckPassiveGrabs
|
||||
* causes a passive grab to activate or all the windows are
|
||||
* tried. PRH
|
||||
*
|
||||
* If a grab is activated, the event has been sent to the client already!
|
||||
*
|
||||
* @param device The device that caused the event.
|
||||
* @param xE The event to handle (most likely {Device}ButtonPress).
|
||||
* @param count Number of events in list.
|
||||
* @return TRUE if a grab has been activated or false otherwise.
|
||||
*/
|
||||
|
||||
Bool
|
||||
|
|
|
|||
134
dix/getevents.c
134
dix/getevents.c
|
|
@ -1,23 +1,25 @@
|
|||
/*
|
||||
* Copyright © 2006 Nokia Corporation
|
||||
* Copyright © 2006 Daniel Stone
|
||||
* Copyright © 2006-2007 Daniel Stone
|
||||
*
|
||||
* 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 this copyright notice and this permission notice appear in
|
||||
* supporting electronic documentation.
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR AUTHORS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Daniel Stone <daniel@fooishbar.org>
|
||||
*/
|
||||
|
|
@ -78,6 +80,23 @@ GetMotionHistorySize(void)
|
|||
return MOTION_HISTORY_SIZE;
|
||||
}
|
||||
|
||||
static void
|
||||
set_key_down(DeviceIntPtr pDev, int key_code)
|
||||
{
|
||||
pDev->key->postdown[key_code >> 3] |= (1 << (key_code & 7));
|
||||
}
|
||||
|
||||
static void
|
||||
set_key_up(DeviceIntPtr pDev, int key_code)
|
||||
{
|
||||
pDev->key->postdown[key_code >> 3] &= ~(1 << (key_code & 7));
|
||||
}
|
||||
|
||||
static Bool
|
||||
key_is_down(DeviceIntPtr pDev, int key_code)
|
||||
{
|
||||
return pDev->key->postdown[key_code >> 3] >> (key_code & 7);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate the motion history buffer.
|
||||
|
|
@ -248,7 +267,7 @@ acceleratePointer(DeviceIntPtr pDev, int first_valuator, int num_valuators,
|
|||
}
|
||||
}
|
||||
else {
|
||||
mult = pow((float)(dx * dx + dy * dy),
|
||||
mult = pow((float)dx * (float)dx + (float)dy * (float)dy,
|
||||
((float)(pDev->ptrfeed->ctrl.num) /
|
||||
(float)(pDev->ptrfeed->ctrl.den) - 1.0) /
|
||||
2.0) / 2.0;
|
||||
|
|
@ -412,17 +431,15 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
|
|||
case XK_Shift_Lock:
|
||||
if (type == KeyRelease)
|
||||
return 0;
|
||||
else if (type == KeyPress &&
|
||||
(pDev->key->down[key_code >> 3] & (key_code & 7)) & 1)
|
||||
type = KeyRelease;
|
||||
else if (type == KeyPress && key_is_down(pDev, key_code))
|
||||
type = KeyRelease;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle core repeating, via press/release/press/release.
|
||||
* FIXME: In theory, if you're repeating with two keyboards in non-XKB,
|
||||
* you could get unbalanced events here. */
|
||||
if (type == KeyPress &&
|
||||
(((pDev->key->down[key_code >> 3] & (key_code & 7))) & 1)) {
|
||||
if (type == KeyPress && key_is_down(pDev, key_code)) {
|
||||
if (!pDev->kbdfeed->ctrl.autoRepeat ||
|
||||
pDev->key->modifierMap[key_code] ||
|
||||
!(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3]
|
||||
|
|
@ -443,13 +460,29 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
|
|||
|
||||
ms = GetTimeInMillis();
|
||||
|
||||
if (pDev->coreEvents) {
|
||||
events->u.keyButtonPointer.time = ms;
|
||||
events->u.u.type = type;
|
||||
events->u.u.detail = key_code;
|
||||
if (type == KeyPress)
|
||||
set_key_down(inputInfo.keyboard, key_code);
|
||||
else if (type == KeyRelease)
|
||||
set_key_up(inputInfo.keyboard, key_code);
|
||||
events++;
|
||||
}
|
||||
|
||||
kbp = (deviceKeyButtonPointer *) events;
|
||||
kbp->time = ms;
|
||||
kbp->deviceid = pDev->id;
|
||||
if (type == KeyPress)
|
||||
kbp->detail = key_code;
|
||||
if (type == KeyPress) {
|
||||
kbp->type = DeviceKeyPress;
|
||||
else if (type == KeyRelease)
|
||||
set_key_down(pDev, key_code);
|
||||
}
|
||||
else if (type == KeyRelease) {
|
||||
kbp->type = DeviceKeyRelease;
|
||||
set_key_up(pDev, key_code);
|
||||
}
|
||||
|
||||
events++;
|
||||
if (num_valuators) {
|
||||
|
|
@ -459,12 +492,6 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type,
|
|||
num_valuators, valuators);
|
||||
}
|
||||
|
||||
if (pDev->coreEvents) {
|
||||
events->u.keyButtonPointer.time = ms;
|
||||
events->u.u.type = type;
|
||||
events->u.u.detail = key_code;
|
||||
}
|
||||
|
||||
return numEvents;
|
||||
}
|
||||
|
||||
|
|
@ -498,14 +525,18 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
|
|||
if ((type == ButtonPress || type == ButtonRelease) && !pDev->button)
|
||||
return 0;
|
||||
|
||||
/* FIXME: I guess it should, in theory, be possible to post button events
|
||||
* from devices without valuators. */
|
||||
if (!pDev->valuator)
|
||||
return 0;
|
||||
|
||||
if (!coreOnly && pDev->coreEvents)
|
||||
num_events = 2;
|
||||
else
|
||||
num_events = 1;
|
||||
|
||||
if (type == MotionNotify && num_valuators <= 0) {
|
||||
if (type == MotionNotify && num_valuators <= 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do we need to send a DeviceValuator event? */
|
||||
if (!coreOnly && sendValuators) {
|
||||
|
|
@ -599,8 +630,27 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
|
|||
pDev->valuator->lastx = x;
|
||||
pDev->valuator->lasty = y;
|
||||
|
||||
if (!coreOnly)
|
||||
{
|
||||
/* for some reason inputInfo.pointer does not have coreEvents set */
|
||||
if (coreOnly || pDev->coreEvents) {
|
||||
events->u.u.type = type;
|
||||
events->u.keyButtonPointer.time = ms;
|
||||
events->u.keyButtonPointer.rootX = x;
|
||||
events->u.keyButtonPointer.rootY = y;
|
||||
|
||||
if (type == ButtonPress || type == ButtonRelease) {
|
||||
/* We hijack SetPointerMapping to work on all core-sending
|
||||
* devices, so we use the device-specific map here instead of
|
||||
* the core one. */
|
||||
events->u.u.detail = pDev->button->map[buttons];
|
||||
}
|
||||
else {
|
||||
events->u.u.detail = 0;
|
||||
}
|
||||
|
||||
events++;
|
||||
}
|
||||
|
||||
if (!coreOnly) {
|
||||
kbp = (deviceKeyButtonPointer *) events;
|
||||
kbp->time = ms;
|
||||
kbp->deviceid = pDev->id;
|
||||
|
|
@ -628,24 +678,6 @@ GetPointerEvents(xEvent *events, DeviceIntPtr pDev, int type, int buttons,
|
|||
}
|
||||
}
|
||||
|
||||
/* for some reason inputInfo.pointer does not have coreEvents set */
|
||||
if (coreOnly || pDev->coreEvents) {
|
||||
events->u.u.type = type;
|
||||
events->u.keyButtonPointer.time = ms;
|
||||
events->u.keyButtonPointer.rootX = x;
|
||||
events->u.keyButtonPointer.rootY = y;
|
||||
|
||||
if (type == ButtonPress || type == ButtonRelease) {
|
||||
/* We hijack SetPointerMapping to work on all core-sending
|
||||
* devices, so we use the device-specific map here instead of
|
||||
* the core one. */
|
||||
events->u.u.detail = pDev->button->map[buttons];
|
||||
}
|
||||
else {
|
||||
events->u.u.detail = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return num_events;
|
||||
}
|
||||
|
||||
|
|
|
|||
47
dix/grabs.c
47
dix/grabs.c
|
|
@ -269,6 +269,42 @@ GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
GrabsAreIdentical(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
|
||||
{
|
||||
if (pFirstGrab->device != pSecondGrab->device ||
|
||||
(pFirstGrab->modifierDevice != pSecondGrab->modifierDevice) ||
|
||||
(pFirstGrab->type != pSecondGrab->type))
|
||||
return FALSE;
|
||||
|
||||
if (!(DetailSupersedesSecond(pFirstGrab->detail,
|
||||
pSecondGrab->detail,
|
||||
(unsigned short)AnyKey) &&
|
||||
DetailSupersedesSecond(pSecondGrab->detail,
|
||||
pFirstGrab->detail,
|
||||
(unsigned short)AnyKey)))
|
||||
return FALSE;
|
||||
|
||||
if (!(DetailSupersedesSecond(pFirstGrab->modifiersDetail,
|
||||
pSecondGrab->modifiersDetail,
|
||||
(unsigned short)AnyModifier) &&
|
||||
DetailSupersedesSecond(pSecondGrab->modifiersDetail,
|
||||
pFirstGrab->modifiersDetail,
|
||||
(unsigned short)AnyModifier)))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepend the new grab to the list of passive grabs on the window.
|
||||
* Any previously existing grab that matches the new grab will be removed.
|
||||
* Adding a new grab that would override another client's grab will result in
|
||||
* a BadAccess.
|
||||
*
|
||||
* @return Success or X error code on failure.
|
||||
*/
|
||||
int
|
||||
AddPassiveGrabToList(GrabPtr pGrab)
|
||||
{
|
||||
|
|
@ -286,11 +322,22 @@ AddPassiveGrabToList(GrabPtr pGrab)
|
|||
}
|
||||
}
|
||||
|
||||
/* Remove all grabs that match the new one exactly */
|
||||
for (grab = wPassiveGrabs(pGrab->window); grab; grab = grab->next)
|
||||
{
|
||||
if (GrabsAreIdentical(pGrab, grab))
|
||||
{
|
||||
DeletePassiveGrabFromList(grab);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pGrab->window->optional && !MakeWindowOptional (pGrab->window))
|
||||
{
|
||||
FreeGrab(pGrab);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
pGrab->next = pGrab->window->optional->passiveGrabs;
|
||||
pGrab->window->optional->passiveGrabs = pGrab;
|
||||
if (AddResource(pGrab->resource, RT_PASSIVEGRAB, (pointer)pGrab))
|
||||
|
|
|
|||
31
dix/main.c
31
dix/main.c
|
|
@ -74,8 +74,6 @@ Equipment Corporation.
|
|||
|
||||
******************************************************************/
|
||||
|
||||
/* $TOG: main.c /main/86 1998/02/09 14:20:03 kaleb $ */
|
||||
|
||||
#define NEED_EVENTS
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
|
|
@ -253,6 +251,7 @@ main(int argc, char *argv[], char *envp[])
|
|||
display = "0";
|
||||
|
||||
InitGlobals();
|
||||
InitRegions();
|
||||
#ifdef XPRINT
|
||||
PrinterInitGlobals();
|
||||
#endif
|
||||
|
|
@ -311,7 +310,7 @@ main(int argc, char *argv[], char *envp[])
|
|||
InitBlockAndWakeupHandlers();
|
||||
/* Perform any operating system dependent initializations you'd like */
|
||||
OsInit();
|
||||
configInitialise();
|
||||
config_init();
|
||||
if(serverGeneration == 1)
|
||||
{
|
||||
CreateWellKnownSockets();
|
||||
|
|
@ -400,14 +399,10 @@ main(int argc, char *argv[], char *envp[])
|
|||
FatalError("failed to initialize core devices");
|
||||
|
||||
InitFonts();
|
||||
#ifdef BUILTIN_FONTS
|
||||
defaultFontPath = "built-ins";
|
||||
#else
|
||||
if (loadableFonts) {
|
||||
SetFontPath(0, 0, (unsigned char *)defaultFontPath, &error);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
}
|
||||
else {
|
||||
if (SetDefaultFontPath(defaultFontPath) != Success)
|
||||
ErrorF("failed to set default font path '%s'",
|
||||
defaultFontPath);
|
||||
|
|
@ -415,22 +410,12 @@ main(int argc, char *argv[], char *envp[])
|
|||
if (!SetDefaultFont(defaultTextFont)) {
|
||||
FatalError("could not open default font '%s'", defaultTextFont);
|
||||
}
|
||||
#ifdef NULL_ROOT_CURSOR
|
||||
cm.width = 0;
|
||||
cm.height = 0;
|
||||
cm.xhot = 0;
|
||||
cm.yhot = 0;
|
||||
|
||||
if (!(rootCursor = AllocCursor(NULL, NULL, &cm, 0, 0, 0, 0, 0, 0))) {
|
||||
FatalError("could not create empty root cursor");
|
||||
}
|
||||
AddResource(FakeClientID(0), RT_CURSOR, (pointer)rootCursor);
|
||||
#else
|
||||
if (!(rootCursor = CreateRootCursor(defaultCursorFont, 0))) {
|
||||
if (!(rootCursor = CreateRootCursor(NULL, 0))) {
|
||||
FatalError("could not open default cursor font '%s'",
|
||||
defaultCursorFont);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DPMSExtension
|
||||
/* check all screens, looking for DPMS Capabilities */
|
||||
DPMSCapableFlag = DPMSSupported();
|
||||
|
|
@ -483,7 +468,7 @@ main(int argc, char *argv[], char *envp[])
|
|||
FreeAllResources();
|
||||
#endif
|
||||
|
||||
configFini();
|
||||
config_fini();
|
||||
CloseDownDevices();
|
||||
for (i = screenInfo.numScreens - 1; i >= 0; i--)
|
||||
{
|
||||
|
|
@ -524,7 +509,7 @@ main(int argc, char *argv[], char *envp[])
|
|||
}
|
||||
|
||||
static int VendorRelease = VENDOR_RELEASE;
|
||||
static char *VendorString = VENDOR_STRING;
|
||||
static char *VendorString = VENDOR_NAME;
|
||||
|
||||
void
|
||||
SetVendorRelease(int release)
|
||||
|
|
|
|||
|
|
@ -91,6 +91,19 @@ PrintPropertys(WindowPtr pWin)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
deliverPropertyNotifyEvent(WindowPtr pWin, int state, Atom atom)
|
||||
{
|
||||
xEvent event;
|
||||
|
||||
event.u.u.type = PropertyNotify;
|
||||
event.u.property.window = pWin->drawable.id;
|
||||
event.u.property.state = state;
|
||||
event.u.property.atom = atom;
|
||||
event.u.property.time = currentTime.milliseconds;
|
||||
DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
|
||||
}
|
||||
|
||||
int
|
||||
ProcRotateProperties(ClientPtr client)
|
||||
{
|
||||
|
|
@ -100,7 +113,6 @@ ProcRotateProperties(ClientPtr client)
|
|||
Atom * atoms;
|
||||
PropertyPtr * props; /* array of pointer */
|
||||
PropertyPtr pProp;
|
||||
xEvent event;
|
||||
|
||||
REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
|
||||
UpdateCurrentTime();
|
||||
|
|
@ -157,16 +169,9 @@ found:
|
|||
delta += stuff->nAtoms;
|
||||
for (i = 0; i < stuff->nAtoms; i++)
|
||||
{
|
||||
/* Generate a PropertyNotify event for each property whose value
|
||||
is changed in the order in which they appear in the request. */
|
||||
deliverPropertyNotifyEvent(pWin, PropertyNewValue,
|
||||
props[i]->propertyName);
|
||||
|
||||
event.u.u.type = PropertyNotify;
|
||||
event.u.property.window = pWin->drawable.id;
|
||||
event.u.property.state = PropertyNewValue;
|
||||
event.u.property.atom = props[i]->propertyName;
|
||||
event.u.property.time = currentTime.milliseconds;
|
||||
DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
|
||||
|
||||
props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
|
||||
}
|
||||
}
|
||||
|
|
@ -243,7 +248,6 @@ ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
|
|||
Bool sendevent)
|
||||
{
|
||||
PropertyPtr pProp;
|
||||
xEvent event;
|
||||
int sizeInBytes;
|
||||
int totalSize;
|
||||
pointer data;
|
||||
|
|
@ -338,15 +342,10 @@ ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
|
|||
pProp->size += len;
|
||||
}
|
||||
}
|
||||
|
||||
if (sendevent)
|
||||
{
|
||||
event.u.u.type = PropertyNotify;
|
||||
event.u.property.window = pWin->drawable.id;
|
||||
event.u.property.state = PropertyNewValue;
|
||||
event.u.property.atom = pProp->propertyName;
|
||||
event.u.property.time = currentTime.milliseconds;
|
||||
DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
|
||||
}
|
||||
deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp->propertyName);
|
||||
|
||||
return(Success);
|
||||
}
|
||||
|
||||
|
|
@ -354,7 +353,6 @@ int
|
|||
DeleteProperty(WindowPtr pWin, Atom propName)
|
||||
{
|
||||
PropertyPtr pProp, prevProp;
|
||||
xEvent event;
|
||||
|
||||
if (!(pProp = wUserProps (pWin)))
|
||||
return(Success);
|
||||
|
|
@ -377,12 +375,7 @@ DeleteProperty(WindowPtr pWin, Atom propName)
|
|||
{
|
||||
prevProp->next = pProp->next;
|
||||
}
|
||||
event.u.u.type = PropertyNotify;
|
||||
event.u.property.window = pWin->drawable.id;
|
||||
event.u.property.state = PropertyDelete;
|
||||
event.u.property.atom = pProp->propertyName;
|
||||
event.u.property.time = currentTime.milliseconds;
|
||||
DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
|
||||
deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName);
|
||||
xfree(pProp->data);
|
||||
xfree(pProp);
|
||||
}
|
||||
|
|
@ -393,17 +386,11 @@ void
|
|||
DeleteAllWindowProperties(WindowPtr pWin)
|
||||
{
|
||||
PropertyPtr pProp, pNextProp;
|
||||
xEvent event;
|
||||
|
||||
pProp = wUserProps (pWin);
|
||||
while (pProp)
|
||||
{
|
||||
event.u.u.type = PropertyNotify;
|
||||
event.u.property.window = pWin->drawable.id;
|
||||
event.u.property.state = PropertyDelete;
|
||||
event.u.property.atom = pProp->propertyName;
|
||||
event.u.property.time = currentTime.milliseconds;
|
||||
DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
|
||||
deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName);
|
||||
pNextProp = pProp->next;
|
||||
xfree(pProp->data);
|
||||
xfree(pProp);
|
||||
|
|
@ -537,16 +524,7 @@ ProcGetProperty(ClientPtr client)
|
|||
reply.propertyType = pProp->type;
|
||||
|
||||
if (stuff->delete && (reply.bytesAfter == 0))
|
||||
{ /* send the event */
|
||||
xEvent event;
|
||||
|
||||
event.u.u.type = PropertyNotify;
|
||||
event.u.property.window = pWin->drawable.id;
|
||||
event.u.property.state = PropertyDelete;
|
||||
event.u.property.atom = pProp->propertyName;
|
||||
event.u.property.time = currentTime.milliseconds;
|
||||
DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
|
||||
}
|
||||
deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName);
|
||||
|
||||
WriteReplyToClient(client, sizeof(xGenericReply), &reply);
|
||||
if (len)
|
||||
|
|
|
|||
|
|
@ -101,8 +101,6 @@ Equipment Corporation.
|
|||
* of the copyright holder.
|
||||
*/
|
||||
|
||||
/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
|
||||
|
||||
/* Routines to manage various kinds of resources:
|
||||
*
|
||||
* CreateNewResourceType, CreateNewResourceClass, InitClientResources,
|
||||
|
|
|
|||
15
dix/tables.c
15
dix/tables.c
|
|
@ -61,11 +61,6 @@ SOFTWARE.
|
|||
#include "swaprep.h"
|
||||
#include "swapreq.h"
|
||||
|
||||
#ifdef K5AUTH
|
||||
extern int
|
||||
k5_stage1(), k5_stage2(), k5_stage3(), k5_bad();
|
||||
#endif
|
||||
|
||||
int (* InitialVector[3]) (
|
||||
ClientPtr /* client */
|
||||
) =
|
||||
|
|
@ -515,13 +510,3 @@ _X_EXPORT ReplySwapPtr ReplySwapVector[256] =
|
|||
ReplyNotSwappd, /* NoOperation */
|
||||
ReplyNotSwappd
|
||||
};
|
||||
|
||||
#ifdef K5AUTH
|
||||
int (*k5_Vector[256])() =
|
||||
{
|
||||
k5_bad,
|
||||
k5_stage1,
|
||||
k5_bad,
|
||||
k5_stage3
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
21
dix/window.c
21
dix/window.c
|
|
@ -175,7 +175,6 @@ static Bool TileScreenSaver(int i, int kind);
|
|||
|
||||
#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
|
||||
|
||||
|
||||
_X_EXPORT int numSaveUndersViewable = 0;
|
||||
_X_EXPORT int deltaSaveUndersViewable = 0;
|
||||
|
||||
|
|
@ -298,7 +297,7 @@ SetWindowToDefaults(WindowPtr pWin)
|
|||
pWin->dontPropagate = 0;
|
||||
pWin->forcedBS = FALSE;
|
||||
#ifdef COMPOSITE
|
||||
pWin->redirectDraw = 0;
|
||||
pWin->redirectDraw = RedirectDrawNone;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -1687,10 +1686,14 @@ _X_EXPORT void
|
|||
SetWinSize (WindowPtr pWin)
|
||||
{
|
||||
#ifdef COMPOSITE
|
||||
if (pWin->redirectDraw)
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
BoxRec box;
|
||||
|
||||
/*
|
||||
* Redirected clients get clip list equal to their
|
||||
* own geometry, not clipped to their parent
|
||||
*/
|
||||
box.x1 = pWin->drawable.x;
|
||||
box.y1 = pWin->drawable.y;
|
||||
box.x2 = pWin->drawable.x + pWin->drawable.width;
|
||||
|
|
@ -1730,10 +1733,14 @@ SetBorderSize (WindowPtr pWin)
|
|||
if (HasBorder (pWin)) {
|
||||
bw = wBorderWidth (pWin);
|
||||
#ifdef COMPOSITE
|
||||
if (pWin->redirectDraw)
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
BoxRec box;
|
||||
|
||||
/*
|
||||
* Redirected clients get clip list equal to their
|
||||
* own geometry, not clipped to their parent
|
||||
*/
|
||||
box.x1 = pWin->drawable.x - bw;
|
||||
box.y1 = pWin->drawable.y - bw;
|
||||
box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
|
||||
|
|
@ -3023,9 +3030,6 @@ UnrealizeTree(
|
|||
deltaSaveUndersViewable--;
|
||||
#endif
|
||||
pChild->viewable = FALSE;
|
||||
if (pChild->backStorage)
|
||||
(*pChild->drawable.pScreen->SaveDoomedAreas)(
|
||||
pChild, &pChild->clipList, 0, 0);
|
||||
(* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
|
||||
pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
}
|
||||
|
|
@ -3153,9 +3157,6 @@ UnmapSubwindows(WindowPtr pWin)
|
|||
#ifdef DO_SAVE_UNDERS
|
||||
pChild->DIXsaveUnder = FALSE;
|
||||
#endif /* DO_SAVE_UNDERS */
|
||||
if (pChild->backStorage)
|
||||
(*pScreen->SaveDoomedAreas)(
|
||||
pChild, &pChild->clipList, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* $XFree86$ */
|
||||
/*
|
||||
Copyright 1996, 1998 The Open Group
|
||||
|
||||
|
|
|
|||
|
|
@ -508,8 +508,7 @@ its parent process after it has set up the various connection schemes.
|
|||
\fIXdm\fP uses this feature to recognize when connecting to the server
|
||||
is possible.
|
||||
.SH FONTS
|
||||
The X server
|
||||
can obtain fonts from directories and/or from font servers.
|
||||
The X server can obtain fonts from directories and/or from font servers.
|
||||
The list of directories and font servers
|
||||
the X server uses when trying to open a font is controlled
|
||||
by the \fIfont path\fP.
|
||||
|
|
@ -517,8 +516,45 @@ by the \fIfont path\fP.
|
|||
The default font path is
|
||||
__default_font_path__ .
|
||||
.LP
|
||||
A special kind of directory can be specified using the the \fBcatalogue\fP:
|
||||
prefix. Directories specified this way can contain symlinks pointing to the
|
||||
real font directories. See the FONTPATH.D section for details.
|
||||
.LP
|
||||
The font path can be set with the \fB\-fp\fP option or by \fIxset\fP(1)
|
||||
after the server has started.
|
||||
.SH "FONTPATH.D"
|
||||
You can specify a special kind of font path in the form \fBcatalogue:<dir>\fR.
|
||||
The directory specified after the catalogue: prefix will be scanned for symlinks
|
||||
and each symlink destination will be added as a local fontfile FPE.
|
||||
.PP
|
||||
The symlink can be suffixed by attributes such as '\fBunscaled\fR', which
|
||||
will be passed through to the underlying fontfile FPE. The only exception is
|
||||
the newly introduced '\fBpri\fR' attribute, which will be used for ordering
|
||||
the font paths specified by the symlinks.
|
||||
|
||||
An example configuration:
|
||||
|
||||
.nf
|
||||
75dpi:unscaled:pri=20 \-> /usr/share/X11/fonts/75dpi
|
||||
ghostscript:pri=60 \-> /usr/share/fonts/default/ghostscript
|
||||
misc:unscaled:pri=10 \-> /usr/share/X11/fonts/misc
|
||||
type1:pri=40 \-> /usr/share/X11/fonts/Type1
|
||||
type1:pri=50 \-> /usr/share/fonts/default/Type1
|
||||
.fi
|
||||
|
||||
This will add /usr/share/X11/fonts/misc as the first FPE with the attribute
|
||||
'unscaled', second FPE will be /usr/share/X11/fonts/75dpi, also with
|
||||
the attribute unscaled etc. This is functionally equivalent to setting
|
||||
the following font path:
|
||||
|
||||
.nf
|
||||
/usr/share/X11/fonts/misc:unscaled,
|
||||
/usr/share/X11/fonts/75dpi:unscaled,
|
||||
/usr/share/X11/fonts/Type1,
|
||||
/usr/share/fonts/default/Type1,
|
||||
/usr/share/fonts/default/ghostscript
|
||||
.fi
|
||||
|
||||
.SH FILES
|
||||
.TP 30
|
||||
.I /etc/X\fBn\fP.hosts
|
||||
|
|
|
|||
288
exa/exa.c
288
exa/exa.c
|
|
@ -32,10 +32,6 @@
|
|||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifdef MITSHM
|
||||
#include "shmint.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "exa_priv.h"
|
||||
|
|
@ -48,6 +44,17 @@ static int exaGeneration;
|
|||
int exaScreenPrivateIndex;
|
||||
int exaPixmapPrivateIndex;
|
||||
|
||||
static _X_INLINE void*
|
||||
ExaGetPixmapAddress(PixmapPtr p)
|
||||
{
|
||||
ExaPixmapPriv(p);
|
||||
|
||||
if (pExaPixmap->offscreen && pExaPixmap->fb_ptr)
|
||||
return pExaPixmap->fb_ptr;
|
||||
else
|
||||
return pExaPixmap->sys_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* exaGetPixmapOffset() returns the offset (in bytes) within the framebuffer of
|
||||
* the beginning of the given pixmap.
|
||||
|
|
@ -62,16 +69,9 @@ unsigned long
|
|||
exaGetPixmapOffset(PixmapPtr pPix)
|
||||
{
|
||||
ExaScreenPriv (pPix->drawable.pScreen);
|
||||
ExaPixmapPriv (pPix);
|
||||
void *ptr;
|
||||
|
||||
/* Return the offscreen pointer if we've hidden the data. */
|
||||
if (pPix->devPrivate.ptr == NULL)
|
||||
ptr = pExaPixmap->fb_ptr;
|
||||
else
|
||||
ptr = pPix->devPrivate.ptr;
|
||||
|
||||
return ((unsigned long)ptr - (unsigned long)pExaScr->info->memoryBase);
|
||||
return ((unsigned long)ExaGetPixmapAddress(pPix) -
|
||||
(unsigned long)pExaScr->info->memoryBase);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -126,7 +126,7 @@ exaGetDrawablePixmap(DrawablePtr pDrawable)
|
|||
* the backing drawable. These coordinates are nonzero only for redirected
|
||||
* windows.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
|
||||
int *xp, int *yp)
|
||||
{
|
||||
|
|
@ -172,29 +172,6 @@ exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2)
|
|||
REGION_UNINIT(pScreen, ®ion);
|
||||
}
|
||||
|
||||
/**
|
||||
* exaDrawableDirty() marks a pixmap backing a drawable as dirty, allowing for
|
||||
* optimizations in pixmap migration when no changes have occurred.
|
||||
*/
|
||||
void
|
||||
exaDrawableDirty (DrawablePtr pDrawable, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
PixmapPtr pPix = exaGetDrawablePixmap(pDrawable);
|
||||
int xoff, yoff;
|
||||
|
||||
x1 = max(x1, pDrawable->x);
|
||||
y1 = max(y1, pDrawable->y);
|
||||
x2 = min(x2, pDrawable->x + pDrawable->width);
|
||||
y2 = min(y2, pDrawable->y + pDrawable->height);
|
||||
|
||||
if (x1 >= x2 || y1 >= y2)
|
||||
return;
|
||||
|
||||
exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
|
||||
|
||||
exaPixmapDirty(pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
|
||||
}
|
||||
|
||||
static Bool
|
||||
exaDestroyPixmap (PixmapPtr pPixmap)
|
||||
{
|
||||
|
|
@ -213,7 +190,8 @@ exaDestroyPixmap (PixmapPtr pPixmap)
|
|||
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
|
||||
pPixmap->devKind = pExaPixmap->sys_pitch;
|
||||
}
|
||||
REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validReg);
|
||||
REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validSys);
|
||||
REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validFB);
|
||||
}
|
||||
return fbDestroyPixmap (pPixmap);
|
||||
}
|
||||
|
|
@ -267,6 +245,9 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
|
|||
pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
|
||||
pExaPixmap->sys_pitch = pPixmap->devKind;
|
||||
|
||||
pPixmap->devPrivate.ptr = NULL;
|
||||
pExaPixmap->offscreen = FALSE;
|
||||
|
||||
pExaPixmap->fb_ptr = NULL;
|
||||
if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
|
||||
pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
|
||||
|
|
@ -276,7 +257,7 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
|
|||
pExaScr->info->pixmapPitchAlign);
|
||||
pExaPixmap->fb_size = pExaPixmap->fb_pitch * h;
|
||||
|
||||
if (pExaPixmap->fb_pitch > 32767) {
|
||||
if (pExaPixmap->fb_pitch > 131071) {
|
||||
fbDestroyPixmap(pPixmap);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -294,11 +275,33 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
|
|||
DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE);
|
||||
|
||||
/* None of the pixmap bits are valid initially */
|
||||
REGION_NULL(pScreen, &pExaPixmap->validReg);
|
||||
REGION_NULL(pScreen, &pExaPixmap->validSys);
|
||||
REGION_NULL(pScreen, &pExaPixmap->validFB);
|
||||
|
||||
return pPixmap;
|
||||
}
|
||||
|
||||
static Bool
|
||||
exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
|
||||
int bitsPerPixel, int devKind, pointer pPixData)
|
||||
{
|
||||
ExaScreenPrivPtr pExaScr;
|
||||
ExaPixmapPrivPtr pExaPixmap;
|
||||
|
||||
if (!pPixmap)
|
||||
return FALSE;
|
||||
|
||||
pExaPixmap = ExaGetPixmapPriv(pPixmap);
|
||||
|
||||
if (pExaPixmap)
|
||||
pExaPixmap->sys_ptr = pPixData;
|
||||
|
||||
pExaScr = ExaGetScreenPriv(pPixmap->drawable.pScreen);
|
||||
|
||||
return pExaScr->SavedModifyPixmapHeader(pPixmap, width, height, depth,
|
||||
bitsPerPixel, devKind, pPixData);
|
||||
}
|
||||
|
||||
/**
|
||||
* exaPixmapIsOffscreen() is used to determine if a pixmap is in offscreen
|
||||
* memory, meaning that acceleration could probably be done to it, and that it
|
||||
|
|
@ -316,18 +319,25 @@ exaPixmapIsOffscreen(PixmapPtr p)
|
|||
{
|
||||
ScreenPtr pScreen = p->drawable.pScreen;
|
||||
ExaScreenPriv(pScreen);
|
||||
ExaPixmapPriv(p);
|
||||
void *save_ptr;
|
||||
Bool ret;
|
||||
|
||||
/* If the devPrivate.ptr is NULL, it's offscreen but we've hidden the data.
|
||||
*/
|
||||
if (p->devPrivate.ptr == NULL)
|
||||
return TRUE;
|
||||
save_ptr = p->devPrivate.ptr;
|
||||
|
||||
if (!save_ptr && pExaPixmap)
|
||||
p->devPrivate.ptr = ExaGetPixmapAddress(p);
|
||||
|
||||
if (pExaScr->info->PixmapIsOffscreen)
|
||||
return pExaScr->info->PixmapIsOffscreen(p);
|
||||
ret = pExaScr->info->PixmapIsOffscreen(p);
|
||||
else
|
||||
ret = ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
|
||||
(CARD8 *) pExaScr->info->memoryBase) <
|
||||
pExaScr->info->memorySize);
|
||||
|
||||
return ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
|
||||
(CARD8 *) pExaScr->info->memoryBase) <
|
||||
pExaScr->info->memorySize);
|
||||
p->devPrivate.ptr = save_ptr;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -356,33 +366,24 @@ exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
|
||||
*
|
||||
* It deals with waiting for synchronization with the card, determining if
|
||||
* PrepareAccess() is necessary, and working around PrepareAccess() failure.
|
||||
*/
|
||||
void
|
||||
exaPrepareAccess(DrawablePtr pDrawable, int index)
|
||||
ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
|
||||
{
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
ExaScreenPriv (pScreen);
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||
|
||||
if (exaPixmapIsOffscreen (pPixmap))
|
||||
exaWaitSync (pDrawable->pScreen);
|
||||
else
|
||||
return;
|
||||
PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||
Bool offscreen = exaPixmapIsOffscreen(pPixmap);
|
||||
|
||||
/* Unhide pixmap pointer */
|
||||
if (pPixmap->devPrivate.ptr == NULL) {
|
||||
ExaPixmapPriv (pPixmap);
|
||||
|
||||
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
|
||||
pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
|
||||
}
|
||||
|
||||
if (!offscreen)
|
||||
return;
|
||||
|
||||
exaWaitSync (pDrawable->pScreen);
|
||||
|
||||
if (pExaScr->info->PrepareAccess == NULL)
|
||||
return;
|
||||
|
||||
|
|
@ -394,6 +395,33 @@ exaPrepareAccess(DrawablePtr pDrawable, int index)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg)
|
||||
{
|
||||
ExaMigrationRec pixmaps[1];
|
||||
|
||||
pixmaps[0].as_dst = index == EXA_PREPARE_DEST;
|
||||
pixmaps[0].as_src = index != EXA_PREPARE_DEST;
|
||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
|
||||
pixmaps[0].pReg = pReg;
|
||||
|
||||
exaDoMigration(pixmaps, 1, FALSE);
|
||||
|
||||
ExaDoPrepareAccess(pDrawable, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
|
||||
*
|
||||
* It deals with waiting for synchronization with the card, determining if
|
||||
* PrepareAccess() is necessary, and working around PrepareAccess() failure.
|
||||
*/
|
||||
void
|
||||
exaPrepareAccess(DrawablePtr pDrawable, int index)
|
||||
{
|
||||
exaPrepareAccessReg(pDrawable, index, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* exaFinishAccess() is EXA's wrapper for the driver's FinishAccess() handler.
|
||||
*
|
||||
|
|
@ -404,18 +432,13 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
|
|||
{
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
ExaScreenPriv (pScreen);
|
||||
PixmapPtr pPixmap;
|
||||
ExaPixmapPrivPtr pExaPixmap;
|
||||
|
||||
pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||
|
||||
pExaPixmap = ExaGetPixmapPriv(pPixmap);
|
||||
PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||
ExaPixmapPriv (pPixmap);
|
||||
|
||||
/* Rehide pixmap pointer if we're doing that. */
|
||||
if (pExaPixmap != NULL && pExaScr->hideOffscreenPixmapData &&
|
||||
pExaPixmap->fb_ptr == pPixmap->devPrivate.ptr)
|
||||
if (pExaPixmap)
|
||||
{
|
||||
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
|
||||
pPixmap->devPrivate.ptr = NULL;
|
||||
}
|
||||
|
||||
if (pExaScr->info->FinishAccess == NULL)
|
||||
|
|
@ -479,11 +502,9 @@ exaValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
|
|||
if (!pGC->tileIsPixel && FbEvenTile (pGC->tile.pixmap->drawable.width *
|
||||
pDrawable->bitsPerPixel))
|
||||
{
|
||||
/* XXX This fixes corruption with tiled pixmaps, but may just be a
|
||||
* workaround for broken drivers
|
||||
*/
|
||||
exaMoveOutPixmap(pGC->tile.pixmap);
|
||||
exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
|
||||
fbPadPixmap (pGC->tile.pixmap);
|
||||
exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
|
||||
exaPixmapDirty(pGC->tile.pixmap, 0, 0,
|
||||
pGC->tile.pixmap->drawable.width,
|
||||
pGC->tile.pixmap->drawable.height);
|
||||
|
|
@ -494,7 +515,9 @@ exaValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
|
|||
changes &= ~GCTile;
|
||||
}
|
||||
|
||||
exaPrepareAccessGC(pGC);
|
||||
fbValidateGC (pGC, changes, pDrawable);
|
||||
exaFinishAccessGC(pGC);
|
||||
|
||||
pGC->ops = (GCOps *) &exaOps;
|
||||
}
|
||||
|
|
@ -524,6 +547,47 @@ exaCreateGC (GCPtr pGC)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
exaPrepareAccessWindow(WindowPtr pWin)
|
||||
{
|
||||
if (pWin->backgroundState == BackgroundPixmap)
|
||||
exaPrepareAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
|
||||
|
||||
if (pWin->borderIsPixel == FALSE)
|
||||
exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_SRC);
|
||||
}
|
||||
|
||||
void
|
||||
exaFinishAccessWindow(WindowPtr pWin)
|
||||
{
|
||||
if (pWin->backgroundState == BackgroundPixmap)
|
||||
exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
|
||||
|
||||
if (pWin->borderIsPixel == FALSE)
|
||||
exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_SRC);
|
||||
}
|
||||
|
||||
static Bool
|
||||
exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
|
||||
{
|
||||
Bool ret;
|
||||
|
||||
exaPrepareAccessWindow(pWin);
|
||||
ret = fbChangeWindowAttributes(pWin, mask);
|
||||
exaFinishAccessWindow(pWin);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RegionPtr
|
||||
exaBitmapToRegion(PixmapPtr pPix)
|
||||
{
|
||||
RegionPtr ret;
|
||||
exaPrepareAccess(&pPix->drawable, EXA_PREPARE_SRC);
|
||||
ret = fbPixmapToRegion(pPix);
|
||||
exaFinishAccess(&pPix->drawable, EXA_PREPARE_SRC);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* exaCloseScreen() unwraps its wrapped screen functions and tears down EXA's
|
||||
* screen private, before calling down to the next CloseSccreen.
|
||||
|
|
@ -545,10 +609,13 @@ exaCloseScreen(int i, ScreenPtr pScreen)
|
|||
pScreen->CreatePixmap = pExaScr->SavedCreatePixmap;
|
||||
pScreen->DestroyPixmap = pExaScr->SavedDestroyPixmap;
|
||||
pScreen->CopyWindow = pExaScr->SavedCopyWindow;
|
||||
pScreen->ChangeWindowAttributes = pExaScr->SavedChangeWindowAttributes;
|
||||
pScreen->BitmapToRegion = pExaScr->SavedBitmapToRegion;
|
||||
#ifdef RENDER
|
||||
if (ps) {
|
||||
ps->Composite = pExaScr->SavedComposite;
|
||||
ps->Glyphs = pExaScr->SavedGlyphs;
|
||||
ps->Trapezoids = pExaScr->SavedTrapezoids;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -592,6 +659,45 @@ exaDriverInit (ScreenPtr pScreen,
|
|||
PictureScreenPtr ps;
|
||||
#endif
|
||||
|
||||
if (!pScreenInfo)
|
||||
return FALSE;
|
||||
|
||||
if (!pScreenInfo->memoryBase) {
|
||||
LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memoryBase must be "
|
||||
"non-zero\n", pScreen->myNum);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!pScreenInfo->memorySize) {
|
||||
LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memorySize must be "
|
||||
"non-zero\n", pScreen->myNum);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pScreenInfo->offScreenBase > pScreenInfo->memorySize) {
|
||||
LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::offScreenBase must be <= "
|
||||
"ExaDriverRec::memorySize\n", pScreen->myNum);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!pScreenInfo->PrepareSolid) {
|
||||
LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::PrepareSolid must be "
|
||||
"non-NULL\n", pScreen->myNum);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!pScreenInfo->PrepareCopy) {
|
||||
LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::PrepareCopy must be "
|
||||
"non-NULL\n", pScreen->myNum);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!pScreenInfo->WaitMarker) {
|
||||
LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::WaitMarker must be "
|
||||
"non-NULL\n", pScreen->myNum);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pScreenInfo->exa_major != EXA_VERSION_MAJOR ||
|
||||
pScreenInfo->exa_minor > EXA_VERSION_MINOR)
|
||||
{
|
||||
|
|
@ -642,32 +748,36 @@ exaDriverInit (ScreenPtr pScreen,
|
|||
pScreen->GetImage = exaGetImage;
|
||||
|
||||
pExaScr->SavedGetSpans = pScreen->GetSpans;
|
||||
pScreen->GetSpans = exaGetSpans;
|
||||
pScreen->GetSpans = ExaCheckGetSpans;
|
||||
|
||||
pExaScr->SavedCopyWindow = pScreen->CopyWindow;
|
||||
pScreen->CopyWindow = exaCopyWindow;
|
||||
|
||||
pExaScr->SavedChangeWindowAttributes = pScreen->ChangeWindowAttributes;
|
||||
pScreen->ChangeWindowAttributes = exaChangeWindowAttributes;
|
||||
|
||||
pExaScr->SavedBitmapToRegion = pScreen->BitmapToRegion;
|
||||
pScreen->BitmapToRegion = exaBitmapToRegion;
|
||||
|
||||
pExaScr->SavedPaintWindowBackground = pScreen->PaintWindowBackground;
|
||||
pScreen->PaintWindowBackground = exaPaintWindow;
|
||||
|
||||
pExaScr->SavedPaintWindowBorder = pScreen->PaintWindowBorder;
|
||||
pScreen->PaintWindowBorder = exaPaintWindow;
|
||||
|
||||
pScreen->BackingStoreFuncs.SaveAreas = ExaCheckSaveAreas;
|
||||
pScreen->BackingStoreFuncs.RestoreAreas = ExaCheckRestoreAreas;
|
||||
#ifdef RENDER
|
||||
if (ps) {
|
||||
pExaScr->SavedComposite = ps->Composite;
|
||||
ps->Composite = exaComposite;
|
||||
|
||||
pExaScr->SavedRasterizeTrapezoid = ps->RasterizeTrapezoid;
|
||||
ps->RasterizeTrapezoid = exaRasterizeTrapezoid;
|
||||
|
||||
pExaScr->SavedAddTriangles = ps->AddTriangles;
|
||||
ps->AddTriangles = exaAddTriangles;
|
||||
pExaScr->SavedTriangles = ps->Triangles;
|
||||
ps->Triangles = exaTriangles;
|
||||
|
||||
pExaScr->SavedGlyphs = ps->Glyphs;
|
||||
ps->Glyphs = exaGlyphs;
|
||||
|
||||
pExaScr->SavedTrapezoids = ps->Trapezoids;
|
||||
ps->Trapezoids = exaTrapezoids;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -676,7 +786,7 @@ exaDriverInit (ScreenPtr pScreen,
|
|||
* Shared pixmaps are almost always a performance loss for us, but this
|
||||
* still allows for SHM PutImage.
|
||||
*/
|
||||
ShmRegisterFuncs(pScreen, NULL);
|
||||
ShmRegisterFuncs(pScreen, &exaShmFuncs);
|
||||
#endif
|
||||
/*
|
||||
* Hookup offscreen pixmaps
|
||||
|
|
@ -697,6 +807,8 @@ exaDriverInit (ScreenPtr pScreen,
|
|||
pExaScr->SavedDestroyPixmap = pScreen->DestroyPixmap;
|
||||
pScreen->DestroyPixmap = exaDestroyPixmap;
|
||||
|
||||
pExaScr->SavedModifyPixmapHeader = pScreen->ModifyPixmapHeader;
|
||||
pScreen->ModifyPixmapHeader = exaModifyPixmapHeader;
|
||||
LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %d bytes\n",
|
||||
pScreen->myNum,
|
||||
pExaScr->info->memorySize - pExaScr->info->offScreenBase);
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ typedef struct _ExaDriver {
|
|||
* @{
|
||||
*/
|
||||
/**
|
||||
* PrepareCopy() sets up the driver for doing a copy within offscreen
|
||||
* PrepareCopy() sets up the driver for doing a copy within video
|
||||
* memory.
|
||||
*
|
||||
* @param pSrcPixmap source pixmap
|
||||
|
|
@ -721,6 +721,9 @@ exaOffscreenAlloc(ScreenPtr pScreen, int size, int align,
|
|||
ExaOffscreenArea *
|
||||
exaOffscreenFree(ScreenPtr pScreen, ExaOffscreenArea *area);
|
||||
|
||||
void
|
||||
ExaOffscreenMarkUsed (PixmapPtr pPixmap);
|
||||
|
||||
unsigned long
|
||||
exaGetPixmapOffset(PixmapPtr pPix);
|
||||
|
||||
|
|
|
|||
827
exa/exa_accel.c
827
exa/exa_accel.c
File diff suppressed because it is too large
Load diff
|
|
@ -90,7 +90,8 @@ exaPixmapIsDirty (PixmapPtr pPix)
|
|||
ExaPixmapPriv (pPix);
|
||||
|
||||
return pExaPixmap == NULL ||
|
||||
REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage));
|
||||
REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage)) ||
|
||||
!REGION_EQUAL(pScreen, &pExaPixmap->validSys, &pExaPixmap->validFB);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -113,20 +114,67 @@ exaPixmapShouldBeInFB (PixmapPtr pPix)
|
|||
|
||||
/**
|
||||
* If the pixmap is currently dirty, this copies at least the dirty area from
|
||||
* the framebuffer memory copy to the system memory copy. Both areas must be
|
||||
* allocated.
|
||||
* FB to system or vice versa. Both areas must be allocated.
|
||||
*/
|
||||
static void
|
||||
exaCopyDirtyToSys (PixmapPtr pPixmap)
|
||||
static _X_INLINE void
|
||||
exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
|
||||
Bool (*transfer) (PixmapPtr pPix, int x, int y, int w, int h,
|
||||
char *sys, int sys_pitch), CARD8 *fallback_src,
|
||||
CARD8 *fallback_dst, int fallback_srcpitch, int fallback_dstpitch,
|
||||
int fallback_index, void (*sync) (ScreenPtr pScreen))
|
||||
{
|
||||
ExaScreenPriv (pPixmap->drawable.pScreen);
|
||||
PixmapPtr pPixmap = migrate->pPix;
|
||||
ExaPixmapPriv (pPixmap);
|
||||
RegionPtr pRegion = DamageRegion (pExaPixmap->pDamage);
|
||||
RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
|
||||
RegionRec CopyReg;
|
||||
CARD8 *save_ptr;
|
||||
int save_pitch;
|
||||
BoxPtr pBox = REGION_RECTS(pRegion);
|
||||
int nbox = REGION_NUM_RECTS(pRegion);
|
||||
Bool do_sync = FALSE;
|
||||
BoxPtr pBox;
|
||||
int nbox;
|
||||
Bool access_prepared = FALSE;
|
||||
|
||||
/* Damaged bits are valid in current copy but invalid in other one */
|
||||
if (exaPixmapIsOffscreen(pPixmap)) {
|
||||
REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
|
||||
damage);
|
||||
REGION_SUBTRACT(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
|
||||
damage);
|
||||
} else {
|
||||
REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
|
||||
damage);
|
||||
REGION_SUBTRACT(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
|
||||
damage);
|
||||
}
|
||||
|
||||
REGION_EMPTY(pScreen, damage);
|
||||
|
||||
/* Copy bits valid in source but not in destination */
|
||||
REGION_NULL(pScreen, &CopyReg);
|
||||
REGION_SUBTRACT(pScreen, &CopyReg, pValidSrc, pValidDst);
|
||||
|
||||
if (migrate->as_dst) {
|
||||
RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
|
||||
|
||||
if (REGION_NIL(pending_damage)) {
|
||||
static Bool firsttime = TRUE;
|
||||
|
||||
if (firsttime) {
|
||||
ErrorF("%s: Pending damage region empty!\n", __func__);
|
||||
firsttime = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, pending_damage);
|
||||
|
||||
if (migrate->pReg)
|
||||
REGION_SUBTRACT(pScreen, &CopyReg, &CopyReg, migrate->pReg);
|
||||
} else {
|
||||
if (migrate->pReg)
|
||||
REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, migrate->pReg);
|
||||
}
|
||||
|
||||
pBox = REGION_RECTS(&CopyReg);
|
||||
nbox = REGION_NUM_RECTS(&CopyReg);
|
||||
|
||||
save_ptr = pPixmap->devPrivate.ptr;
|
||||
save_pitch = pPixmap->devKind;
|
||||
|
|
@ -142,41 +190,57 @@ exaCopyDirtyToSys (PixmapPtr pPixmap)
|
|||
if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
|
||||
continue;
|
||||
|
||||
if (pExaScr->info->DownloadFromScreen == NULL ||
|
||||
!pExaScr->info->DownloadFromScreen (pPixmap,
|
||||
pBox->x1, pBox->y1,
|
||||
pBox->x2 - pBox->x1,
|
||||
pBox->y2 - pBox->y1,
|
||||
pExaPixmap->sys_ptr
|
||||
+ pBox->y1 * pExaPixmap->sys_pitch
|
||||
+ pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
|
||||
pExaPixmap->sys_pitch))
|
||||
if (!transfer || !transfer (pPixmap,
|
||||
pBox->x1, pBox->y1,
|
||||
pBox->x2 - pBox->x1,
|
||||
pBox->y2 - pBox->y1,
|
||||
pExaPixmap->sys_ptr
|
||||
+ pBox->y1 * pExaPixmap->sys_pitch
|
||||
+ pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
|
||||
pExaPixmap->sys_pitch))
|
||||
{
|
||||
exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
|
||||
if (!access_prepared) {
|
||||
ExaDoPrepareAccess(&pPixmap->drawable, fallback_index);
|
||||
access_prepared = TRUE;
|
||||
}
|
||||
exaMemcpyBox (pPixmap, pBox,
|
||||
pExaPixmap->fb_ptr, pExaPixmap->fb_pitch,
|
||||
pExaPixmap->sys_ptr, pExaPixmap->sys_pitch);
|
||||
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
|
||||
fallback_src, fallback_srcpitch,
|
||||
fallback_dst, fallback_dstpitch);
|
||||
}
|
||||
else
|
||||
do_sync = TRUE;
|
||||
|
||||
pBox++;
|
||||
}
|
||||
|
||||
/* Make sure the bits have actually landed, since we don't necessarily sync
|
||||
* when accessing pixmaps in system memory.
|
||||
*/
|
||||
if (do_sync)
|
||||
exaWaitSync (pPixmap->drawable.pScreen);
|
||||
if (access_prepared)
|
||||
exaFinishAccess(&pPixmap->drawable, fallback_index);
|
||||
else
|
||||
sync (pPixmap->drawable.pScreen);
|
||||
|
||||
pPixmap->devPrivate.ptr = save_ptr;
|
||||
pPixmap->devKind = save_pitch;
|
||||
|
||||
/* The previously damaged bits are now no longer damaged but valid */
|
||||
REGION_UNION(pPixmap->drawable.pScreen,
|
||||
&pExaPixmap->validReg, &pExaPixmap->validReg, pRegion);
|
||||
DamageEmpty (pExaPixmap->pDamage);
|
||||
/* The copied bits are now valid in destination */
|
||||
REGION_UNION(pScreen, pValidDst, pValidDst, &CopyReg);
|
||||
|
||||
REGION_UNINIT(pScreen, &CopyReg);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the pixmap is currently dirty, this copies at least the dirty area from
|
||||
* the framebuffer memory copy to the system memory copy. Both areas must be
|
||||
* allocated.
|
||||
*/
|
||||
static void
|
||||
exaCopyDirtyToSys (ExaMigrationPtr migrate)
|
||||
{
|
||||
PixmapPtr pPixmap = migrate->pPix;
|
||||
ExaScreenPriv (pPixmap->drawable.pScreen);
|
||||
ExaPixmapPriv (pPixmap);
|
||||
|
||||
exaCopyDirty(migrate, &pExaPixmap->validSys, &pExaPixmap->validFB,
|
||||
pExaScr->info->DownloadFromScreen, pExaPixmap->fb_ptr,
|
||||
pExaPixmap->sys_ptr, pExaPixmap->fb_pitch,
|
||||
pExaPixmap->sys_pitch, EXA_PREPARE_SRC, exaWaitSync);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -185,97 +249,16 @@ exaCopyDirtyToSys (PixmapPtr pPixmap)
|
|||
* allocated.
|
||||
*/
|
||||
static void
|
||||
exaCopyDirtyToFb (PixmapPtr pPixmap)
|
||||
exaCopyDirtyToFb (ExaMigrationPtr migrate)
|
||||
{
|
||||
PixmapPtr pPixmap = migrate->pPix;
|
||||
ExaScreenPriv (pPixmap->drawable.pScreen);
|
||||
ExaPixmapPriv (pPixmap);
|
||||
RegionPtr pRegion = DamageRegion (pExaPixmap->pDamage);
|
||||
CARD8 *save_ptr;
|
||||
int save_pitch;
|
||||
BoxPtr pBox = REGION_RECTS(pRegion);
|
||||
int nbox = REGION_NUM_RECTS(pRegion);
|
||||
Bool do_sync = FALSE;
|
||||
|
||||
save_ptr = pPixmap->devPrivate.ptr;
|
||||
save_pitch = pPixmap->devKind;
|
||||
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
|
||||
pPixmap->devKind = pExaPixmap->fb_pitch;
|
||||
|
||||
while (nbox--) {
|
||||
pBox->x1 = max(pBox->x1, 0);
|
||||
pBox->y1 = max(pBox->y1, 0);
|
||||
pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
|
||||
pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
|
||||
|
||||
if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
|
||||
continue;
|
||||
|
||||
if (pExaScr->info->UploadToScreen == NULL ||
|
||||
!pExaScr->info->UploadToScreen (pPixmap,
|
||||
pBox->x1, pBox->y1,
|
||||
pBox->x2 - pBox->x1,
|
||||
pBox->y2 - pBox->y1,
|
||||
pExaPixmap->sys_ptr
|
||||
+ pBox->y1 * pExaPixmap->sys_pitch
|
||||
+ pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
|
||||
pExaPixmap->sys_pitch))
|
||||
{
|
||||
exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
|
||||
exaMemcpyBox (pPixmap, pBox,
|
||||
pExaPixmap->sys_ptr, pExaPixmap->sys_pitch,
|
||||
pExaPixmap->fb_ptr, pExaPixmap->fb_pitch);
|
||||
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
|
||||
}
|
||||
else
|
||||
do_sync = TRUE;
|
||||
|
||||
pBox++;
|
||||
}
|
||||
|
||||
if (do_sync)
|
||||
exaMarkSync (pPixmap->drawable.pScreen);
|
||||
|
||||
pPixmap->devPrivate.ptr = save_ptr;
|
||||
pPixmap->devKind = save_pitch;
|
||||
|
||||
/* The previously damaged bits are now no longer damaged but valid */
|
||||
REGION_UNION(pPixmap->drawable.pScreen,
|
||||
&pExaPixmap->validReg, &pExaPixmap->validReg, pRegion);
|
||||
DamageEmpty (pExaPixmap->pDamage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies out important pixmap data and removes references to framebuffer area.
|
||||
* Called when the memory manager decides it's time to kick the pixmap out of
|
||||
* framebuffer entirely.
|
||||
*/
|
||||
void
|
||||
exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
|
||||
{
|
||||
PixmapPtr pPixmap = area->privData;
|
||||
ExaPixmapPriv(pPixmap);
|
||||
RegionPtr pDamageReg = DamageRegion(pExaPixmap->pDamage);
|
||||
|
||||
DBG_MIGRATE (("Save %p (%p) (%dx%d) (%c)\n", pPixmap,
|
||||
(void*)(ExaGetPixmapPriv(pPixmap)->area ?
|
||||
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
|
||||
pPixmap->drawable.width,
|
||||
pPixmap->drawable.height,
|
||||
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
|
||||
|
||||
if (exaPixmapIsOffscreen(pPixmap)) {
|
||||
exaCopyDirtyToSys (pPixmap);
|
||||
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
|
||||
pPixmap->devKind = pExaPixmap->sys_pitch;
|
||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
}
|
||||
|
||||
pExaPixmap->fb_ptr = NULL;
|
||||
pExaPixmap->area = NULL;
|
||||
|
||||
/* Mark all valid bits as damaged, so they'll get copied to FB next time */
|
||||
REGION_UNION(pPixmap->drawable.pScreen, pDamageReg, pDamageReg,
|
||||
&pExaPixmap->validReg);
|
||||
exaCopyDirty(migrate, &pExaPixmap->validFB, &pExaPixmap->validSys,
|
||||
pExaScr->info->UploadToScreen, pExaPixmap->sys_ptr,
|
||||
pExaPixmap->fb_ptr, pExaPixmap->sys_pitch,
|
||||
pExaPixmap->fb_pitch, EXA_PREPARE_DEST, exaMarkSync);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -293,10 +276,11 @@ exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
|
|||
* we mark the pixmap dirty, so that the next exaMoveInPixmap will actually move
|
||||
* all the data, since it's almost surely all valid now.
|
||||
*/
|
||||
void
|
||||
exaMoveInPixmap (PixmapPtr pPixmap)
|
||||
static void
|
||||
exaDoMoveInPixmap (ExaMigrationPtr migrate)
|
||||
{
|
||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||
PixmapPtr pPixmap = migrate->pPix;
|
||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||
ExaScreenPriv (pScreen);
|
||||
ExaPixmapPriv (pPixmap);
|
||||
|
||||
|
|
@ -304,10 +288,6 @@ exaMoveInPixmap (PixmapPtr pPixmap)
|
|||
if (pExaScr->swappedOut)
|
||||
return;
|
||||
|
||||
/* If we're already in FB, our work is done. */
|
||||
if (exaPixmapIsOffscreen(pPixmap))
|
||||
return;
|
||||
|
||||
/* If we're not allowed to move, then fail. */
|
||||
if (exaPixmapIsPinned(pPixmap))
|
||||
return;
|
||||
|
|
@ -331,6 +311,11 @@ exaMoveInPixmap (PixmapPtr pPixmap)
|
|||
pExaPixmap->area->offset;
|
||||
}
|
||||
|
||||
exaCopyDirtyToFb (migrate);
|
||||
|
||||
if (exaPixmapIsOffscreen(pPixmap))
|
||||
return;
|
||||
|
||||
DBG_MIGRATE (("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap,
|
||||
(ExaGetPixmapPriv(pPixmap)->area ?
|
||||
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
|
||||
|
|
@ -338,28 +323,37 @@ exaMoveInPixmap (PixmapPtr pPixmap)
|
|||
pPixmap->drawable.height,
|
||||
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
|
||||
|
||||
exaCopyDirtyToFb (pPixmap);
|
||||
pExaPixmap->offscreen = TRUE;
|
||||
|
||||
if (pExaScr->hideOffscreenPixmapData)
|
||||
pPixmap->devPrivate.ptr = NULL;
|
||||
else
|
||||
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
|
||||
pPixmap->devKind = pExaPixmap->fb_pitch;
|
||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
}
|
||||
|
||||
void
|
||||
exaMoveInPixmap (PixmapPtr pPixmap)
|
||||
{
|
||||
static ExaMigrationRec migrate = { .as_dst = FALSE, .as_src = TRUE,
|
||||
.pReg = NULL };
|
||||
|
||||
migrate.pPix = pPixmap;
|
||||
exaDoMoveInPixmap (&migrate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches the current active location of the pixmap to system memory, copying
|
||||
* updated data out if necessary.
|
||||
*/
|
||||
void
|
||||
exaMoveOutPixmap (PixmapPtr pPixmap)
|
||||
static void
|
||||
exaDoMoveOutPixmap (ExaMigrationPtr migrate)
|
||||
{
|
||||
PixmapPtr pPixmap = migrate->pPix;
|
||||
ExaPixmapPriv (pPixmap);
|
||||
|
||||
if (exaPixmapIsPinned(pPixmap))
|
||||
if (!pExaPixmap->area || exaPixmapIsPinned(pPixmap))
|
||||
return;
|
||||
|
||||
exaCopyDirtyToSys (migrate);
|
||||
|
||||
if (exaPixmapIsOffscreen(pPixmap)) {
|
||||
|
||||
DBG_MIGRATE (("<- %p (%p) (%dx%d) (%c)\n", pPixmap,
|
||||
|
|
@ -369,21 +363,53 @@ exaMoveOutPixmap (PixmapPtr pPixmap)
|
|||
pPixmap->drawable.height,
|
||||
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
|
||||
|
||||
exaCopyDirtyToSys (pPixmap);
|
||||
pExaPixmap->offscreen = FALSE;
|
||||
|
||||
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
|
||||
pPixmap->devKind = pExaPixmap->sys_pitch;
|
||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
exaMoveOutPixmap (PixmapPtr pPixmap)
|
||||
{
|
||||
static ExaMigrationRec migrate = { .as_dst = FALSE, .as_src = TRUE,
|
||||
.pReg = NULL };
|
||||
|
||||
migrate.pPix = pPixmap;
|
||||
exaDoMoveOutPixmap (&migrate);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies out important pixmap data and removes references to framebuffer area.
|
||||
* Called when the memory manager decides it's time to kick the pixmap out of
|
||||
* framebuffer entirely.
|
||||
*/
|
||||
void
|
||||
exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
|
||||
{
|
||||
PixmapPtr pPixmap = area->privData;
|
||||
ExaPixmapPriv(pPixmap);
|
||||
|
||||
exaMoveOutPixmap(pPixmap);
|
||||
|
||||
pExaPixmap->fb_ptr = NULL;
|
||||
pExaPixmap->area = NULL;
|
||||
|
||||
/* Mark all FB bits as invalid, so all valid system bits get copied to FB
|
||||
* next time */
|
||||
REGION_EMPTY(pPixmap->drawable.pScreen, &pExaPixmap->validFB);
|
||||
}
|
||||
|
||||
/**
|
||||
* For the "greedy" migration scheme, pushes the pixmap toward being located in
|
||||
* framebuffer memory.
|
||||
*/
|
||||
static void
|
||||
exaMigrateTowardFb (PixmapPtr pPixmap)
|
||||
exaMigrateTowardFb (ExaMigrationPtr migrate)
|
||||
{
|
||||
PixmapPtr pPixmap = migrate->pPix;
|
||||
ExaPixmapPriv (pPixmap);
|
||||
|
||||
if (pExaPixmap == NULL) {
|
||||
|
|
@ -403,7 +429,7 @@ exaMigrateTowardFb (PixmapPtr pPixmap)
|
|||
(pointer)pPixmap, pExaPixmap->score));
|
||||
|
||||
if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) {
|
||||
exaMoveInPixmap(pPixmap);
|
||||
exaDoMoveInPixmap(migrate);
|
||||
pExaPixmap->score = 0;
|
||||
}
|
||||
|
||||
|
|
@ -413,7 +439,7 @@ exaMigrateTowardFb (PixmapPtr pPixmap)
|
|||
if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN &&
|
||||
!exaPixmapIsOffscreen(pPixmap))
|
||||
{
|
||||
exaMoveInPixmap (pPixmap);
|
||||
exaDoMoveInPixmap(migrate);
|
||||
}
|
||||
|
||||
ExaOffscreenMarkUsed (pPixmap);
|
||||
|
|
@ -424,8 +450,9 @@ exaMigrateTowardFb (PixmapPtr pPixmap)
|
|||
* system memory.
|
||||
*/
|
||||
static void
|
||||
exaMigrateTowardSys (PixmapPtr pPixmap)
|
||||
exaMigrateTowardSys (ExaMigrationPtr migrate)
|
||||
{
|
||||
PixmapPtr pPixmap = migrate->pPix;
|
||||
ExaPixmapPriv (pPixmap);
|
||||
|
||||
if (pExaPixmap == NULL) {
|
||||
|
|
@ -447,7 +474,7 @@ exaMigrateTowardSys (PixmapPtr pPixmap)
|
|||
pExaPixmap->score--;
|
||||
|
||||
if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area)
|
||||
exaMoveOutPixmap (pPixmap);
|
||||
exaDoMoveOutPixmap(migrate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -459,21 +486,29 @@ exaAssertNotDirty (PixmapPtr pPixmap)
|
|||
{
|
||||
ExaPixmapPriv (pPixmap);
|
||||
CARD8 *dst, *src;
|
||||
RegionPtr pValidReg = &pExaPixmap->validReg;
|
||||
int dst_pitch, src_pitch, cpp, y, nbox = REGION_NUM_RECTS(pValidReg);
|
||||
BoxPtr pBox = REGION_RECTS(pValidReg);
|
||||
RegionRec ValidReg;
|
||||
int dst_pitch, src_pitch, cpp, y, nbox;
|
||||
BoxPtr pBox;
|
||||
Bool ret = TRUE;
|
||||
|
||||
if (pExaPixmap == NULL || pExaPixmap->fb_ptr == NULL)
|
||||
if (exaPixmapIsPinned(pPixmap) || pExaPixmap->area == NULL)
|
||||
return ret;
|
||||
|
||||
dst = pExaPixmap->sys_ptr;
|
||||
REGION_NULL(pScreen, &ValidReg);
|
||||
REGION_INTERSECT(pScreen, &ValidReg, &pExaPixmap->validFB,
|
||||
&pExaPixmap->validSys);
|
||||
nbox = REGION_NUM_RECTS(&ValidReg);
|
||||
|
||||
if (!nbox)
|
||||
goto out;
|
||||
|
||||
pBox = REGION_RECTS(&ValidReg);
|
||||
|
||||
dst_pitch = pExaPixmap->sys_pitch;
|
||||
src = pExaPixmap->fb_ptr;
|
||||
src_pitch = pExaPixmap->fb_pitch;
|
||||
cpp = pPixmap->drawable.bitsPerPixel / 8;
|
||||
|
||||
exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
|
||||
ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
|
||||
while (nbox--) {
|
||||
int rowbytes;
|
||||
|
||||
|
|
@ -486,24 +521,23 @@ exaAssertNotDirty (PixmapPtr pPixmap)
|
|||
continue;
|
||||
|
||||
rowbytes = (pBox->x2 - pBox->x1) * cpp;
|
||||
src += pBox->y1 * src_pitch + pBox->x1 * cpp;
|
||||
dst += pBox->y1 * dst_pitch + pBox->x1 * cpp;
|
||||
src = pExaPixmap->fb_ptr + pBox->y1 * src_pitch + pBox->x1 * cpp;
|
||||
dst = pExaPixmap->sys_ptr + pBox->y1 * dst_pitch + pBox->x1 * cpp;
|
||||
|
||||
for (y = pBox->y2 - pBox->y1; y; y--) {
|
||||
if (memcmp(dst + pBox->y1 * dst_pitch + pBox->x1 * cpp,
|
||||
src + pBox->y1 * src_pitch + pBox->x1 * cpp,
|
||||
(pBox->x2 - pBox->x1) * cpp) != 0) {
|
||||
for (y = pBox->y1; y < pBox->y2;
|
||||
y++, src += src_pitch, dst += dst_pitch) {
|
||||
if (memcmp(dst, src, rowbytes) != 0) {
|
||||
ret = FALSE;
|
||||
exaPixmapDirty(pPixmap, pBox->x1, pBox->y1, pBox->x2,
|
||||
pBox->y2);
|
||||
break;
|
||||
}
|
||||
src += src_pitch;
|
||||
dst += dst_pitch;
|
||||
}
|
||||
src -= pBox->y1 * src_pitch + pBox->x1 * cpp;
|
||||
dst -= pBox->y1 * dst_pitch + pBox->x1 * cpp;
|
||||
}
|
||||
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
|
||||
|
||||
out:
|
||||
REGION_UNINIT(pScreen, &ValidReg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -558,7 +592,7 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
|
|||
{
|
||||
for (i = 0; i < npixmaps; i++) {
|
||||
if (!exaPixmapIsDirty (pixmaps[i].pPix))
|
||||
exaMoveOutPixmap (pixmaps[i].pPix);
|
||||
exaDoMoveOutPixmap (pixmaps + i);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -569,17 +603,17 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
|
|||
*/
|
||||
if (!can_accel) {
|
||||
for (i = 0; i < npixmaps; i++) {
|
||||
exaMigrateTowardSys (pixmaps[i].pPix);
|
||||
exaMigrateTowardSys (pixmaps + i);
|
||||
if (!exaPixmapIsDirty (pixmaps[i].pPix))
|
||||
exaMoveOutPixmap (pixmaps[i].pPix);
|
||||
exaDoMoveOutPixmap (pixmaps + i);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Finally, the acceleration path. Move them all in. */
|
||||
for (i = 0; i < npixmaps; i++) {
|
||||
exaMigrateTowardFb(pixmaps[i].pPix);
|
||||
exaMoveInPixmap(pixmaps[i].pPix);
|
||||
exaMigrateTowardFb(pixmaps + i);
|
||||
exaDoMoveInPixmap(pixmaps + i);
|
||||
}
|
||||
} else if (pExaScr->migration == ExaMigrationGreedy) {
|
||||
/* If we can't accelerate, either because the driver can't or because one of
|
||||
|
|
@ -595,7 +629,7 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
|
|||
*/
|
||||
if (!can_accel) {
|
||||
for (i = 0; i < npixmaps; i++)
|
||||
exaMigrateTowardSys (pixmaps[i].pPix);
|
||||
exaMigrateTowardSys (pixmaps + i);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -603,14 +637,14 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
|
|||
if (exaPixmapIsOffscreen(pixmaps[i].pPix)) {
|
||||
/* Found one in FB, so move all to FB. */
|
||||
for (j = 0; j < npixmaps; j++)
|
||||
exaMigrateTowardFb(pixmaps[j].pPix);
|
||||
exaMigrateTowardFb(pixmaps + i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Nobody's in FB, so move all away from FB. */
|
||||
for (i = 0; i < npixmaps; i++)
|
||||
exaMigrateTowardSys(pixmaps[i].pPix);
|
||||
exaMigrateTowardSys(pixmaps + i);
|
||||
} else if (pExaScr->migration == ExaMigrationAlways) {
|
||||
/* Always move the pixmaps out if we can't accelerate. If we can
|
||||
* accelerate, try to move them all in. If that fails, then move them
|
||||
|
|
@ -618,26 +652,25 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
|
|||
*/
|
||||
if (!can_accel) {
|
||||
for (i = 0; i < npixmaps; i++)
|
||||
exaMoveOutPixmap(pixmaps[i].pPix);
|
||||
exaDoMoveOutPixmap(pixmaps + i);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now, try to move them all into FB */
|
||||
for (i = 0; i < npixmaps; i++) {
|
||||
exaMoveInPixmap(pixmaps[i].pPix);
|
||||
ExaOffscreenMarkUsed (pixmaps[i].pPix);
|
||||
exaDoMoveInPixmap(pixmaps + i);
|
||||
}
|
||||
|
||||
/* If we couldn't fit everything in, then kick back out */
|
||||
/* If we couldn't fit everything in, abort */
|
||||
for (i = 0; i < npixmaps; i++) {
|
||||
if (!exaPixmapIsOffscreen(pixmaps[i].pPix)) {
|
||||
EXA_FALLBACK(("Pixmap %p (%dx%d) not in fb\n", pixmaps[i].pPix,
|
||||
pixmaps[i].pPix->drawable.width,
|
||||
pixmaps[i].pPix->drawable.height));
|
||||
for (j = 0; j < npixmaps; j++)
|
||||
exaMoveOutPixmap(pixmaps[j].pPix);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Yay, everything's offscreen, mark memory as used */
|
||||
for (i = 0; i < npixmaps; i++) {
|
||||
ExaOffscreenMarkUsed (pixmaps[i].pPix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ ExaOffscreenValidate (ScreenPtr pScreen)
|
|||
assert (area->offset >= area->base_offset &&
|
||||
area->offset < (area->base_offset + area->size));
|
||||
if (prev)
|
||||
assert (prev->base_offset + prev->area.size == area->base_offset);
|
||||
assert (prev->base_offset + prev->size == area->base_offset);
|
||||
prev = area;
|
||||
}
|
||||
assert (prev->base_offset + prev->size == pExaScr->info->memorySize);
|
||||
|
|
@ -341,13 +341,15 @@ exaEnableDisableFBAccess (int index, Bool enable)
|
|||
ScreenPtr pScreen = screenInfo.screens[index];
|
||||
ExaScreenPriv (pScreen);
|
||||
|
||||
if (!enable) {
|
||||
if (!enable && pExaScr->disableFbCount++ == 0) {
|
||||
if (pExaScr->info->exa_minor < 1)
|
||||
ExaOffscreenSwapOut (pScreen);
|
||||
else
|
||||
ExaOffscreenEjectPixmaps (pScreen);
|
||||
pExaScr->swappedOut = TRUE;
|
||||
} else {
|
||||
}
|
||||
|
||||
if (enable && --pExaScr->disableFbCount == 0) {
|
||||
if (pExaScr->info->exa_minor < 1)
|
||||
ExaOffscreenSwapIn (pScreen);
|
||||
pExaScr->swappedOut = FALSE;
|
||||
|
|
@ -427,7 +429,7 @@ ExaOffscreenMarkUsed (PixmapPtr pPixmap)
|
|||
ExaScreenPriv (pPixmap->drawable.pScreen);
|
||||
static int iter = 0;
|
||||
|
||||
if (!pExaPixmap->area)
|
||||
if (!pExaPixmap || !pExaPixmap->area)
|
||||
return;
|
||||
|
||||
/* The numbers here are arbitrary. We may want to tune these. */
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@
|
|||
#include <X11/X.h>
|
||||
#define NEED_EVENTS
|
||||
#include <X11/Xproto.h>
|
||||
#ifdef MITSHM
|
||||
#include "shmint.h"
|
||||
#endif
|
||||
#include "scrnintstr.h"
|
||||
#include "pixmapstr.h"
|
||||
#include "windowstr.h"
|
||||
|
|
@ -103,16 +106,20 @@ typedef struct {
|
|||
DestroyPixmapProcPtr SavedDestroyPixmap;
|
||||
PaintWindowBorderProcPtr SavedPaintWindowBorder;
|
||||
CopyWindowProcPtr SavedCopyWindow;
|
||||
ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
|
||||
BitmapToRegionProcPtr SavedBitmapToRegion;
|
||||
ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader;
|
||||
#ifdef RENDER
|
||||
CompositeProcPtr SavedComposite;
|
||||
RasterizeTrapezoidProcPtr SavedRasterizeTrapezoid;
|
||||
AddTrianglesProcPtr SavedAddTriangles;
|
||||
TrianglesProcPtr SavedTriangles;
|
||||
GlyphsProcPtr SavedGlyphs;
|
||||
TrapezoidsProcPtr SavedTrapezoids;
|
||||
#endif
|
||||
|
||||
Bool swappedOut;
|
||||
enum ExaMigrationHeuristic migration;
|
||||
Bool hideOffscreenPixmapData;
|
||||
Bool checkDirtyCorrectness;
|
||||
unsigned disableFbCount;
|
||||
} ExaScreenPrivRec, *ExaScreenPrivPtr;
|
||||
|
||||
/*
|
||||
|
|
@ -152,6 +159,7 @@ extern int exaPixmapPrivateIndex;
|
|||
typedef struct {
|
||||
ExaOffscreenArea *area;
|
||||
int score; /**< score for the move-in vs move-out heuristic */
|
||||
Bool offscreen;
|
||||
|
||||
CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */
|
||||
int sys_pitch; /**< pitch of pixmap in system memory */
|
||||
|
|
@ -167,16 +175,17 @@ typedef struct {
|
|||
*/
|
||||
DamagePtr pDamage;
|
||||
/**
|
||||
* The valid region marks the valid bits of a drawable (at least, as it's
|
||||
* derived from damage, which may be overreported).
|
||||
* The valid regions mark the valid bits (at least, as they're derived from
|
||||
* damage, which may be overreported) of a pixmap's system and FB copies.
|
||||
*/
|
||||
RegionRec validReg;
|
||||
RegionRec validSys, validFB;
|
||||
} ExaPixmapPrivRec, *ExaPixmapPrivPtr;
|
||||
|
||||
typedef struct _ExaMigrationRec {
|
||||
Bool as_dst;
|
||||
Bool as_src;
|
||||
PixmapPtr pPix;
|
||||
RegionPtr pReg;
|
||||
} ExaMigrationRec, *ExaMigrationPtr;
|
||||
|
||||
/**
|
||||
|
|
@ -185,6 +194,12 @@ typedef struct _ExaMigrationRec {
|
|||
*/
|
||||
void exaDDXDriverInit (ScreenPtr pScreen);
|
||||
|
||||
void
|
||||
exaPrepareAccessWindow(WindowPtr pWin);
|
||||
|
||||
void
|
||||
exaFinishAccessWindow(WindowPtr pWin);
|
||||
|
||||
/* exa_unaccel.c */
|
||||
void
|
||||
exaPrepareAccessGC(GCPtr pGC);
|
||||
|
|
@ -249,12 +264,6 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
|
|||
DrawablePtr pDrawable,
|
||||
int w, int h, int x, int y);
|
||||
|
||||
void
|
||||
ExaCheckGetImage (DrawablePtr pDrawable,
|
||||
int x, int y, int w, int h,
|
||||
unsigned int format, unsigned long planeMask,
|
||||
char *d);
|
||||
|
||||
void
|
||||
ExaCheckGetSpans (DrawablePtr pDrawable,
|
||||
int wMax,
|
||||
|
|
@ -263,20 +272,6 @@ ExaCheckGetSpans (DrawablePtr pDrawable,
|
|||
int nspans,
|
||||
char *pdstStart);
|
||||
|
||||
void
|
||||
ExaCheckSaveAreas (PixmapPtr pPixmap,
|
||||
RegionPtr prgnSave,
|
||||
int xorg,
|
||||
int yorg,
|
||||
WindowPtr pWin);
|
||||
|
||||
void
|
||||
ExaCheckRestoreAreas (PixmapPtr pPixmap,
|
||||
RegionPtr prgnSave,
|
||||
int xorg,
|
||||
int yorg,
|
||||
WindowPtr pWin);
|
||||
|
||||
void
|
||||
ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what);
|
||||
|
||||
|
|
@ -284,22 +279,41 @@ CARD32
|
|||
exaGetPixmapFirstPixel (PixmapPtr pPixmap);
|
||||
|
||||
/* exa_accel.c */
|
||||
|
||||
static _X_INLINE Bool
|
||||
exaGCReadsDestination(DrawablePtr pDrawable, unsigned long planemask,
|
||||
unsigned int fillStyle, unsigned char alu)
|
||||
{
|
||||
return ((alu != GXcopy && alu != GXclear &&alu != GXset &&
|
||||
alu != GXcopyInverted) || fillStyle == FillStippled ||
|
||||
!EXA_PM_IS_SOLID(pDrawable, planemask));
|
||||
}
|
||||
|
||||
void
|
||||
exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
|
||||
|
||||
Bool
|
||||
exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
|
||||
DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu);
|
||||
|
||||
void
|
||||
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
|
||||
|
||||
void
|
||||
exaShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int format,
|
||||
int w, int h, int sx, int sy, int sw, int sh, int dx, int dy,
|
||||
char *data);
|
||||
|
||||
void
|
||||
exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
|
||||
unsigned int format, unsigned long planeMask, char *d);
|
||||
|
||||
void
|
||||
exaGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth,
|
||||
int nspans, char *pdstStart);
|
||||
|
||||
extern const GCOps exaOps;
|
||||
|
||||
#ifdef MITSHM
|
||||
extern ShmFuncs exaShmFuncs;
|
||||
#endif
|
||||
|
||||
#ifdef RENDER
|
||||
void
|
||||
ExaCheckComposite (CARD8 op,
|
||||
|
|
@ -317,9 +331,6 @@ ExaCheckComposite (CARD8 op,
|
|||
#endif
|
||||
|
||||
/* exa_offscreen.c */
|
||||
void
|
||||
ExaOffscreenMarkUsed (PixmapPtr pPixmap);
|
||||
|
||||
void
|
||||
ExaOffscreenSwapOut (ScreenPtr pScreen);
|
||||
|
||||
|
|
@ -333,6 +344,12 @@ void
|
|||
ExaOffscreenFini (ScreenPtr pScreen);
|
||||
|
||||
/* exa.c */
|
||||
void
|
||||
ExaDoPrepareAccess(DrawablePtr pDrawable, int index);
|
||||
|
||||
void
|
||||
exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg);
|
||||
|
||||
void
|
||||
exaPrepareAccess(DrawablePtr pDrawable, int index);
|
||||
|
||||
|
|
@ -343,7 +360,8 @@ void
|
|||
exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
|
||||
|
||||
void
|
||||
exaDrawableDirty(DrawablePtr pDrawable, int x1, int y1, int x2, int y2);
|
||||
exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
|
||||
int *xp, int *yp);
|
||||
|
||||
Bool
|
||||
exaDrawableIsOffscreen (DrawablePtr pDrawable);
|
||||
|
|
@ -375,6 +393,9 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
|
|||
void *closure);
|
||||
|
||||
/* exa_render.c */
|
||||
Bool
|
||||
exaOpReadsDestination (CARD8 op);
|
||||
|
||||
void
|
||||
exaComposite(CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
|
|
@ -390,12 +411,14 @@ exaComposite(CARD8 op,
|
|||
CARD16 height);
|
||||
|
||||
void
|
||||
exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap,
|
||||
int x_off, int y_off);
|
||||
exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
||||
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
|
||||
int ntrap, xTrapezoid *traps);
|
||||
|
||||
void
|
||||
exaAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri,
|
||||
xTriangle *tris);
|
||||
exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
||||
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
|
||||
int ntri, xTriangle *tris);
|
||||
|
||||
void
|
||||
exaGlyphs (CARD8 op,
|
||||
|
|
|
|||
498
exa/exa_render.c
498
exa/exa_render.c
|
|
@ -111,7 +111,7 @@ exaPrintCompositeFallback(CARD8 op,
|
|||
}
|
||||
#endif /* DEBUG_TRACE_FALL */
|
||||
|
||||
static Bool
|
||||
Bool
|
||||
exaOpReadsDestination (CARD8 op)
|
||||
{
|
||||
/* FALSE (does not read destination) is the list of ops in the protocol
|
||||
|
|
@ -261,16 +261,21 @@ exaTryDriverSolidFill(PicturePtr pSrc,
|
|||
width, height))
|
||||
return 1;
|
||||
|
||||
pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
|
||||
exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
|
||||
|
||||
REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y);
|
||||
|
||||
pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
|
||||
pixel = exaGetPixmapFirstPixel (pSrcPix);
|
||||
|
||||
pixmaps[0].as_dst = TRUE;
|
||||
pixmaps[0].as_src = FALSE;
|
||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
|
||||
pixmaps[0].pPix = pDstPix;
|
||||
pixmaps[0].pReg = ®ion;
|
||||
exaDoMigration(pixmaps, 1, TRUE);
|
||||
|
||||
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
|
||||
if (!pDstPix) {
|
||||
if (!exaPixmapIsOffscreen(pDstPix)) {
|
||||
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -297,15 +302,13 @@ exaTryDriverSolidFill(PicturePtr pSrc,
|
|||
|
||||
nbox = REGION_NUM_RECTS(®ion);
|
||||
pbox = REGION_RECTS(®ion);
|
||||
|
||||
while (nbox--)
|
||||
{
|
||||
(*pExaScr->info->Solid) (pDstPix,
|
||||
pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
|
||||
pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
|
||||
exaPixmapDirty (pDstPix, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
|
||||
pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
|
||||
(*pExaScr->info->Solid) (pDstPix, pbox->x1, pbox->y1, pbox->x2, pbox->y2);
|
||||
pbox++;
|
||||
}
|
||||
|
||||
(*pExaScr->info->DoneSolid) (pDstPix);
|
||||
exaMarkSync(pDst->pDrawable->pScreen);
|
||||
|
||||
|
|
@ -366,28 +369,35 @@ exaTryDriverComposite(CARD8 op,
|
|||
xSrc += pSrc->pDrawable->x;
|
||||
ySrc += pSrc->pDrawable->y;
|
||||
|
||||
if (pExaScr->info->CheckComposite &&
|
||||
!(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
|
||||
xSrc, ySrc, xMask, yMask, xDst, yDst,
|
||||
width, height))
|
||||
return 1;
|
||||
|
||||
if (pExaScr->info->CheckComposite &&
|
||||
!(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
|
||||
{
|
||||
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||
return -1;
|
||||
}
|
||||
pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
|
||||
exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
|
||||
|
||||
REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y);
|
||||
|
||||
pixmaps[0].as_dst = TRUE;
|
||||
pixmaps[0].as_src = exaOpReadsDestination(op);
|
||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
|
||||
pixmaps[0].pPix = pDstPix;
|
||||
pixmaps[0].pReg = pixmaps[0].as_src ? NULL : ®ion;
|
||||
pixmaps[1].as_dst = FALSE;
|
||||
pixmaps[1].as_src = TRUE;
|
||||
pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
|
||||
pixmaps[1].pReg = NULL;
|
||||
if (pMask) {
|
||||
pixmaps[2].as_dst = FALSE;
|
||||
pixmaps[2].as_src = TRUE;
|
||||
pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable);
|
||||
pixmaps[2].pReg = NULL;
|
||||
exaDoMigration(pixmaps, 3, TRUE);
|
||||
} else {
|
||||
exaDoMigration(pixmaps, 2, TRUE);
|
||||
|
|
@ -397,9 +407,8 @@ exaTryDriverComposite(CARD8 op,
|
|||
if (pMask)
|
||||
pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x,
|
||||
&mask_off_y);
|
||||
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
|
||||
|
||||
if (!pDstPix) {
|
||||
if (!exaPixmapIsOffscreen(pDstPix)) {
|
||||
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -429,25 +438,23 @@ exaTryDriverComposite(CARD8 op,
|
|||
nbox = REGION_NUM_RECTS(®ion);
|
||||
pbox = REGION_RECTS(®ion);
|
||||
|
||||
xMask -= xDst;
|
||||
yMask -= yDst;
|
||||
xMask = xMask + mask_off_x - xDst - dst_off_x;
|
||||
yMask = yMask + mask_off_y - yDst - dst_off_y;
|
||||
|
||||
xSrc -= xDst;
|
||||
ySrc -= yDst;
|
||||
xSrc = xSrc + src_off_x - xDst - dst_off_x;
|
||||
ySrc = ySrc + src_off_y - yDst - dst_off_y;
|
||||
|
||||
while (nbox--)
|
||||
{
|
||||
(*pExaScr->info->Composite) (pDstPix,
|
||||
pbox->x1 + xSrc + src_off_x,
|
||||
pbox->y1 + ySrc + src_off_y,
|
||||
pbox->x1 + xMask + mask_off_x,
|
||||
pbox->y1 + yMask + mask_off_y,
|
||||
pbox->x1 + dst_off_x,
|
||||
pbox->y1 + dst_off_y,
|
||||
pbox->x1 + xSrc,
|
||||
pbox->y1 + ySrc,
|
||||
pbox->x1 + xMask,
|
||||
pbox->y1 + yMask,
|
||||
pbox->x1,
|
||||
pbox->y1,
|
||||
pbox->x2 - pbox->x1,
|
||||
pbox->y2 - pbox->y1);
|
||||
exaPixmapDirty (pDstPix, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
|
||||
pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
|
||||
pbox++;
|
||||
}
|
||||
(*pExaScr->info->DoneComposite) (pDstPix);
|
||||
|
|
@ -565,6 +572,8 @@ exaComposite(CARD8 op,
|
|||
int ret = -1;
|
||||
Bool saveSrcRepeat = pSrc->repeat;
|
||||
Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
|
||||
PixmapPtr pSrcPixmap = NULL;
|
||||
RegionRec region;
|
||||
|
||||
/* We currently don't support acceleration of gradients, or other pictures
|
||||
* with a NULL pDrawable.
|
||||
|
|
@ -583,22 +592,25 @@ exaComposite(CARD8 op,
|
|||
|
||||
if (!pMask)
|
||||
{
|
||||
if (op == PictOpSrc)
|
||||
if ((op == PictOpSrc &&
|
||||
((pSrc->format == pDst->format) ||
|
||||
(pSrc->format==PICT_a8r8g8b8 && pDst->format==PICT_x8r8g8b8) ||
|
||||
(pSrc->format==PICT_a8b8g8r8 && pDst->format==PICT_x8b8g8r8))) ||
|
||||
(op == PictOpOver && !pSrc->alphaMap && !pDst->alphaMap &&
|
||||
pSrc->format == pDst->format &&
|
||||
(pSrc->format==PICT_x8r8g8b8 || pSrc->format==PICT_x8b8g8r8)))
|
||||
{
|
||||
if (pSrc->pDrawable->width == 1 &&
|
||||
pSrc->pDrawable->height == 1 && pSrc->repeat &&
|
||||
pSrc->repeatType == RepeatNormal)
|
||||
pSrc->pDrawable->height == 1 &&
|
||||
pSrc->repeat)
|
||||
{
|
||||
ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
|
||||
width, height);
|
||||
if (ret == 1)
|
||||
goto done;
|
||||
}
|
||||
else if (!pSrc->repeat && !pSrc->transform &&
|
||||
pSrc->format == pDst->format)
|
||||
else if (pSrcPixmap && !pSrc->repeat && !pSrc->transform)
|
||||
{
|
||||
RegionRec region;
|
||||
|
||||
xDst += pDst->pDrawable->x;
|
||||
yDst += pDst->pDrawable->y;
|
||||
xSrc += pSrc->pDrawable->x;
|
||||
|
|
@ -617,6 +629,44 @@ exaComposite(CARD8 op,
|
|||
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||
goto done;
|
||||
}
|
||||
else if (pSrcPixmap && !pSrc->transform &&
|
||||
pSrc->repeatType == RepeatNormal)
|
||||
{
|
||||
DDXPointRec srcOrg;
|
||||
|
||||
/* Let's see if the driver can do the repeat in one go */
|
||||
if (pExaScr->info->PrepareComposite && !pSrc->alphaMap &&
|
||||
!pDst->alphaMap)
|
||||
{
|
||||
ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc,
|
||||
ySrc, xMask, yMask, xDst, yDst,
|
||||
width, height);
|
||||
if (ret == 1)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Now see if we can use exaFillRegionTiled() */
|
||||
xDst += pDst->pDrawable->x;
|
||||
yDst += pDst->pDrawable->y;
|
||||
xSrc += pSrc->pDrawable->x;
|
||||
ySrc += pSrc->pDrawable->y;
|
||||
|
||||
if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, xSrc,
|
||||
ySrc, xMask, yMask, xDst, yDst,
|
||||
width, height))
|
||||
goto done;
|
||||
|
||||
srcOrg.x = (xSrc - xDst) % pSrcPixmap->drawable.width;
|
||||
srcOrg.y = (ySrc - yDst) % pSrcPixmap->drawable.height;
|
||||
|
||||
ret = exaFillRegionTiled(pDst->pDrawable, ®ion, pSrcPixmap,
|
||||
&srcOrg, FB_ALLONES, GXcopy);
|
||||
|
||||
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
|
||||
|
||||
if (ret)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -627,8 +677,8 @@ exaComposite(CARD8 op,
|
|||
pMask->repeat = 0;
|
||||
|
||||
if (pExaScr->info->PrepareComposite &&
|
||||
(!pSrc->repeat || pSrc->repeat == RepeatNormal) &&
|
||||
(!pMask || !pMask->repeat || pMask->repeat == RepeatNormal) &&
|
||||
(!pSrc->repeat || pSrc->repeatType == RepeatNormal) &&
|
||||
(!pMask || !pMask->repeat || pMask->repeatType == RepeatNormal) &&
|
||||
!pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap)
|
||||
{
|
||||
Bool isSrcSolid;
|
||||
|
|
@ -660,27 +710,6 @@ exaComposite(CARD8 op,
|
|||
}
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
ExaMigrationRec pixmaps[3];
|
||||
/* failure to accelerate was not due to pixmaps being in the wrong
|
||||
* locations.
|
||||
*/
|
||||
pixmaps[0].as_dst = TRUE;
|
||||
pixmaps[0].as_src = exaOpReadsDestination(op);
|
||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
|
||||
pixmaps[1].as_dst = FALSE;
|
||||
pixmaps[1].as_src = TRUE;
|
||||
pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
|
||||
if (pMask) {
|
||||
pixmaps[2].as_dst = FALSE;
|
||||
pixmaps[2].as_src = TRUE;
|
||||
pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable);
|
||||
exaDoMigration(pixmaps, 3, FALSE);
|
||||
} else {
|
||||
exaDoMigration(pixmaps, 2, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
fallback:
|
||||
#if DEBUG_TRACE_FALL
|
||||
exaPrintCompositeFallback (op, pSrc, pMask, pDst);
|
||||
|
|
@ -688,11 +717,6 @@ fallback:
|
|||
|
||||
ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
|
||||
xMask, yMask, xDst, yDst, width, height);
|
||||
exaDrawableDirty(pDst->pDrawable,
|
||||
pDst->pDrawable->x + xDst,
|
||||
pDst->pDrawable->y + yDst,
|
||||
pDst->pDrawable->x + xDst + width,
|
||||
pDst->pDrawable->y + yDst + height);
|
||||
|
||||
done:
|
||||
pSrc->repeat = saveSrcRepeat;
|
||||
|
|
@ -701,55 +725,262 @@ done:
|
|||
}
|
||||
#endif
|
||||
|
||||
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
|
||||
|
||||
/**
|
||||
* exaRasterizeTrapezoid is just a wrapper around the software implementation.
|
||||
* Same as miCreateAlphaPicture, except it uses ExaCheckPolyFillRect instead
|
||||
* of PolyFillRect to initialize the pixmap after creating it, to prevent
|
||||
* the pixmap from being migrated.
|
||||
*
|
||||
* The trapezoid specification is basically too hard to be done in hardware (at
|
||||
* the very least, without programmability), so we just do the appropriate
|
||||
* Prepare/FinishAccess for it before using fbtrap.c.
|
||||
* See the comments about exaTrapezoids and exaTriangles.
|
||||
*/
|
||||
void
|
||||
exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap,
|
||||
int x_off, int y_off)
|
||||
static PicturePtr
|
||||
exaCreateAlphaPicture (ScreenPtr pScreen,
|
||||
PicturePtr pDst,
|
||||
PictFormatPtr pPictFormat,
|
||||
CARD16 width,
|
||||
CARD16 height)
|
||||
{
|
||||
DrawablePtr pDraw = pPicture->pDrawable;
|
||||
ExaMigrationRec pixmaps[1];
|
||||
PixmapPtr pPixmap;
|
||||
PicturePtr pPicture;
|
||||
GCPtr pGC;
|
||||
int error;
|
||||
xRectangle rect;
|
||||
|
||||
pixmaps[0].as_dst = TRUE;
|
||||
pixmaps[0].as_src = TRUE;
|
||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDraw);
|
||||
exaDoMigration(pixmaps, 1, FALSE);
|
||||
if (width > 32767 || height > 32767)
|
||||
return 0;
|
||||
|
||||
exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
|
||||
fbRasterizeTrapezoid(pPicture, trap, x_off, y_off);
|
||||
exaDrawableDirty(pDraw, pDraw->x, pDraw->y,
|
||||
pDraw->x + pDraw->width, pDraw->y + pDraw->height);
|
||||
exaFinishAccess(pDraw, EXA_PREPARE_DEST);
|
||||
if (!pPictFormat)
|
||||
{
|
||||
if (pDst->polyEdge == PolyEdgeSharp)
|
||||
pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
|
||||
else
|
||||
pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
|
||||
if (!pPictFormat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
|
||||
pPictFormat->depth);
|
||||
if (!pPixmap)
|
||||
return 0;
|
||||
pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
|
||||
if (!pGC)
|
||||
{
|
||||
(*pScreen->DestroyPixmap) (pPixmap);
|
||||
return 0;
|
||||
}
|
||||
ValidateGC (&pPixmap->drawable, pGC);
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
ExaCheckPolyFillRect (&pPixmap->drawable, pGC, 1, &rect);
|
||||
exaPixmapDirty (pPixmap, 0, 0, width, height);
|
||||
FreeScratchGC (pGC);
|
||||
pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
|
||||
0, 0, serverClient, &error);
|
||||
(*pScreen->DestroyPixmap) (pPixmap);
|
||||
return pPicture;
|
||||
}
|
||||
|
||||
/**
|
||||
* exaAddTriangles does migration and syncing before dumping down to the
|
||||
* software implementation.
|
||||
* exaTrapezoids is essentially a copy of miTrapezoids that uses
|
||||
* exaCreateAlphaPicture instead of miCreateAlphaPicture.
|
||||
*
|
||||
* The problem with miCreateAlphaPicture is that it calls PolyFillRect
|
||||
* to initialize the contents after creating the pixmap, which
|
||||
* causes the pixmap to be moved in for acceleration. The subsequent
|
||||
* call to RasterizeTrapezoid won't be accelerated however, which
|
||||
* forces the pixmap to be moved out again.
|
||||
*
|
||||
* exaCreateAlphaPicture avoids this roundtrip by using ExaCheckPolyFillRect
|
||||
* to initialize the contents.
|
||||
*/
|
||||
void
|
||||
exaAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri,
|
||||
xTriangle *tris)
|
||||
exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
||||
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
|
||||
int ntrap, xTrapezoid *traps)
|
||||
{
|
||||
DrawablePtr pDraw = pPicture->pDrawable;
|
||||
ExaMigrationRec pixmaps[1];
|
||||
ScreenPtr pScreen = pDst->pDrawable->pScreen;
|
||||
PictureScreenPtr ps = GetPictureScreen(pScreen);
|
||||
BoxRec bounds;
|
||||
Bool direct = op == PictOpAdd && miIsSolidAlpha (pSrc);
|
||||
|
||||
pixmaps[0].as_dst = TRUE;
|
||||
pixmaps[0].as_src = TRUE;
|
||||
pixmaps[0].pPix = exaGetDrawablePixmap (pDraw);
|
||||
exaDoMigration(pixmaps, 1, FALSE);
|
||||
if (maskFormat || direct) {
|
||||
miTrapezoidBounds (ntrap, traps, &bounds);
|
||||
|
||||
exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
|
||||
fbAddTriangles(pPicture, x_off, y_off, ntri, tris);
|
||||
exaDrawableDirty(pDraw, pDraw->x, pDraw->y,
|
||||
pDraw->x + pDraw->width, pDraw->y + pDraw->height);
|
||||
exaFinishAccess(pDraw, EXA_PREPARE_DEST);
|
||||
if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for solid alpha add
|
||||
*/
|
||||
if (direct)
|
||||
{
|
||||
DrawablePtr pDraw = pDst->pDrawable;
|
||||
PixmapPtr pixmap = exaGetDrawablePixmap (pDraw);
|
||||
ExaPixmapPriv (pixmap);
|
||||
RegionRec migration;
|
||||
RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
|
||||
int xoff, yoff;
|
||||
|
||||
exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff);
|
||||
|
||||
xoff += pDraw->x;
|
||||
yoff += pDraw->y;
|
||||
|
||||
bounds.x1 += xoff;
|
||||
bounds.y1 += yoff;
|
||||
bounds.x2 += xoff;
|
||||
bounds.y2 += yoff;
|
||||
|
||||
REGION_INIT(pScreen, &migration, &bounds, 1);
|
||||
REGION_UNION(pScreen, pending_damage, pending_damage, &migration);
|
||||
REGION_UNINIT(pScreen, &migration);
|
||||
|
||||
exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
|
||||
|
||||
for (; ntrap; ntrap--, traps++)
|
||||
(*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
|
||||
|
||||
exaFinishAccess(pDraw, EXA_PREPARE_DEST);
|
||||
}
|
||||
else if (maskFormat)
|
||||
{
|
||||
PicturePtr pPicture;
|
||||
INT16 xDst, yDst;
|
||||
INT16 xRel, yRel;
|
||||
|
||||
xDst = traps[0].left.p1.x >> 16;
|
||||
yDst = traps[0].left.p1.y >> 16;
|
||||
|
||||
pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat,
|
||||
bounds.x2 - bounds.x1,
|
||||
bounds.y2 - bounds.y1);
|
||||
if (!pPicture)
|
||||
return;
|
||||
|
||||
exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
|
||||
for (; ntrap; ntrap--, traps++)
|
||||
(*ps->RasterizeTrapezoid) (pPicture, traps,
|
||||
-bounds.x1, -bounds.y1);
|
||||
exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
|
||||
|
||||
xRel = bounds.x1 + xSrc - xDst;
|
||||
yRel = bounds.y1 + ySrc - yDst;
|
||||
CompositePicture (op, pSrc, pPicture, pDst,
|
||||
xRel, yRel, 0, 0, bounds.x1, bounds.y1,
|
||||
bounds.x2 - bounds.x1,
|
||||
bounds.y2 - bounds.y1);
|
||||
FreePicture (pPicture, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pDst->polyEdge == PolyEdgeSharp)
|
||||
maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
|
||||
else
|
||||
maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
|
||||
for (; ntrap; ntrap--, traps++)
|
||||
exaTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* exaTriangles is essentially a copy of miTriangles that uses
|
||||
* exaCreateAlphaPicture instead of miCreateAlphaPicture.
|
||||
*
|
||||
* The problem with miCreateAlphaPicture is that it calls PolyFillRect
|
||||
* to initialize the contents after creating the pixmap, which
|
||||
* causes the pixmap to be moved in for acceleration. The subsequent
|
||||
* call to AddTriangles won't be accelerated however, which forces the pixmap
|
||||
* to be moved out again.
|
||||
*
|
||||
* exaCreateAlphaPicture avoids this roundtrip by using ExaCheckPolyFillRect
|
||||
* to initialize the contents.
|
||||
*/
|
||||
void
|
||||
exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
|
||||
PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
|
||||
int ntri, xTriangle *tris)
|
||||
{
|
||||
ScreenPtr pScreen = pDst->pDrawable->pScreen;
|
||||
PictureScreenPtr ps = GetPictureScreen(pScreen);
|
||||
BoxRec bounds;
|
||||
Bool direct = op == PictOpAdd && miIsSolidAlpha (pSrc);
|
||||
|
||||
if (maskFormat || direct) {
|
||||
miTriangleBounds (ntri, tris, &bounds);
|
||||
|
||||
if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for solid alpha add
|
||||
*/
|
||||
if (direct)
|
||||
{
|
||||
DrawablePtr pDraw = pDst->pDrawable;
|
||||
PixmapPtr pixmap = exaGetDrawablePixmap (pDraw);
|
||||
ExaPixmapPriv (pixmap);
|
||||
RegionRec migration;
|
||||
RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
|
||||
int xoff, yoff;
|
||||
|
||||
exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff);
|
||||
|
||||
xoff += pDraw->x;
|
||||
yoff += pDraw->y;
|
||||
|
||||
bounds.x1 += xoff;
|
||||
bounds.y1 += yoff;
|
||||
bounds.x2 += xoff;
|
||||
bounds.y2 += yoff;
|
||||
|
||||
REGION_INIT(pScreen, &migration, &bounds, 1);
|
||||
REGION_UNION(pScreen, pending_damage, pending_damage, &migration);
|
||||
REGION_UNINIT(pScreen, &migration);
|
||||
|
||||
exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
|
||||
(*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
|
||||
exaFinishAccess(pDraw, EXA_PREPARE_DEST);
|
||||
}
|
||||
else if (maskFormat)
|
||||
{
|
||||
PicturePtr pPicture;
|
||||
INT16 xDst, yDst;
|
||||
INT16 xRel, yRel;
|
||||
|
||||
xDst = tris[0].p1.x >> 16;
|
||||
yDst = tris[0].p1.y >> 16;
|
||||
|
||||
pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat,
|
||||
bounds.x2 - bounds.x1,
|
||||
bounds.y2 - bounds.y1);
|
||||
if (!pPicture)
|
||||
return;
|
||||
|
||||
exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
|
||||
(*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
|
||||
exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
|
||||
|
||||
xRel = bounds.x1 + xSrc - xDst;
|
||||
yRel = bounds.y1 + ySrc - yDst;
|
||||
CompositePicture (op, pSrc, pPicture, pDst,
|
||||
xRel, yRel, 0, 0, bounds.x1, bounds.y1,
|
||||
bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
|
||||
FreePicture (pPicture, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pDst->polyEdge == PolyEdgeSharp)
|
||||
maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
|
||||
else
|
||||
maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
|
||||
|
||||
for (; ntri; ntri--, tris++)
|
||||
exaTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -825,10 +1056,15 @@ exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
|
||||
|
||||
/* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The
|
||||
* issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to
|
||||
* migrate these pixmaps. So, instead we create a pixmap at the beginning of
|
||||
* the loop and upload each glyph into the pixmap before compositing.
|
||||
*
|
||||
* This is now used even when Composite can't be accelerated for better
|
||||
* migration control.
|
||||
*/
|
||||
void
|
||||
exaGlyphs (CARD8 op,
|
||||
|
|
@ -848,7 +1084,7 @@ exaGlyphs (CARD8 op,
|
|||
PicturePtr pMask;
|
||||
ScreenPtr pScreen = pDst->pDrawable->pScreen;
|
||||
int width = 0, height = 0;
|
||||
int x, y;
|
||||
int x, y, x1, y1;
|
||||
int xDst = list->xOff, yDst = list->yOff;
|
||||
int n;
|
||||
int error;
|
||||
|
|
@ -876,23 +1112,18 @@ exaGlyphs (CARD8 op,
|
|||
}
|
||||
}
|
||||
|
||||
/* If the driver doesn't support accelerated composite, there's no point in
|
||||
* going to this extra work. Assume that any driver that supports Composite
|
||||
* will be able to support component alpha using the two-pass helper.
|
||||
*/
|
||||
if (!pExaScr->info->PrepareComposite)
|
||||
{
|
||||
miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (maskFormat)
|
||||
{
|
||||
GCPtr pGC;
|
||||
xRectangle rect;
|
||||
|
||||
miGlyphExtents (nlist, list, glyphs, &extents);
|
||||
|
||||
|
||||
extents.x1 = max(extents.x1, 0);
|
||||
extents.y1 = max(extents.y1, 0);
|
||||
extents.x2 = min(extents.x2, pDst->pDrawable->width);
|
||||
extents.y2 = min(extents.y2, pDst->pDrawable->height);
|
||||
|
||||
if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
|
||||
return;
|
||||
width = extents.x2 - extents.x1;
|
||||
|
|
@ -917,7 +1148,11 @@ exaGlyphs (CARD8 op,
|
|||
rect.y = 0;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
|
||||
ExaCheckPolyFillRect (&pMaskPixmap->drawable, pGC, 1, &rect);
|
||||
if (pExaScr->info->PrepareComposite)
|
||||
(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
|
||||
else
|
||||
exaPixmapDirty(pMaskPixmap, 0, 0, width, height);
|
||||
FreeScratchGC (pGC);
|
||||
x = -extents.x1;
|
||||
y = -extents.y1;
|
||||
|
|
@ -981,15 +1216,24 @@ exaGlyphs (CARD8 op,
|
|||
* it'll stick there.
|
||||
*/
|
||||
pixmaps[0].as_dst = TRUE;
|
||||
pixmaps[0].as_src = TRUE;
|
||||
pixmaps[0].as_src = FALSE;
|
||||
pixmaps[0].pPix = pPixmap;
|
||||
exaDoMigration (pixmaps, 1, TRUE);
|
||||
pixmaps[0].pReg = NULL;
|
||||
exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL);
|
||||
|
||||
while (n--)
|
||||
{
|
||||
GlyphPtr glyph = *glyphs++;
|
||||
pointer glyphdata = (pointer) (glyph + 1);
|
||||
|
||||
DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable;
|
||||
|
||||
x1 = x - glyph->info.x;
|
||||
y1 = y - glyph->info.y;
|
||||
|
||||
if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height ||
|
||||
(x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0)
|
||||
goto nextglyph;
|
||||
|
||||
(*pScreen->ModifyPixmapHeader) (pScratchPixmap,
|
||||
glyph->info.width,
|
||||
glyph->info.height,
|
||||
|
|
@ -1038,6 +1282,15 @@ exaGlyphs (CARD8 op,
|
|||
pScratchPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
}
|
||||
|
||||
#ifdef MITSHM
|
||||
if (pExaScr->info->PrepareComposite)
|
||||
exaShmPutImage(&pPixmap->drawable, pGC,
|
||||
pPixmap->drawable.depth, ZPixmap,
|
||||
glyph->info.width, glyph->info.height, 0, 0,
|
||||
glyph->info.width, glyph->info.height, 0, 0,
|
||||
glyphdata);
|
||||
else
|
||||
#endif
|
||||
exaCopyArea (&pScratchPixmap->drawable, &pPixmap->drawable, pGC,
|
||||
0, 0, glyph->info.width, glyph->info.height, 0, 0);
|
||||
}
|
||||
|
|
@ -1048,17 +1301,18 @@ exaGlyphs (CARD8 op,
|
|||
if (maskFormat)
|
||||
{
|
||||
exaComposite (PictOpAdd, pPicture, NULL, pMask, 0, 0, 0, 0,
|
||||
x - glyph->info.x, y - glyph->info.y,
|
||||
glyph->info.width, glyph->info.height);
|
||||
x1, y1, glyph->info.width, glyph->info.height);
|
||||
exaPixmapDirty(pMaskPixmap, x1, y1, x1 + glyph->info.width,
|
||||
y1 + glyph->info.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
exaComposite (op, pSrc, pPicture, pDst,
|
||||
xSrc + (x - glyph->info.x) - xDst,
|
||||
ySrc + (y - glyph->info.y) - yDst,
|
||||
0, 0, x - glyph->info.x, y - glyph->info.y,
|
||||
glyph->info.width, glyph->info.height);
|
||||
xSrc + x1 - xDst, ySrc + y1 - yDst,
|
||||
0, 0, x1, y1, glyph->info.width,
|
||||
glyph->info.height);
|
||||
}
|
||||
nextglyph:
|
||||
x += glyph->info.xOff;
|
||||
y += glyph->info.yOff;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@
|
|||
|
||||
#include "exa_priv.h"
|
||||
|
||||
#ifdef RENDER
|
||||
#include "mipict.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These functions wrap the low-level fb rendering functions and
|
||||
* synchronize framebuffer/accelerated drawing by stalling until
|
||||
|
|
@ -35,10 +39,13 @@
|
|||
*
|
||||
* Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are
|
||||
* 1bpp and never in fb, so we don't worry about them.
|
||||
* We should worry about them for completeness sake and going forward.
|
||||
*/
|
||||
void
|
||||
exaPrepareAccessGC(GCPtr pGC)
|
||||
{
|
||||
if (pGC->stipple)
|
||||
exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
|
||||
if (pGC->fillStyle == FillTiled)
|
||||
exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
|
||||
}
|
||||
|
|
@ -50,7 +57,9 @@ void
|
|||
exaFinishAccessGC(GCPtr pGC)
|
||||
{
|
||||
if (pGC->fillStyle == FillTiled)
|
||||
exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
|
||||
exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_MASK);
|
||||
if (pGC->stipple)
|
||||
exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_SRC);
|
||||
}
|
||||
|
||||
#if DEBUG_TRACE_FALL
|
||||
|
|
@ -89,7 +98,11 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
|
|||
char *bits)
|
||||
{
|
||||
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
|
||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||
if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
|
||||
pGC->alu))
|
||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||
else
|
||||
ExaDoPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||
fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
|
||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||
}
|
||||
|
|
@ -201,32 +214,11 @@ ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
|
|||
{
|
||||
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
|
||||
|
||||
if (nrect) {
|
||||
int x1 = max(prect->x, 0), y1 = max(prect->y, 0);
|
||||
int x2 = min(prect->x + prect->width, pDrawable->width);
|
||||
int y2 = min(prect->y + prect->height, pDrawable->height);
|
||||
|
||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||
exaPrepareAccessGC (pGC);
|
||||
fbPolyFillRect (pDrawable, pGC, nrect, prect);
|
||||
exaFinishAccessGC (pGC);
|
||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||
|
||||
/* Only track bounding box of damage, as this path can degenerate to
|
||||
* zillions of damage boxes
|
||||
*/
|
||||
while (--nrect)
|
||||
{
|
||||
prect++;
|
||||
x1 = min(x1, prect->x);
|
||||
x2 = max(x2, prect->x + prect->width);
|
||||
y1 = min(y1, prect->y);
|
||||
y2 = max(y2, prect->y + prect->height);
|
||||
}
|
||||
|
||||
exaDrawableDirty (pDrawable, pDrawable->x + x1, pDrawable->y + y1,
|
||||
pDrawable->x + x2, pDrawable->y + y2);
|
||||
}
|
||||
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
|
||||
exaPrepareAccessGC (pGC);
|
||||
fbPolyFillRect (pDrawable, pGC, nrect, prect);
|
||||
exaFinishAccessGC (pGC);
|
||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -272,19 +264,6 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
|
|||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||
}
|
||||
|
||||
void
|
||||
ExaCheckGetImage (DrawablePtr pDrawable,
|
||||
int x, int y, int w, int h,
|
||||
unsigned int format, unsigned long planeMask,
|
||||
char *d)
|
||||
{
|
||||
EXA_FALLBACK(("from %p (%c)\n", pDrawable,
|
||||
exaDrawableLocation(pDrawable)));
|
||||
exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
|
||||
fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
|
||||
exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
|
||||
}
|
||||
|
||||
void
|
||||
ExaCheckGetSpans (DrawablePtr pDrawable,
|
||||
int wMax,
|
||||
|
|
@ -299,34 +278,6 @@ ExaCheckGetSpans (DrawablePtr pDrawable,
|
|||
exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
|
||||
}
|
||||
|
||||
void
|
||||
ExaCheckSaveAreas (PixmapPtr pPixmap,
|
||||
RegionPtr prgnSave,
|
||||
int xorg,
|
||||
int yorg,
|
||||
WindowPtr pWin)
|
||||
{
|
||||
EXA_FALLBACK(("from %p (%c)\n", &pPixmap->drawable,
|
||||
exaDrawableLocation(&pPixmap->drawable)));
|
||||
exaPrepareAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
|
||||
fbSaveAreas (pPixmap, prgnSave, xorg, yorg, pWin);
|
||||
exaFinishAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
|
||||
}
|
||||
|
||||
void
|
||||
ExaCheckRestoreAreas (PixmapPtr pPixmap,
|
||||
RegionPtr prgnSave,
|
||||
int xorg,
|
||||
int yorg,
|
||||
WindowPtr pWin)
|
||||
{
|
||||
EXA_FALLBACK(("to %p (%c)\n", &pPixmap->drawable,
|
||||
exaDrawableLocation(&pPixmap->drawable)));
|
||||
exaPrepareAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
|
||||
fbRestoreAreas (pPixmap, prgnSave, xorg, yorg, pWin);
|
||||
exaFinishAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
|
||||
}
|
||||
|
||||
/* XXX: Note the lack of a prepare on the tile, if the window has a tiled
|
||||
* background. This function happens to only be called if pExaScr->swappedOut,
|
||||
* so we actually end up not having to do it since the tile won't be in fb.
|
||||
|
|
@ -338,7 +289,9 @@ ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what)
|
|||
EXA_FALLBACK(("from %p (%c)\n", pWin,
|
||||
exaDrawableLocation(&pWin->drawable)));
|
||||
exaPrepareAccess (&pWin->drawable, EXA_PREPARE_DEST);
|
||||
exaPrepareAccessWindow(pWin);
|
||||
fbPaintWindow (pWin, pRegion, what);
|
||||
exaFinishAccessWindow(pWin);
|
||||
exaFinishAccess (&pWin->drawable, EXA_PREPARE_DEST);
|
||||
}
|
||||
|
||||
|
|
@ -356,9 +309,30 @@ ExaCheckComposite (CARD8 op,
|
|||
CARD16 width,
|
||||
CARD16 height)
|
||||
{
|
||||
RegionRec region;
|
||||
int xoff, yoff;
|
||||
|
||||
REGION_NULL(pScreen, ®ion);
|
||||
|
||||
if (!exaOpReadsDestination(op)) {
|
||||
if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
|
||||
xSrc, ySrc, xMask, yMask, xDst, yDst,
|
||||
width, height))
|
||||
return;
|
||||
|
||||
exaGetDrawableDeltas (pDst->pDrawable,
|
||||
exaGetDrawablePixmap(pDst->pDrawable),
|
||||
&xoff, &yoff);
|
||||
|
||||
REGION_TRANSLATE(pScreen, ®ion, xoff, yoff);
|
||||
|
||||
exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, ®ion);
|
||||
} else
|
||||
exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
|
||||
|
||||
EXA_FALLBACK(("from picts %p/%p to pict %p\n",
|
||||
pSrc, pMask, pDst));
|
||||
exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
|
||||
|
||||
if (pSrc->pDrawable != NULL)
|
||||
exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
|
||||
if (pMask && pMask->pDrawable != NULL)
|
||||
|
|
@ -380,36 +354,64 @@ ExaCheckComposite (CARD8 op,
|
|||
if (pSrc->pDrawable != NULL)
|
||||
exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
|
||||
exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
|
||||
|
||||
REGION_UNINIT(pScreen, ®ion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps
|
||||
* that happen to be 1x1. Pixmap must be at least 8bpp.
|
||||
*
|
||||
* XXX This really belongs in fb, so it can be aware of tiling and etc.
|
||||
*/
|
||||
CARD32
|
||||
exaGetPixmapFirstPixel (PixmapPtr pPixmap)
|
||||
{
|
||||
CARD32 pixel;
|
||||
ExaMigrationRec pixmaps[1];
|
||||
void *fb;
|
||||
Bool need_finish = FALSE;
|
||||
BoxRec box;
|
||||
RegionRec migration;
|
||||
ExaPixmapPriv (pPixmap);
|
||||
Bool sys_valid = !miPointInRegion(&pExaPixmap->validSys, 0, 0, &box);
|
||||
Bool damaged = miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0,
|
||||
&box);
|
||||
Bool offscreen = exaPixmapIsOffscreen(pPixmap);
|
||||
|
||||
pixmaps[0].as_dst = FALSE;
|
||||
pixmaps[0].as_src = TRUE;
|
||||
pixmaps[0].pPix = pPixmap;
|
||||
exaDoMigration (pixmaps, 1, FALSE);
|
||||
fb = pExaPixmap->sys_ptr;
|
||||
|
||||
/* Try to avoid framebuffer readbacks */
|
||||
if ((!offscreen && !sys_valid && !damaged) ||
|
||||
(offscreen && (!sys_valid || damaged)))
|
||||
{
|
||||
box.x1 = 0;
|
||||
box.y1 = 0;
|
||||
box.x2 = 1;
|
||||
box.y2 = 1;
|
||||
REGION_INIT(pScreen, &migration, &box, 1);
|
||||
|
||||
need_finish = TRUE;
|
||||
|
||||
exaPrepareAccessReg(&pPixmap->drawable, EXA_PREPARE_SRC, &migration);
|
||||
fb = pPixmap->devPrivate.ptr;
|
||||
}
|
||||
|
||||
exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
|
||||
switch (pPixmap->drawable.bitsPerPixel) {
|
||||
case 32:
|
||||
pixel = *(CARD32 *)(pPixmap->devPrivate.ptr);
|
||||
pixel = *(CARD32 *)fb;
|
||||
break;
|
||||
case 16:
|
||||
pixel = *(CARD16 *)(pPixmap->devPrivate.ptr);
|
||||
pixel = *(CARD16 *)fb;
|
||||
break;
|
||||
default:
|
||||
pixel = *(CARD8 *)(pPixmap->devPrivate.ptr);
|
||||
pixel = *(CARD8 *)fb;
|
||||
break;
|
||||
}
|
||||
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
|
||||
|
||||
if (need_finish) {
|
||||
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
|
||||
REGION_UNINIT(pScreen, &migration);
|
||||
}
|
||||
|
||||
return pixel;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
noinst_LTLIBRARIES = libfb.la libwfb.la libfbmmx.la
|
||||
noinst_LTLIBRARIES = libfb.la libwfb.la
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir)/hw/xfree86/os-support \
|
||||
|
|
@ -12,25 +12,8 @@ endif
|
|||
|
||||
libfb_la_CFLAGS = $(AM_CFLAGS)
|
||||
|
||||
if MMX_CAPABLE
|
||||
libfb_la_CFLAGS += -DUSE_MMX
|
||||
|
||||
libfbmmx_la_CFLAGS = \
|
||||
$(DIX_CFLAGS) \
|
||||
-DUSE_MMX \
|
||||
-mmmx \
|
||||
-msse \
|
||||
-Winline \
|
||||
--param inline-unit-growth=10000 \
|
||||
--param large-function-growth=10000
|
||||
endif
|
||||
|
||||
libwfb_la_CFLAGS = $(AM_CFLAGS) -DFB_ACCESS_WRAPPER
|
||||
|
||||
libfbmmx_la_SOURCES = \
|
||||
fbmmx.c \
|
||||
fbmmx.h
|
||||
|
||||
libfb_la_SOURCES = \
|
||||
fb.h \
|
||||
fb24_32.c \
|
||||
|
|
@ -41,8 +24,6 @@ libfb_la_SOURCES = \
|
|||
fbbits.h \
|
||||
fbblt.c \
|
||||
fbbltone.c \
|
||||
fbbstore.c \
|
||||
fbcompose.c \
|
||||
fbcopy.c \
|
||||
fbfill.c \
|
||||
fbfillrect.c \
|
||||
|
|
@ -70,12 +51,8 @@ libfb_la_SOURCES = \
|
|||
fbutil.c \
|
||||
fbwindow.c \
|
||||
fbpseudocolor.c \
|
||||
fbpseudocolor.h \
|
||||
fbedge.c \
|
||||
fbedgeimp.h
|
||||
fbpseudocolor.h
|
||||
|
||||
libwfb_la_SOURCES = $(libfb_la_SOURCES)
|
||||
|
||||
libfb_la_LIBADD = libfbmmx.la
|
||||
|
||||
EXTRA_DIST = fbcmap.c fbcmap_mi.c
|
||||
|
|
|
|||
60
fb/fb.h
60
fb/fb.h
|
|
@ -26,6 +26,8 @@
|
|||
#define _FB_H_
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <pixman.h>
|
||||
|
||||
#include "scrnintstr.h"
|
||||
#include "pixmap.h"
|
||||
#include "pixmapstr.h"
|
||||
|
|
@ -607,16 +609,6 @@ extern int fbGetWinPrivateIndex(void);
|
|||
extern const GCOps fbGCOps;
|
||||
extern const GCFuncs fbGCFuncs;
|
||||
|
||||
#ifdef TEKX11
|
||||
#define FB_OLD_GC
|
||||
#define FB_OLD_SCREEN
|
||||
#endif
|
||||
|
||||
#ifdef FB_OLD_SCREEN
|
||||
# define FB_OLD_MISCREENINIT /* miScreenInit requires 14 args, not 13 */
|
||||
extern WindowPtr *WindowTable;
|
||||
#endif
|
||||
|
||||
#ifdef FB_24_32BIT
|
||||
#define FB_SCREEN_PRIVATE
|
||||
#endif
|
||||
|
|
@ -667,15 +659,6 @@ typedef struct {
|
|||
|
||||
/* private field of GC */
|
||||
typedef struct {
|
||||
#ifdef FB_OLD_GC
|
||||
unsigned char pad1;
|
||||
unsigned char pad2;
|
||||
unsigned char pad3;
|
||||
unsigned fExpose:1;
|
||||
unsigned freeCompClip:1;
|
||||
PixmapPtr pRotatedPixmap;
|
||||
RegionPtr pCompositeClip;
|
||||
#endif
|
||||
FbBits and, xor; /* reduced rop values */
|
||||
FbBits bgand, bgxor; /* for stipples */
|
||||
FbBits fg, bg, pm; /* expanded and filled */
|
||||
|
|
@ -688,17 +671,10 @@ typedef struct {
|
|||
#define fbGetGCPrivate(pGC) ((FbGCPrivPtr)\
|
||||
(pGC)->devPrivates[fbGetGCPrivateIndex()].ptr)
|
||||
|
||||
#ifdef FB_OLD_GC
|
||||
#define fbGetCompositeClip(pGC) (fbGetGCPrivate(pGC)->pCompositeClip)
|
||||
#define fbGetExpose(pGC) (fbGetGCPrivate(pGC)->fExpose)
|
||||
#define fbGetFreeCompClip(pGC) (fbGetGCPrivate(pGC)->freeCompClip)
|
||||
#define fbGetRotatedPixmap(pGC) (fbGetGCPrivate(pGC)->pRotatedPixmap)
|
||||
#else
|
||||
#define fbGetCompositeClip(pGC) ((pGC)->pCompositeClip)
|
||||
#define fbGetExpose(pGC) ((pGC)->fExpose)
|
||||
#define fbGetFreeCompClip(pGC) ((pGC)->freeCompClip)
|
||||
#define fbGetRotatedPixmap(pGC) ((pGC)->pRotatedPixmap)
|
||||
#endif
|
||||
|
||||
#define fbGetScreenPixmap(s) ((PixmapPtr) (s)->devPrivate)
|
||||
#ifdef FB_NO_WINDOW_PIXMAPS
|
||||
|
|
@ -773,12 +749,6 @@ typedef struct {
|
|||
((pDrawable)->type == DRAWABLE_PIXMAP ? \
|
||||
TRUE : fbWindowEnabled((WindowPtr) pDrawable))
|
||||
|
||||
#ifdef FB_OLD_SCREEN
|
||||
#define BitsPerPixel(d) (\
|
||||
((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \
|
||||
(PixmapWidthPaddingInfo[d].padRoundUp+1)))
|
||||
#endif
|
||||
|
||||
#define FbPowerOfTwo(w) (((w) & ((w) - 1)) == 0)
|
||||
/*
|
||||
* Accelerated tiles are power of 2 width <= FB_UNIT
|
||||
|
|
@ -1291,23 +1261,6 @@ fbBltPlane (FbBits *src,
|
|||
FbStip bgxor,
|
||||
Pixel planeMask);
|
||||
|
||||
/*
|
||||
* fbbstore.c
|
||||
*/
|
||||
void
|
||||
fbSaveAreas(PixmapPtr pPixmap,
|
||||
RegionPtr prgnSave,
|
||||
int xorg,
|
||||
int yorg,
|
||||
WindowPtr pWin);
|
||||
|
||||
void
|
||||
fbRestoreAreas(PixmapPtr pPixmap,
|
||||
RegionPtr prgnRestore,
|
||||
int xorg,
|
||||
int yorg,
|
||||
WindowPtr pWin);
|
||||
|
||||
/*
|
||||
* fbcmap.c
|
||||
*/
|
||||
|
|
@ -1788,13 +1741,11 @@ fbQueryBestSize (int class,
|
|||
unsigned short *width, unsigned short *height,
|
||||
ScreenPtr pScreen);
|
||||
|
||||
#ifndef FB_OLD_SCREEN
|
||||
PixmapPtr
|
||||
_fbGetWindowPixmap (WindowPtr pWindow);
|
||||
|
||||
void
|
||||
_fbSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap);
|
||||
#endif
|
||||
|
||||
Bool
|
||||
fbSetupScreen(ScreenPtr pScreen,
|
||||
|
|
@ -2030,7 +1981,7 @@ fbEvenTile (FbBits *dst,
|
|||
int height,
|
||||
|
||||
FbBits *tile,
|
||||
FbStride tileStride,
|
||||
FbStride tileStride,
|
||||
int tileHeight,
|
||||
|
||||
int alu,
|
||||
|
|
@ -2147,4 +2098,9 @@ void
|
|||
fbPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
|
||||
|
||||
|
||||
pixman_image_t *image_from_pict (PicturePtr pict,
|
||||
Bool has_clip);
|
||||
void free_pixman_pict (PicturePtr, pixman_image_t *);
|
||||
|
||||
#endif /* _FB_H_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* $XFree86$
|
||||
*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue