Merge remote-tracking branch 'ajax/xserver-next'

This commit is contained in:
Keith Packard 2011-03-14 13:06:41 -07:00
commit 0ac4931753
33 changed files with 525 additions and 492 deletions

View File

@ -809,7 +809,11 @@ accelPointer(DeviceIntPtr dev, ValuatorMask* valuators, CARD32 ms)
* miPointerSetPosition() and then scale back into device coordinates (if
* needed). miPSP will change x/y if the screen was crossed.
*
* The coordinates provided are always absolute. The parameter mode whether
* it was relative or absolute movement that landed us at those coordinates.
*
* @param dev The device to be moved.
* @param mode Movement mode (Absolute or Relative)
* @param x Pointer to current x-axis value, may be modified.
* @param y Pointer to current y-axis value, may be modified.
* @param x_frac Fractional part of current x-axis value, may be modified.
@ -821,7 +825,8 @@ accelPointer(DeviceIntPtr dev, ValuatorMask* valuators, CARD32 ms)
* @param screeny_frac Fractional part of screen y coordinate, as above.
*/
static void
positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac,
positionSprite(DeviceIntPtr dev, int mode,
int *x, int *y, float x_frac, float y_frac,
ScreenPtr scr, int *screenx, int *screeny, float *screenx_frac, float *screeny_frac)
{
int old_screenx, old_screeny;
@ -860,7 +865,7 @@ positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac,
old_screeny = *screeny;
/* This takes care of crossing screens for us, as well as clipping
* to the current screen. */
miPointerSetPosition(dev, screenx, screeny);
miPointerSetPosition(dev, mode, screenx, screeny);
if(!IsMaster(dev) || !IsFloating(dev)) {
DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
@ -1178,7 +1183,8 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
set_raw_valuators(raw, &mask, raw->valuators.data);
positionSprite(pDev, &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac);
positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative,
&x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac);
updateHistory(pDev, &mask, ms);
/* Update the valuators with the true value sent to the client*/

View File

@ -54,9 +54,9 @@ fbComposite (CARD8 op,
int msk_xoff, msk_yoff;
int dst_xoff, dst_yoff;
miCompositeSourceValidate (pSrc, xSrc - xDst, ySrc - yDst, width, height);
miCompositeSourceValidate (pSrc);
if (pMask)
miCompositeSourceValidate (pMask, xMask - xDst, yMask - yDst, width, height);
miCompositeSourceValidate (pMask);
src = image_from_pict (pSrc, FALSE, &src_xoff, &src_yoff);
mask = image_from_pict (pMask, FALSE, &msk_xoff, &msk_yoff);

View File

@ -858,8 +858,6 @@ static const __DRIextension *loader_extensions[] = {
static const char dri_driver_path[] = DRI_DRIVER_PATH;
static Bool
glxDRIEnterVT (int index, int flags)
{
@ -971,13 +969,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
drm_handle_t hFB;
int junk;
__GLXDRIscreen *screen;
char filename[128];
Bool isCapable;
size_t buffer_size;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
const __DRIconfig **driConfigs;
const __DRIextension **extensions;
int i;
if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") ||
!DRIQueryDirectRenderingCapable(pScreen, &isCapable) ||
@ -1052,42 +1047,15 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
goto handle_error;
}
snprintf(filename, sizeof filename, "%s/%s_dri.so",
dri_driver_path, driverName);
screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
screen->driver = glxProbeDriver(driverName,
(void **)&screen->core,
__DRI_CORE, __DRI_CORE_VERSION,
(void **)&screen->legacy,
__DRI_LEGACY, __DRI_LEGACY_VERSION);
if (screen->driver == NULL) {
LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
filename, dlerror());
goto handle_error;
}
extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
driverName, dlerror());
goto handle_error;
}
for (i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
extensions[i]->version >= __DRI_CORE_VERSION) {
screen->core = (__DRIcoreExtension *) extensions[i];
}
if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0 &&
extensions[i]->version >= __DRI_LEGACY_VERSION) {
screen->legacy = (__DRIlegacyExtension *) extensions[i];
}
}
if (screen->core == NULL || screen->legacy == NULL) {
LogMessage(X_ERROR,
"AIGLX error: %s does not export required DRI extension\n",
driverName);
goto handle_error;
}
/*
* Get device-specific info. pDevPriv will point to a struct
* (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
@ -1172,7 +1140,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
pScrn->LeaveVT = glxDRILeaveVT;
LogMessage(X_INFO,
"AIGLX: Loaded and initialized %s\n", filename);
"AIGLX: Loaded and initialized %s\n", driverName);
return &screen->base;

View File

@ -599,8 +599,6 @@ static const __DRIextension *loader_extensions[] = {
NULL
};
static const char dri_driver_path[] = DRI_DRIVER_PATH;
static Bool
glxDRIEnterVT (int index, int flags)
{
@ -702,12 +700,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
{
const char *driverName, *deviceName;
__GLXDRIscreen *screen;
char filename[128];
size_t buffer_size;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
const __DRIextension **extensions;
const __DRIconfig **driConfigs;
int i;
screen = calloc(1, sizeof *screen);
if (screen == NULL)
@ -729,40 +724,12 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
__glXInitExtensionEnableBits(screen->glx_enable_bits);
snprintf(filename, sizeof filename,
"%s/%s_dri.so", dri_driver_path, driverName);
screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
screen->driver = glxProbeDriver(driverName, (void **)&screen->core, __DRI_CORE, 1,
(void **)&screen->dri2, __DRI_DRI2, 1);
if (screen->driver == NULL) {
LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
filename, dlerror());
goto handle_error;
}
extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
driverName, dlerror());
goto handle_error;
}
for (i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
extensions[i]->version >= 1) {
screen->core = (const __DRIcoreExtension *) extensions[i];
}
if (strcmp(extensions[i]->name, __DRI_DRI2) == 0 &&
extensions[i]->version >= 1) {
screen->dri2 = (const __DRIdri2Extension *) extensions[i];
}
}
if (screen->core == NULL || screen->dri2 == NULL) {
LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n",
driverName);
goto handle_error;
}
screen->driScreen =
(*screen->dri2->createNewScreen)(pScreen->myNum,
screen->fd,
@ -816,7 +783,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
pScrn->LeaveVT = glxDRILeaveVT;
LogMessage(X_INFO,
"AIGLX: Loaded and initialized %s\n", filename);
"AIGLX: Loaded and initialized %s\n", driverName);
return &screen->base;

View File

@ -29,6 +29,7 @@
#include <stdint.h>
#include <errno.h>
#include <dlfcn.h>
#include <sys/time.h>
#include <GL/gl.h>
#include <GL/glxtokens.h>
@ -204,3 +205,59 @@ glxConvertConfigs(const __DRIcoreExtension *core,
return head.next;
}
static const char dri_driver_path[] = DRI_DRIVER_PATH;
void *
glxProbeDriver(const char *driverName,
void **coreExt, const char *coreName, int coreVersion,
void **renderExt, const char *renderName, int renderVersion)
{
int i;
void *driver;
char filename[PATH_MAX];
const __DRIextension **extensions;
snprintf(filename, sizeof filename, "%s/%s_dri.so",
dri_driver_path, driverName);
driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
if (driver == NULL) {
LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
filename, dlerror());
goto cleanup_failure;
}
extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
driverName, dlerror());
goto cleanup_failure;
}
for (i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, coreName) == 0 &&
extensions[i]->version >= coreVersion) {
*coreExt = (void *)extensions[i];
}
if (strcmp(extensions[i]->name, renderName) == 0 &&
extensions[i]->version >= renderVersion) {
*renderExt = (void *)extensions[i];
}
}
if (*coreExt == NULL || *renderExt == NULL) {
LogMessage(X_ERROR,
"AIGLX error: %s does not export required DRI extension\n",
driverName);
goto cleanup_failure;
}
return driver;
cleanup_failure:
if (driver)
dlclose(driver);
*coreExt = *renderExt = NULL;
return NULL;
}

View File

@ -38,4 +38,9 @@ glxConvertConfigs(const __DRIcoreExtension *core,
extern const __DRIsystemTimeExtension systemTimeExtension;
void *
glxProbeDriver(const char *name,
void **coreExt, const char *coreName, int coreVersion,
void **renderExt, const char *renderName, int renderVersion);
#endif

View File

@ -201,6 +201,14 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
if (texBuffer == NULL)
return Success;
#if __DRI_TEX_BUFFER_VERSION >= 2
if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) {
(*texBuffer->setTexBuffer2)(context->driContext,
glxPixmap->target,
glxPixmap->format,
drawable->driDrawable);
} else
#endif
texBuffer->setTexBuffer(context->driContext,
glxPixmap->target,
drawable->driDrawable);
@ -427,17 +435,12 @@ initializeExtensions(__GLXDRIscreen *screen)
}
}
static const char dri_driver_path[] = DRI_DRIVER_PATH;
static __GLXscreen *
__glXDRIscreenProbe(ScreenPtr pScreen)
{
const char *driverName = "swrast";
__GLXDRIscreen *screen;
char filename[128];
const __DRIextension **extensions;
const __DRIconfig **driConfigs;
int i;
screen = calloc(1, sizeof *screen);
if (screen == NULL)
@ -449,40 +452,15 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
screen->base.swapInterval = NULL;
screen->base.pScreen = pScreen;
snprintf(filename, sizeof filename,
"%s/%s_dri.so", dri_driver_path, driverName);
screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
screen->driver = glxProbeDriver(driverName,
(void **)&screen->core,
__DRI_CORE, __DRI_CORE_VERSION,
(void **)&screen->swrast,
__DRI_SWRAST, __DRI_SWRAST_VERSION);
if (screen->driver == NULL) {
LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
filename, dlerror());
goto handle_error;
}
extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
driverName, dlerror());
goto handle_error;
}
for (i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
extensions[i]->version >= __DRI_CORE_VERSION) {
screen->core = (const __DRIcoreExtension *) extensions[i];
}
if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0 &&
extensions[i]->version >= __DRI_SWRAST_VERSION) {
screen->swrast = (const __DRIswrastExtension *) extensions[i];
}
}
if (screen->core == NULL || screen->swrast == NULL) {
LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n",
driverName);
goto handle_error;
}
screen->driScreen =
(*screen->swrast->createNewScreen)(pScreen->myNum,
loader_extensions,
@ -508,7 +486,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
screen->base.GLXminor = 4;
LogMessage(X_INFO,
"AIGLX: Loaded and initialized %s\n", filename);
"AIGLX: Loaded and initialized %s\n", driverName);
return &screen->base;

View File

@ -249,8 +249,6 @@ typedef struct _DMXScreenInfo {
TrapezoidsProcPtr Trapezoids;
TrianglesProcPtr Triangles;
TriStripProcPtr TriStrip;
TriFanProcPtr TriFan;
} DMXScreenInfo;
/* Global variables available to all Xserver/hw/dmx routines. */

