Merge branch 'master' into XACE-SELINUX

Conflicts:

	dix/devices.c
	dix/property.c
	include/dix.h
This commit is contained in:
Eamon Walsh 2007-08-02 14:27:03 -04:00 committed by Eamon Walsh
commit e34fcd2bf4
755 changed files with 15815 additions and 5800 deletions

1
.gitignore vendored
View File

@ -21,6 +21,7 @@ install-sh
libtool
ltmain.sh
missing
ylwrap
xorg-server.pc
stamp-h?
do-not-use-config.h

2717
COPYING

File diff suppressed because it is too large Load Diff

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

@ -1260,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,
@ -1285,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.
*/
@ -1302,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)
@ -1317,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 );
}
@ -1679,7 +1709,6 @@ DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
xGLXGetDrawableAttributesReply reply;
CARD32 attributes[4];
int numAttribs;
PixmapPtr pixmap;
glxPixmap = (__GLXpixmap *)LookupIDByType(drawId, __glXPixmapRes);
if (!glxPixmap) {
@ -1694,19 +1723,11 @@ DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
reply.numAttribs = numAttribs;
attributes[0] = GLX_TEXTURE_TARGET_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;
/* XXX this is merely less wrong, see fdo bug #8991 */
pixmap = (PixmapPtr) glxPixmap->pDraw;
if ((pixmap->drawable.width & (pixmap->drawable.width - 1)) ||
(pixmap->drawable.height & (pixmap->drawable.height - 1))
/* || strstr(CALL_GetString(GL_EXTENSIONS,
"GL_ARB_texture_non_power_of_two")) */)
attributes[1] = GLX_TEXTURE_RECTANGLE_EXT;
else
attributes[1] = GLX_TEXTURE_2D_EXT;
if (client->swapped) {
__glXSwapGetDrawableAttributesReply(client, &reply, attributes);
} else {

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

@ -54,6 +54,7 @@ typedef struct {
ScreenPtr pScreen;
Bool idExists;
int refcnt;
GLenum target;
#ifdef XF86DRI
DamagePtr pDamage;
__DRIcontext *pDRICtx;

View File

@ -374,20 +374,13 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
{
RegionPtr pRegion = NULL;
PixmapPtr pixmap;
int w, h, bpp, override = 0;
GLenum target, format, type;
int bpp, override = 0;
GLenum format, type;
ScreenPtr pScreen = glxPixmap->pScreen;
__GLXDRIscreen * const screen =
(__GLXDRIscreen *) __glXgetActiveScreen(pScreen->myNum);
pixmap = (PixmapPtr) glxPixmap->pDraw;
w = pixmap->drawable.width;
h = pixmap->drawable.height;
if (h & (h - 1) || w & (w - 1))
target = GL_TEXTURE_RECTANGLE_ARB;
else
target = GL_TEXTURE_2D;
if (screen->texOffsetStart && screen->driScreen.setTexOffset) {
__GLXpixmap **texOffsetOverride = screen->texOffsetOverride;
@ -416,7 +409,7 @@ alreadyin:
glxPixmap->pDRICtx = &((__GLXDRIcontext*)baseContext)->driContext;
CALL_GetIntegerv(GET_DISPATCH(), (target == GL_TEXTURE_2D ?
CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ?
GL_TEXTURE_BINDING_2D :
GL_TEXTURE_BINDING_RECTANGLE_NV,
&texname));
@ -481,7 +474,7 @@ nooverride:
pixmap->drawable.y) );
CALL_TexImage2D( GET_DISPATCH(),
(target,
(glxPixmap->target,
0,
bpp == 4 ? 4 : 3,
pixmap->drawable.width,
@ -511,7 +504,7 @@ nooverride:
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,
@ -758,9 +751,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,
@ -815,10 +815,8 @@ createDrawable(__DRInativeDisplay *dpy, int screen,
return GL_FALSE;
__glXDRIenterServer(GL_FALSE);
retval = DRICreateDrawable(screenInfo.screens[screen],
drawable,
pDrawable,
hHWDrawable);
retval = DRICreateDrawable(screenInfo.screens[screen], __pGlxClient,
pDrawable, hHWDrawable);
__glXDRIleaveServer(GL_FALSE);
return retval;
}
@ -834,9 +832,8 @@ destroyDrawable(__DRInativeDisplay *dpy, int screen, __DRIid drawable)
return GL_FALSE;
__glXDRIenterServer(GL_FALSE);
retval = DRIDestroyDrawable(screenInfo.screens[screen],
drawable,
pDrawable);
retval = DRIDestroyDrawable(screenInfo.screens[screen], __pGlxClient,
pDrawable);
__glXDRIleaveServer(GL_FALSE);
return retval;
}
@ -927,7 +924,7 @@ getDrawableInfo(__DRInativeDisplay *dpy, int screen,
*ppBackClipRects = NULL;
}
return GL_TRUE;
return retval;
}
static int
@ -973,7 +970,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");

View File

@ -61,6 +61,11 @@ xGLXSingleReply __glXReply;
*/
static __GLXclientState *__glXClients[MAXCLIENTS + 1];
/*
** Client that called into GLX dispatch.
*/
ClientPtr __pGlxClient;
/*
** Forward declarations.
*/
@ -167,10 +172,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.
@ -549,6 +556,8 @@ static int __glXDispatch(ClientPtr client)
GLboolean rendering = opcode <= X_GLXRenderLarge;
__glXleaveServer(rendering);
__pGlxClient = client;
retval = (*proc)(cl, (GLbyte *) stuff);
__glXenterServer(rendering);

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

@ -110,6 +110,8 @@ void __glXScreenInitVisuals(__GLXscreen *screen);
extern __GLXcontext *__glXLastContext;
extern __GLXcontext *__glXForceCurrent(__GLXclientState*, GLXContextTag, int*);
extern ClientPtr __pGlxClient;
int __glXError(int error);
/*

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

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

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

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

@ -1292,11 +1292,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(
@ -1574,11 +1570,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

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

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

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

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

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

@ -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)
@ -508,7 +507,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 +546,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 +567,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;

View File

@ -1,6 +1,4 @@
/*
* $Id$
*
* Copyright © 2006 Sun Microsystems
*
* Permission to use, copy, modify, distribute, and sell this software and its
@ -201,106 +199,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 +284,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)
{

View File

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

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;
@ -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,514 +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 (!(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);
/* listDevices doesn't take any arguments */
if (strcmp(dbus_message_get_member(message), "listDevices") == 0)
ret = configListDevices(message, NULL, reply, &r_iter, &error);
else
{
if (!dbus_message_iter_init(message, &iter)) {
ErrorF("[config] failed to init iterator\n");
dbus_message_unref(reply);
dbus_error_free(&error);
return DBUS_HANDLER_RESULT_NEED_MEMORY; /* ?? */
}
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);
}
if (ret != BadDrawable && ret != BadAlloc) {
if (!strlen(dbus_message_get_signature(reply)))
{
ret = -ret; /* return errors as negative numbers */
if (!dbus_message_iter_append_basic(&r_iter, DBUS_TYPE_INT32, &ret)) {
ErrorF("[config] couldn't append to iterator\n");
dbus_message_unref(reply);
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,18 +18,18 @@ org.x.config.input:
Option names beginning with _ are not allowed; they are reserved
for internal use.
Returns one signed int32, which is the device id of the new device.
If the return value is a negative number, it represents the X
Status, as defined in X.h. BadMatch will be returned if the options
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.)
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.
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.
Returns one signed int32 which represents an X status as defined in
@ -34,4 +37,4 @@ org.x.config.input:
org.x.config.input.listDevices:
Lists the currently active devices. No argument.
Return value is sequence of <id> <name> <id> <name> ...
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();
}

441
config/dbus.c Normal file
View File

@ -0,0 +1,441 @@
/*
* 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;
if (!dbus_message_iter_init(message, &iter)) {
ErrorF("[config/dbus] couldn't initialise iterator\n");
return BadAlloc;
}
dbus_message_iter_init_append(reply, &reply_iter);
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] 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;
if (!dbus_message_iter_init(message, &iter)) {
ErrorF("[config] failed to init iterator\n");
return BadAlloc;
}
dbus_message_iter_init_append(reply, &reply_iter);
if (!dbus_message_get_args(message, error, DBUS_TYPE_UINT32,
&deviceid, DBUS_TYPE_INVALID)) {
MALFORMED_MESSAGE_ERROR();
}
dev = LookupDeviceIntRec(deviceid);
if (!dev) {
DebugF("[config] bogus device id %d given\n", deviceid);
ret = BadMatch;
goto unwind;
}
DebugF("[config] 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);
}

371
config/hal.c Normal file
View File

@ -0,0 +1,371 @@
/*
* 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,
DBusError *error)
{
char *prop, *ret;
prop = libhal_device_get_property_string(hal_ctx, udi, name, error);
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,
DBusError *error)
{
char **props, *ret, *str;
int i, len = 0;
props = libhal_device_get_property_strlist(hal_ctx, udi, prop, error);
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", &error);
path = get_prop_string(hal_ctx, udi, "input.device", &error);
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", &error);
if (!name)
name = xstrdup("(unnamed)");
if (type & TYPE_KEYS) {
xkb_rules = get_prop_string(hal_ctx, udi, "input.xkb_rules", &error);
xkb_model = get_prop_string(hal_ctx, udi, "input.xkb_model", &error);
xkb_layout = get_prop_string(hal_ctx, udi, "input.xkb_layout", &error);
xkb_variant = get_prop_string(hal_ctx, udi, "input.xkb_variant",
&error);
xkb_options = get_prop_string_array(hal_ctx, udi, "input.xkb_options",
&error);
}
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?\n");
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);
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?\n");
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">keyboard</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>

View File

@ -1,31 +1,34 @@
dnl $Id$
dnl Copyright © 2003-2007 Keith Packard, Daniel Stone
dnl
dnl Copyright © 2003-2005 Keith Packard, Daniel Stone
dnl Permission is hereby granted, free of charge, to any person obtaining a
dnl copy of this software and associated documentation files (the "Software"),
dnl to deal in the Software without restriction, including without limitation
dnl the rights to use, copy, modify, merge, publish, distribute, sublicense,
dnl and/or sell copies of the Software, and to permit persons to whom the
dnl Software is furnished to do so, subject to the following conditions:
dnl
dnl Permission to use, copy, modify, distribute, and sell this software and its
dnl documentation for any purpose is hereby granted without fee, provided that
dnl the above copyright notice appear in all copies and that both that
dnl copyright notice and this permission notice appear in supporting
dnl documentation, and that the names of Keith Packard and Daniel Stone not be
dnl used in advertising or publicity pertaining to distribution of the software
dnl without specific, written prior permission. Keith Packard and Daniel Stone
dnl make no representations about the suitability of this software for any
dnl purpose. It is provided "as is" without express or implied warranty.
dnl The above copyright notice and this permission notice (including the next
dnl paragraph) shall be included in all copies or substantial portions of the
dnl Software.
dnl
dnl KEITH PACKARD AND DANIEL STONE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
dnl SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
dnl IN NO EVENT SHALL KEITH PACKARD OR DANIEL STONE BE LIABLE FOR ANY SPECIAL,
dnl INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
dnl LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
dnl OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dnl PERFORMANCE OF THIS SOFTWARE.
dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
dnl IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
dnl THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
dnl LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
dnl FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
dnl DEALINGS IN THE SOFTWARE.
dnl
dnl Authors: Keith Packard <keithp@keithp.com>
dnl Daniel Stone <daniel@fooishbar.org>
dnl an unwitting cast of miscellaneous others
dnl
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.57)
dnl This is the not the Xorg version number, it's the server version number.
dnl Yes, that's weird.
AC_INIT([xorg-server], 1.3.99.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
AC_INIT([xorg-server], 1.3.99.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([dist-bzip2 foreign])
AM_MAINTAINER_MODE
@ -362,19 +365,6 @@ case $host_os in
esac
AM_CONDITIONAL(KDRIVE_HW, test "x$KDRIVE_HW" = xyes)
AC_MSG_CHECKING(for MMX capable platform)
if test "x$use_x86_asm" = xyes && test "x$GCC" = xyes ; then
AC_PREPROC_IFELSE([
#if (!defined (__GNUC__) || __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4))
#error Not supported
#endif
], mmx_capable=yes, mmx_capable=no)
else
mmx_capable=no
fi
AC_MSG_RESULT([$mmx_capable])
AM_CONDITIONAL(MMX_CAPABLE, [test "x$mmx_capable" = xyes])
DEFAULT_VENDOR_NAME="The X.Org Foundation"
DEFAULT_VENDOR_NAME_SHORT="X.Org"
DEFAULT_VERSION_MAJOR=7
@ -533,7 +523,8 @@ AC_ARG_ENABLE(fontcache, AS_HELP_STRING([--enable-fontcache], [Build FontCa
AC_ARG_ENABLE(dbe, AS_HELP_STRING([--disable-dbe], [Build DBE extension (default: enabled)]), [DBE=$enableval], [DBE=yes])
AC_ARG_ENABLE(xf86bigfont, AS_HELP_STRING([--disable-xf86bigfont], [Build XF86 Big Font extension (default: enabled)]), [XF86BIGFONT=$enableval], [XF86BIGFONT=yes])
AC_ARG_ENABLE(dpms, AS_HELP_STRING([--disable-dpms], [Build DPMS extension (default: enabled)]), [DPMSExtension=$enableval], [DPMSExtension=yes])
AC_ARG_ENABLE(dbus, AS_HELP_STRING([--disable-dbus], [Build D-BUS support (default: auto)]), [DBUS=$enableval], [DBUS=auto])
AC_ARG_ENABLE(config-dbus, AS_HELP_STRING([--enable-config-dbus], [Build D-BUS API support (default: no)]), [CONFIG_DBUS_API=$enableval], [CONFIG_DBUS_API=no])
AC_ARG_ENABLE(config-hal, AS_HELP_STRING([--disable-config-hal], [Build HAL support (default: auto)]), [CONFIG_HAL=$enableval], [CONFIG_HAL=auto])
AC_ARG_ENABLE(xfree86-utils, AS_HELP_STRING([--enable-xfree86-utils], [Build xfree86 DDX utilities (default: enabled)]), [XF86UTILS=$enableval], [XF86UTILS=yes])
dnl DDXes.
@ -627,23 +618,53 @@ XEXT_INC='-I$(top_srcdir)/Xext'
XEXT_LIB='$(top_builddir)/Xext/libXext.la'
XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
PIXMAN="[pixman >= 0.9.1]"
PIXMAN="[pixman >= 0.9.2]"
dnl Core modules for most extensions, et al.
REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto [xproto >= 7.0.9] xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]"
REQUIRED_LIBS="xfont xau fontenc $PIXMAN"
if test "x$DBUS" = xauto; then
PKG_CHECK_MODULES(DBUS, dbus-1, [DBUS=yes], [DBUS=no])
dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config
dnl API.
PKG_CHECK_MODULES(DBUS, dbus-1, [HAVE_DBUS=yes], [HAVE_DBUS=no])
if test "x$HAVE_DBUS" = xyes; then
AC_DEFINE(HAVE_DBUS, 1, [Have D-Bus support])
fi
if test "x$DBUS" = xyes; then
PKG_CHECK_MODULES(DBUS, dbus-1)
AC_DEFINE(HAVE_DBUS, 1, [Have D-BUS support])
REQUIRED_MODULES="$REQUIRED_MODULES dbus-1"
REQUIRED_LIBS="$REQUIRED_LIBS dbus-1"
AM_CONDITIONAL(HAVE_DBUS, [test "x$HAVE_DBUS" = xyes])
if test "x$CONFIG_DBUS_API" = xauto; then
CONFIG_DBUS_API="$HAVE_DBUS"
fi
if test "x$CONFIG_DBUS_API" = xyes; then
if ! test "x$HAVE_DBUS" = xyes; then
AC_MSG_ERROR([D-Bus configuration API requested, but D-Bus is not installed.])
fi
AC_DEFINE(CONFIG_DBUS_API, 1, [Use the D-Bus input configuration API])
NEED_DBUS="yes"
fi
AM_CONDITIONAL(CONFIG_DBUS_API, [test "x$CONFIG_DBUS_API" = xyes])
PKG_CHECK_MODULES(HAL, hal, [HAVE_HAL=yes], [HAVE_HAL=no])
if test "x$CONFIG_HAL" = xauto; then
CONFIG_HAL="$HAVE_HAL"
fi
if test "x$CONFIG_HAL" = xyes; then
if ! test "x$HAVE_HAL" = xyes; then
AC_MSG_ERROR([HAL hotplug API requested, but HAL is not installed.])
fi
AC_DEFINE(CONFIG_HAL, 1, [Use the HAL hotplug API])
REQUIRED_LIBS="$REQUIRED_LIBS hal"
NEED_DBUS="yes"
fi
AM_CONDITIONAL(CONFIG_HAL, [test "x$CONFIG_HAL" = xyes])
if test "x$NEED_DBUS" = xyes; then
REQUIRED_LIBS="$REQUIRED_LIBS dbus-1"
fi
CONFIG_LIB='$(top_builddir)/config/libconfig.a'
AM_CONDITIONAL(DBUS, [test "x$DBUS" = xyes])
AM_CONDITIONAL(XV, [test "x$XV" = xyes])
if test "x$XV" = xyes; then
@ -663,7 +684,7 @@ fi
AM_CONDITIONAL(COMPOSITE, [test "x$COMPOSITE" = xyes])
if test "x$COMPOSITE" = xyes; then
AC_DEFINE(COMPOSITE, 1, [Support Composite Extension])
REQUIRED_MODULES="$REQUIRED_MODULES [compositeproto >= 0.3]"
REQUIRED_MODULES="$REQUIRED_MODULES [compositeproto >= 0.4]"
COMPOSITE_LIB='$(top_builddir)/composite/libcomposite.la'
COMPOSITE_INC='-I$(top_srcdir)/composite'
fi
@ -848,6 +869,7 @@ fi
if test "x$BUILTIN_FONTS" = xyes; then
AC_DEFINE(BUILTIN_FONTS, 1, [Use only built-in fonts])
AC_DEFINE(NOFONTSERVERACCESS, 1, [Avoid using a font server])
FONTPATH="built-ins"
fi
if test "x$XCALIBRATE" = xyes && test "$KDRIVE" = yes; then
@ -1062,11 +1084,14 @@ if ! test "x$have_clock_gettime" = xno; then
CLOCK_LIBS=""
fi
LIBS_SAVE="$LIBS"
LIBS="$CLOCK_LIBS"
AC_RUN_IFELSE([
#define _POSIX_C_SOURCE 199309L
#include <time.h>
int main(int argc, char *argv[]) {
int main(int argc, char *argv[[]]) {
struct timespec tp;
if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
@ -1076,6 +1101,8 @@ int main(int argc, char *argv[]) {
}
], [MONOTONIC_CLOCK=yes], [MONOTONIC_CLOCK=no],
[MONOTONIC_CLOCK="cross compiling"])
LIBS="$LIBS_SAVE"
else
MONOTONIC_CLOCK=no
fi
@ -1191,7 +1218,7 @@ AC_MSG_RESULT([$XNEST])
AM_CONDITIONAL(XNEST, [test "x$XNEST" = xyes])
if test "x$XNEST" = xyes; then
XNEST_LIBS="$XSERVER_LIBS $FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB $LIBS"
XNEST_LIBS="$MI_LIB $CONFIG_LIB $XSERVER_LIBS $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB $LIBS"
AC_SUBST([XNEST_LIBS])
fi
@ -1505,6 +1532,7 @@ return 0;}
fi
if test "x$DGA" = xyes; then
XORG_MODULES="$XORG_MODULES xf86dgaproto"
PKG_CHECK_MODULES(DGA, xf86dgaproto)
AC_DEFINE(DGA, 1, [Support DGA extension])
AC_DEFINE(XFreeXDGA, 1, [Build XDGA support])
fi
@ -1514,6 +1542,7 @@ return 0;}
fi
if test "x$XF86MISC" = xyes; then
XORG_MODULES="$XORG_MODULES xf86miscproto"
PKG_CHECK_MODULES(XF86MISC, xf86miscproto)
AC_DEFINE(XF86MISC, 1, [Support XFree86 miscellaneous extensions])
fi
@ -1522,6 +1551,7 @@ return 0;}
fi
if test "x$XF86VIDMODE" = xyes; then
XORG_MODULES="$XORG_MODULES xf86vidmodeproto"
PKG_CHECK_MODULES(XF86VIDMODE, xf86vidmodeproto)
AC_DEFINE(XF86VIDMODE, 1, [Support XFree86 Video Mode extension])
fi
@ -1748,7 +1778,7 @@ _AM_DEPENDENCIES([OBJC])
dnl kdrive DDX
XEYPHR_LIBS=
XEPHYR_LIBS=
XEPHYR_INCS=
XSDL_LIBS=
XSDL_INCS=
@ -1813,7 +1843,7 @@ if test "$KDRIVE" = yes; then
# Xephyr needs nanosleep() which is in librt on Solaris
AC_CHECK_FUNC([nanosleep], [],
AC_CHECK_LIB([rt], [nanosleep], XEPHYR_LIBS="$XEPHYR_LIBS -lrt"))
XEPHYR_LIBS="$XEPHYR_LIBS $XSERVER_LIBS"
if test "x$TSLIB" = xyes; then
PKG_CHECK_MODULES([TSLIB], [tslib-0.0], [HAVE_TSLIB="yes"], [HAVE_TSLIB="no"])
if test "x$HAVE_TSLIB" = xno; then
@ -1830,9 +1860,6 @@ if test "$KDRIVE" = yes; then
KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS"
# dix os fb mi extension glx (NOTYET) damage shadow xpstubs
#KDRIVE_PURE_LIBS="$DIX_LIB $OS_LIB $FB_LIB $XEXT_LIB $MIEXT_DAMAGE_LIB \
# $MIEXT_SHADOW_LIB $XPSTUBS_LIB"
KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB"
KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.a'
case $host_os in
@ -1842,15 +1869,11 @@ if test "$KDRIVE" = yes; then
;;
esac
KDRIVE_STUB_LIB='$(top_builddir)/hw/kdrive/src/libkdrivestubs.a'
KDRIVE_LIBS="$XSERVERLIBS_LIBS $DIX_LIB $CONFIG_LIB $KDRIVE_LIB $TSLIB_LIBS $KDRIVE_OS_LIB $KDRIVE_PURE_LIBS $KDRIVE_STUB_LIB"
KDRIVE_LOCAL_LIBS="$DIX_LIB $CONFIG_LIB $KDRIVE_LIB $TSLIB_LIBS $KDRIVE_OS_LIB $KDRIVE_PURE_LIBS $KDRIVE_STUB_LIB"
KDRIVE_LIBS="$XSERVERLIBS_LIBS $KDRIVE_LOCAL_LIBS"
# check if we can build Xephyr
PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"])
XEPHYR_LIBS="$XEPHYR_LIBS $XSERVER_LIBS"
# Xephyr needs nanosleep() which is in librt on Solaris
AC_CHECK_FUNC([nanosleep], [],
AC_CHECK_LIB([rt], [nanosleep], XEPHYR_LIBS="$XEPHYR_LIBS -lrt"))
AC_SUBST([XEPHYR_LIBS])
AC_SUBST([XEPHYR_INCS])
@ -1861,6 +1884,7 @@ AC_SUBST([KDRIVE_INCS])
AC_SUBST([KDRIVE_PURE_INCS])
AC_SUBST([KDRIVE_CFLAGS])
AC_SUBST([KDRIVE_PURE_LIBS])
AC_SUBST([KDRIVE_LOCAL_LIBS])
AC_SUBST([KDRIVE_LIBS])
AM_CONDITIONAL(KDRIVELINUX, [test "x$KDRIVELINUX" = xyes])
AM_CONDITIONAL(TSLIB, [test "x$HAVE_TSLIB" = xyes])
@ -1871,8 +1895,6 @@ AM_CONDITIONAL(XSDLSERVER, [test x"$XSDL" = xyes])
AM_CONDITIONAL(XEPHYR, [test "x$KDRIVE" = xyes && test "x$XEPHYR" = xyes])
AM_CONDITIONAL(BUILD_KDRIVEFBDEVLIB, [test "x$KDRIVE" = xyes && test "x$KDRIVEFBDEVLIB" = xyes])
AM_CONDITIONAL(XFAKESERVER, [test "x$KDRIVE" = xyes && test "x$XFAKE" = xyes])
AM_CONDITIONAL(KDRIVEVESA, [test x"$ac_cv_header_sys_vm86_h" = xyes])
AM_CONDITIONAL(KDRIVEFBDEV, [test x"$ac_cv_header_linux_fb_h" = xyes])
dnl these only go in xkb-config.h (which is shared by the Xorg and Xnest servers)
AC_DEFINE(__XKBDEFRULES__, "xorg", [Default XKB rules])

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

@ -58,3 +58,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

@ -81,9 +81,20 @@ SOFTWARE.
#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)
{
@ -139,6 +150,7 @@ AddInputDevice(DeviceProc deviceProc, Bool autoStart)
#ifdef XKB
dev->xkb_interest = NULL;
#endif
dev->config_info = NULL;
/* must pre-allocate one private for the new devPrivates support */
dev->nPrivates = 1;
dev->devPrivates = (DevUnion *)xcalloc(1, sizeof(DevUnion));
@ -160,6 +172,15 @@ 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)
{
@ -196,6 +217,13 @@ EnableDevice(DeviceIntPtr dev)
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)
{
@ -226,6 +254,14 @@ DisableDevice(DeviceIntPtr dev)
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)
{
@ -250,6 +286,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)
{
@ -264,6 +304,9 @@ CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
return;
}
/**
* Device control function for the Virtual Core Keyboard.
*/
static int
CoreKeyboardProc(DeviceIntPtr pDev, int what)
{
@ -324,6 +367,9 @@ CoreKeyboardProc(DeviceIntPtr pDev, int what)
return Success;
}
/**
* Device control function for the Virtual Core Pointer.
*/
static int
CorePointerProc(DeviceIntPtr pDev, int what)
{
@ -354,6 +400,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)
{
@ -413,6 +465,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)
{
@ -448,6 +508,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)
{
@ -550,6 +617,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)
{
@ -571,6 +642,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)
{

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>
@ -2629,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.
@ -2728,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>
*/
@ -443,9 +445,17 @@ 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;
events++;
}
kbp = (deviceKeyButtonPointer *) events;
kbp->time = ms;
kbp->deviceid = pDev->id;
kbp->detail = key_code;
if (type == KeyPress)
kbp->type = DeviceKeyPress;
else if (type == KeyRelease)
@ -459,12 +469,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 +502,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 +607,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 +655,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>
@ -314,7 +312,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();
@ -397,14 +395,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);
@ -412,22 +406,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();
@ -480,7 +464,7 @@ main(int argc, char *argv[], char *envp[])
FreeAllResources();
#endif
configFini();
config_fini();
CloseDownDevices();
for (i = screenInfo.numScreens - 1; i >= 0; i--)
{

View File

@ -104,6 +104,19 @@ FindProperty(WindowPtr pWin, Atom propertyName)
return pProp;
}
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)
{
@ -113,7 +126,6 @@ ProcRotateProperties(ClientPtr client)
Atom * atoms;
PropertyPtr * props; /* array of pointer */
PropertyPtr pProp;
xEvent event;
REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
UpdateCurrentTime();
@ -164,16 +176,9 @@ ProcRotateProperties(ClientPtr client)
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];
}
}
@ -241,7 +246,6 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
pointer value, Bool sendevent)
{
PropertyPtr pProp;
xEvent event;
int sizeInBytes, totalSize, rc;
pointer data;
@ -344,15 +348,10 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
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);
}
@ -369,7 +368,6 @@ int
DeleteProperty(WindowPtr pWin, Atom propName)
{
PropertyPtr pProp, prevProp;
xEvent event;
if (!(pProp = wUserProps (pWin)))
return(Success);
@ -392,12 +390,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);
dixFreePrivates(pProp->devPrivates);
xfree(pProp->data);
xfree(pProp);
@ -409,17 +402,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;
dixFreePrivates(pProp->devPrivates);
xfree(pProp->data);
@ -553,16 +540,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

