diff --git a/dix/getevents.c b/dix/getevents.c index 441c20f56..c3b7ced45 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -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*/ diff --git a/fb/fbpict.c b/fb/fbpict.c index 312f3df21..133f4226c 100644 --- a/fb/fbpict.c +++ b/fb/fbpict.c @@ -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); diff --git a/glx/glxdri.c b/glx/glxdri.c index 7717fcfb7..3a573372a 100644 --- a/glx/glxdri.c +++ b/glx/glxdri.c @@ -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; diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 8d21c937b..18927d75d 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -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; diff --git a/glx/glxdricommon.c b/glx/glxdricommon.c index 86797a0ef..9149e0db1 100644 --- a/glx/glxdricommon.c +++ b/glx/glxdricommon.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -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; +} diff --git a/glx/glxdricommon.h b/glx/glxdricommon.h index 41e2d2770..2c55e60a6 100644 --- a/glx/glxdricommon.h +++ b/glx/glxdricommon.h @@ -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 diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c index 08ea33865..78b24ff62 100644 --- a/glx/glxdriswrast.c +++ b/glx/glxdriswrast.c @@ -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; diff --git a/hw/dmx/dmx.h b/hw/dmx/dmx.h index bf4b92cb2..c6b6199a5 100644 --- a/hw/dmx/dmx.h +++ b/hw/dmx/dmx.h @@ -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. */ diff --git a/hw/dmx/dmxpict.c b/hw/dmx/dmxpict.c index bbde8fde1..1fb54620a 100644 --- a/hw/dmx/dmxpict.c +++ b/hw/dmx/dmxpict.c @@ -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); -} diff --git a/hw/dmx/dmxpict.h b/hw/dmx/dmxpict.h index 3c8a09ce4..a732991e4 100644 --- a/hw/dmx/dmxpict.h +++ b/hw/dmx/dmxpict.h @@ -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); diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c index 883c48cc0..c712df72c 100644 --- a/hw/xfree86/common/xf86Configure.c +++ b/hw/xfree86/common/xf86Configure.c @@ -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) { diff --git a/hw/xfree86/os-support/xf86_OSlib.h b/hw/xfree86/os-support/xf86_OSlib.h index 147a201ee..24c92fbbc 100644 --- a/hw/xfree86/os-support/xf86_OSlib.h +++ b/hw/xfree86/os-support/xf86_OSlib.h @@ -370,6 +370,9 @@ #include /* 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" diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c index e4fce309f..1cff3bc5c 100644 --- a/hw/xfree86/parser/scan.c +++ b/hw/xfree86/parser/scan.c @@ -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" diff --git a/include/misc.h b/include/misc.h index 0717db64d..803f5bade 100644 --- a/include/misc.h +++ b/include/misc.h @@ -79,6 +79,7 @@ OF THIS SOFTWARE. #include #include +#include #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 +#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. diff --git a/include/propertyst.h b/include/propertyst.h index fd1148eb7..1edd11d5d 100644 --- a/include/propertyst.h +++ b/include/propertyst.h @@ -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; diff --git a/include/resource.h b/include/resource.h index 763aa99d9..772b7b877 100644 --- a/include/resource.h +++ b/include/resource.h @@ -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) diff --git a/mi/mipointer.c b/mi/mipointer.c index 209ea06be..c578d0b1d 100644 --- a/mi/mipointer.c +++ b/mi/mipointer.c @@ -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; diff --git a/mi/mipointer.h b/mi/mipointer.h index 3c8611022..539096e78 100644 --- a/mi/mipointer.h +++ b/mi/mipointer.h @@ -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); diff --git a/miext/cw/cw.h b/miext/cw/cw.h index 31eb9e57c..e2bb9ad88 100644 --- a/miext/cw/cw.h +++ b/miext/cw/cw.h @@ -106,8 +106,6 @@ typedef struct { TrapezoidsProcPtr Trapezoids; TrianglesProcPtr Triangles; - TriStripProcPtr TriStrip; - TriFanProcPtr TriFan; RasterizeTrapezoidProcPtr RasterizeTrapezoid; } cwScreenRec, *cwScreenPtr; diff --git a/miext/cw/cw_render.c b/miext/cw/cw_render.c index 165c44f46..1f990aefa 100644 --- a/miext/cw/cw_render.c +++ b/miext/cw/cw_render.c @@ -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); } diff --git a/os/access.c b/os/access.c index eb1a21d42..3856e606e 100644 --- a/os/access.c +++ b/os/access.c @@ -165,17 +165,6 @@ SOFTWARE. #endif /* WIN32 */ -#ifndef PATH_MAX -#include -#ifndef PATH_MAX -#ifdef MAXPATHLEN -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif -#endif -#endif - #define X_INCLUDE_NETDB_H #include @@ -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) diff --git a/os/osinit.c b/os/osinit.c index 018e4047d..45d202def 100644 --- a/os/osinit.c +++ b/os/osinit.c @@ -63,17 +63,10 @@ SOFTWARE. #include #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 diff --git a/os/utils.c b/os/utils.c index 18fd91151..a365aca81 100644 --- a/os/utils.c +++ b/os/utils.c @@ -231,17 +231,6 @@ OsSignal(int sig, OsSigHandlerPtr handler) #define LOCK_PREFIX "/.X" #define LOCK_SUFFIX "-lock" -#ifndef PATH_MAX -#include -#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; diff --git a/randr/randr.c b/randr/randr.c index 607770520..d33712928 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -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; diff --git a/randr/randrstr.h b/randr/randrstr.h index 7ea608003..d8dd37d96 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -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); diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index 98206a2b9..d4d8f2ad2 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -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; + } + } +} diff --git a/render/mipict.c b/render/mipict.c index 3b7388879..08b2fa722 100644 --- a/render/mipict.c +++ b/render/mipict.c @@ -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 */ diff --git a/render/mipict.h b/render/mipict.h index d1495891e..f6d9deefd 100644 --- a/render/mipict.h +++ b/render/mipict.h @@ -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); diff --git a/render/mitri.c b/render/mitri.c index b258c2156..b322a7c62 100644 --- a/render/mitri.c +++ b/render/mitri.c @@ -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); -} diff --git a/render/picture.c b/render/picture.c index 0028cc76a..015d63364 100644 --- a/render/picture.c +++ b/render/picture.c @@ -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 diff --git a/render/picturestr.h b/render/picturestr.h index ae69eef10..7c7edb1c4 100644 --- a/render/picturestr.h +++ b/render/picturestr.h @@ -381,8 +381,6 @@ typedef struct _PictureScreen { TrapezoidsProcPtr Trapezoids; TrianglesProcPtr Triangles; - TriStripProcPtr TriStrip; - TriFanProcPtr TriFan; RasterizeTrapezoidProcPtr RasterizeTrapezoid; diff --git a/test/Makefile.am b/test/Makefile.am index 456221e46..be54e5f24 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -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) \ diff --git a/test/list.c b/test/list.c new file mode 100644 index 000000000..a87d2db70 --- /dev/null +++ b/test/list.c @@ -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 +#endif + +#include +#include +#include +#include + +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(); +}