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:
José Fonseca 2007-09-12 17:43:33 +01:00
commit c13e2a941d
969 changed files with 13565 additions and 193939 deletions

31
.gitignore vendored
View file

@ -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

2717
COPYING

File diff suppressed because it is too large Load diff

View file

@ -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)

View file

@ -40,6 +40,7 @@ libglxdri_la_SOURCES = \
libglx_la_SOURCES = \
g_disptab.h \
glxbyteorder.h \
glxcmds.c \
glxcmdsswap.c \
glxcontext.h \

View file

@ -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;

View file

@ -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)

View file

@ -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 {

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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 *

View file

@ -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);

View file

@ -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 *);

View file

@ -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:

View file

@ -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 = {

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1,4 +1,3 @@
/* $XFree86$ */
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif

View file

@ -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

View file

@ -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 \

View file

@ -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 \

View file

@ -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 \

View file

@ -1,4 +1,3 @@
/* $XFree86$ */
/****************************************************************************
Copyright 1987, 1988, 1989, 1990, 1991, 1992 by

View file

@ -1,4 +1,3 @@
/* $XFree86$ */
/****************************************************************************
Copyright 1987, 1988, 1989, 1990, 1991 by Digital Equipment Corp., Maynard, MA

View file

@ -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

View file

@ -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 */

View file

@ -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, &reg, &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, &reg, &reg, &pBuffer->clipList);
if (pBuffer->backgroundState != None)

View file

@ -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.

View file

@ -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>

View file

@ -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",

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

View file

@ -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

View file

@ -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>

View file

@ -1,3 +1 @@
/* $XFree86$ */
extern void XineramifyXv(void);

View file

@ -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)

View file

@ -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;

View file

@ -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=

View file

@ -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

View file

@ -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(

View file

@ -1,4 +1,3 @@
/* $XFree86$ */
/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
/***********************************************************

View file

@ -1,4 +1,3 @@
/* $XFree86$ */
/***********************************************************
Copyright (c) 1987 X Consortium

View file

@ -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);
}

View file

@ -1,4 +1,3 @@
/* $XFree86$ */
/*
Copyright (c) 1987 X Consortium

View file

@ -1,4 +1,3 @@
/* $XFree86$ */
/***********************************************************
Copyright (c) 1987 X Consortium

View file

@ -1,4 +1,3 @@
/* $XFree86$ */
/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
/***********************************************************

View file

@ -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;

View file

@ -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 \

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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;

View file

@ -1,5 +1,3 @@
/* $XFree86$ */
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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
View 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

View file

@ -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 */

View file

@ -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
View 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
View 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
View 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
View 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>

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,4 @@
/*
* $Id$
*
* Copyright © 2002 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View file

@ -1,6 +1,4 @@
/*
* $Id$
*
* Copyright © 2002 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View file

@ -1,6 +1,4 @@
/*
* $Id$
*
* Copyright © 2002 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View file

@ -29,7 +29,6 @@
* Header file for DIX-related DBE
*
*****************************************************************************/
/* $XFree86$ */
#ifndef DBE_STRUCT_H
#define DBE_STRUCT_H

View file

@ -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>

View file

@ -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

View file

@ -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;

View file

@ -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;
}
}
}

View file

@ -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++)
{

View file

@ -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;

View file

@ -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

View file

@ -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;
}

View file

@ -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))

View file

@ -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)

View file

@ -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)

View file

@ -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,

View file

@ -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

View file

@ -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);
}
}
}

View file

@ -1,4 +1,3 @@
/* $XFree86$ */
/*
Copyright 1996, 1998 The Open Group

View file

@ -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
View file

@ -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, &region);
}
/**
* 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);

View file

@ -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);

File diff suppressed because it is too large Load diff

View file

@ -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);
}
}
}

View file

@ -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. */

View file

@ -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,

View file

@ -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, &region, 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 = &region;
exaDoMigration(pixmaps, 1, TRUE);
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
if (!pDstPix) {
if (!exaPixmapIsOffscreen(pDstPix)) {
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return 0;
}
@ -297,15 +302,13 @@ exaTryDriverSolidFill(PicturePtr pSrc,
nbox = REGION_NUM_RECTS(&region);
pbox = REGION_RECTS(&region);
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 (&region, 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, &region);
return -1;
}
pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
REGION_TRANSLATE(pScreen, &region, 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 : &region;
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, &region);
return 0;
}
@ -429,25 +438,23 @@ exaTryDriverComposite(CARD8 op,
nbox = REGION_NUM_RECTS(&region);
pbox = REGION_RECTS(&region);
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, &region);
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 (&region, 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, &region, pSrcPixmap,
&srcOrg, FB_ALLONES, GXcopy);
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
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;
}

View file

@ -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, &region);
if (!exaOpReadsDestination(op)) {
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height))
return;
exaGetDrawableDeltas (pDst->pDrawable,
exaGetDrawablePixmap(pDst->pDrawable),
&xoff, &yoff);
REGION_TRANSLATE(pScreen, &region, xoff, yoff);
exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, &region);
} 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, &region);
}
/**
* 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;
}

View file

@ -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
View file

@ -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_ */

View file

@ -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