@ -299,7 +299,7 @@ SetWindowToDefaults(WindowPtr pWin)
pWin->dontPropagate = 0;
pWin->forcedBS = FALSE;
#ifdef COMPOSITE
pWin->redirectDraw = 0;
pWin->redirectDraw = RedirectDrawNone;
#endif
}
@ -1693,10 +1693,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;
@ -1736,10 +1740,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;

View File

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

View File

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

View File

@ -643,15 +643,13 @@ exaPolyFillRect(DrawablePtr pDrawable,
int n;
ExaMigrationRec pixmaps[2];
RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED);
RegionPtr pDamageReg = DamageRegion(ExaGetPixmapPriv(pPixmap)->pDamage);
/* Compute intersection of rects and clip region */
REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y);
REGION_INTERSECT(pScreen, pReg, pClip, pReg);
if (!REGION_NUM_RECTS(pReg)) {
REGION_DESTROY(pScreen, pReg);
return;
goto out;
}
pixmaps[0].as_dst = TRUE;
@ -680,7 +678,7 @@ exaPolyFillRect(DrawablePtr pDrawable,
(pGC->fillStyle == FillTiled && !pGC->tileIsPixel &&
exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg,
pGC->planemask, pGC->alu))) {
goto damage;
goto out;
}
}
@ -709,13 +707,7 @@ fallback:
}
ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect);
damage:
REGION_TRANSLATE(pScreen, pReg, xoff, yoff);
REGION_UNION(pScreen, pDamageReg, pReg, pDamageReg);
REGION_DESTROY(pScreen, pReg);
return;
goto out;
}
xorg = pDrawable->x;
@ -754,8 +746,6 @@ damage:
(*pExaScr->info->Solid) (pPixmap,
fullX1 + xoff, fullY1 + yoff,
fullX2 + xoff, fullY2 + yoff);
exaPixmapDirty (pPixmap, fullX1 + xoff, fullY1 + yoff,
fullX2 + xoff, fullY2 + yoff);
}
else
{
@ -786,14 +776,15 @@ damage:
(*pExaScr->info->Solid) (pPixmap,
partX1 + xoff, partY1 + yoff,
partX2 + xoff, partY2 + yoff);
exaPixmapDirty (pPixmap, partX1 + xoff, partY1 + yoff,
partX2 + xoff, partY2 + yoff);
}
}
}
}
(*pExaScr->info->DoneSolid) (pPixmap);
exaMarkSync(pDrawable->pScreen);
out:
REGION_DESTROY(pScreen, pReg);
}
static void
@ -1329,6 +1320,9 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
int xoff, yoff;
Bool ok;
if (pExaScr->swappedOut || (w == 1 && h == 1))
goto fallback;
if (pExaScr->info->DownloadFromScreen == NULL)
goto migrate_and_fallback;
@ -1342,9 +1336,6 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
if (pDrawable->bitsPerPixel < 8)
goto migrate_and_fallback;
if (pExaScr->swappedOut)
goto fallback;
pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
if (pPix == NULL)
goto fallback;