View File

@ -165,8 +165,6 @@ Bool dmxPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
DMX_WRAP(Trapezoids, dmxTrapezoids, dmxScreen, ps);
DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps);
DMX_WRAP(TriStrip, dmxTriStrip, dmxScreen, ps);
DMX_WRAP(TriFan, dmxTriFan, dmxScreen, ps);
return TRUE;
}
@ -1237,88 +1235,3 @@ void dmxTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps);
}
/** Composite a triangle strip on the appropriate screen. For a
* complete description see the protocol document of the RENDER
* library. */
void dmxTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc,
int npoint, xPointFixed *points)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
PictureScreenPtr ps = GetPictureScreen(pScreen);
dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst);
DMX_UNWRAP(TriStrip, dmxScreen, ps);
#if 0
if (ps->TriStrip)
ps->TriStrip(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points);
#endif
/* Draw trapezoids on back-end server */
if (pDstPriv->pict) {
XRenderPictFormat *pFormat;
pFormat = dmxFindFormat(dmxScreen, maskFormat);
if (!pFormat) {
/* FIXME: Error! */
}
XRenderCompositeTriStrip(dmxScreen->beDisplay,
op,
pSrcPriv->pict,
pDstPriv->pict,
pFormat,
xSrc, ySrc,
(XPointFixed *)points,
npoint);
dmxSync(dmxScreen, FALSE);
}
DMX_WRAP(TriStrip, dmxTriStrip, dmxScreen, ps);
}
/** Composite a triangle fan on the appropriate screen. For a complete
* description see the protocol document of the RENDER library. */
void dmxTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc,
int npoint, xPointFixed *points)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
PictureScreenPtr ps = GetPictureScreen(pScreen);
dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst);
DMX_UNWRAP(TriFan, dmxScreen, ps);
#if 0
if (ps->TriFan)
ps->TriFan(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points);
#endif
/* Draw trapezoids on back-end server */
if (pDstPriv->pict) {
XRenderPictFormat *pFormat;
pFormat = dmxFindFormat(dmxScreen, maskFormat);
if (!pFormat) {
/* FIXME: Error! */
}
XRenderCompositeTriFan(dmxScreen->beDisplay,
op,
pSrcPriv->pict,
pDstPriv->pict,
pFormat,
xSrc, ySrc,
(XPointFixed *)points,
npoint);
dmxSync(dmxScreen, FALSE);
}
DMX_WRAP(TriFan, dmxTriFan, dmxScreen, ps);
}

View File

@ -100,16 +100,6 @@ extern void dmxTriangles(CARD8 op,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc,
int ntri, xTriangle *tris);
extern void dmxTriStrip(CARD8 op,
PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc,
int npoint, xPointFixed *points);
extern void dmxTriFan(CARD8 op,
PicturePtr pSrc, PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc,
int npoint, xPointFixed *points);
extern int dmxBECreateGlyphSet(int idx, GlyphSetPtr glyphSet);
extern Bool dmxBEFreeGlyphSet(ScreenPtr pScreen, GlyphSetPtr glyphSet);

View File

@ -39,6 +39,7 @@
#include "xf86Bus.h"
#include "xf86Sbus.h"
#endif
#include "misc.h"
typedef struct _DevToConfig {
GDevRec GDev;
@ -514,10 +515,6 @@ configureDDCMonitorSection (int screennum)
return ptr;
}
#if !defined(PATH_MAX)
# define PATH_MAX 1024
#endif
void
DoConfigure(void)
{

View File

@ -370,6 +370,9 @@
#include <sys/wait.h> /* May need to adjust this for other OSs */
/* For PATH_MAX */
#include "misc.h"
/*
* Hack originally for ISC 2.2 POSIX headers, but may apply elsewhere,
* and it's safe, so just do it.
@ -390,14 +393,6 @@
# undef _POSIX_SOURCE
#endif /* _POSIX_SOURCE */
#if !defined(PATH_MAX)
# if defined(MAXPATHLEN)
# define PATH_MAX MAXPATHLEN
# else
# define PATH_MAX 1024
# endif /* MAXPATHLEN */
#endif /* !PATH_MAX */
#ifndef DEV_MEM
#define DEV_MEM "/dev/mem"

View File

@ -77,18 +77,13 @@
#undef _POSIX_SOURCE
#endif /* _POSIX_SOURCE */
#if !defined(PATH_MAX)
#if defined(MAXPATHLEN)
#define PATH_MAX MAXPATHLEN
#else
#define PATH_MAX 1024
#endif /* MAXPATHLEN */
#endif /* !PATH_MAX */
#if !defined(MAXHOSTNAMELEN)
#define MAXHOSTNAMELEN 32
#endif /* !MAXHOSTNAMELEN */
/* For PATH_MAX */
#include "misc.h"
#include "Configint.h"
#include "xf86tokens.h"

View File

@ -79,6 +79,7 @@ OF THIS SOFTWARE.
#include <X11/Xdefs.h>
#include <stddef.h>
#include <stdint.h>
#ifndef MAXSCREENS
#define MAXSCREENS 16
@ -91,7 +92,7 @@ OF THIS SOFTWARE.
#define EXTENSION_EVENT_BASE 64
#define EXTENSION_BASE 128
typedef unsigned long ATOM;
typedef uint32_t ATOM;
#ifndef TRUE
#define TRUE 1
@ -178,6 +179,17 @@ typedef struct _xReq *xReqPtr;
#endif
#ifndef PATH_MAX
#include <sys/param.h>
#ifndef PATH_MAX
#ifdef MAXPATHLEN
#define PATH_MAX MAXPATHLEN
#else
#define PATH_MAX 1024
#endif
#endif
#endif
/**
* Calculate the number of bytes needed to hold bits.
* @param bits The minimum number of bits needed.

View File

@ -58,8 +58,8 @@ typedef struct _Property {
struct _Property *next;
ATOM propertyName;
ATOM type; /* ignored by server */
short format; /* format of data for swapping - 8,16,32 */
long size; /* size of data in (format/8) bytes */
uint32_t format; /* format of data for swapping - 8,16,32 */
uint32_t size; /* size of data in (format/8) bytes */
pointer data; /* private to client */
PrivateRec *devPrivates;
} PropertyRec;