View File

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

@ -369,31 +369,48 @@ ExaCheckComposite (CARD8 op,
/**
* 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;
void *fb;
Bool need_finish = FALSE;
BoxRec box;
ExaMigrationRec pixmaps[1];
ExaPixmapPriv (pPixmap);
pixmaps[0].as_dst = FALSE;
pixmaps[0].as_src = TRUE;
pixmaps[0].pPix = pPixmap;
exaDoMigration (pixmaps, 1, FALSE);
/* Try to avoid framebuffer readbacks */
if (exaPixmapIsOffscreen(pPixmap)) {
if (!miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box)) {
fb = pExaPixmap->sys_ptr;
} else {
need_finish = TRUE;
fb = pPixmap->devPrivate.ptr;
pixmaps[0].as_dst = FALSE;
pixmaps[0].as_src = TRUE;
pixmaps[0].pPix = pPixmap;
exaDoMigration (pixmaps, 1, FALSE);
exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
}
}
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);
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 \
@ -73,6 +56,4 @@ libfb_la_SOURCES = \
libwfb_la_SOURCES = $(libfb_la_SOURCES)
libfb_la_LIBADD = libfbmmx.la
EXTRA_DIST = fbcmap.c fbcmap_mi.c

35
fb/fb.h
View File

@ -610,16 +610,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
@ -670,15 +660,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 */
@ -691,17 +672,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
@ -776,12 +750,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
@ -1791,13 +1759,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,
@ -2033,6 +1999,7 @@ fbEvenTile (FbBits *dst,
int height,
FbBits *tile,
FbStride tileStride,
int tileHeight,
int alu,

View File

@ -1,6 +1,4 @@
/*
* $XFree86$
*
* Copyright © 2000 SuSE, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* Id: fballpriv.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
@ -49,10 +47,6 @@ int fbGetWinPrivateIndex(void)
#endif
int fbGeneration;
#ifdef FB_OLD_SCREEN
#define miAllocateGCPrivateIndex() AllocateGCPrivateIndex()
#endif
Bool
fbAllocatePrivates(ScreenPtr pScreen, int *pGCIndex)
{

View File

@ -1,6 +1,4 @@
/*
* Id: fbarc.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* Id: fbbits.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

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

View File

@ -1,6 +1,4 @@
/*
* Id: fbblt.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* Id: fbbltone.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* Id: fbbstore.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* Id: fbcopy.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
@ -29,7 +27,6 @@
#include <stdlib.h>
#include "fb.h"
#include "fbmmx.h"
void
fbCopyNtoN (DrawablePtr pSrcDrawable,

View File

@ -1,6 +1,4 @@
/*
* Id: fbfill.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
@ -27,7 +25,6 @@
#endif
#include "fb.h"
#include "fbmmx.h"
void
fbFill (DrawablePtr pDrawable,
@ -47,22 +44,18 @@ fbFill (DrawablePtr pDrawable,
switch (pGC->fillStyle) {
case FillSolid:
#ifdef USE_MMX
if (!pPriv->and && fbHaveMMX())
{
if (fbFillmmx (dst, dstStride, dstBpp, x + dstXoff, y + dstYoff, width, height, pPriv->xor))
{
fbFinishAccess (pDrawable);
return;
}
}
#ifndef FB_ACCESS_WRAPPER
if (pPriv->and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
x + dstXoff, y + dstYoff,
width, height,
pPriv->xor))
#endif
fbSolid (dst + (y + dstYoff) * dstStride,
dstStride,
(x + dstXoff) * dstBpp,
dstBpp,
width * dstBpp, height,
pPriv->and, pPriv->xor);
fbSolid (dst + (y + dstYoff) * dstStride,
dstStride,
(x + dstXoff) * dstBpp,
dstBpp,
width * dstBpp, height,
pPriv->and, pPriv->xor);
break;
case FillStippled:
case FillOpaqueStippled: {
@ -218,26 +211,20 @@ fbSolidBoxClipped (DrawablePtr pDrawable,
if (partY2 <= partY1)
continue;
#ifdef USE_MMX
if (!and && fbHaveMMX())
{
if (fbFillmmx (dst, dstStride, dstBpp,
partX1 + dstXoff, partX2 + dstYoff, (partX2 - partX1), (partY2 - partY1),
xor))
{
fbFinishAccess (pDrawable);
return;
}
}
#ifndef FB_ACCESS_WRAPPER
if (and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp,
partX1 + dstXoff, partY1 + dstYoff,
(partX2 - partX1), (partY2 - partY1),
xor))
#endif
fbSolid (dst + (partY1 + dstYoff) * dstStride,
dstStride,
(partX1 + dstXoff) * dstBpp,
dstBpp,
(partX2 - partX1) * dstBpp,
(partY2 - partY1),
and, xor);
fbSolid (dst + (partY1 + dstYoff) * dstStride,
dstStride,
(partX1 + dstXoff) * dstBpp,
dstBpp,
(partX2 - partX1) * dstBpp,
(partY2 - partY1),
and, xor);
}
fbFinishAccess (pDrawable);
}

View File

@ -1,6 +1,4 @@
/*
* Id: fbfillrect.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* Id: fbfillsp.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* Id: fbgc.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* Id: fbgetsp.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* Id: fbimage.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

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

View File

@ -1,341 +0,0 @@
/*
* Copyright © 2004, 2005 Red Hat, Inc.
* Copyright © 2004 Nicholas Miell
* Copyright © 2005 Trolltech AS
*
* 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 Red Hat not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. Red Hat makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
* Author: Søren Sandmann (sandmann@redhat.com)
* Minor Improvements: Nicholas Miell (nmiell@gmail.com)
* MMX code paths for fbcompose.c by Lars Knoll (lars@trolltech.com)
*
* Based on work by Owen Taylor
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#ifdef USE_MMX
#if defined(__amd64__) || defined(__x86_64__)
#define USE_SSE
#endif
#include <mmintrin.h>
#ifdef USE_SSE
#include <xmmintrin.h> /* for _mm_shuffle_pi16 and _MM_SHUFFLE */
#endif
#ifdef RENDER
#include "fb.h"
#include "fbmmx.h"
#include "picturestr.h"
#include "mipict.h"
#include "fbpict.h"
#define noVERBOSE
#ifdef VERBOSE
#define CHECKPOINT() ErrorF ("at %s %d\n", __FUNCTION__, __LINE__)
#else
#define CHECKPOINT()
#endif
typedef unsigned long long ullong;
#ifdef __GNUC__
typedef ullong mmxdatafield;
#endif
#ifdef _MSC_VER
typedef unsigned __int64 ullong;
typedef __m64 mmxdatafield;
#endif
Bool
fbFillmmx (FbBits *bits,
FbStride stride,
int bpp,
int x,
int y,
int width,
int height,
FbBits xor)
{
ullong fill;
__m64 vfill;
CARD32 byte_width;
CARD8 *byte_line;
#ifdef __GNUC__
__m64 v1, v2, v3, v4, v5, v6, v7;
#endif
if (bpp == 16 && (xor >> 16 != (xor & 0xffff)))
return FALSE;
if (bpp != 16 && bpp != 32)
return FALSE;
if (bpp == 16)
{
stride = stride * sizeof (FbBits) / 2;
byte_line = (CARD8 *)(((CARD16 *)bits) + stride * y + x);
byte_width = 2 * width;
stride *= 2;
}
else
{
stride = stride * sizeof (FbBits) / 4;
byte_line = (CARD8 *)(((CARD32 *)bits) + stride * y + x);
byte_width = 4 * width;
stride *= 4;
}
fill = ((ullong)xor << 32) | xor;
vfill = (__m64)fill;
#ifdef __GNUC__
__asm__ (
"movq %7, %0\n"
"movq %7, %1\n"
"movq %7, %2\n"
"movq %7, %3\n"
"movq %7, %4\n"
"movq %7, %5\n"
"movq %7, %6\n"
: "=y" (v1), "=y" (v2), "=y" (v3),
"=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
: "y" (vfill));
#endif
while (height--)
{
int w;
CARD8 *d = byte_line;
byte_line += stride;
w = byte_width;
while (w >= 2 && ((unsigned long)d & 3))
{
*(CARD16 *)d = xor;
w -= 2;
d += 2;
}
while (w >= 4 && ((unsigned long)d & 7))
{
*(CARD32 *)d = xor;
w -= 4;
d += 4;
}
while (w >= 64)
{
#ifdef __GNUC__
__asm__ (
"movq %1, (%0)\n"
"movq %2, 8(%0)\n"
"movq %3, 16(%0)\n"
"movq %4, 24(%0)\n"
"movq %5, 32(%0)\n"
"movq %6, 40(%0)\n"
"movq %7, 48(%0)\n"
"movq %8, 56(%0)\n"
:
: "r" (d),
"y" (vfill), "y" (v1), "y" (v2), "y" (v3),
"y" (v4), "y" (v5), "y" (v6), "y" (v7)
: "memory");
#else
*(__m64*) (d + 0) = vfill;
*(__m64*) (d + 8) = vfill;
*(__m64*) (d + 16) = vfill;
*(__m64*) (d + 24) = vfill;
*(__m64*) (d + 32) = vfill;
*(__m64*) (d + 40) = vfill;
*(__m64*) (d + 48) = vfill;
*(__m64*) (d + 56) = vfill;
#endif
w -= 64;
d += 64;
}
while (w >= 4)
{
*(CARD32 *)d = xor;
w -= 4;
d += 4;
}
if (w >= 2)
{
*(CARD16 *)d = xor;
w -= 2;
d += 2;
}
}
_mm_empty();
return TRUE;
}
Bool
fbBltmmx (FbBits *src_bits,
FbBits *dst_bits,
FbStride src_stride,
FbStride dst_stride,
int src_bpp,
int dst_bpp,
int src_x, int src_y,
int dst_x, int dst_y,
int width, int height)
{
CARD8 * src_bytes;
CARD8 * dst_bytes;
int byte_width;
if (src_bpp != dst_bpp)
return FALSE;
if (src_bpp == 16)
{
src_stride = src_stride * sizeof (FbBits) / 2;
dst_stride = dst_stride * sizeof (FbBits) / 2;
src_bytes = (CARD8 *)(((CARD16 *)src_bits) + src_stride * (src_y) + (src_x));
dst_bytes = (CARD8 *)(((CARD16 *)dst_bits) + dst_stride * (dst_y) + (dst_x));
byte_width = 2 * width;
src_stride *= 2;
dst_stride *= 2;
} else if (src_bpp == 32) {
src_stride = src_stride * sizeof (FbBits) / 4;
dst_stride = dst_stride * sizeof (FbBits) / 4;
src_bytes = (CARD8 *)(((CARD32 *)src_bits) + src_stride * (src_y) + (src_x));
dst_bytes = (CARD8 *)(((CARD32 *)dst_bits) + dst_stride * (dst_y) + (dst_x));
byte_width = 4 * width;
src_stride *= 4;
dst_stride *= 4;
} else {
return FALSE;
}
while (height--)
{
int w;
CARD8 *s = src_bytes;
CARD8 *d = dst_bytes;
src_bytes += src_stride;
dst_bytes += dst_stride;
w = byte_width;
while (w >= 2 && ((unsigned long)d & 3))
{
*(CARD16 *)d = *(CARD16 *)s;
w -= 2;
s += 2;
d += 2;
}
while (w >= 4 && ((unsigned long)d & 7))
{
*(CARD32 *)d = *(CARD32 *)s;
w -= 4;
s += 4;
d += 4;
}
while (w >= 64)
{
#ifdef __GNUC__
__asm__ (
"movq (%1), %%mm0\n"
"movq 8(%1), %%mm1\n"
"movq 16(%1), %%mm2\n"
"movq 24(%1), %%mm3\n"
"movq 32(%1), %%mm4\n"
"movq 40(%1), %%mm5\n"
"movq 48(%1), %%mm6\n"
"movq 56(%1), %%mm7\n"
"movq %%mm0, (%0)\n"
"movq %%mm1, 8(%0)\n"
"movq %%mm2, 16(%0)\n"
"movq %%mm3, 24(%0)\n"
"movq %%mm4, 32(%0)\n"
"movq %%mm5, 40(%0)\n"
"movq %%mm6, 48(%0)\n"
"movq %%mm7, 56(%0)\n"
:
: "r" (d), "r" (s)
: "memory",
"%mm0", "%mm1", "%mm2", "%mm3",
"%mm4", "%mm5", "%mm6", "%mm7");
#else
__m64 v0 = *(__m64 *)(s + 0);
__m64 v1 = *(__m64 *)(s + 8);
__m64 v2 = *(__m64 *)(s + 16);
__m64 v3 = *(__m64 *)(s + 24);
__m64 v4 = *(__m64 *)(s + 32);
__m64 v5 = *(__m64 *)(s + 40);
__m64 v6 = *(__m64 *)(s + 48);
__m64 v7 = *(__m64 *)(s + 56);
*(__m64 *)(d + 0) = v0;
*(__m64 *)(d + 8) = v1;
*(__m64 *)(d + 16) = v2;
*(__m64 *)(d + 24) = v3;
*(__m64 *)(d + 32) = v4;
*(__m64 *)(d + 40) = v5;
*(__m64 *)(d + 48) = v6;
*(__m64 *)(d + 56) = v7;
#endif
w -= 64;
s += 64;
d += 64;
}
while (w >= 4)
{
*(CARD32 *)d = *(CARD32 *)s;
w -= 4;
s += 4;
d += 4;
}
if (w >= 2)
{
*(CARD16 *)d = *(CARD16 *)s;
w -= 2;
s += 2;
d += 2;
}
}
_mm_empty();
return TRUE;
}
#endif /* RENDER */
#endif /* USE_MMX */

View File

@ -1,64 +0,0 @@
/*
* Copyright © 2004 Red Hat, Inc.
* Copyright © 2005 Trolltech AS
*
* 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 Red Hat not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. Red Hat makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
* Author: Søren Sandmann (sandmann@redhat.com)
* Lars Knoll (lars@trolltech.com)
*
* Based on work by Owen Taylor
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#ifdef USE_MMX
#if !defined(__amd64__) && !defined(__x86_64__)
Bool fbHaveMMX(void);
#else
#define fbHaveMMX() TRUE
#endif
#else
#define fbHaveMMX() FALSE
#endif
#ifdef USE_MMX
Bool fbBltmmx (FbBits *src_bits,
FbBits *dst_bits,
FbStride src_stride,
FbStride dst_stride,
int src_bpp,
int dst_bpp,
int src_x, int src_y,
int dst_x, int dst_y,
int width, int height);
Bool fbFillmmx (FbBits *bits,
FbStride stride,
int bpp,
int x,
int y,
int width,
int height,
FbBits xor);
#endif /* USE_MMX */

View File

@ -413,11 +413,7 @@ fbOverlayFinishScreenInit(ScreenPtr pScreen,
return FALSE;
if (! miScreenInit(pScreen, 0, xsize, ysize, dpix, dpiy, 0,
depth1, ndepths, depths,
defaultVisual, nvisuals, visuals
#ifdef FB_OLD_MISCREENINIT
, (miBSFuncPtr) 0
#endif
))
defaultVisual, nvisuals, visuals))
return FALSE;
/* MI thinks there's no frame buffer */
#ifdef MITSHM