View File

@ -56,7 +56,7 @@ SOFTWARE.
/* classes for Resource routines */
typedef unsigned long RESTYPE;
typedef uint32_t RESTYPE;
#define RC_VANILLA ((RESTYPE)0)
#define RC_CACHED ((RESTYPE)1<<31)

View File

@ -272,6 +272,9 @@ miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen,
pPointer->generateEvent = generateEvent;
if (pScreen->ConstrainCursorHarder)
pScreen->ConstrainCursorHarder(pDev, pScreen, Absolute, &x, &y);
/* device dependent - must pend signal and call miPointerWarpCursor */
(*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y);
if (!generateEvent)
@ -560,14 +563,18 @@ miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen,
* This function is called during the pointer update path in
* GetPointerEvents and friends (and the same in the xwin DDX).
*
* The coordinates provided are always absolute. The parameter mode whether
* it was relative or absolute movement that landed us at those coordinates.
*
* @param pDev The device to move
* @param mode Movement mode (Absolute or Relative)
* @param[in,out] x The x coordiante in screen coordinates (in regards to total
* desktop size)
* @param[in,out] y The y coordiante in screen coordinates (in regards to total
* desktop size)
*/
void
miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y)
miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y)
{
miPointerScreenPtr pScreenPriv;
ScreenPtr pScreen;
@ -612,6 +619,9 @@ miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y)
if (*y >= pPointer->limits.y2)
*y = pPointer->limits.y2 - 1;
if (pScreen->ConstrainCursorHarder)
pScreen->ConstrainCursorHarder(pDev, pScreen, mode, x, y);
if (pPointer->x == *x && pPointer->y == *y &&
pPointer->pScreen == pScreen)
return;

View File

@ -133,6 +133,7 @@ extern _X_EXPORT void miPointerGetPosition(
* x and y are modified in-place. */
extern _X_EXPORT void miPointerSetPosition(
DeviceIntPtr pDev,
int mode,
int *x,
int *y);

View File

@ -106,8 +106,6 @@ typedef struct {
TrapezoidsProcPtr Trapezoids;
TrianglesProcPtr Triangles;
TriStripProcPtr TriStrip;
TriFanProcPtr TriFan;
RasterizeTrapezoidProcPtr RasterizeTrapezoid;
} cwScreenRec, *cwScreenPtr;

View File

@ -371,66 +371,6 @@ cwTriangles (CARD8 op,
cwPsWrap(Triangles, cwTriangles);
}
static void
cwTriStrip (CARD8 op,
PicturePtr pSrcPicture,
PicturePtr pDstPicture,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int npoint,
xPointFixed *points)
{
ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
cwPsDecl(pScreen);
cwSrcPictureDecl;
cwDstPictureDecl;
int i;
cwPsUnwrap(TriStrip);
if (dst_picture_x_off || dst_picture_y_off) {
for (i = 0; i < npoint; i++)
{
points[i].x += dst_picture_x_off << 16;
points[i].y += dst_picture_y_off << 16;
}
}
(*ps->TriStrip) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
xSrc + src_picture_x_off, ySrc + src_picture_y_off,
npoint, points);
cwPsWrap(TriStrip, cwTriStrip);
}
static void
cwTriFan (CARD8 op,
PicturePtr pSrcPicture,
PicturePtr pDstPicture,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int npoint,
xPointFixed *points)
{
ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
cwPsDecl(pScreen);
cwSrcPictureDecl;
cwDstPictureDecl;
int i;
cwPsUnwrap(TriFan);
if (dst_picture_x_off || dst_picture_y_off) {
for (i = 0; i < npoint; i++)
{
points[i].x += dst_picture_x_off << 16;
points[i].y += dst_picture_y_off << 16;
}
}
(*ps->TriFan) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
xSrc + src_picture_x_off, ySrc + src_picture_y_off,
npoint, points);
cwPsWrap(TriFan, cwTriFan);
}
void
cwInitializeRender (ScreenPtr pScreen)
{
@ -443,8 +383,6 @@ cwInitializeRender (ScreenPtr pScreen)
cwPsWrap(CompositeRects, cwCompositeRects);
cwPsWrap(Trapezoids, cwTrapezoids);
cwPsWrap(Triangles, cwTriangles);
cwPsWrap(TriStrip, cwTriStrip);
cwPsWrap(TriFan, cwTriFan);
/* There is no need to wrap AddTraps as far as we can tell. AddTraps can
* only be done on alpha-only pictures, and we won't be getting
* alpha-only window pictures, so there's no need to translate.
@ -463,7 +401,5 @@ cwFiniRender (ScreenPtr pScreen)
cwPsUnwrap(CompositeRects);
cwPsUnwrap(Trapezoids);
cwPsUnwrap(Triangles);
cwPsUnwrap(TriStrip);
cwPsUnwrap(TriFan);
}

View File

@ -165,17 +165,6 @@ SOFTWARE.
#endif /* WIN32 */
#ifndef PATH_MAX
#include <sys/param.h>
#ifndef PATH_MAX
#ifdef MAXPATHLEN
#define PATH_MAX MAXPATHLEN
#else
#define PATH_MAX 1024
#endif
#endif
#endif
#define X_INCLUDE_NETDB_H
#include <X11/Xos_r.h>
@ -185,14 +174,6 @@ SOFTWARE.
#include "xace.h"
#ifndef PATH_MAX
#ifdef MAXPATHLEN
#define PATH_MAX MAXPATHLEN
#else
#define PATH_MAX 1024
#endif
#endif
Bool defeatAccessControl = FALSE;
#define acmp(a1, a2, len) memcmp((char *)(a1), (char *)(a2), len)

View File

@ -63,17 +63,10 @@ SOFTWARE.
#include <execinfo.h>
#endif
#include "misc.h"
#include "dixstruct.h"
#ifndef PATH_MAX
#ifdef MAXPATHLEN
#define PATH_MAX MAXPATHLEN
#else
#define PATH_MAX 1024
#endif
#endif
#if !defined(SYSV) && !defined(WIN32)
#include <sys/resource.h>

View File

@ -231,17 +231,6 @@ OsSignal(int sig, OsSigHandlerPtr handler)
#define LOCK_PREFIX "/.X"
#define LOCK_SUFFIX "-lock"
#ifndef PATH_MAX
#include <sys/param.h>
#ifndef PATH_MAX
#ifdef MAXPATHLEN
#define PATH_MAX MAXPATHLEN
#else
#define PATH_MAX 1024
#endif
#endif
#endif
static Bool StillLocking = FALSE;
static char LockFile[PATH_MAX];
static Bool nolock = FALSE;

View File

@ -270,6 +270,8 @@ Bool RRScreenInit(ScreenPtr pScreen)
wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
pScreen->ConstrainCursorHarder = RRConstrainCursorHarder;
pScrPriv->numOutputs = 0;
pScrPriv->outputs = NULL;
pScrPriv->numCrtcs = 0;

View File

@ -297,6 +297,7 @@ typedef struct _rrScrPriv {
int rate;
int size;
#endif
Bool discontiguous;
} rrScrPrivRec, *rrScrPrivPtr;
extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
@ -700,6 +701,9 @@ ProcRRGetPanning (ClientPtr client);
int
ProcRRSetPanning (ClientPtr client);
void
RRConstrainCursorHarder (DeviceIntPtr, ScreenPtr, int, int *, int *);
/* rrdispatch.c */
extern _X_EXPORT Bool
RRClientKnowsRates (ClientPtr pClient);

View File

@ -1,5 +1,6 @@
/*
* Copyright © 2006 Keith Packard
* Copyright 2010 Red Hat, Inc
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@ -22,6 +23,7 @@
#include "randrstr.h"
#include "swaprep.h"
#include "mipointer.h"
RESTYPE RRCrtcType;
@ -292,6 +294,92 @@ RRCrtcPendingProperties (RRCrtcPtr crtc)
return FALSE;
}
static void
crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom)
{
*left = crtc->x;
*top = crtc->y;
switch (crtc->rotation) {
case RR_Rotate_0:
case RR_Rotate_180:
default:
*right = crtc->x + crtc->mode->mode.width;
*bottom = crtc->y + crtc->mode->mode.height;
return;
case RR_Rotate_90:
case RR_Rotate_270:
*right = crtc->x + crtc->mode->mode.height;
*bottom = crtc->y + crtc->mode->mode.width;
return;
}
}
/* overlapping counts as adjacent */
static Bool
crtcs_adjacent(const RRCrtcPtr a, const RRCrtcPtr b)
{
/* left, right, top, bottom... */
int al, ar, at, ab;
int bl, br, bt, bb;
int cl, cr, ct, cb; /* the overlap, if any */
crtc_bounds(a, &al, &ar, &at, &ab);
crtc_bounds(b, &bl, &br, &bt, &bb);
cl = max(al, bl);
cr = min(ar, br);
ct = max(at, bt);
cb = min(ab, bb);
return (cl <= cr) && (ct <= cb);
}
/* Depth-first search and mark all CRTCs reachable from cur */
static void
mark_crtcs (rrScrPrivPtr pScrPriv, int *reachable, int cur)
{
int i;
reachable[cur] = TRUE;
for (i = 0; i < pScrPriv->numCrtcs; ++i) {
if (reachable[i] || !pScrPriv->crtcs[i]->mode)
continue;
if (crtcs_adjacent(pScrPriv->crtcs[cur], pScrPriv->crtcs[i]))
mark_crtcs(pScrPriv, reachable, i);
}
}
static void
RRComputeContiguity (ScreenPtr pScreen)
{
rrScrPriv(pScreen);
Bool discontiguous = TRUE;
int i, n = pScrPriv->numCrtcs;
int *reachable = calloc(n, sizeof(int));
if (!reachable)
goto out;
/* Find first enabled CRTC and start search for reachable CRTCs from it */
for (i = 0; i < n; ++i) {
if (pScrPriv->crtcs[i]->mode) {
mark_crtcs(pScrPriv, reachable, i);
break;
}
}
/* Check that all enabled CRTCs were marked as reachable */
for (i = 0; i < n; ++i)
if (pScrPriv->crtcs[i]->mode && !reachable[i])
goto out;
discontiguous = FALSE;
out:
free(reachable);
pScrPriv->discontiguous = discontiguous;
}
/*
* Request that the Crtc be reconfigured
*/
@ -306,6 +394,7 @@ RRCrtcSet (RRCrtcPtr crtc,
{
ScreenPtr pScreen = crtc->pScreen;
Bool ret = FALSE;
Bool recompute = TRUE;
rrScrPriv(pScreen);
/* See if nothing changed */
@ -318,6 +407,7 @@ RRCrtcSet (RRCrtcPtr crtc,
!RRCrtcPendingProperties (crtc) &&
!RRCrtcPendingTransform (crtc))
{
recompute = FALSE;
ret = TRUE;
}
else
@ -381,6 +471,10 @@ RRCrtcSet (RRCrtcPtr crtc,
RRPostPendingProperties (outputs[o]);
}
}
if (recompute)
RRComputeContiguity(pScreen);
return ret;
}
@ -1349,3 +1443,64 @@ ProcRRGetCrtcTransform (ClientPtr client)
free(reply);
return Success;
}
void
RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x, int *y)
{
rrScrPriv (pScreen);
int i;
/* intentional dead space -> let it float */
if (pScrPriv->discontiguous)
return;
/* if we're moving inside a crtc, we're fine */
for (i = 0; i < pScrPriv->numCrtcs; i++) {
RRCrtcPtr crtc = pScrPriv->crtcs[i];
int left, right, top, bottom;
if (!crtc->mode)
continue;
crtc_bounds(crtc, &left, &right, &top, &bottom);
if ((*x >= left) && (*x <= right) && (*y >= top) && (*y <= bottom))
return;
}
/* if we're trying to escape, clamp to the CRTC we're coming from */
for (i = 0; i < pScrPriv->numCrtcs; i++) {
RRCrtcPtr crtc = pScrPriv->crtcs[i];
int nx, ny;
int left, right, top, bottom;
if (!crtc->mode)
continue;
crtc_bounds(crtc, &left, &right, &top, &bottom);
miPointerGetPosition(pDev, &nx, &ny);
if ((nx >= left) && (nx <= right) && (ny >= top) && (ny <= bottom)) {
if ((*x <= left) || (*x >= right)) {
int dx = *x - nx;
if (dx > 0)
*x = right;
else if (dx < 0)
*x = left;
}
if ((*y <= top) || (*y >= bottom)) {
int dy = *y - ny;
if (dy > 0)
*y = bottom;
else if (dy < 0)
*y = top;
}
return;
}
}
}