View File

@ -36,7 +36,6 @@
#include "picturestr.h"
#include "mipict.h"
#include "fbpict.h"
#include "fbmmx.h"
#define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
@ -211,7 +210,7 @@ fbCompositeGeneral (CARD8 op,
CARD16 width,
CARD16 height)
{
return fbComposite (op, pSrc, pMask, pDst,
fbComposite (op, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height);
}
@ -468,203 +467,3 @@ fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
return TRUE;
}
#ifdef USE_MMX
/* The CPU detection code needs to be in a file not compiled with
* "-mmmx -msse", as gcc would generate CMOV instructions otherwise
* that would lead to SIGILL instructions on old CPUs that don't have
* it.
*/
#if !defined(__amd64__) && !defined(__x86_64__)
#ifdef HAVE_GETISAX
#include <sys/auxv.h>
#endif
enum CPUFeatures {
NoFeatures = 0,
MMX = 0x1,
MMX_Extensions = 0x2,
SSE = 0x6,
SSE2 = 0x8,
CMOV = 0x10
};
static unsigned int detectCPUFeatures(void) {
unsigned int features = 0;
unsigned int result = 0;
#ifdef HAVE_GETISAX
if (getisax(&result, 1)) {
if (result & AV_386_CMOV)
features |= CMOV;
if (result & AV_386_MMX)
features |= MMX;
if (result & AV_386_AMD_MMX)
features |= MMX_Extensions;
if (result & AV_386_SSE)
features |= SSE;
if (result & AV_386_SSE2)
features |= SSE2;
}
#else
char vendor[13];
#ifdef _MSC_VER
int vendor0 = 0, vendor1, vendor2;
#endif
vendor[0] = 0;
vendor[12] = 0;
#ifdef __GNUC__
/* see p. 118 of amd64 instruction set manual Vol3 */
/* We need to be careful about the handling of %ebx and
* %esp here. We can't declare either one as clobbered
* since they are special registers (%ebx is the "PIC
* register" holding an offset to global data, %esp the
* stack pointer), so we need to make sure they have their
* original values when we access the output operands.
*/
__asm__ ("pushf\n"
"pop %%eax\n"
"mov %%eax, %%ecx\n"
"xor $0x00200000, %%eax\n"
"push %%eax\n"
"popf\n"
"pushf\n"
"pop %%eax\n"
"mov $0x0, %%edx\n"
"xor %%ecx, %%eax\n"
"jz 1f\n"
"mov $0x00000000, %%eax\n"
"push %%ebx\n"
"cpuid\n"
"mov %%ebx, %%eax\n"
"pop %%ebx\n"
"mov %%eax, %1\n"
"mov %%edx, %2\n"
"mov %%ecx, %3\n"
"mov $0x00000001, %%eax\n"
"push %%ebx\n"
"cpuid\n"
"pop %%ebx\n"
"1:\n"
"mov %%edx, %0\n"
: "=r" (result),
"=m" (vendor[0]),
"=m" (vendor[4]),
"=m" (vendor[8])
:
: "%eax", "%ecx", "%edx"
);
#elif defined (_MSC_VER)
_asm {
pushfd
pop eax
mov ecx, eax
xor eax, 00200000h
push eax
popfd
pushfd
pop eax
mov edx, 0
xor eax, ecx
jz nocpuid
mov eax, 0
push ebx
cpuid
mov eax, ebx
pop ebx
mov vendor0, eax
mov vendor1, edx
mov vendor2, ecx
mov eax, 1
push ebx
cpuid
pop ebx
nocpuid:
mov result, edx
}
memmove (vendor+0, &vendor0, 4);
memmove (vendor+4, &vendor1, 4);
memmove (vendor+8, &vendor2, 4);
#else
# error unsupported compiler
#endif
features = 0;
if (result) {
/* result now contains the standard feature bits */
if (result & (1 << 15))
features |= CMOV;
if (result & (1 << 23))
features |= MMX;
if (result & (1 << 25))
features |= SSE;
if (result & (1 << 26))
features |= SSE2;
if ((features & MMX) && !(features & SSE) &&
(strcmp(vendor, "AuthenticAMD") == 0 ||
strcmp(vendor, "Geode by NSC") == 0)) {
/* check for AMD MMX extensions */
#ifdef __GNUC__
__asm__("push %%ebx\n"
"mov $0x80000000, %%eax\n"
"cpuid\n"
"xor %%edx, %%edx\n"
"cmp $0x1, %%eax\n"
"jge 2f\n"
"mov $0x80000001, %%eax\n"
"cpuid\n"
"2:\n"
"pop %%ebx\n"
"mov %%edx, %0\n"
: "=r" (result)
:
: "%eax", "%ecx", "%edx"
);
#elif defined _MSC_VER
_asm {
push ebx
mov eax, 80000000h
cpuid
xor edx, edx
cmp eax, 1
jge notamd
mov eax, 80000001h
cpuid
notamd:
pop ebx
mov result, edx
}
#endif
if (result & (1<<22))
features |= MMX_Extensions;
}
}
#endif /* HAVE_GETISAX */
return features;
}
Bool
fbHaveMMX (void)
{
static Bool initialized = FALSE;
static Bool mmx_present;
if (!initialized)
{
unsigned int features = detectCPUFeatures();
mmx_present = (features & (MMX|MMX_Extensions)) == (MMX|MMX_Extensions);
initialized = TRUE;
}
return mmx_present;
}
#endif /* __amd64__ */
#endif