View File

@ -333,12 +333,8 @@ miClipPictureSrc (RegionPtr pRegion,
return TRUE;
}
void
miCompositeSourceValidate (PicturePtr pPicture,
INT16 x,
INT16 y,
CARD16 width,
CARD16 height)
static void
SourceValidateOnePicture (PicturePtr pPicture)
{
DrawablePtr pDrawable = pPicture->pDrawable;
ScreenPtr pScreen;
@ -347,50 +343,22 @@ miCompositeSourceValidate (PicturePtr pPicture,
return;
pScreen = pDrawable->pScreen;
if (pScreen->SourceValidate)
{
if (pPicture->transform)
{
xPoint points[4];
int i;
int xmin, ymin, xmax, ymax;
#define VectorSet(i,_x,_y) { points[i].x = _x; points[i].y = _y; }
VectorSet (0, x, y);
VectorSet (1, x + width, y);
VectorSet (2, x, y + height);
VectorSet (3, x + width, y + height);
xmin = ymin = 32767;
xmax = ymax = -32737;
for (i = 0; i < 4; i++)
{
PictVector t;
t.vector[0] = IntToxFixed (points[i].x);
t.vector[1] = IntToxFixed (points[i].y);
t.vector[2] = xFixed1;
if (pixman_transform_point (pPicture->transform, &t))
{
int tx = xFixedToInt (t.vector[0]);
int ty = xFixedToInt (t.vector[1]);
if (tx < xmin) xmin = tx;
if (tx > xmax) xmax = tx;
if (ty < ymin) ymin = ty;
if (ty > ymax) ymax = ty;
}
}
x = xmin;
y = ymin;
width = xmax - xmin;
height = ymax - ymin;
}
x += pPicture->pDrawable->x;
y += pPicture->pDrawable->y;
(*pScreen->SourceValidate) (pDrawable, x, y, width, height,
pPicture->subWindowMode);
pScreen->SourceValidate (
pDrawable, 0, 0, pDrawable->width, pDrawable->height, pPicture->subWindowMode);
}
}
void
miCompositeSourceValidate (PicturePtr pPicture)
{
SourceValidateOnePicture (pPicture);
if (pPicture->alphaMap)
SourceValidateOnePicture (pPicture->alphaMap);
}
/*
* returns FALSE if the final region is empty. Indistinguishable from
* an allocation failure, but rendering ignores those anyways.
@ -480,9 +448,9 @@ miComputeCompositeRegion (RegionPtr pRegion,
}
miCompositeSourceValidate (pSrc, xSrc, ySrc, width, height);
miCompositeSourceValidate (pSrc);
if (pMask)
miCompositeSourceValidate (pMask, xMask, yMask, width, height);
miCompositeSourceValidate (pMask);
return TRUE;
}
@ -633,8 +601,6 @@ miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
ps->CompositeRects = miCompositeRects;
ps->Trapezoids = 0;
ps->Triangles = 0;
ps->TriStrip = miTriStrip;
ps->TriFan = miTriFan;
ps->RasterizeTrapezoid = 0; /* requires DDX support */
ps->AddTraps = 0; /* requires DDX support */

View File

@ -81,11 +81,8 @@ miChangePictureFilter (PicturePtr pPicture,
int nparams);
extern _X_EXPORT void
miCompositeSourceValidate (PicturePtr pPicture,
INT16 x,
INT16 y,
CARD16 width,
CARD16 height);
miCompositeSourceValidate (PicturePtr pPicture);
extern _X_EXPORT Bool
miComputeCompositeRegion (RegionPtr pRegion,
PicturePtr pSrc,
@ -151,26 +148,6 @@ miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds);
extern _X_EXPORT void
miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds);
extern _X_EXPORT void
miTriStrip (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int npoint,
xPointFixed *points);
extern _X_EXPORT void
miTriFan (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int npoint,
xPointFixed *points);
extern _X_EXPORT Bool
miInitIndexed (ScreenPtr pScreen,
PictFormatPtr pFormat);

View File

@ -66,67 +66,3 @@ miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds)
{
miPointFixedBounds (ntri * 3, (xPointFixed *) tris, bounds);
}
void
miTriStrip (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int npoint,
xPointFixed *points)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
xTriangle *tris, *tri;
int ntri;
if (npoint < 3)
return;
ntri = npoint - 2;
tris = malloc(ntri * sizeof (xTriangle));
if (!tris)
return;
for (tri = tris; npoint >= 3; npoint--, points++, tri++)
{
tri->p1 = points[0];
tri->p2 = points[1];
tri->p3 = points[2];
}
(*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
free(tris);
}
void
miTriFan (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int npoint,
xPointFixed *points)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
xTriangle *tris, *tri;
xPointFixed *first;
int ntri;
if (npoint < 3)
return;
ntri = npoint - 2;
tris = malloc(ntri * sizeof (xTriangle));
if (!tris)
return;
first = points++;
for (tri = tris; npoint >= 3; npoint--, points++, tri++)
{
tri->p1 = *first;
tri->p2 = points[0];
tri->p3 = points[1];
}
(*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
free(tris);
}

View File

@ -1773,11 +1773,25 @@ CompositeTriStrip (CARD8 op,
int npoints,
xPointFixed *points)
{
PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
ScreenPtr pScreen = pDst->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
xTriangle *tris, *tri;
int ntri;
ValidatePicture (pSrc);
ValidatePicture (pDst);
(*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
if (npoints < 3)
return;
ntri = npoints - 2;
tris = malloc(ntri * sizeof (xTriangle));
if (!tris)
return;
for (tri = tris; npoints >= 3; npoints--, points++, tri++)
{
tri->p1 = points[0];
tri->p2 = points[1];
tri->p3 = points[2];
}
CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
free(tris);
}
void
@ -1790,11 +1804,26 @@ CompositeTriFan (CARD8 op,
int npoints,
xPointFixed *points)
{
PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen);
ScreenPtr pScreen = pDst->pDrawable->pScreen;
xTriangle *tris, *tri;
xPointFixed *first;
int ntri;
ValidatePicture (pSrc);
ValidatePicture (pDst);
(*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
if (npoints < 3)
return;
ntri = npoints - 2;
tris = malloc(ntri * sizeof (xTriangle));
if (!tris)
return;
first = points++;
for (tri = tris; npoints >= 3; npoints--, points++, tri++)
{
tri->p1 = *first;
tri->p2 = points[0];
tri->p3 = points[1];
}
CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
free(tris);
}
void

View File

@ -381,8 +381,6 @@ typedef struct _PictureScreen {
TrapezoidsProcPtr Trapezoids;
TrianglesProcPtr Triangles;
TriStripProcPtr TriStrip;
TriFanProcPtr TriFan;
RasterizeTrapezoidProcPtr RasterizeTrapezoid;

View File

@ -1,6 +1,6 @@
if UNITTESTS
SUBDIRS= . xi2
check_PROGRAMS = xkb input xtest
check_PROGRAMS = xkb input xtest list
check_LTLIBRARIES = libxservertest.la
TESTS=$(check_PROGRAMS)
@ -16,6 +16,7 @@ endif
xkb_LDADD=$(TEST_LDADD)
input_LDADD=$(TEST_LDADD)
xtest_LDADD=$(TEST_LDADD)
list_LDADD=$(TEST_LDADD)
libxservertest_la_LIBADD = \
$(XSERVER_LIBS) \

176
test/list.c Normal file
View File

@ -0,0 +1,176 @@
/**
* Copyright © 2011 Red Hat, Inc.
*
* 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.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/Xlib.h>
#include <list.h>
#include <string.h>
#include <glib.h>
struct parent {
int a;
struct list children;
int b;
};
struct child {
int foo;
int bar;
struct list node;
};
static void
test_list_init(void)
{
struct parent parent, tmp;
memset(&parent, 0, sizeof(parent));
parent.a = 0xa5a5a5;
parent.b = ~0xa5a5a5;
tmp = parent;
list_init(&parent.children);
/* test we haven't touched anything else. */
g_assert(parent.a == tmp.a);
g_assert(parent.b == tmp.b);
g_assert(list_is_empty(&parent.children));
}
static void
test_list_add(void)
{
struct parent parent = {0};
struct child child[3];
struct child *c;
list_init(&parent.children);
list_add(&child[0].node, &parent.children);
g_assert(!list_is_empty(&parent.children));
c = list_first_entry(&parent.children, struct child, node);
g_assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
/* note: list_add prepends */
list_add(&child[1].node, &parent.children);
c = list_first_entry(&parent.children, struct child, node);
g_assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
list_add(&child[2].node, &parent.children);
c = list_first_entry(&parent.children, struct child, node);
g_assert(memcmp(c, &child[2], sizeof(struct child)) == 0);
};
static void
test_list_del(void)
{
struct parent parent = {0};
struct child child[3];
struct child *c;
list_init(&parent.children);
list_add(&child[0].node, &parent.children);
g_assert(!list_is_empty(&parent.children));
list_del(&parent.children);
g_assert(list_is_empty(&parent.children));
list_add(&child[0].node, &parent.children);
list_del(&child[0].node);
g_assert(list_is_empty(&parent.children));
list_add(&child[0].node, &parent.children);
list_add(&child[1].node, &parent.children);
c = list_first_entry(&parent.children, struct child, node);
g_assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
/* delete first node */
list_del(&child[1].node);
g_assert(!list_is_empty(&parent.children));
g_assert(list_is_empty(&child[1].node));
c = list_first_entry(&parent.children, struct child, node);
g_assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
/* delete last node */
list_add(&child[1].node, &parent.children);
list_del(&child[0].node);
c = list_first_entry(&parent.children, struct child, node);
g_assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
/* delete list head */
list_add(&child[0].node, &parent.children);
list_del(&parent.children);
g_assert(list_is_empty(&parent.children));
g_assert(!list_is_empty(&child[1].node));
g_assert(!list_is_empty(&child[2].node));
}
static void
test_list_for_each(void)
{
struct parent parent = {0};
struct child child[3];
struct child *c;
int i = 0;
list_init(&parent.children);
list_add(&child[2].node, &parent.children);
list_add(&child[1].node, &parent.children);
list_add(&child[0].node, &parent.children);
list_for_each_entry(c, &parent.children, node) {
g_assert(memcmp(c, &child[i], sizeof(struct child)) == 0);
i++;
}
/* foreach on empty list */
list_del(&parent.children);
g_assert(list_is_empty(&parent.children));
list_for_each_entry(c, &parent.children, node) {
g_assert(0); /* we must not get here */
}
}
int main(int argc, char** argv)
{
g_test_init(&argc, &argv,NULL);
g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id=");
g_test_add_func("/list/init", test_list_init);
g_test_add_func("/list/add", test_list_add);
g_test_add_func("/list/del", test_list_del);
g_test_add_func("/list/for_each", test_list_for_each);
return g_test_run();
}