View File

@ -1,6 +1,4 @@
/*
* Id: fbpixmap.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* Id: fbpoint.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* Id: fbpush.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* Id: fbrop.h,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -81,7 +81,6 @@ fbQueryBestSize (int class,
}
}
#ifndef FB_OLD_SCREEN
PixmapPtr
_fbGetWindowPixmap (WindowPtr pWindow)
{
@ -97,7 +96,6 @@ _fbSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
pWindow->devPrivates[fbWinPrivateIndex].ptr = (pointer) pPixmap;
#endif
}
#endif
Bool
fbSetupScreen(ScreenPtr pScreen,
@ -141,7 +139,6 @@ fbSetupScreen(ScreenPtr pScreen,
pScreen->ResolveColor = fbResolveColor;
pScreen->BitmapToRegion = fbPixmapToRegion;
#ifndef FB_OLD_SCREEN
pScreen->GetWindowPixmap = _fbGetWindowPixmap;
pScreen->SetWindowPixmap = _fbSetWindowPixmap;
@ -150,7 +147,6 @@ fbSetupScreen(ScreenPtr pScreen,
pScreen->BackingStoreFuncs.SetClipmaskRgn = 0;
pScreen->BackingStoreFuncs.GetImagePixmap = 0;
pScreen->BackingStoreFuncs.GetSpansPixmap = 0;
#endif
return TRUE;
}
@ -247,11 +243,7 @@ fbFinishScreenInit(ScreenPtr pScreen,
return FALSE;
if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
rootdepth, ndepths, depths,
defaultVisual, nvisuals, visuals
#ifdef FB_OLD_MISCREENINIT
, (miBSFuncPtr) 0
#endif
))
defaultVisual, nvisuals, visuals))
return FALSE;
/* overwrite miCloseScreen with our own */
pScreen->CloseScreen = fbCloseScreen;
@ -313,26 +305,3 @@ fbScreenInit(ScreenPtr pScreen,
return TRUE;
}
#endif
#ifdef FB_OLD_SCREEN
const miBSFuncRec fbBSFuncRec = {
fbSaveAreas,
fbRestoreAreas,
(void (*)(GCPtr, RegionPtr)) 0,
(PixmapPtr (*)(void)) 0,
(PixmapPtr (*)(void)) 0,
};
#endif
#if 0
void
fbInitializeBackingStore (ScreenPtr pScreen)
{
#ifdef FB_OLD_SCREEN
miInitializeBackingStore (pScreen, (miBSFuncRec *) &fbBSFuncRec);
#else
miInitializeBackingStore (pScreen);
#endif
}
#endif

View File

@ -1,6 +1,4 @@
/*
* Id: fbseg.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* Id: fbsetsp.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
*
* Copyright © 1998 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its

View File

@ -1,6 +1,4 @@
/*
* $XFree86$
*
* Copyright © 1998 Keith Packard
*
* 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