diff options
Diffstat (limited to 'xorg-server')
199 files changed, 2483 insertions, 3701 deletions
diff --git a/xorg-server/Xext/hashtable.c b/xorg-server/Xext/hashtable.c index 471ecca1c..41b2e0013 100644 --- a/xorg-server/Xext/hashtable.c +++ b/xorg-server/Xext/hashtable.c @@ -54,7 +54,7 @@ ht_create(int keySize, ht->elements = 0; ht->bucketBits = INITHASHSIZE; numBuckets = 1 << ht->bucketBits; - ht->buckets = malloc(numBuckets * sizeof(*ht->buckets)); + ht->buckets = xallocarray(numBuckets, sizeof(*ht->buckets)); ht->cdata = cdata; if (ht->buckets) { @@ -92,7 +92,7 @@ double_size(HashTable ht) int newNumBuckets = 1 << newBucketBits; int c; - newBuckets = malloc(newNumBuckets * sizeof(*ht->buckets)); + newBuckets = xallocarray(newNumBuckets, sizeof(*ht->buckets)); if (newBuckets) { for (c = 0; c < newNumBuckets; ++c) { xorg_list_init(&newBuckets[c]); diff --git a/xorg-server/Xext/panoramiX.c b/xorg-server/Xext/panoramiX.c index 2bbae2f5e..209df292c 100644 --- a/xorg-server/Xext/panoramiX.c +++ b/xorg-server/Xext/panoramiX.c @@ -747,13 +747,13 @@ PanoramiXMaybeAddDepth(DepthPtr pDepth) j = PanoramiXNumDepths; PanoramiXNumDepths++; - PanoramiXDepths = realloc(PanoramiXDepths, - PanoramiXNumDepths * sizeof(DepthRec)); + PanoramiXDepths = reallocarray(PanoramiXDepths, + PanoramiXNumDepths, sizeof(DepthRec)); PanoramiXDepths[j].depth = pDepth->depth; PanoramiXDepths[j].numVids = 0; /* XXX suboptimal, should grow these dynamically */ if (pDepth->numVids) - PanoramiXDepths[j].vids = malloc(sizeof(VisualID) * pDepth->numVids); + PanoramiXDepths[j].vids = xallocarray(pDepth->numVids, sizeof(VisualID)); else PanoramiXDepths[j].vids = NULL; } @@ -789,8 +789,8 @@ PanoramiXMaybeAddVisual(VisualPtr pVisual) /* found a matching visual on all screens, add it to the subset list */ j = PanoramiXNumVisuals; PanoramiXNumVisuals++; - PanoramiXVisuals = realloc(PanoramiXVisuals, - PanoramiXNumVisuals * sizeof(VisualRec)); + PanoramiXVisuals = reallocarray(PanoramiXVisuals, + PanoramiXNumVisuals, sizeof(VisualRec)); memcpy(&PanoramiXVisuals[j], pVisual, sizeof(VisualRec)); diff --git a/xorg-server/Xext/panoramiXprocs.c b/xorg-server/Xext/panoramiXprocs.c index 413a66afb..9eb29bd74 100644 --- a/xorg-server/Xext/panoramiXprocs.c +++ b/xorg-server/Xext/panoramiXprocs.c @@ -1106,7 +1106,7 @@ PanoramiXCopyArea(ClientPtr client) } pitch = PixmapBytePad(stuff->width, drawables[0]->depth); - if (!(data = calloc(1, stuff->height * pitch))) + if (!(data = calloc(stuff->height, pitch))) return BadAlloc; XineramaGetImageData(drawables, srcx, srcy, @@ -1341,7 +1341,7 @@ PanoramiXPolyPoint(ClientPtr client) isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq)); if (npoint > 0) { - origPts = malloc(npoint * sizeof(xPoint)); + origPts = xallocarray(npoint, sizeof(xPoint)); memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint)); FOR_NSCREENS_FORWARD(j) { @@ -1406,7 +1406,7 @@ PanoramiXPolyLine(ClientPtr client) isRoot = IS_ROOT_DRAWABLE(draw); npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq)); if (npoint > 0) { - origPts = malloc(npoint * sizeof(xPoint)); + origPts = xallocarray(npoint, sizeof(xPoint)); memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint)); FOR_NSCREENS_FORWARD(j) { @@ -1475,7 +1475,7 @@ PanoramiXPolySegment(ClientPtr client) return BadLength; nsegs >>= 3; if (nsegs > 0) { - origSegs = malloc(nsegs * sizeof(xSegment)); + origSegs = xallocarray(nsegs, sizeof(xSegment)); memcpy((char *) origSegs, (char *) &stuff[1], nsegs * sizeof(xSegment)); FOR_NSCREENS_FORWARD(j) { @@ -1543,7 +1543,7 @@ PanoramiXPolyRectangle(ClientPtr client) return BadLength; nrects >>= 3; if (nrects > 0) { - origRecs = malloc(nrects * sizeof(xRectangle)); + origRecs = xallocarray(nrects, sizeof(xRectangle)); memcpy((char *) origRecs, (char *) &stuff[1], nrects * sizeof(xRectangle)); FOR_NSCREENS_FORWARD(j) { @@ -1610,7 +1610,7 @@ PanoramiXPolyArc(ClientPtr client) return BadLength; narcs /= sizeof(xArc); if (narcs > 0) { - origArcs = malloc(narcs * sizeof(xArc)); + origArcs = xallocarray(narcs, sizeof(xArc)); memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc)); FOR_NSCREENS_FORWARD(j) { @@ -1672,7 +1672,7 @@ PanoramiXFillPoly(ClientPtr client) count = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq)); if (count > 0) { - locPts = malloc(count * sizeof(DDXPointRec)); + locPts = xallocarray(count, sizeof(DDXPointRec)); memcpy((char *) locPts, (char *) &stuff[1], count * sizeof(DDXPointRec)); FOR_NSCREENS_FORWARD(j) { @@ -1741,7 +1741,7 @@ PanoramiXPolyFillRectangle(ClientPtr client) return BadLength; things >>= 3; if (things > 0) { - origRects = malloc(things * sizeof(xRectangle)); + origRects = xallocarray(things, sizeof(xRectangle)); memcpy((char *) origRects, (char *) &stuff[1], things * sizeof(xRectangle)); FOR_NSCREENS_FORWARD(j) { @@ -1808,7 +1808,7 @@ PanoramiXPolyFillArc(ClientPtr client) return BadLength; narcs /= sizeof(xArc); if (narcs > 0) { - origArcs = malloc(narcs * sizeof(xArc)); + origArcs = xallocarray(narcs, sizeof(xArc)); memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc)); FOR_NSCREENS_FORWARD(j) { @@ -1988,8 +1988,7 @@ PanoramiXGetImage(ClientPtr client) if (linesPerBuf > h) linesPerBuf = h; } - length = linesPerBuf * widthBytesLine; - if (!(pBuf = malloc(length))) + if (!(pBuf = xallocarray(linesPerBuf, widthBytesLine))) return BadAlloc; WriteReplyToClient(client, sizeof(xGetImageReply), &xgi); diff --git a/xorg-server/Xext/saver.c b/xorg-server/Xext/saver.c index 2c14ea00e..0e20467c9 100644 --- a/xorg-server/Xext/saver.c +++ b/xorg-server/Xext/saver.c @@ -853,7 +853,7 @@ ScreenSaverSetAttributes(ClientPtr client) goto bail; } /* over allocate for override redirect */ - pAttr->values = values = malloc((len + 1) * sizeof(unsigned long)); + pAttr->values = values = xallocarray(len + 1, sizeof(unsigned long)); if (!values) { ret = BadAlloc; goto bail; diff --git a/xorg-server/Xext/shape.c b/xorg-server/Xext/shape.c index bb479b159..2fc789ec1 100644 --- a/xorg-server/Xext/shape.c +++ b/xorg-server/Xext/shape.c @@ -996,7 +996,7 @@ ProcShapeGetRectangles(ClientPtr client) nrects = RegionNumRects(region); box = RegionRects(region); - rects = malloc(nrects * sizeof(xRectangle)); + rects = xallocarray(nrects, sizeof(xRectangle)); if (!rects && nrects) return BadAlloc; for (i = 0; i < nrects; i++, box++) { diff --git a/xorg-server/Xext/shm.c b/xorg-server/Xext/shm.c index db9d47450..b359a9035 100644 --- a/xorg-server/Xext/shm.c +++ b/xorg-server/Xext/shm.c @@ -260,7 +260,7 @@ ShmDestroyPixmap(PixmapPtr pPixmap) pScreen->DestroyPixmap = ShmDestroyPixmap; if (shmdesc) - ShmDetachSegment(shmdesc, pPixmap->drawable.id); + ShmDetachSegment(shmdesc, 0); return ret; } @@ -427,7 +427,7 @@ ProcShmAttach(ClientPtr client) /*ARGSUSED*/ static int ShmDetachSegment(void *value, /* must conform to DeleteType */ - XID shmseg) + XID unused) { ShmDescPtr shmdesc = (ShmDescPtr) value; ShmDescPtr *prev; @@ -971,6 +971,12 @@ ProcPanoramiXShmCreatePixmap(ClientPtr client) stuff->offset); if (pMap) { + result = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, + RT_PIXMAP, pMap, RT_NONE, NULL, DixCreateAccess); + if (result != Success) { + pDraw->pScreen->DestroyPixmap(pMap); + return result; + } dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc); shmdesc->refcnt++; pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; diff --git a/xorg-server/Xext/sync.c b/xorg-server/Xext/sync.c index ba08cd1bb..41405619c 100644 --- a/xorg-server/Xext/sync.c +++ b/xorg-server/Xext/sync.c @@ -620,7 +620,7 @@ SyncAwaitTriggerFired(SyncTrigger * pTrigger) pAwaitUnion = (SyncAwaitUnion *) pAwait->pHeader; numwaits = pAwaitUnion->header.num_waitconditions; - ppAwait = malloc(numwaits * sizeof(SyncAwait *)); + ppAwait = xallocarray(numwaits, sizeof(SyncAwait *)); if (!ppAwait) goto bail; @@ -1514,7 +1514,7 @@ SyncAwaitPrologue(ClientPtr client, int items) /* all the memory for the entire await list is allocated * here in one chunk */ - pAwaitUnion = malloc((items + 1) * sizeof(SyncAwaitUnion)); + pAwaitUnion = xallocarray(items + 1, sizeof(SyncAwaitUnion)); if (!pAwaitUnion) return NULL; diff --git a/xorg-server/Xext/xcmisc.c b/xorg-server/Xext/xcmisc.c index 1e9101059..ed25650cd 100644 --- a/xorg-server/Xext/xcmisc.c +++ b/xorg-server/Xext/xcmisc.c @@ -101,7 +101,7 @@ ProcXCMiscGetXIDList(ClientPtr client) if (stuff->count > UINT32_MAX / sizeof(XID)) return BadAlloc; - pids = (XID *) malloc(stuff->count * sizeof(XID)); + pids = xallocarray(stuff->count, sizeof(XID)); if (!pids) { return BadAlloc; } diff --git a/xorg-server/Xext/xf86bigfont.c b/xorg-server/Xext/xf86bigfont.c index 46b3242d1..95b537170 100644 --- a/xorg-server/Xext/xf86bigfont.c +++ b/xorg-server/Xext/xf86bigfont.c @@ -401,7 +401,7 @@ ProcXF86BigfontQueryFont(ClientPtr client) } else { #endif - pCI = malloc(nCharInfos * sizeof(xCharInfo)); + pCI = xallocarray(nCharInfos, sizeof(xCharInfo)); if (!pCI) return BadAlloc; #ifdef HAS_SHM @@ -463,7 +463,7 @@ ProcXF86BigfontQueryFont(ClientPtr client) if (hashModulus > nCharInfos + 1) hashModulus = nCharInfos + 1; - tmp = malloc((4 * nCharInfos + 1) * sizeof(CARD16)); + tmp = xallocarray(4 * nCharInfos + 1, sizeof(CARD16)); if (!tmp) { if (!pDesc) free(pCI); diff --git a/xorg-server/Xext/xres.c b/xorg-server/Xext/xres.c index 273793806..6b87c3ddc 100644 --- a/xorg-server/Xext/xres.c +++ b/xorg-server/Xext/xres.c @@ -223,7 +223,7 @@ ProcXResQueryClients(ClientPtr client) REQUEST_SIZE_MATCH(xXResQueryClientsReq); - current_clients = malloc(currentMaxClients * sizeof(int)); + current_clients = xallocarray(currentMaxClients, sizeof(int)); num_clients = 0; for (i = 0; i < currentMaxClients; i++) { diff --git a/xorg-server/Xext/xselinux_label.c b/xorg-server/Xext/xselinux_label.c index 2c33d1cbf..8559385b9 100644 --- a/xorg-server/Xext/xselinux_label.c +++ b/xorg-server/Xext/xselinux_label.c @@ -64,7 +64,7 @@ SELinuxArraySet(SELinuxArrayRec * rec, unsigned key, void *val) { if (key >= rec->size) { /* Need to increase size of array */ - rec->array = realloc(rec->array, (key + 1) * sizeof(val)); + rec->array = reallocarray(rec->array, key + 1, sizeof(val)); if (!rec->array) return FALSE; memset(rec->array + rec->size, 0, (key - rec->size + 1) * sizeof(val)); diff --git a/xorg-server/Xext/xvmain.c b/xorg-server/Xext/xvmain.c index 0abf190dc..93e5f0cd3 100644 --- a/xorg-server/Xext/xvmain.c +++ b/xorg-server/Xext/xvmain.c @@ -1102,7 +1102,7 @@ XvFillColorKey(DrawablePtr pDraw, CARD32 key, RegionPtr region) (void) ChangeGC(NullClient, gc, GCForeground | GCSubwindowMode, pval); ValidateGC(pDraw, gc); - rects = malloc(nbox * sizeof(xRectangle)); + rects = xallocarray(nbox, sizeof(xRectangle)); if (rects) { for (i = 0; i < nbox; i++, pbox++) { rects[i].x = pbox->x1 - pDraw->x; diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c index 0857bcee6..1c586d051 100644 --- a/xorg-server/Xi/exevents.c +++ b/xorg-server/Xi/exevents.c @@ -471,9 +471,9 @@ DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to) oldTrace = to->focus->trace; memcpy(to->focus, from->focus, sizeof(FocusClassRec)); - to->focus->trace = realloc(oldTrace, - to->focus->traceSize * - sizeof(WindowPtr)); + to->focus->trace = reallocarray(oldTrace, + to->focus->traceSize, + sizeof(WindowPtr)); if (!to->focus->trace && to->focus->traceSize) FatalError("[Xi] no memory for trace.\n"); memcpy(to->focus->trace, from->focus->trace, diff --git a/xorg-server/Xi/getprop.c b/xorg-server/Xi/getprop.c index 4d6ce6338..19f18af21 100644 --- a/xorg-server/Xi/getprop.c +++ b/xorg-server/Xi/getprop.c @@ -118,7 +118,7 @@ ProcXGetDeviceDontPropagateList(ClientPtr client) ClassFromMask(NULL, others->dontPropagateMask[i], i, &count, COUNT); if (count) { rep.count = count; - buf = (XEventClass *) malloc(rep.count * sizeof(XEventClass)); + buf = xallocarray(rep.count, sizeof(XEventClass)); rep.length = bytes_to_int32(rep.count * sizeof(XEventClass)); tbuf = buf; diff --git a/xorg-server/Xi/xiproperty.c b/xorg-server/Xi/xiproperty.c index 8e8e4b061..e3b8f5abe 100644 --- a/xorg-server/Xi/xiproperty.c +++ b/xorg-server/Xi/xiproperty.c @@ -221,7 +221,7 @@ list_atoms(DeviceIntPtr dev, int *natoms, Atom **atoms_return) if (nprops) { Atom *a; - atoms = malloc(nprops * sizeof(Atom)); + atoms = xallocarray(nprops, sizeof(Atom)); if (!atoms) return BadAlloc; a = atoms; @@ -687,7 +687,6 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type, { XIPropertyPtr prop; int size_in_bytes; - int total_size; unsigned long total_len; XIPropertyValuePtr prop_value; XIPropertyValueRec new_value; @@ -725,9 +724,8 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type, if (mode == PropModeReplace || len > 0) { void *new_data = NULL, *old_data = NULL; - total_size = total_len * size_in_bytes; - new_value.data = (void *) malloc(total_size); - if (!new_value.data && total_size) { + new_value.data = xallocarray(total_len, size_in_bytes); + if (!new_value.data && total_len && size_in_bytes) { if (add) XIDestroyDeviceProperty(prop); return BadAlloc; diff --git a/xorg-server/Xi/xiquerypointer.c b/xorg-server/Xi/xiquerypointer.c index 7ec0c851d..b9e295815 100644 --- a/xorg-server/Xi/xiquerypointer.c +++ b/xorg-server/Xi/xiquerypointer.c @@ -152,10 +152,10 @@ ProcXIQueryPointer(ClientPtr client) rep.buttons_len = bytes_to_int32(bits_to_bytes(pDev->button->numButtons)); rep.length += rep.buttons_len; - buttons_size = rep.buttons_len * 4; - buttons = calloc(1, buttons_size); + buttons = calloc(rep.buttons_len, 4); if (!buttons) return BadAlloc; + buttons_size = rep.buttons_len * 4; for (i = 1; i < pDev->button->numButtons; i++) if (BitIsOn(pDev->button->down, i)) diff --git a/xorg-server/composite/compinit.c b/xorg-server/composite/compinit.c index 3ac075a46..cf61f2a57 100644 --- a/xorg-server/composite/compinit.c +++ b/xorg-server/composite/compinit.c @@ -223,8 +223,8 @@ compRegisterAlternateVisuals(CompScreenPtr cs, VisualID * vids, int nVisuals) { VisualID *p; - p = realloc(cs->alternateVisuals, - sizeof(VisualID) * (cs->numAlternateVisuals + nVisuals)); + p = reallocarray(cs->alternateVisuals, + cs->numAlternateVisuals + nVisuals, sizeof(VisualID)); if (p == NULL) return FALSE; @@ -253,8 +253,8 @@ CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen, CompScreenPtr cs = GetCompScreen(pScreen); CompImplicitRedirectException *p; - p = realloc(cs->implicitRedirectExceptions, - sizeof(p[0]) * (cs->numImplicitRedirectExceptions + 1)); + p = reallocarray(cs->implicitRedirectExceptions, + cs->numImplicitRedirectExceptions + 1, sizeof(p[0])); if (p == NULL) return FALSE; diff --git a/xorg-server/config/config.c b/xorg-server/config/config.c index b5d634b87..de45cc350 100644 --- a/xorg-server/config/config.c +++ b/xorg-server/config/config.c @@ -130,7 +130,8 @@ device_is_duplicate(const char *config_info) struct OdevAttributes * config_odev_allocate_attributes(void) { - struct OdevAttributes *attribs = XNFcalloc(sizeof (struct OdevAttributes)); + struct OdevAttributes *attribs = + xnfcalloc(1, sizeof (struct OdevAttributes)); attribs->fd = -1; return attribs; } diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 606298bdc..f760730c3 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -219,7 +219,7 @@ dnl Checks for library functions. AC_CHECK_FUNCS([backtrace ffs geteuid getuid issetugid getresuid \ getdtablesize getifaddrs getpeereid getpeerucred getprogname getzoneid \ mmap seteuid shmctl64 strncasecmp vasprintf vsnprintf walkcontext]) -AC_REPLACE_FUNCS([strcasecmp strcasestr strlcat strlcpy strndup]) +AC_REPLACE_FUNCS([reallocarray strcasecmp strcasestr strlcat strlcpy strndup]) AC_CHECK_DECLS([program_invocation_short_name], [], [], [[#include <errno.h>]]) @@ -560,17 +560,7 @@ dnl GLX build options AC_ARG_ENABLE(aiglx, AS_HELP_STRING([--enable-aiglx], [Build accelerated indirect GLX (default: enabled)]), [AIGLX=$enableval], [AIGLX=yes]) -XORG_TLS -AC_ARG_ENABLE(glx-tls, AS_HELP_STRING([--enable-glx-tls], [Build GLX with TLS support (default: auto)]), - [GLX_USE_TLS=$enableval - if test "x$GLX_USE_TLS" = "xyes" && test "${ac_cv_tls}" = "none" ; then - AC_MSG_ERROR([GLX with TLS support requested, but the compiler does not support it.]) - fi], - [GLX_USE_TLS=no - if test "${ac_cv_tls}" != "none" ; then - GLX_USE_TLS=yes - fi]) -AC_SUBST(GLX_TLS, ${GLX_USE_TLS}) + AC_ARG_WITH(khronos-spec-dir, AS_HELP_STRING([--with-khronos-spec-dir=PATH], [Path to Khronos OpenGL registry database files (default: auto)]), [KHRONOS_SPEC_DIR="${withval}"], [KHRONOS_SPEC_DIR=auto]) @@ -1324,10 +1314,6 @@ if test "x$AIGLX" = xyes -a \( "x$DRI2" = xyes \); then fi AM_CONDITIONAL(AIGLX_DRI_LOADER, { test "x$DRI2" = xyes; } && test "x$AIGLX" = xyes) -if test "x$GLX_USE_TLS" = xyes ; then - GLX_DEFINES="-DGLX_USE_TLS -DPTHREADS" - GLX_SYS_LIBS="$GLX_SYS_LIBS -lpthread" -fi AC_SUBST([GLX_DEFINES]) AC_SUBST([GLX_SYS_LIBS]) @@ -1976,7 +1962,7 @@ if test "x$XORG" = xyes; then sparc*) SOLARIS_INOUT_ARCH="sparcv8plus" ;; - i*86) + i*86|x86_64*) if test x$SOLARIS_64 = xyes ; then SOLARIS_INOUT_ARCH="amd64" else @@ -2006,11 +1992,6 @@ if test "x$XORG" = xyes; then ;; esac - case $host_cpu in - i*86) - ;; - esac - if test "x$DGA" = xauto; then PKG_CHECK_MODULES(DGA, $DGAPROTO, [DGA=yes], [DGA=no]) fi @@ -2423,7 +2404,8 @@ if test "$KDRIVE" = yes; then fi ;; esac - KDRIVE_LOCAL_LIBS="$MAIN_LIB $DIX_LIB $KDRIVE_LIB" + KDRIVE_MAIN_LIB="$MAIN_LIB" + KDRIVE_LOCAL_LIBS="$DIX_LIB $KDRIVE_LIB" KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS" KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB" KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $GLX_SYS_LIBS $DLOPEN_LIBS $TSLIB_LIBS" @@ -2435,6 +2417,7 @@ AC_SUBST([KDRIVE_INCS]) AC_SUBST([KDRIVE_PURE_INCS]) AC_SUBST([KDRIVE_CFLAGS]) AC_SUBST([KDRIVE_PURE_LIBS]) +AC_SUBST([KDRIVE_MAIN_LIB]) AC_SUBST([KDRIVE_LOCAL_LIBS]) AC_SUBST([KDRIVE_LIBS]) AM_CONDITIONAL(KDRIVELINUX, [test "x$KDRIVELINUX" = xyes]) diff --git a/xorg-server/dbe/dbe.c b/xorg-server/dbe/dbe.c index e5d928d7b..23f7e164d 100644 --- a/xorg-server/dbe/dbe.c +++ b/xorg-server/dbe/dbe.c @@ -287,11 +287,10 @@ ProcDbeAllocateBackBufferName(ClientPtr client) } /* malloc/realloc a new array and initialize all elements to 0. */ - pDbeWindowPriv->IDs = (XID *) realloc(pIDs, - (pDbeWindowPriv-> - maxAvailableIDs + - DBE_INCR_MAX_IDS) * - sizeof(XID)); + pDbeWindowPriv->IDs = + reallocarray(pIDs, + pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS, + sizeof(XID)); if (!pDbeWindowPriv->IDs) { return BadAlloc; } @@ -470,7 +469,7 @@ ProcDbeSwapBuffers(ClientPtr client) dbeSwapInfo = (xDbeSwapInfo *) &stuff[1]; /* Allocate array to record swap information. */ - swapInfo = (DbeSwapInfoPtr) malloc(nStuff * sizeof(DbeSwapInfoRec)); + swapInfo = xallocarray(nStuff, sizeof(DbeSwapInfoRec)); if (swapInfo == NULL) { return BadAlloc; } @@ -580,8 +579,7 @@ ProcDbeGetVisualInfo(ClientPtr client) return BadAlloc; /* Make sure any specified drawables are valid. */ if (stuff->n != 0) { - if (!(pDrawables = (DrawablePtr *) malloc(stuff->n * - sizeof(DrawablePtr)))) { + if (!(pDrawables = xallocarray(stuff->n, sizeof(DrawablePtr)))) { return BadAlloc; } diff --git a/xorg-server/dbe/midbe.c b/xorg-server/dbe/midbe.c index 8f759107a..9684d45bd 100644 --- a/xorg-server/dbe/midbe.c +++ b/xorg-server/dbe/midbe.c @@ -87,7 +87,7 @@ miDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo * pScrVisInfo) } /* Allocate an array of XdbeVisualInfo items. */ - if (!(visInfo = (XdbeVisualInfo *) malloc(count * sizeof(XdbeVisualInfo)))) { + if (!(visInfo = xallocarray(count, sizeof(XdbeVisualInfo)))) { return FALSE; /* memory alloc failure */ } diff --git a/xorg-server/dix/atom.c b/xorg-server/dix/atom.c index 22cd0dc0e..7de7fb05e 100644 --- a/xorg-server/dix/atom.c +++ b/xorg-server/dix/atom.c @@ -119,7 +119,7 @@ MakeAtom(const char *string, unsigned len, Bool makeit) if ((lastAtom + 1) >= tableLength) { NodePtr *table; - table = realloc(nodeTable, tableLength * (2 * sizeof(NodePtr))); + table = reallocarray(nodeTable, tableLength, 2 * sizeof(NodePtr)); if (!table) { if (nd->string != string) { /* nd->string has been strdup'ed */ @@ -200,7 +200,7 @@ InitAtoms(void) { FreeAllAtoms(); tableLength = InitialTableSize; - nodeTable = malloc(InitialTableSize * sizeof(NodePtr)); + nodeTable = xallocarray(InitialTableSize, sizeof(NodePtr)); if (!nodeTable) AtomError(); nodeTable[None] = NULL; diff --git a/xorg-server/dix/colormap.c b/xorg-server/dix/colormap.c index 4d408d5d2..a3e5a2c09 100644 --- a/xorg-server/dix/colormap.c +++ b/xorg-server/dix/colormap.c @@ -296,7 +296,7 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--) pent->refcnt = AllocPrivate; pmap->freeRed = 0; - ppix = malloc(size * sizeof(Pixel)); + ppix = xallocarray(size, sizeof(Pixel)); if (!ppix) { free(pmap); return BadAlloc; @@ -337,7 +337,7 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, for (pent = &pmap->green[size - 1]; pent >= pmap->green; pent--) pent->refcnt = AllocPrivate; pmap->freeGreen = 0; - ppix = malloc(size * sizeof(Pixel)); + ppix = xallocarray(size, sizeof(Pixel)); if (!ppix) { free(pmap->clientPixelsRed[client]); free(pmap); @@ -352,7 +352,7 @@ CreateColormap(Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, for (pent = &pmap->blue[size - 1]; pent >= pmap->blue; pent--) pent->refcnt = AllocPrivate; pmap->freeBlue = 0; - ppix = malloc(size * sizeof(Pixel)); + ppix = xallocarray(size, sizeof(Pixel)); if (!ppix) { free(pmap->clientPixelsGreen[client]); free(pmap->clientPixelsRed[client]); @@ -702,7 +702,7 @@ UpdateColors(ColormapPtr pmap) pVisual = pmap->pVisual; size = pVisual->ColormapEntries; - defs = malloc(size * sizeof(xColorItem)); + defs = xallocarray(size, sizeof(xColorItem)); if (!defs) return; n = 0; @@ -792,8 +792,8 @@ AllocColor(ColormapPtr pmap, *pgreen = pmap->red[pixR].co.local.green; *pblue = pmap->red[pixR].co.local.blue; npix = pmap->numPixelsRed[client]; - ppix = (Pixel *) realloc(pmap->clientPixelsRed[client], - (npix + 1) * sizeof(Pixel)); + ppix = reallocarray(pmap->clientPixelsRed[client], + npix + 1, sizeof(Pixel)); if (!ppix) return BadAlloc; ppix[npix] = pixR; @@ -814,22 +814,22 @@ AllocColor(ColormapPtr pmap, *pgreen = pmap->green[pixG].co.local.green; *pblue = pmap->blue[pixB].co.local.blue; npix = pmap->numPixelsRed[client]; - ppix = (Pixel *) realloc(pmap->clientPixelsRed[client], - (npix + 1) * sizeof(Pixel)); + ppix = reallocarray(pmap->clientPixelsRed[client], + npix + 1, sizeof(Pixel)); if (!ppix) return BadAlloc; ppix[npix] = pixR; pmap->clientPixelsRed[client] = ppix; npix = pmap->numPixelsGreen[client]; - ppix = (Pixel *) realloc(pmap->clientPixelsGreen[client], - (npix + 1) * sizeof(Pixel)); + ppix = reallocarray(pmap->clientPixelsGreen[client], + npix + 1, sizeof(Pixel)); if (!ppix) return BadAlloc; ppix[npix] = pixG; pmap->clientPixelsGreen[client] = ppix; npix = pmap->numPixelsBlue[client]; - ppix = (Pixel *) realloc(pmap->clientPixelsBlue[client], - (npix + 1) * sizeof(Pixel)); + ppix = reallocarray(pmap->clientPixelsBlue[client], + npix + 1, sizeof(Pixel)); if (!ppix) return BadAlloc; ppix[npix] = pixB; @@ -1279,7 +1279,7 @@ FindColor(ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb * prgb, break; } npix = nump[client]; - ppix = (Pixel *) realloc(pixp[client], (npix + 1) * sizeof(Pixel)); + ppix = reallocarray(pixp[client], npix + 1, sizeof(Pixel)); if (!ppix) { pent->refcnt--; if (!pent->fShared) @@ -1647,9 +1647,9 @@ AllocDirect(int client, ColormapPtr pmap, int c, int r, int g, int b, for (p = pixels; p < pixels + c; p++) *p = 0; - ppixRed = malloc(npixR * sizeof(Pixel)); - ppixGreen = malloc(npixG * sizeof(Pixel)); - ppixBlue = malloc(npixB * sizeof(Pixel)); + ppixRed = xallocarray(npixR, sizeof(Pixel)); + ppixGreen = xallocarray(npixG, sizeof(Pixel)); + ppixBlue = xallocarray(npixB, sizeof(Pixel)); if (!ppixRed || !ppixGreen || !ppixBlue) { free(ppixBlue); free(ppixGreen); @@ -1662,19 +1662,19 @@ AllocDirect(int client, ColormapPtr pmap, int c, int r, int g, int b, okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask); if (okR && okG && okB) { - rpix = (Pixel *) realloc(pmap->clientPixelsRed[client], - (pmap->numPixelsRed[client] + (c << r)) * - sizeof(Pixel)); + rpix = reallocarray(pmap->clientPixelsRed[client], + pmap->numPixelsRed[client] + (c << r), + sizeof(Pixel)); if (rpix) pmap->clientPixelsRed[client] = rpix; - gpix = (Pixel *) realloc(pmap->clientPixelsGreen[client], - (pmap->numPixelsGreen[client] + (c << g)) * - sizeof(Pixel)); + gpix = reallocarray(pmap->clientPixelsGreen[client], + pmap->numPixelsGreen[client] + (c << g), + sizeof(Pixel)); if (gpix) pmap->clientPixelsGreen[client] = gpix; - bpix = (Pixel *) realloc(pmap->clientPixelsBlue[client], - (pmap->numPixelsBlue[client] + (c << b)) * - sizeof(Pixel)); + bpix = reallocarray(pmap->clientPixelsBlue[client], + pmap->numPixelsBlue[client] + (c << b), + sizeof(Pixel)); if (bpix) pmap->clientPixelsBlue[client] = bpix; } @@ -1747,7 +1747,7 @@ AllocPseudo(int client, ColormapPtr pmap, int c, int r, Bool contig, npix = c << r; if ((r >= 32) || (npix > pmap->freeRed) || (npix < c)) return BadAlloc; - if (!(ppixTemp = malloc(npix * sizeof(Pixel)))) + if (!(ppixTemp = xallocarray(npix, sizeof(Pixel)))) return BadAlloc; ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask); @@ -1755,9 +1755,8 @@ AllocPseudo(int client, ColormapPtr pmap, int c, int r, Bool contig, /* all the allocated pixels are added to the client pixel list, * but only the unique ones are returned to the client */ - ppix = (Pixel *) realloc(pmap->clientPixelsRed[client], - (pmap->numPixelsRed[client] + - npix) * sizeof(Pixel)); + ppix = reallocarray(pmap->clientPixelsRed[client], + pmap->numPixelsRed[client] + npix, sizeof(Pixel)); if (!ppix) { for (p = ppixTemp; p < ppixTemp + npix; p++) pmap->red[*p].refcnt = 0; @@ -1960,7 +1959,7 @@ AllocShared(ColormapPtr pmap, Pixel * ppix, int c, int r, int g, int b, npixClientNew = c << (r + g + b); npixShared = (c << r) + (c << g) + (c << b); - psharedList = malloc(npixShared * sizeof(SHAREDCOLOR *)); + psharedList = xallocarray(npixShared, sizeof(SHAREDCOLOR *)); if (!psharedList) return FALSE; ppshared = psharedList; @@ -2204,7 +2203,7 @@ FreeCo(ColormapPtr pmap, int client, int color, int npixIn, Pixel * ppixIn, npix++; } } - pptr = (Pixel *) realloc(ppixClient, npixNew * sizeof(Pixel)); + pptr = reallocarray(ppixClient, npixNew, sizeof(Pixel)); if (pptr) ppixClient = pptr; npixClient = npixNew; @@ -2469,8 +2468,8 @@ IsMapInstalled(Colormap map, WindowPtr pWin) Colormap *pmaps; int imap, nummaps, found; - pmaps = - malloc(pWin->drawable.pScreen->maxInstalledCmaps * sizeof(Colormap)); + pmaps = xallocarray(pWin->drawable.pScreen->maxInstalledCmaps, + sizeof(Colormap)); if (!pmaps) return FALSE; nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) @@ -2521,8 +2520,8 @@ ResizeVisualArray(ScreenPtr pScreen, int new_visual_count, DepthPtr depth) first_new_vid = depth->numVids; first_new_visual = pScreen->numVisuals; - vids = - realloc(depth->vids, (depth->numVids + new_visual_count) * sizeof(XID)); + vids = reallocarray(depth->vids, depth->numVids + new_visual_count, + sizeof(XID)); if (!vids) return FALSE; @@ -2530,7 +2529,7 @@ ResizeVisualArray(ScreenPtr pScreen, int new_visual_count, DepthPtr depth) depth->vids = vids; numVisuals = pScreen->numVisuals + new_visual_count; - visuals = realloc(pScreen->visuals, numVisuals * sizeof(VisualRec)); + visuals = reallocarray(pScreen->visuals, numVisuals, sizeof(VisualRec)); if (!visuals) { return FALSE; } diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c index d8e7f9c40..1f8dabddd 100644 --- a/xorg-server/dix/devices.c +++ b/xorg-server/dix/devices.c @@ -177,6 +177,9 @@ DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, if (!isfinite(f[i])) return BadValue; + if (!dev->valuator) + return BadMatch; + if (!checkonly) DeviceSetTransform(dev, f); } @@ -1469,8 +1472,8 @@ InitStringFeedbackClassDeviceStruct(DeviceIntPtr dev, feedc->ctrl.num_symbols_displayed = 0; feedc->ctrl.max_symbols = max_symbols; feedc->ctrl.symbols_supported = - malloc(sizeof(KeySym) * num_symbols_supported); - feedc->ctrl.symbols_displayed = malloc(sizeof(KeySym) * max_symbols); + xallocarray(num_symbols_supported, sizeof(KeySym)); + feedc->ctrl.symbols_displayed = xallocarray(max_symbols, sizeof(KeySym)); if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed) { free(feedc->ctrl.symbols_supported); free(feedc->ctrl.symbols_displayed); diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c index 17fa75e19..9208582a6 100644 --- a/xorg-server/dix/dispatch.c +++ b/xorg-server/dix/dispatch.c @@ -344,7 +344,7 @@ Dispatch(void) nextFreeClientID = 1; nClients = 0; - clientReady = malloc(sizeof(int) * MaxClients); + clientReady = xallocarray(MaxClients, sizeof(int)); if (!clientReady) return; @@ -963,7 +963,7 @@ ProcQueryTree(ClientPtr client) if (numChildren) { int curChild = 0; - childIDs = malloc(numChildren * sizeof(Window)); + childIDs = xallocarray(numChildren, sizeof(Window)); if (!childIDs) return BadAlloc; for (pChild = pWin->lastChild; pChild != pHead; @@ -2786,7 +2786,7 @@ ProcQueryColors(ClientPtr client) count = bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq)); - prgbs = calloc(1, count * sizeof(xrgb)); + prgbs = calloc(count, sizeof(xrgb)); if (!prgbs && count) return BadAlloc; if ((rc = @@ -2908,10 +2908,10 @@ ProcCreateCursor(ClientPtr client) if (stuff->x > width || stuff->y > height) return BadMatch; - n = BitmapBytePad(width) * height; - srcbits = calloc(1, n); + srcbits = calloc(BitmapBytePad(width), height); if (!srcbits) return BadAlloc; + n = BitmapBytePad(width) * height; mskbits = malloc(n); if (!mskbits) { free(srcbits); diff --git a/xorg-server/dix/dixfonts.c b/xorg-server/dix/dixfonts.c index bc2732fb9..be389e82f 100644 --- a/xorg-server/dix/dixfonts.c +++ b/xorg-server/dix/dixfonts.c @@ -168,9 +168,8 @@ QueueFontWakeup(FontPathElementPtr fpe) } } if (num_slept_fpes == size_slept_fpes) { - new = (FontPathElementPtr *) - realloc(slept_fpes, - sizeof(FontPathElementPtr) * (size_slept_fpes + 4)); + new = reallocarray(slept_fpes, size_slept_fpes + 4, + sizeof(FontPathElementPtr)); if (!new) return; slept_fpes = new; @@ -424,7 +423,7 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, * copy the current FPE list, so that if it gets changed by another client * while we're blocking, the request still appears atomic */ - c->fpe_list = malloc(sizeof(FontPathElementPtr) * num_fpes); + c->fpe_list = xallocarray(num_fpes, sizeof(FontPathElementPtr)); if (!c->fpe_list) { free((void *) c->fontname); free(c); @@ -821,7 +820,7 @@ ListFonts(ClientPtr client, unsigned char *pattern, unsigned length, if (!(c = malloc(sizeof *c))) return BadAlloc; - c->fpe_list = malloc(sizeof(FontPathElementPtr) * num_fpes); + c->fpe_list = xallocarray(num_fpes, sizeof(FontPathElementPtr)); if (!c->fpe_list) { free(c); return BadAlloc; @@ -1072,7 +1071,7 @@ StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern, if (!(c = malloc(sizeof *c))) goto badAlloc; - c->fpe_list = malloc(sizeof(FontPathElementPtr) * num_fpes); + c->fpe_list = xallocarray(num_fpes, sizeof(FontPathElementPtr)); if (!c->fpe_list) { free(c); goto badAlloc; @@ -1441,7 +1440,7 @@ doImageText(ClientPtr client, ITclosurePtr c) *new_closure = *c; c = new_closure; - data = malloc(c->nChars * itemSize); + data = xallocarray(c->nChars, itemSize); if (!data) { free(c); c = old_closure; @@ -1597,7 +1596,7 @@ SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist) unsigned char *cp = paths; FontPathElementPtr fpe = NULL, *fplist; - fplist = malloc(sizeof(FontPathElementPtr) * npaths); + fplist = xallocarray(npaths, sizeof(FontPathElementPtr)); if (!fplist) { *bad = 0; return BadAlloc; @@ -1894,8 +1893,7 @@ RegisterFPEFunctions(NameCheckFunc name_func, FPEFunctions *new; /* grow the list */ - new = (FPEFunctions *) realloc(fpe_functions, - (num_fpe_types + 1) * sizeof(FPEFunctions)); + new = reallocarray(fpe_functions, num_fpe_types + 1, sizeof(FPEFunctions)); if (!new) return -1; fpe_functions = new; diff --git a/xorg-server/dix/enterleave.c b/xorg-server/dix/enterleave.c index 54f4b8554..7f1f94165 100644 --- a/xorg-server/dix/enterleave.c +++ b/xorg-server/dix/enterleave.c @@ -714,7 +714,7 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) } } - sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); + sev = ev = xallocarray(evcount, sizeof(xEvent)); FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); if (b != NULL) { diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c index c232ebadc..efaf91d2b 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -1057,6 +1057,7 @@ MonthChangedOrBadTime(CARD32 *ms) void NoticeTime(const DeviceIntPtr dev, TimeStamp time) { + currentTime = time; lastDeviceEventTime[XIAllDevices].time = currentTime; lastDeviceEventTime[dev->id].time = currentTime; @@ -4785,8 +4786,8 @@ SetInputFocus(ClientPtr client, depth++; if (depth > focus->traceSize) { focus->traceSize = depth + 1; - focus->trace = realloc(focus->trace, - focus->traceSize * sizeof(WindowPtr)); + focus->trace = reallocarray(focus->trace, focus->traceSize, + sizeof(WindowPtr)); } focus->traceGood = depth; for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--) diff --git a/xorg-server/dix/extension.c b/xorg-server/dix/extension.c index 56e3abc14..e81f673b2 100644 --- a/xorg-server/dix/extension.c +++ b/xorg-server/dix/extension.c @@ -103,8 +103,7 @@ AddExtension(const char *name, int NumEvents, int NumErrors, return ((ExtensionEntry *) NULL); } i = NumExtensions; - newexts = (ExtensionEntry **) realloc(extensions, - (i + 1) * sizeof(ExtensionEntry *)); + newexts = reallocarray(extensions, i + 1, sizeof(ExtensionEntry *)); if (!newexts) { free((void *) ext->name); dixFreePrivates(ext->devPrivates, PRIVATE_EXTENSION); @@ -153,8 +152,7 @@ AddExtensionAlias(const char *alias, ExtensionEntry * ext) if (!ext) return FALSE; - aliases = realloc(ext->aliases, - (ext->num_aliases + 1) * sizeof(char *)); + aliases = reallocarray(ext->aliases, ext->num_aliases + 1, sizeof(char *)); if (!aliases) return FALSE; ext->aliases = aliases; diff --git a/xorg-server/dix/glyphcurs.c b/xorg-server/dix/glyphcurs.c index eca6a4cb8..3ff6ae83e 100644 --- a/xorg-server/dix/glyphcurs.c +++ b/xorg-server/dix/glyphcurs.c @@ -78,7 +78,6 @@ ServerBitsFromGlyph(FontPtr pfont, unsigned ch, CursorMetricPtr cm, GCPtr pGC; xRectangle rect; PixmapPtr ppix; - long nby; char *pbits; ChangeGCVal gcval[3]; unsigned char char2b[2]; @@ -88,8 +87,7 @@ ServerBitsFromGlyph(FontPtr pfont, unsigned ch, CursorMetricPtr cm, char2b[1] = (unsigned char) (ch & 0xff); pScreen = screenInfo.screens[0]; - nby = BitmapBytePad(cm->width) * (long) cm->height; - pbits = calloc(1, nby); + pbits = calloc(BitmapBytePad(cm->width), cm->height); if (!pbits) return BadAlloc; diff --git a/xorg-server/dix/grabs.c b/xorg-server/dix/grabs.c index b92f1e7ce..2a307a2b9 100644 --- a/xorg-server/dix/grabs.c +++ b/xorg-server/dix/grabs.c @@ -594,10 +594,10 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab) i++; if (!i) return TRUE; - deletes = malloc(i * sizeof(GrabPtr)); - adds = malloc(i * sizeof(GrabPtr)); - updates = malloc(i * sizeof(Mask **)); - details = malloc(i * sizeof(Mask *)); + deletes = xallocarray(i, sizeof(GrabPtr)); + adds = xallocarray(i, sizeof(GrabPtr)); + updates = xallocarray(i, sizeof(Mask **)); + details = xallocarray(i, sizeof(Mask *)); if (!deletes || !adds || !updates || !details) { free(details); free(updates); diff --git a/xorg-server/dix/property.c b/xorg-server/dix/property.c index ff7f31aa9..99608af72 100644 --- a/xorg-server/dix/property.c +++ b/xorg-server/dix/property.c @@ -136,8 +136,8 @@ ProcRotateProperties(ClientPtr client) return rc; atoms = (Atom *) &stuff[1]; - props = malloc(stuff->nAtoms * sizeof(PropertyPtr)); - saved = malloc(stuff->nAtoms * sizeof(PropertyRec)); + props = xallocarray(stuff->nAtoms, sizeof(PropertyPtr)); + saved = xallocarray(stuff->nAtoms, sizeof(PropertyRec)); if (!props || !saved) { rc = BadAlloc; goto out; @@ -313,7 +313,7 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, /* do nothing */ } else if (mode == PropModeAppend) { - data = malloc((pProp->size + len) * sizeInBytes); + data = xallocarray(pProp->size + len, sizeInBytes); if (!data) return BadAlloc; memcpy(data, pProp->data, pProp->size * sizeInBytes); @@ -322,7 +322,7 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, pProp->size += len; } else if (mode == PropModePrepend) { - data = malloc(sizeInBytes * (len + pProp->size)); + data = xallocarray(len + pProp->size, sizeInBytes); if (!data) return BadAlloc; memcpy(data + totalSize, pProp->data, pProp->size * sizeInBytes); @@ -581,7 +581,7 @@ ProcListProperties(ClientPtr client) for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) numProps++; - if (numProps && !(pAtoms = malloc(numProps * sizeof(Atom)))) + if (numProps && !(pAtoms = xallocarray(numProps, sizeof(Atom)))) return BadAlloc; numProps = 0; diff --git a/xorg-server/dix/region.c b/xorg-server/dix/region.c index 04e590170..fd7313990 100644 --- a/xorg-server/dix/region.c +++ b/xorg-server/dix/region.c @@ -1247,7 +1247,7 @@ RegionValidate(RegionPtr badreg, Bool *pOverlap) if (sizeRI == numRI) { /* Oops, allocate space for new region information */ sizeRI <<= 1; - rit = (RegionInfo *) realloc(ri, sizeRI * sizeof(RegionInfo)); + rit = (RegionInfo *) reallocarray(ri, sizeRI, sizeof(RegionInfo)); if (!rit) goto bail; ri = rit; diff --git a/xorg-server/dix/resource.c b/xorg-server/dix/resource.c index 964f0b306..af8e162bb 100644 --- a/xorg-server/dix/resource.c +++ b/xorg-server/dix/resource.c @@ -510,7 +510,7 @@ CreateNewResourceType(DeleteType deleteFunc, const char *name) if (next & lastResourceClass) return 0; - types = realloc(resourceTypes, (next + 1) * sizeof(*resourceTypes)); + types = reallocarray(resourceTypes, next + 1, sizeof(*resourceTypes)); if (!types) return 0; @@ -834,10 +834,10 @@ RebuildTable(int client) */ j = 2 * clientTable[client].buckets; - tails = malloc(j * sizeof(ResourcePtr *)); + tails = xallocarray(j, sizeof(ResourcePtr *)); if (!tails) return; - resources = malloc(j * sizeof(ResourcePtr)); + resources = xallocarray(j, sizeof(ResourcePtr)); if (!resources) { free(tails); return; diff --git a/xorg-server/dix/touch.c b/xorg-server/dix/touch.c index 1eeed78bd..49d16ab37 100644 --- a/xorg-server/dix/touch.c +++ b/xorg-server/dix/touch.c @@ -101,7 +101,7 @@ TouchResizeQueue(ClientPtr client, void *closure) * don't need to do it often */ size = dev->last.num_touches + dev->last.num_touches / 2 + 1; - tmp = realloc(dev->last.touches, size * sizeof(*dev->last.touches)); + tmp = reallocarray(dev->last.touches, size, sizeof(*dev->last.touches)); if (tmp) { int j; @@ -350,7 +350,7 @@ TouchBeginTouch(DeviceIntPtr dev, int sourceid, uint32_t touchid, /* If we get here, then we've run out of touches: enlarge dev->touch and * try again. */ - tmp = realloc(t->touches, (t->num_touches + 1) * sizeof(*ti)); + tmp = reallocarray(t->touches, t->num_touches + 1, sizeof(*ti)); if (tmp) { t->touches = tmp; t->num_touches++; @@ -547,8 +547,8 @@ TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite) return FALSE; if (srcsprite->spriteTraceGood > sprite->spriteTraceSize) { - trace = realloc(sprite->spriteTrace, - srcsprite->spriteTraceSize * sizeof(*trace)); + trace = reallocarray(sprite->spriteTrace, + srcsprite->spriteTraceSize, sizeof(*trace)); if (!trace) { sprite->spriteTraceGood = 0; return FALSE; diff --git a/xorg-server/doc/Xserver-spec.xml b/xorg-server/doc/Xserver-spec.xml index 4c344194d..72a544b55 100644 --- a/xorg-server/doc/Xserver-spec.xml +++ b/xorg-server/doc/Xserver-spec.xml @@ -1992,7 +1992,7 @@ regions, these blocks may need to be reallocated by your region software. For instance, in the sample server, a RegionRec has some header information and a pointer to a dynamically allocated rectangle list. Periodically, the rectangle list needs to be expanded with -Xrealloc(), whereupon the new pointer is remembered in the RegionRec.</para> +realloc(), whereupon the new pointer is remembered in the RegionRec.</para> <para> Most of the region operations come in two forms: a function pointer in the Screen structure, and a macro. The server can be compiled so that @@ -2598,7 +2598,7 @@ VisualRec data structure along with other display characteristics like the depth and other numbers.</para> <para> The allowable DepthRec's and VisualRec's are pointed to by fields in the ScreenRec. -These are set up when InitOutput() is called; you should Xalloc() appropriate blocks +These are set up when InitOutput() is called; you should malloc() appropriate blocks or use static variables initialized to the correct values.</para> </section> <section> @@ -3897,7 +3897,7 @@ for CT_NONE, etc. are in Xserver/include/gc.h.) This routine is responsible for incrementing any necessary reference counts (e.g. for a pixmap clip mask) for the new clipmask and freeing anything that used to be in the GC's clipMask field. The lists of rectangles passed -in can be freed with Xfree(), the regions can be destroyed with the +in can be freed with free(), the regions can be destroyed with the RegionDestroy field in the screen, and pixmaps can be destroyed by calling the screen's DestroyPixmap function. DIX and MI code expect what they pass in to this to be freed or otherwise inaccessible, and @@ -5104,9 +5104,6 @@ mi and fb implementations.</para> <row><entry><function>WaitForSomething</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row> <row><entry><function>WindowExposures</function></entry><entry><literal>mi</literal></entry><entry><para>Window</para></entry></row> <row><entry><function>WriteToClient</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row> -<row><entry><function>Xalloc</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row> -<row><entry><function>Xfree</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row> -<row><entry><function>Xrealloc</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row> </tbody> </tgroup> </table> diff --git a/xorg-server/exa/exa_accel.c b/xorg-server/exa/exa_accel.c index 5aa7d1078..b26d5c804 100644 --- a/xorg-server/exa/exa_accel.c +++ b/xorg-server/exa/exa_accel.c @@ -386,7 +386,7 @@ exaHWCopyNtoN(DrawablePtr pSrcDrawable, exaGetDrawableDeltas(pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y); exaGetDrawableDeltas(pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y); - rects = malloc(nbox * sizeof(xRectangle)); + rects = xallocarray(nbox, sizeof(xRectangle)); if (rects) { int i; @@ -626,7 +626,7 @@ exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, return; } - prect = malloc(sizeof(xRectangle) * npt); + prect = xallocarray(npt, sizeof(xRectangle)); for (i = 0; i < npt; i++) { prect[i].x = ppt[i].x; prect[i].y = ppt[i].y; @@ -667,7 +667,7 @@ exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, return; } - prect = malloc(sizeof(xRectangle) * (npt - 1)); + prect = xallocarray(npt - 1, sizeof(xRectangle)); x1 = ppt[0].x; y1 = ppt[0].y; /* If we have any non-horizontal/vertical, fall back. */ @@ -738,7 +738,7 @@ exaPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSeg) } } - prect = malloc(sizeof(xRectangle) * nseg); + prect = xallocarray(nseg, sizeof(xRectangle)); for (i = 0; i < nseg; i++) { if (pSeg[i].x1 < pSeg[i].x2) { prect[i].x = pSeg[i].x1; diff --git a/xorg-server/exa/exa_glyphs.c b/xorg-server/exa/exa_glyphs.c index 41f3694f2..cf21ea914 100644 --- a/xorg-server/exa/exa_glyphs.c +++ b/xorg-server/exa/exa_glyphs.c @@ -211,8 +211,8 @@ exaRealizeGlyphCaches(ScreenPtr pScreen, unsigned int format) cache->picture = pPicture; cache->picture->refcnt++; - cache->hashEntries = malloc(sizeof(int) * cache->hashSize); - cache->glyphs = malloc(sizeof(ExaCachedGlyphRec) * cache->size); + cache->hashEntries = xallocarray(cache->hashSize, sizeof(int)); + cache->glyphs = xallocarray(cache->size, sizeof(ExaCachedGlyphRec)); cache->glyphCount = 0; if (!cache->hashEntries || !cache->glyphs) diff --git a/xorg-server/exa/exa_migration_mixed.c b/xorg-server/exa/exa_migration_mixed.c index cf66327b3..7d3fca7c0 100644 --- a/xorg-server/exa/exa_migration_mixed.c +++ b/xorg-server/exa/exa_migration_mixed.c @@ -205,8 +205,8 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg) /* Do we need to allocate our system buffer? */ if (!pExaPixmap->sys_ptr) { - pExaPixmap->sys_ptr = malloc(pExaPixmap->sys_pitch * - pPixmap->drawable.height); + pExaPixmap->sys_ptr = xallocarray(pExaPixmap->sys_pitch, + pPixmap->drawable.height); if (!pExaPixmap->sys_ptr) FatalError("EXA: malloc failed for size %d bytes\n", pExaPixmap->sys_pitch * pPixmap->drawable.height); diff --git a/xorg-server/fb/fbcopy.c b/xorg-server/fb/fbcopy.c index 5bbabc39f..6af10ccf7 100644 --- a/xorg-server/fb/fbcopy.c +++ b/xorg-server/fb/fbcopy.c @@ -194,7 +194,7 @@ fbCopyNto1(DrawablePtr pSrcDrawable, height = pbox->y2 - pbox->y1; tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT); - tmp = malloc(tmpStride * height * sizeof(FbStip)); + tmp = xallocarray(tmpStride * height, sizeof(FbStip)); if (!tmp) return; diff --git a/xorg-server/fb/fbpict.c b/xorg-server/fb/fbpict.c index c8378ad90..021f17883 100644 --- a/xorg-server/fb/fbpict.c +++ b/xorg-server/fb/fbpict.c @@ -124,7 +124,7 @@ fbGlyphs(CARD8 op, pixman_glyph_cache_freeze (glyphCache); if (n_glyphs > N_STACK_GLYPHS) { - if (!(pglyphs = malloc (n_glyphs * sizeof (pixman_glyph_t)))) + if (!(pglyphs = xallocarray(n_glyphs, sizeof(pixman_glyph_t)))) goto out; } diff --git a/xorg-server/glamor/Makefile.am b/xorg-server/glamor/Makefile.am index db72cb11c..c48802999 100644 --- a/xorg-server/glamor/Makefile.am +++ b/xorg-server/glamor/Makefile.am @@ -14,7 +14,7 @@ libglamor_la_SOURCES = \ glamor_font.c \ glamor_font.h \ glamor_glx.c \ - glamor_glyphs.c \ + glamor_composite_glyphs.c \ glamor_image.c \ glamor_lines.c \ glamor_segs.c \ diff --git a/xorg-server/glamor/glamor.c b/xorg-server/glamor/glamor.c index 6f4f30927..807f28ebd 100644 --- a/xorg-server/glamor/glamor.c +++ b/xorg-server/glamor/glamor.c @@ -1,5 +1,5 @@ /* - * Copyright © 2008 Intel Corporation + * Copyright © 2008,2011 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -23,7 +23,7 @@ * Authors: * Eric Anholt <eric@anholt.net> * Zhigang Gong <zhigang.gong@linux.intel.com> - * + * Chad Versace <chad.versace@linux.intel.com> */ /** @file glamor.c @@ -288,16 +288,6 @@ glamor_create_screen_resources(ScreenPtr screen) ret = screen->CreateScreenResources(screen); screen->CreateScreenResources = glamor_create_screen_resources; - if (!glamor_glyphs_init(screen)) { - ErrorF("Failed to initialize glyphs\n"); - ret = FALSE; - } - - if (!glamor_realize_glyph_caches(screen)) { - ErrorF("Failed to initialize glyph cache\n"); - ret = FALSE; - } - return ret; } @@ -336,7 +326,11 @@ glamor_init(ScreenPtr screen, unsigned int flags) { glamor_screen_private *glamor_priv; int gl_version; + int glsl_major, glsl_minor; int max_viewport_size[2]; + const char *shading_version_string; + int shading_version_offset; + PictureScreenPtr ps = GetPictureScreenIfSet(screen); if (flags & ~GLAMOR_VALID_FLAGS) { @@ -380,14 +374,40 @@ glamor_init(ScreenPtr screen, unsigned int flags) gl_version = epoxy_gl_version(); - /* Would be nice to have a cleaner test for GLSL 1.30 support, - * but for now this should suffice - */ - if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP && gl_version >= 30) - glamor_priv->glsl_version = 130; - else - glamor_priv->glsl_version = 120; + shading_version_string = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION); + + if (!shading_version_string) { + LogMessage(X_WARNING, + "glamor%d: Failed to get GLSL version\n", + screen->myNum); + goto fail; + } + + shading_version_offset = 0; + if (strncmp("OpenGL ES GLSL ES ", shading_version_string, 18) == 0) + shading_version_offset = 18; + if (sscanf(shading_version_string + shading_version_offset, + "%i.%i", + &glsl_major, + &glsl_minor) != 2) { + LogMessage(X_WARNING, + "glamor%d: Failed to parse GLSL version string %s\n", + screen->myNum, shading_version_string); + goto fail; + } + glamor_priv->glsl_version = glsl_major * 100 + glsl_minor; + + if (glamor_priv->gl_flavor == GLAMOR_GL_ES2) { + /* Force us back to the base version of our programs on an ES + * context, anyway. Basically glamor only uses desktop 1.20 + * or 1.30 currently. 1.30's new features are also present in + * ES 3.0, but our glamor_program.c constructions use a lot of + * compatibility features (to reduce the diff between 1.20 and + * 1.30 programs). + */ + glamor_priv->glsl_version = 120; + } /* We'd like to require GL_ARB_map_buffer_range or * GL_OES_map_buffer_range, since it offers more information to @@ -479,6 +499,11 @@ glamor_init(ScreenPtr screen, unsigned int flags) glamor_priv->saved_procs.block_handler = screen->BlockHandler; screen->BlockHandler = _glamor_block_handler; + if (!glamor_composite_glyphs_init(screen)) { + ErrorF("Failed to initialize composite masks\n"); + goto fail; + } + glamor_priv->saved_procs.create_gc = screen->CreateGC; screen->CreateGC = glamor_create_gc; @@ -520,10 +545,7 @@ glamor_init(ScreenPtr screen, unsigned int flags) ps->CompositeRects = miCompositeRects; glamor_priv->saved_procs.glyphs = ps->Glyphs; - ps->Glyphs = glamor_glyphs; - - glamor_priv->saved_procs.unrealize_glyph = ps->UnrealizeGlyph; - ps->UnrealizeGlyph = glamor_glyph_unrealize; + ps->Glyphs = glamor_composite_glyphs; glamor_priv->saved_procs.create_picture = ps->CreatePicture; ps->CreatePicture = glamor_create_picture; @@ -604,7 +626,7 @@ glamor_close_screen(ScreenPtr screen) glamor_priv = glamor_get_screen_private(screen); glamor_sync_close(screen); - glamor_glyphs_fini(screen); + glamor_composite_glyphs_fini(screen); screen->CloseScreen = glamor_priv->saved_procs.close_screen; screen->CreateScreenResources = glamor_priv->saved_procs.create_screen_resources; @@ -625,7 +647,6 @@ glamor_close_screen(ScreenPtr screen) ps->CreatePicture = glamor_priv->saved_procs.create_picture; ps->CompositeRects = glamor_priv->saved_procs.composite_rects; ps->Glyphs = glamor_priv->saved_procs.glyphs; - ps->UnrealizeGlyph = glamor_priv->saved_procs.unrealize_glyph; screen->SetWindowPixmap = glamor_priv->saved_procs.set_window_pixmap; screen_pixmap = screen->GetScreenPixmap(screen); diff --git a/xorg-server/glamor/glamor.h b/xorg-server/glamor/glamor.h index d07182d9e..0d57fff88 100644 --- a/xorg-server/glamor/glamor.h +++ b/xorg-server/glamor/glamor.h @@ -105,8 +105,6 @@ extern _X_EXPORT void glamor_set_screen_pixmap(PixmapPtr screen_pixmap, extern _X_EXPORT uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap); -extern _X_EXPORT Bool glamor_glyphs_init(ScreenPtr pScreen); - extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex); diff --git a/xorg-server/glamor/glamor_composite_glyphs.c b/xorg-server/glamor/glamor_composite_glyphs.c new file mode 100644 index 000000000..39ed854bc --- /dev/null +++ b/xorg-server/glamor/glamor_composite_glyphs.c @@ -0,0 +1,551 @@ +/* + * Copyright © 2014 Keith Packard + * + * 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 not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make 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. + */ +#include <stdlib.h> +#include "Xprintf.h" + +#include "glamor_priv.h" +#include "glamor_transform.h" +#include "glamor_transfer.h" + +#include <mipict.h> + +#define DEFAULT_ATLAS_DIM 1024 + +static DevPrivateKeyRec glamor_glyph_private_key; + +struct glamor_glyph_private { + int16_t x; + int16_t y; + uint32_t serial; +}; + +struct glamor_glyph_atlas { + PixmapPtr atlas; + PictFormatPtr format; + int x, y; + int row_height; + int nglyph; + uint32_t serial; +}; + +static inline struct glamor_glyph_private *glamor_get_glyph_private(PixmapPtr pixmap) { + return dixLookupPrivate(&pixmap->devPrivates, &glamor_glyph_private_key); +} + +static inline void +glamor_copy_glyph(PixmapPtr glyph_pixmap, + DrawablePtr atlas_draw, + int16_t x, + int16_t y) +{ + DrawablePtr glyph_draw = &glyph_pixmap->drawable; + BoxRec box = { + .x1 = 0, + .y1 = 0, + .x2 = glyph_draw->width, + .y2 = glyph_draw->height, + }; + + if (glyph_pixmap->drawable.bitsPerPixel == atlas_draw->bitsPerPixel) { + glamor_upload_boxes((PixmapPtr) atlas_draw, + &box, 1, + 0, 0, + x, y, + glyph_pixmap->devPrivate.ptr, + glyph_pixmap->devKind); + } else { + GCPtr scratch_gc = GetScratchGC(atlas_draw->depth, atlas_draw->pScreen); + ChangeGCVal changes[2]; + if (!scratch_gc) + return; + + /* If we're dealing with 1-bit glyphs, we upload them to + * the cache as normal 8-bit alpha, since that's what GL + * can handle. + */ + assert(glyph_draw->depth == 1); + assert(atlas_draw->depth == 8); + + changes[0].val = 0xff; + changes[1].val = 0x00; + if (ChangeGC(NullClient, scratch_gc, + GCForeground|GCBackground, changes) != Success) + goto bail_gc; + ValidateGC(atlas_draw, scratch_gc); + + (*scratch_gc->ops->CopyPlane)(glyph_draw, + atlas_draw, + scratch_gc, + 0, 0, + glyph_draw->width, + glyph_draw->height, + x, y, 0x1); + + bail_gc: + FreeScratchGC(scratch_gc); + } +} + +static Bool +glamor_glyph_atlas_init(ScreenPtr screen, struct glamor_glyph_atlas *atlas) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + PictFormatPtr format = atlas->format; + + atlas->atlas = glamor_create_pixmap(screen, glamor_priv->glyph_atlas_dim, + glamor_priv->glyph_atlas_dim, format->depth, 0); + atlas->x = 0; + atlas->y = 0; + atlas->row_height = 0; + atlas->serial++; + atlas->nglyph = 0; + return TRUE; +} + +static Bool +glamor_glyph_can_add(struct glamor_glyph_atlas *atlas, int dim, DrawablePtr glyph_draw) +{ + /* Step down */ + if (atlas->x + glyph_draw->width > dim) { + atlas->x = 0; + atlas->y += atlas->row_height; + atlas->row_height = 0; + } + + /* Check for overfull */ + if (atlas->y + glyph_draw->height > dim) + return FALSE; + + return TRUE; +} + +static Bool +glamor_glyph_add(struct glamor_glyph_atlas *atlas, DrawablePtr glyph_draw) +{ + PixmapPtr glyph_pixmap = (PixmapPtr) glyph_draw; + struct glamor_glyph_private *glyph_priv = glamor_get_glyph_private(glyph_pixmap); + + glamor_copy_glyph(glyph_pixmap, &atlas->atlas->drawable, atlas->x, atlas->y); + + glyph_priv->x = atlas->x; + glyph_priv->y = atlas->y; + glyph_priv->serial = atlas->serial; + + atlas->x += glyph_draw->width; + if (atlas->row_height < glyph_draw->height) + atlas->row_height = glyph_draw->height; + + atlas->nglyph++; + + return TRUE; +} + +static const glamor_facet glamor_facet_composite_glyphs_130 = { + .name = "composite_glyphs", + .version = 130, + .vs_vars = ("attribute vec4 primitive;\n" + "attribute vec2 source;\n" + "varying vec2 glyph_pos;\n"), + .vs_exec = (" vec2 pos = primitive.zw * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n" + GLAMOR_POS(gl_Position, (primitive.xy + pos)) + " glyph_pos = (source + pos) * ATLAS_DIM_INV;\n"), + .fs_vars = ("varying vec2 glyph_pos;\n"), + .fs_exec = (" vec4 mask = texture2D(atlas, glyph_pos);\n"), + .source_name = "source", + .locations = glamor_program_location_atlas, +}; + +static const glamor_facet glamor_facet_composite_glyphs_120 = { + .name = "composite_glyphs", + .vs_vars = ("attribute vec2 primitive;\n" + "attribute vec2 source;\n" + "varying vec2 glyph_pos;\n"), + .vs_exec = (GLAMOR_POS(gl_Position, primitive) + " glyph_pos = source.xy * ATLAS_DIM_INV;\n"), + .fs_vars = ("varying vec2 glyph_pos;\n"), + .fs_exec = (" vec4 mask = texture2D(atlas, glyph_pos);\n"), + .source_name = "source", + .locations = glamor_program_location_atlas, +}; + +static inline Bool +glamor_glyph_use_130(glamor_screen_private *glamor_priv) { + return glamor_priv->glsl_version >= 130; +} + +static Bool +glamor_glyphs_init_facet(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + return asprintf(&glamor_priv->glyph_defines, "#define ATLAS_DIM_INV %20.18f\n", 1.0/glamor_priv->glyph_atlas_dim) > 0; +} + +static void +glamor_glyphs_fini_facet(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + free(glamor_priv->glyph_defines); +} + +static void +glamor_glyphs_flush(CARD8 op, PicturePtr src, PicturePtr dst, + glamor_program *prog, + struct glamor_glyph_atlas *atlas, int nglyph) +{ + DrawablePtr drawable = dst->pDrawable; + glamor_screen_private *glamor_priv = glamor_get_screen_private(drawable->pScreen); + PixmapPtr atlas_pixmap = atlas->atlas; + glamor_pixmap_private *atlas_priv = glamor_get_pixmap_private(atlas_pixmap); + glamor_pixmap_fbo *atlas_fbo = glamor_pixmap_fbo_at(atlas_priv, 0, 0); + PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); + glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); + int box_x, box_y; + int off_x, off_y; + + glamor_put_vbo_space(drawable->pScreen); + + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, atlas_fbo->tex); + + for (;;) { + if (!glamor_use_program_render(prog, op, src, dst)) + break; + + glUniform1i(prog->atlas_uniform, 1); + + glamor_pixmap_loop(pixmap_priv, box_x, box_y) { + BoxPtr box = RegionRects(dst->pCompositeClip); + int nbox = RegionNumRects(dst->pCompositeClip); + + glamor_set_destination_drawable(drawable, box_x, box_y, TRUE, FALSE, prog->matrix_uniform, &off_x, &off_y); + + /* Run over the clip list, drawing the glyphs + * in each box + */ + + while (nbox--) { + glScissor(box->x1 + off_x, + box->y1 + off_y, + box->x2 - box->x1, + box->y2 - box->y1); + box++; + + if (glamor_glyph_use_130(glamor_priv)) + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, nglyph); + else + glamor_glDrawArrays_GL_QUADS(glamor_priv, nglyph * 4); + } + } + if (prog->alpha != glamor_program_alpha_ca_first) + break; + prog++; + } + + glDisable(GL_SCISSOR_TEST); + + glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 0); + glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0); + glDisableVertexAttribArray(GLAMOR_VERTEX_POS); + glDisable(GL_BLEND); +} + +static GLshort * +glamor_glyph_start(ScreenPtr screen, int count) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + GLshort *v; + char *vbo_offset; + + /* Set up the vertex buffers for the font and destination */ + + if (glamor_glyph_use_130(glamor_priv)) { + v = glamor_get_vbo_space(screen, count * (6 * sizeof (GLshort)), &vbo_offset); + + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribDivisor(GLAMOR_VERTEX_POS, 1); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 4, GL_SHORT, GL_FALSE, + 6 * sizeof (GLshort), vbo_offset); + + glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + glVertexAttribDivisor(GLAMOR_VERTEX_SOURCE, 1); + glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_SHORT, GL_FALSE, + 6 * sizeof (GLshort), vbo_offset + 4 * sizeof (GLshort)); + } else { + v = glamor_get_vbo_space(screen, count * (16 * sizeof (GLshort)), &vbo_offset); + + glEnableVertexAttribArray(GLAMOR_VERTEX_POS); + glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_SHORT, GL_FALSE, + 4 * sizeof (GLshort), vbo_offset); + + glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); + glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_SHORT, GL_FALSE, + 4 * sizeof (GLshort), vbo_offset + 2 * sizeof (GLshort)); + } + return v; +} + +static inline struct glamor_glyph_atlas * +glamor_atlas_for_glyph(glamor_screen_private *glamor_priv, DrawablePtr drawable) +{ + if (drawable->depth == 32) + return glamor_priv->glyph_atlas_argb; + else + return glamor_priv->glyph_atlas_a; +} + +void +glamor_composite_glyphs(CARD8 op, + PicturePtr src, + PicturePtr dst, + PictFormatPtr glyph_format, + INT16 x_src, + INT16 y_src, int nlist, GlyphListPtr list, + GlyphPtr *glyphs) +{ + int glyphs_queued; + GLshort *v = NULL; + DrawablePtr drawable = dst->pDrawable; + ScreenPtr screen = drawable->pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_program *prog = NULL; + PicturePtr glyph_pict = NULL; + DrawablePtr glyph_draw; + glamor_program_render *glyphs_program = &glamor_priv->glyphs_program; + struct glamor_glyph_atlas *glyph_atlas = NULL; + int x = 0, y = 0; + int n; + int glyph_atlas_dim = glamor_priv->glyph_atlas_dim; + int glyph_max_dim = glamor_priv->glyph_max_dim; + int nglyph = 0; + int screen_num = screen->myNum; + + for (n = 0; n < nlist; n++) + nglyph += list[n].len; + + glamor_make_current(glamor_priv); + + glyphs_queued = 0; + + while (nlist--) { + x += list->xOff; + y += list->yOff; + n = list->len; + list++; + while (n--) { + GlyphPtr glyph = *glyphs++; + + /* Glyph not empty? + */ + if (glyph->info.width && glyph->info.height) { + glamor_pixmap_private *glyph_pix_priv; + + glyph_pict = GlyphPicture(glyph)[screen_num]; + glyph_draw = glyph_pict->pDrawable; + glyph_pix_priv = glamor_get_pixmap_private((PixmapPtr) glyph_draw); + + /* Need to draw with slow path? + */ + if (_X_UNLIKELY(glyph_draw->width > glyph_max_dim || + glyph_draw->height > glyph_max_dim || + (glyph_pix_priv != 0 && glyph_pix_priv->type != GLAMOR_MEMORY))) + { + if (glyphs_queued) { + glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued); + glyphs_queued = 0; + } + bail_one: + glamor_composite(op, src, glyph_pict, dst, + x_src + (x - glyph->info.x), (y - glyph->info.y), + 0, 0, + x - glyph->info.x, y - glyph->info.y, + glyph_draw->width, glyph_draw->height); + } else { + struct glamor_glyph_private *glyph_priv = glamor_get_glyph_private((PixmapPtr)(glyph_draw)); + struct glamor_glyph_atlas *next_atlas = glamor_atlas_for_glyph(glamor_priv, glyph_draw); + + /* Switching source glyph format? + */ + if (_X_UNLIKELY(next_atlas != glyph_atlas)) { + if (glyphs_queued) { + glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued); + glyphs_queued = 0; + } + glyph_atlas = next_atlas; + } + + /* Glyph not cached in current atlas? + */ + if (_X_UNLIKELY(glyph_priv->serial != glyph_atlas->serial)) { + if (!glamor_glyph_can_add(glyph_atlas, glyph_atlas_dim, glyph_draw)) { + if (glyphs_queued) { + glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued); + glyphs_queued = 0; + } + if (glyph_atlas->atlas) { + (*screen->DestroyPixmap)(glyph_atlas->atlas); + glyph_atlas->atlas = NULL; + } + } + if (!glyph_atlas->atlas) + glamor_glyph_atlas_init(screen, glyph_atlas); + glamor_glyph_add(glyph_atlas, glyph_draw); + } + + /* First glyph in the current atlas? + */ + if (_X_UNLIKELY(glyphs_queued == 0)) { + if (glamor_glyph_use_130(glamor_priv)) + prog = glamor_setup_program_render(op, src, glyph_pict, dst, + glyphs_program, + &glamor_facet_composite_glyphs_130, + glamor_priv->glyph_defines); + else + prog = glamor_setup_program_render(op, src, glyph_pict, dst, + glyphs_program, + &glamor_facet_composite_glyphs_120, + glamor_priv->glyph_defines); + if (!prog) + goto bail_one; + v = glamor_glyph_start(screen, nglyph); + } + + /* Add the glyph + */ + + glyphs_queued++; + if (_X_LIKELY(glamor_glyph_use_130(glamor_priv))) { + v[0] = x - glyph->info.x; + v[1] = y - glyph->info.y; + v[2] = glyph_draw->width; + v[3] = glyph_draw->height; + v[4] = glyph_priv->x; + v[5] = glyph_priv->y; + v += 6; + } else { + v[0] = x - glyph->info.x; + v[1] = y - glyph->info.y; + v[2] = glyph_priv->x; + v[3] = glyph_priv->y; + v += 4; + + v[0] = x - glyph->info.x + glyph_draw->width; + v[1] = y - glyph->info.y; + v[2] = glyph_priv->x + glyph_draw->width; + v[3] = glyph_priv->y; + v += 4; + + v[0] = x - glyph->info.x + glyph_draw->width; + v[1] = y - glyph->info.y + glyph_draw->height; + v[2] = glyph_priv->x + glyph_draw->width; + v[3] = glyph_priv->y + glyph_draw->height; + v += 4; + + v[0] = x - glyph->info.x; + v[1] = y - glyph->info.y + glyph_draw->height; + v[2] = glyph_priv->x; + v[3] = glyph_priv->y + glyph_draw->height; + v += 4; + } + } + } + x += glyph->info.xOff; + y += glyph->info.yOff; + nglyph--; + } + } + + if (glyphs_queued) + glamor_glyphs_flush(op, src, dst, prog, glyph_atlas, glyphs_queued); + + return; +} + +static struct glamor_glyph_atlas * +glamor_alloc_glyph_atlas(ScreenPtr screen, int depth, CARD32 f) +{ + PictFormatPtr format; + struct glamor_glyph_atlas *glyph_atlas; + + format = PictureMatchFormat(screen, depth, f); + if (!format) + return NULL; + glyph_atlas = calloc (1, sizeof (struct glamor_glyph_atlas)); + if (!glyph_atlas) + return NULL; + glyph_atlas->format = format; + glyph_atlas->serial = 1; + + return glyph_atlas; +} + +Bool +glamor_composite_glyphs_init(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + if (!dixRegisterPrivateKey(&glamor_glyph_private_key, PRIVATE_PIXMAP, sizeof (struct glamor_glyph_private))) + return FALSE; + + /* Make glyph atlases of a reasonable size, but no larger than the maximum + * supported by the hardware + */ + glamor_priv->glyph_atlas_dim = MIN(DEFAULT_ATLAS_DIM, glamor_priv->max_fbo_size); + + /* Don't stick huge glyphs in the atlases */ + glamor_priv->glyph_max_dim = glamor_priv->glyph_atlas_dim / 8; + + glamor_priv->glyph_atlas_a = glamor_alloc_glyph_atlas(screen, 8, PICT_a8); + if (!glamor_priv->glyph_atlas_a) + return FALSE; + glamor_priv->glyph_atlas_argb = glamor_alloc_glyph_atlas(screen, 32, PICT_a8r8g8b8); + if (!glamor_priv->glyph_atlas_argb) { + free (glamor_priv->glyph_atlas_a); + return FALSE; + } + if (!glamor_glyphs_init_facet(screen)) + return FALSE; + return TRUE; +} + +static void +glamor_free_glyph_atlas(struct glamor_glyph_atlas *atlas) +{ + if (!atlas) + return; + if (atlas->atlas) + FreePicture(atlas->atlas, 0); + free (atlas); +} + +void +glamor_composite_glyphs_fini(ScreenPtr screen) +{ + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + + glamor_glyphs_fini_facet(screen); + glamor_free_glyph_atlas(glamor_priv->glyph_atlas_a); + glamor_free_glyph_atlas(glamor_priv->glyph_atlas_argb); +} diff --git a/xorg-server/glamor/glamor_compositerects.c b/xorg-server/glamor/glamor_compositerects.c index e188d8a3f..885a6c065 100644 --- a/xorg-server/glamor/glamor_compositerects.c +++ b/xorg-server/glamor/glamor_compositerects.c @@ -57,7 +57,7 @@ _pixman_region_init_clipped_rectangles(pixman_region16_t * region, unsigned int i, j; if (num_rects > ARRAY_SIZE(stack_boxes)) { - boxes = malloc(sizeof(pixman_box16_t) * num_rects); + boxes = xallocarray(num_rects, sizeof(pixman_box16_t)); if (boxes == NULL) return FALSE; } diff --git a/xorg-server/glamor/glamor_copy.c b/xorg-server/glamor/glamor_copy.c index 75fe8a700..028acf239 100644 --- a/xorg-server/glamor/glamor_copy.c +++ b/xorg-server/glamor/glamor_copy.c @@ -53,7 +53,7 @@ static const glamor_facet glamor_facet_copyarea = { .vs_exec = (GLAMOR_POS(gl_Position, primitive.xy) " fill_pos = (fill_offset + primitive.xy) * fill_size_inv;\n"), .fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n", - .locations = glamor_program_location_fill, + .locations = glamor_program_location_fillsamp | glamor_program_location_fillpos, .use = use_copyarea, }; @@ -140,7 +140,7 @@ static const glamor_facet glamor_facet_copyplane = { " gl_FragColor = fg;\n" " else\n" " gl_FragColor = bg;\n"), - .locations = glamor_program_location_fill|glamor_program_location_fg|glamor_program_location_bg|glamor_program_location_bitplane, + .locations = glamor_program_location_fillsamp|glamor_program_location_fillpos|glamor_program_location_fg|glamor_program_location_bg|glamor_program_location_bitplane, .use = use_copyplane, }; @@ -212,7 +212,7 @@ glamor_copy_cpu_fbo(DrawablePtr src, if (gc && gc->alu != GXcopy) goto bail; - if (gc && !glamor_pm_is_solid(dst, gc->planemask)) + if (gc && !glamor_pm_is_solid(gc->depth, gc->planemask)) goto bail; glamor_make_current(glamor_priv); @@ -262,7 +262,7 @@ glamor_copy_fbo_cpu(DrawablePtr src, if (gc && gc->alu != GXcopy) goto bail; - if (gc && !glamor_pm_is_solid(dst, gc->planemask)) + if (gc && !glamor_pm_is_solid(gc->depth, gc->planemask)) goto bail; glamor_make_current(glamor_priv); @@ -319,7 +319,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src, glamor_make_current(glamor_priv); - if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask)) + if (gc && !glamor_set_planemask(gc->depth, gc->planemask)) goto bail_ctx; if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy)) @@ -338,7 +338,7 @@ glamor_copy_fbo_fbo_draw(DrawablePtr src, if (!prog->prog) { if (!glamor_build_program(screen, prog, - copy_facet, NULL)) + copy_facet, NULL, NULL, NULL)) goto bail_ctx; } @@ -419,7 +419,6 @@ glamor_copy_fbo_fbo_temp(DrawablePtr src, { ScreenPtr screen = dst->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); - PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); PixmapPtr tmp_pixmap; BoxRec bounds; int n; @@ -434,7 +433,7 @@ glamor_copy_fbo_fbo_temp(DrawablePtr src, */ glamor_make_current(glamor_priv); - if (gc && !glamor_set_planemask(dst_pixmap, gc->planemask)) + if (gc && !glamor_set_planemask(gc->depth, gc->planemask)) goto bail_ctx; if (!glamor_set_alu(screen, gc ? gc->alu : GXcopy)) diff --git a/xorg-server/glamor/glamor_core.c b/xorg-server/glamor/glamor_core.c index 55174541f..965024e68 100644 --- a/xorg-server/glamor/glamor_core.c +++ b/xorg-server/glamor/glamor_core.c @@ -35,7 +35,7 @@ #include "glamor_priv.h" -const Bool +Bool glamor_get_drawable_location(const DrawablePtr drawable) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); diff --git a/xorg-server/glamor/glamor_dash.c b/xorg-server/glamor/glamor_dash.c index 4281ff0a8..101228e40 100644 --- a/xorg-server/glamor/glamor_dash.c +++ b/xorg-server/glamor/glamor_dash.c @@ -170,7 +170,7 @@ glamor_dash_setup(DrawablePtr drawable, GCPtr gc) if (!prog->prog) { if (!glamor_build_program(screen, prog, &glamor_facet_double_dash_lines, - NULL)) + NULL, NULL, NULL)) goto bail; } diff --git a/xorg-server/glamor/glamor_egl.c b/xorg-server/glamor/glamor_egl.c index 6033780f8..dc5456118 100644 --- a/xorg-server/glamor/glamor_egl.c +++ b/xorg-server/glamor/glamor_egl.c @@ -595,6 +595,7 @@ glamor_egl_close_screen(ScreenPtr screen) return screen->CloseScreen(screen); } +#ifdef DRI3 static int glamor_dri3_open_client(ClientPtr client, ScreenPtr screen, @@ -651,12 +652,12 @@ static dri3_screen_info_rec glamor_dri3_info = { .pixmap_from_fd = glamor_pixmap_from_fd, .fd_from_pixmap = glamor_fd_from_pixmap, }; +#endif /* DRI3 */ void glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); - glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); struct glamor_egl_screen_private *glamor_egl = glamor_egl_get_screen_private(scrn); @@ -668,7 +669,9 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx) glamor_ctx->make_current = glamor_egl_make_current; +#ifdef DRI3 if (glamor_egl->dri3_capable) { + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); /* Tell the core that we have the interfaces for import/export * of pixmaps. */ @@ -691,6 +694,7 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx) } } } +#endif } static void diff --git a/xorg-server/glamor/glamor_glyphs.c b/xorg-server/glamor/glamor_glyphs.c deleted file mode 100644 index 2cf0c7d16..000000000 --- a/xorg-server/glamor/glamor_glyphs.c +++ /dev/null @@ -1,1769 +0,0 @@ -/* - * Copyright © 2008 Red Hat, Inc. - * Partly based on code Copyright © 2000 SuSE, Inc. - * - * 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. - * - * Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat - * 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. - * - * 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 SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * 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: Owen Taylor <otaylor@fishsoup.net> - * Based on code by: Keith Packard - */ - -#include <stdlib.h> - -#include "glamor_priv.h" - -#include <mipict.h> - -#if DEBUG_GLYPH_CACHE -#define DBG_GLYPH_CACHE(a) ErrorF a -#else -#define DBG_GLYPH_CACHE(a) -#endif - -/* Width of the pixmaps we use for the caches; this should be less than - * max texture size of the driver; this may need to actually come from - * the driver. - */ - -/* Maximum number of glyphs we buffer on the stack before flushing - * rendering to the mask or destination surface. - */ -#define GLYPH_BUFFER_SIZE 1024 - -typedef struct { - PicturePtr source; - glamor_composite_rect_t rects[GLYPH_BUFFER_SIZE + 4]; - int count; -} glamor_glyph_buffer_t; - -struct glamor_glyph { - glamor_glyph_cache_t *cache; - uint16_t x, y; - uint16_t size, pos; - unsigned long long left_x1_map, left_x2_map; - unsigned long long right_x1_map, right_x2_map; /* Use to check real intersect or not. */ - Bool has_edge_map; - Bool cached; -}; - -typedef enum { - GLAMOR_GLYPH_SUCCESS, /* Glyph added to render buffer */ - GLAMOR_GLYPH_FAIL, /* out of memory, etc */ - GLAMOR_GLYPH_NEED_FLUSH, /* would evict a glyph already in the buffer */ -} glamor_glyph_cache_result_t; - -#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) -static DevPrivateKeyRec glamor_glyph_key; - -static inline struct glamor_glyph * -glamor_glyph_get_private(ScreenPtr screen, GlyphPtr glyph) -{ - struct glamor_glyph *privates = (struct glamor_glyph*)glyph->devPrivates; - - return &privates[screen->myNum]; -} - -/* - * Mask cache is located at the corresponding cache picture's last row. - * and is deadicated for the mask picture when do the glyphs_via_mask. - * - * As we split the glyphs list according to its overlapped or non-overlapped, - * we can reduce the length of glyphs to do the glyphs_via_mask to 2 or 3 - * glyphs one time for most cases. Thus it give us a case to allocate a - * small portion of the corresponding cache directly as the mask picture. - * Then we can rendering the glyphs to this mask picture, and latter we - * can accumulate the second steps, composite the mask to the dest with - * the other non-overlapped glyphs's rendering process. - * Another major benefit is we now only need to clear a relatively small mask - * region then before. It also make us implement a bunch mask picture clearing - * algorithm to avoid too frequently small region clearing. - * - * If there is no any overlapping, this method will not get performance gain. - * If there is some overlapping, then this algorithm can get about 15% performance - * gain. - */ - -static void -clear_mask_cache_bitmap(glamor_glyph_mask_cache_t *maskcache, - unsigned int clear_mask_bits) -{ - unsigned int i = 0; - BoxRec box[MASK_CACHE_WIDTH]; - int box_cnt = 0; - - assert((clear_mask_bits & ~MASK_CACHE_MASK) == 0); - for (i = 0; i < MASK_CACHE_WIDTH; i++) { - if (clear_mask_bits & (1 << i)) { - box[box_cnt].x1 = maskcache->mcache[i].x; - box[box_cnt].x2 = maskcache->mcache[i].x + MASK_CACHE_MAX_SIZE; - box[box_cnt].y1 = maskcache->mcache[i].y; - box[box_cnt].y2 = maskcache->mcache[i].y + MASK_CACHE_MAX_SIZE; - box_cnt++; - } - } - glamor_solid_boxes(maskcache->pixmap, box, box_cnt, 0); - maskcache->cleared_bitmap |= clear_mask_bits; -} - -static void -clear_mask_cache(glamor_glyph_mask_cache_t *maskcache) -{ - int x = 0; - int cnt = MASK_CACHE_WIDTH; - unsigned int i = 0; - struct glamor_glyph_mask_cache_entry *mce; - - glamor_solid(maskcache->pixmap, 0, CACHE_PICTURE_SIZE, CACHE_PICTURE_SIZE, - MASK_CACHE_MAX_SIZE, 0); - mce = &maskcache->mcache[0]; - while (cnt--) { - mce->width = 0; - mce->height = 0; - mce->x = x; - mce->y = CACHE_PICTURE_SIZE; - mce->idx = i++; - x += MASK_CACHE_MAX_SIZE; - mce++; - } - maskcache->free_bitmap = MASK_CACHE_MASK; - maskcache->cleared_bitmap = MASK_CACHE_MASK; -} - -static int -find_continuous_bits(unsigned int bits, int bits_cnt, unsigned int *pbits_mask) -{ - int idx = 0; - unsigned int bits_mask; - - bits_mask = ((1LL << bits_cnt) - 1); - - if (_X_UNLIKELY(bits_cnt > 56)) { - while (bits) { - if ((bits & bits_mask) == bits_mask) { - *pbits_mask = bits_mask << idx; - return idx; - } - bits >>= 1; - idx++; - } - } - else { - idx = __fls(bits); - while (bits) { - unsigned int temp_bits; - - temp_bits = bits_mask << (idx - bits_cnt + 1); - if ((bits & temp_bits) == temp_bits) { - *pbits_mask = temp_bits; - return (idx - bits_cnt + 1); - } - /* Find first zero. And clear the tested bit. */ - bits &= ~(1LL << idx); - idx = __fls(~bits); - bits &= ~((1LL << idx) - 1); - idx--; - } - } - return -1; -} - -static struct glamor_glyph_mask_cache_entry * -get_mask_cache(glamor_glyph_mask_cache_t *maskcache, int blocks) -{ - int free_cleared_bit, idx = -1; - int retry_cnt = 0; - unsigned int bits_mask = 0; - - if (maskcache->free_bitmap == 0) - return NULL; - retry: - free_cleared_bit = maskcache->free_bitmap & maskcache->cleared_bitmap; - if (free_cleared_bit && blocks == 1) { - idx = __fls(free_cleared_bit); - bits_mask = 1 << idx; - } - else if (free_cleared_bit && blocks > 1) { - idx = find_continuous_bits(free_cleared_bit, blocks, &bits_mask); - } - - if (idx < 0) { - clear_mask_cache_bitmap(maskcache, maskcache->free_bitmap); - if (retry_cnt++ > 2) - return NULL; - goto retry; - } - - maskcache->cleared_bitmap &= ~bits_mask; - maskcache->free_bitmap &= ~bits_mask; - DEBUGF("get idx %d free %x clear %x \n", - idx, maskcache->free_bitmap, maskcache->cleared_bitmap); - return &maskcache->mcache[idx]; -} - -static void -put_mask_cache_bitmap(glamor_glyph_mask_cache_t *maskcache, - unsigned int bitmap) -{ - maskcache->free_bitmap |= bitmap; - DEBUGF("put bitmap %x free %x clear %x \n", - bitmap, maskcache->free_bitmap, maskcache->cleared_bitmap); -} - -static void -glamor_unrealize_glyph_caches(ScreenPtr pScreen) -{ - glamor_screen_private *glamor = glamor_get_screen_private(pScreen); - int i; - - if (!glamor->glyph_caches_realized) - return; - - for (i = 0; i < GLAMOR_NUM_GLYPH_CACHE_FORMATS; i++) { - glamor_glyph_cache_t *cache = &glamor->glyphCaches[i]; - - if (cache->picture) - FreePicture(cache->picture, 0); - - if (cache->glyphs) - free(cache->glyphs); - - if (glamor->mask_cache[i]) - free(glamor->mask_cache[i]); - } - glamor->glyph_caches_realized = FALSE; -} - -void -glamor_glyphs_fini(ScreenPtr pScreen) -{ - glamor_unrealize_glyph_caches(pScreen); -} - -/* All caches for a single format share a single pixmap for glyph storage, - * allowing mixing glyphs of different sizes without paying a penalty - * for switching between source pixmaps. (Note that for a size of font - * right at the border between two sizes, we might be switching for almost - * every glyph.) - * - * This function allocates the storage pixmap, and then fills in the - * rest of the allocated structures for all caches with the given format. - */ - -Bool -glamor_realize_glyph_caches(ScreenPtr pScreen) -{ - glamor_screen_private *glamor = glamor_get_screen_private(pScreen); - - unsigned int formats[] = { - PIXMAN_a8, - PIXMAN_a8r8g8b8, - }; - int i; - - if (glamor->glyph_caches_realized) - return TRUE; - - memset(glamor->glyphCaches, 0, sizeof(glamor->glyphCaches)); - - for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) { - glamor_glyph_cache_t *cache = &glamor->glyphCaches[i]; - PixmapPtr pixmap; - PicturePtr picture; - XID component_alpha; - int depth = PIXMAN_FORMAT_DEPTH(formats[i]); - int error; - PictFormatPtr pPictFormat = - PictureMatchFormat(pScreen, depth, formats[i]); - if (!pPictFormat) - goto bail; - - /* Now allocate the pixmap and picture */ - pixmap = pScreen->CreatePixmap(pScreen, - CACHE_PICTURE_SIZE, - CACHE_PICTURE_SIZE + MASK_CACHE_MAX_SIZE, - depth, GLAMOR_CREATE_NO_LARGE); - if (!pixmap) - goto bail; - - component_alpha = NeedsComponent(pPictFormat->format); - picture = CreatePicture(0, &pixmap->drawable, pPictFormat, - CPComponentAlpha, &component_alpha, - serverClient, &error); - - pScreen->DestroyPixmap(pixmap); - if (!picture) - goto bail; - - ValidatePicture(picture); - - cache->picture = picture; - cache->glyphs = calloc(sizeof(GlyphPtr), GLYPH_CACHE_SIZE); - if (!cache->glyphs) - goto bail; - - cache->evict = rand() % GLYPH_CACHE_SIZE; - glamor->mask_cache[i] = calloc(1, sizeof(*glamor->mask_cache[i])); - glamor->mask_cache[i]->pixmap = pixmap; - clear_mask_cache(glamor->mask_cache[i]); - } - assert(i == GLAMOR_NUM_GLYPH_CACHE_FORMATS); - - glamor->glyph_caches_realized = TRUE; - return TRUE; - - bail: - glamor_unrealize_glyph_caches(pScreen); - return FALSE; -} - -/** - * Called by glamor_create_screen_resources() to set up the glyph cache. - * - * This was previously required to be called by the drivers, but not - * as of the xserver 1.16 ABI. - */ -Bool -glamor_glyphs_init(ScreenPtr pScreen) -{ - if (!dixRegisterPrivateKey(&glamor_glyph_key, - PRIVATE_GLYPH, - screenInfo.numScreens * sizeof(struct glamor_glyph))) - return FALSE; - - return TRUE; -} - -/* The most efficient thing to way to upload the glyph to the screen - * is to use CopyArea; glamor pixmaps are always offscreen. - */ -static void -glamor_glyph_cache_upload_glyph(ScreenPtr screen, - glamor_glyph_cache_t *cache, - GlyphPtr glyph, int x, int y) -{ - PicturePtr pGlyphPicture = GlyphPicture(glyph)[screen->myNum]; - PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable; - PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable; - PixmapPtr scratch; - BoxRec box; - GCPtr gc; - - gc = GetScratchGC(pCachePixmap->drawable.depth, screen); - if (!gc) - return; - - ValidateGC(&pCachePixmap->drawable, gc); - - scratch = pGlyphPixmap; - if (pGlyphPixmap->drawable.depth != pCachePixmap->drawable.depth) { - - scratch = glamor_create_pixmap(screen, - glyph->info.width, - glyph->info.height, - pCachePixmap->drawable.depth, 0); - if (scratch) { - PicturePtr picture; - int error; - - picture = - CreatePicture(0, - &scratch->drawable, - PictureMatchFormat - (screen, - pCachePixmap->drawable.depth, - cache->picture->format), - 0, NULL, serverClient, &error); - if (picture) { - ValidatePicture(picture); - glamor_composite(PictOpSrc, - pGlyphPicture, - NULL, picture, - 0, 0, 0, 0, 0, - 0, glyph->info.width, glyph->info.height); - FreePicture(picture, 0); - } - } - else { - scratch = pGlyphPixmap; - } - } - - box.x1 = x; - box.y1 = y; - box.x2 = x + glyph->info.width; - box.y2 = y + glyph->info.height; - glamor_copy(&scratch->drawable, - &pCachePixmap->drawable, NULL, - &box, 1, -x, -y, FALSE, FALSE, 0, NULL); - if (scratch != pGlyphPixmap) - screen->DestroyPixmap(scratch); - - FreeScratchGC(gc); -} - -void -glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph) -{ - struct glamor_glyph *priv; - - /* Use Lookup in case we have not attached to this glyph. */ - priv = glamor_glyph_get_private(screen, glyph); - - if (priv->cached) - priv->cache->glyphs[priv->pos] = NULL; -} - -/* Cut and paste from render/glyph.c - probably should export it instead */ -static void -glamor_glyph_extents(int nlist, - GlyphListPtr list, GlyphPtr *glyphs, BoxPtr extents) -{ - int x1, x2, y1, y2; - int x, y, n; - - x1 = y1 = MAXSHORT; - x2 = y2 = MINSHORT; - x = y = 0; - while (nlist--) { - x += list->xOff; - y += list->yOff; - n = list->len; - list++; - while (n--) { - GlyphPtr glyph = *glyphs++; - int v; - - v = x - glyph->info.x; - if (v < x1) - x1 = v; - v += glyph->info.width; - if (v > x2) - x2 = v; - - v = y - glyph->info.y; - if (v < y1) - y1 = v; - v += glyph->info.height; - if (v > y2) - y2 = v; - - x += glyph->info.xOff; - y += glyph->info.yOff; - } - } - - extents->x1 = x1 < MINSHORT ? MINSHORT : x1; - extents->x2 = x2 > MAXSHORT ? MAXSHORT : x2; - extents->y1 = y1 < MINSHORT ? MINSHORT : y1; - extents->y2 = y2 > MAXSHORT ? MAXSHORT : y2; -} - -static void -glamor_glyph_priv_get_edge_map(GlyphPtr glyph, struct glamor_glyph *priv, - PicturePtr glyph_picture) -{ - PixmapPtr glyph_pixmap = (PixmapPtr) glyph_picture->pDrawable; - int j; - unsigned long long left_x1_map = 0, left_x2_map = 0; - unsigned long long right_x1_map = 0, right_x2_map = 0; - int bitsPerPixel; - int stride; - void *bits; - int width; - unsigned int left_x1_data = 0, left_x2_data = 0; - unsigned int right_x1_data = 0, right_x2_data = 0; - - bitsPerPixel = glyph_pixmap->drawable.bitsPerPixel; - stride = glyph_pixmap->devKind; - bits = glyph_pixmap->devPrivate.ptr; - width = glyph->info.width; - - if (glyph_pixmap->drawable.width < 2 - || !(glyph_pixmap->drawable.depth == 8 - || glyph_pixmap->drawable.depth == 1 - || glyph_pixmap->drawable.depth == 32)) { - priv->has_edge_map = FALSE; - return; - } - - left_x1_map = left_x2_map = 0; - right_x1_map = right_x2_map = 0; - - for (j = 0; j < glyph_pixmap->drawable.height; j++) { - if (bitsPerPixel == 8) { - unsigned char *data; - - data = (unsigned char *) ((unsigned char *) bits + stride * j); - left_x1_data = *data++; - left_x2_data = *data; - data = - (unsigned char *) ((unsigned char *) bits + stride * j + width - - 2); - right_x1_data = *data++; - right_x2_data = *data; - } - else if (bitsPerPixel == 32) { - left_x1_data = *((unsigned int *) bits + stride / 4 * j); - left_x2_data = *((unsigned int *) bits + stride / 4 * j + 1); - right_x1_data = - *((unsigned int *) bits + stride / 4 * j + width - 2); - right_x2_data = - *((unsigned int *) bits + stride / 4 * j + width - 1); - } - else if (bitsPerPixel == 1) { - unsigned char temp; - - temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr - + glyph_pixmap->devKind * j) & 0x3; - left_x1_data = temp & 0x1; - left_x2_data = temp & 0x2; - - temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr - + glyph_pixmap->devKind * j - + (glyph_pixmap->drawable.width - 2) / 8); - right_x1_data = temp - & (1 << ((glyph_pixmap->drawable.width - 2) % 8)); - temp = *((unsigned char *) glyph_pixmap->devPrivate.ptr - + glyph_pixmap->devKind * j - + (glyph_pixmap->drawable.width - 1) / 8); - right_x2_data = temp - & (1 << ((glyph_pixmap->drawable.width - 1) % 8)); - } - left_x1_map |= (left_x1_data != 0) << j; - left_x2_map |= (left_x2_data != 0) << j; - right_x1_map |= (right_x1_data != 0) << j; - right_x2_map |= (right_x2_data != 0) << j; - } - - priv->left_x1_map = left_x1_map; - priv->left_x2_map = left_x2_map; - priv->right_x1_map = right_x1_map; - priv->right_x2_map = right_x2_map; - priv->has_edge_map = TRUE; - return; -} - -/** - * Returns TRUE if the glyphs in the lists intersect. Only checks based on - * bounding box, which appears to be good enough to catch most cases at least. - */ - -#define INTERSECTED_TYPE_MASK 1 -#define NON_INTERSECTED 0 -#define INTERSECTED 1 - -struct glamor_glyph_list { - int nlist; - GlyphListPtr list; - GlyphPtr *glyphs; - int type; -}; - -static Bool -glyph_new_fixed_list(struct glamor_glyph_list *fixed_list, - GlyphPtr *cur_glyphs, - GlyphPtr ** head_glyphs, - GlyphListPtr cur_list, - int cur_pos, int cur_x, int cur_y, - int x1, int y1, int x2, int y2, - GlyphListPtr *head_list, - int *head_pos, - int *head_x, - int *head_y, int *fixed_cnt, int type, BoxPtr prev_extents) -{ - int x_off = 0; - int y_off = 0; - int n_off = 0; - int list_cnt; - - if (type == NON_INTERSECTED) { - if (x1 < prev_extents->x2 && x2 > prev_extents->x1 - && y1 < prev_extents->y2 && y2 > prev_extents->y1) - return FALSE; - x_off = (*(cur_glyphs - 1))->info.xOff; - y_off = (*(cur_glyphs - 1))->info.yOff; - n_off = 1; - } - - list_cnt = cur_list - *head_list + 1; - if (cur_pos <= n_off) { - DEBUGF("break at %d n_off %d\n", cur_pos, n_off); - list_cnt--; - if (cur_pos < n_off) { - /* we overlap with previous list's last glyph. */ - x_off += cur_list->xOff; - y_off += cur_list->yOff; - cur_list--; - cur_pos = cur_list->len; - if (cur_pos <= n_off) { - list_cnt--; - } - } - } - DEBUGF("got %d lists\n", list_cnt); - if (list_cnt != 0) { - fixed_list->list = malloc(list_cnt * sizeof(*cur_list)); - memcpy(fixed_list->list, *head_list, list_cnt * sizeof(*cur_list)); - fixed_list->list[0].xOff = *head_x; - fixed_list->list[0].yOff = *head_y; - fixed_list->glyphs = *head_glyphs; - fixed_list->type = type & INTERSECTED_TYPE_MASK; - fixed_list->nlist = list_cnt; - if (cur_list != *head_list) { - fixed_list->list[0].len = (*head_list)->len - *head_pos; - if (cur_pos != n_off) - fixed_list->list[list_cnt - 1].len = cur_pos - n_off; - } - else - fixed_list->list[0].len = cur_pos - *head_pos - n_off; - (*fixed_cnt)++; - } - - if (type <= INTERSECTED) { - *head_list = cur_list; - *head_pos = cur_pos - n_off; - *head_x = cur_x - x_off; - *head_y = cur_y - y_off; - *head_glyphs = cur_glyphs - n_off; - } - return TRUE; -} - -/* - * This function detects glyph lists's overlapping. - * - * If check_fake_overlap is set, then it will check the glyph's left - * and right small boxes's real overlapping pixels. And if there is - * no real pixel overlapping, then it will not be treated as overlapped - * case. And we also can configured it to ignore less than 2 pixels - * overlappig. - * - * This function analyzes all the lists and split the list to multiple - * lists which are pure overlapped glyph lists or pure non-overlapped - * list if the overlapping only ocurr on the two adjacent glyphs. - * Otherwise, it return -1. - * - **/ - -static int -glamor_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs, - PictFormatShort mask_format, - ScreenPtr screen, Bool check_fake_overlap, - struct glamor_glyph_list *fixed_list, int fixed_size) -{ - int x1, x2, y1, y2; - int n; - int x, y; - BoxPtr extents; - BoxRec prev_extents; - Bool first = TRUE, first_list = TRUE; - Bool need_free_list_region = FALSE; - Bool need_free_fixed_list = FALSE; - struct glamor_glyph *priv = NULL; - Bool in_non_intersected_list = -1; - GlyphListPtr head_list; - int head_x, head_y, head_pos; - int fixed_cnt = 0; - GlyphPtr *head_glyphs; - GlyphListPtr cur_list = list; - RegionRec list_region; - RegionRec current_region; - BoxRec current_box; - - if (nlist > 1) { - pixman_region_init(&list_region); - need_free_list_region = TRUE; - } - - pixman_region_init(¤t_region); - - extents = pixman_region_extents(¤t_region); - - x = 0; - y = 0; - x1 = x2 = y1 = y2 = 0; - n = 0; - extents->x1 = 0; - extents->y1 = 0; - extents->x2 = 0; - extents->y2 = 0; - - head_list = list; - DEBUGF("has %d lists.\n", nlist); - while (nlist--) { - BoxRec left_box, right_box = { 0 }; - Bool has_left_edge_box = FALSE, has_right_edge_box = FALSE; - Bool left_to_right; - struct glamor_glyph *left_priv = NULL, *right_priv = NULL; - - x += list->xOff; - y += list->yOff; - n = list->len; - left_to_right = TRUE; - cur_list = list++; - - if (_X_UNLIKELY(!first_list)) { - pixman_region_init_with_extents(¤t_region, extents); - pixman_region_union(&list_region, &list_region, ¤t_region); - first = TRUE; - } - else { - head_list = cur_list; - head_pos = cur_list->len - n; - head_x = x; - head_y = y; - head_glyphs = glyphs; - } - - DEBUGF("current list %p has %d glyphs\n", cur_list, n); - while (n--) { - GlyphPtr glyph = *glyphs++; - - DEBUGF("the %dth glyph\n", cur_list->len - n - 1); - if (glyph->info.width == 0 || glyph->info.height == 0) { - x += glyph->info.xOff; - y += glyph->info.yOff; - continue; - } - if (mask_format - && mask_format != GlyphPicture(glyph)[screen->myNum]->format) { - need_free_fixed_list = TRUE; - goto done; - } - - x1 = x - glyph->info.x; - if (x1 < MINSHORT) - x1 = MINSHORT; - y1 = y - glyph->info.y; - if (y1 < MINSHORT) - y1 = MINSHORT; - if (check_fake_overlap) - priv = glamor_glyph_get_private(screen, glyph); - - x2 = x1 + glyph->info.width; - y2 = y1 + glyph->info.height; - - if (x2 > MAXSHORT) - x2 = MAXSHORT; - if (y2 > MAXSHORT) - y2 = MAXSHORT; - - if (first) { - extents->x1 = x1; - extents->y1 = y1; - extents->x2 = x2; - extents->y2 = y2; - - prev_extents = *extents; - - first = FALSE; - if (check_fake_overlap && priv - && priv->has_edge_map && glyph->info.yOff == 0) { - left_box.x1 = x1; - left_box.x2 = x1 + 1; - left_box.y1 = y1; - - right_box.x1 = x2 - 2; - right_box.x2 = x2 - 1; - right_box.y1 = y1; - left_priv = right_priv = priv; - has_left_edge_box = TRUE; - has_right_edge_box = TRUE; - } - } - else { - if (_X_UNLIKELY(!first_list)) { - current_box.x1 = x1; - current_box.y1 = y1; - current_box.x2 = x2; - current_box.y2 = y2; - if (pixman_region_contains_rectangle - (&list_region, ¤t_box) != PIXMAN_REGION_OUT) { - need_free_fixed_list = TRUE; - goto done; - } - } - - if (x1 < extents->x2 && x2 > extents->x1 - && y1 < extents->y2 && y2 > extents->y1) { - - if (check_fake_overlap && - (has_left_edge_box || has_right_edge_box) - && priv->has_edge_map && glyph->info.yOff == 0) { - int left_dx, right_dx; - unsigned long long intersected; - - left_dx = has_left_edge_box ? 1 : 0; - right_dx = has_right_edge_box ? 1 : 0; - if (x1 + 1 < extents->x2 - right_dx && - x2 - 1 > extents->x1 + left_dx) - goto real_intersected; - - if (left_to_right && has_right_edge_box) { - if (x1 == right_box.x1) { - intersected = - ((priv->left_x1_map & right_priv-> - right_x1_map) - | (priv->left_x2_map & right_priv-> - right_x2_map)); - if (intersected) - goto real_intersected; - } - else if (x1 == right_box.x2) { - intersected = - (priv->left_x1_map & right_priv-> - right_x2_map); - if (intersected) { -#ifdef GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK - /* tolerate with two pixels overlap. */ - intersected &= ~(1 << __fls(intersected)); - if ((intersected & (intersected - 1))) -#endif - goto real_intersected; - } - } - } - else if (!left_to_right && has_left_edge_box) { - if (x2 - 1 == left_box.x1) { - intersected = - (priv->right_x2_map & left_priv-> - left_x1_map); - if (intersected) { -#ifdef GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK - /* tolerate with two pixels overlap. */ - intersected &= ~(1 << __fls(intersected)); - if ((intersected & (intersected - 1))) -#endif - goto real_intersected; - } - } - else if (x2 - 1 == right_box.x2) { - if ((priv->right_x1_map & left_priv-> - left_x1_map) - || (priv->right_x2_map & left_priv-> - left_x2_map)) - goto real_intersected; - } - } - else { - if (x1 < extents->x2 && x1 + 2 > extents->x1) - goto real_intersected; - } - goto non_intersected; - } - else { - real_intersected: - DEBUGF("overlap with previous glyph.\n"); - if (in_non_intersected_list == 1) { - if (fixed_cnt >= fixed_size) { - need_free_fixed_list = TRUE; - goto done; - } - if (!glyph_new_fixed_list(&fixed_list[fixed_cnt], - glyphs - 1, - &head_glyphs, - cur_list, - cur_list->len - (n + 1), - x, y, x1, y1, x2, y2, - &head_list, &head_pos, - &head_x, &head_y, - &fixed_cnt, - NON_INTERSECTED, - &prev_extents)) { - need_free_fixed_list = TRUE; - goto done; - } - } - - in_non_intersected_list = 0; - - } - } - else { - non_intersected: - DEBUGF("doesn't overlap with previous glyph.\n"); - if (in_non_intersected_list == 0) { - if (fixed_cnt >= fixed_size) { - need_free_fixed_list = TRUE; - goto done; - } - if (!glyph_new_fixed_list(&fixed_list[fixed_cnt], - glyphs - 1, - &head_glyphs, - cur_list, - cur_list->len - (n + 1), x, y, - x1, y1, x2, y2, - &head_list, - &head_pos, - &head_x, - &head_y, &fixed_cnt, - INTERSECTED, &prev_extents)) { - need_free_fixed_list = TRUE; - goto done; - } - } - in_non_intersected_list = 1; - } - prev_extents = *extents; - } - - if (check_fake_overlap && priv - && priv->has_edge_map && glyph->info.yOff == 0) { - if (!has_left_edge_box || x1 < extents->x1) { - left_box.x1 = x1; - left_box.x2 = x1 + 1; - left_box.y1 = y1; - has_left_edge_box = TRUE; - left_priv = priv; - } - - if (!has_right_edge_box || x2 > extents->x2) { - right_box.x1 = x2 - 2; - right_box.x2 = x2 - 1; - right_box.y1 = y1; - has_right_edge_box = TRUE; - right_priv = priv; - } - } - - if (x1 < extents->x1) - extents->x1 = x1; - if (x2 > extents->x2) - extents->x2 = x2; - - if (y1 < extents->y1) - extents->y1 = y1; - if (y2 > extents->y2) - extents->y2 = y2; - - x += glyph->info.xOff; - y += glyph->info.yOff; - } - first_list = FALSE; - } - - if (in_non_intersected_list == 0 && fixed_cnt == 0) { - fixed_cnt = -1; - goto done; - } - - if ((in_non_intersected_list != -1 || head_pos != n) && (fixed_cnt > 0)) { - if (fixed_cnt >= fixed_size) { - need_free_fixed_list = TRUE; - goto done; - } - if (!glyph_new_fixed_list(&fixed_list[fixed_cnt], - glyphs - 1, - &head_glyphs, - cur_list, - cur_list->len - (n + 1), x, y, - x1, y1, x2, y2, - &head_list, - &head_pos, - &head_x, - &head_y, &fixed_cnt, - (!in_non_intersected_list) | 0x80, - &prev_extents)) { - need_free_fixed_list = TRUE; - goto done; - } - } - - done: - if (need_free_list_region) - pixman_region_fini(&list_region); - pixman_region_fini(¤t_region); - - if (need_free_fixed_list && fixed_cnt >= 0) { - while (fixed_cnt--) { - free(fixed_list[fixed_cnt].list); - } - } - - DEBUGF("Got %d fixed list \n", fixed_cnt); - return fixed_cnt; -} - -static inline unsigned int -glamor_glyph_size_to_count(int size) -{ - size /= GLYPH_MIN_SIZE; - return size * size; -} - -static inline unsigned int -glamor_glyph_count_to_mask(int count) -{ - return ~(count - 1); -} - -static inline unsigned int -glamor_glyph_size_to_mask(int size) -{ - return glamor_glyph_count_to_mask(glamor_glyph_size_to_count(size)); -} - -static PicturePtr -glamor_glyph_cache(glamor_screen_private *glamor, GlyphPtr glyph, int *out_x, - int *out_y) -{ - ScreenPtr screen = glamor->screen; - PicturePtr glyph_picture = GlyphPicture(glyph)[screen->myNum]; - glamor_glyph_cache_t *cache = - &glamor->glyphCaches[PICT_FORMAT_RGB(glyph_picture->format) != 0]; - struct glamor_glyph *priv = NULL, *evicted_priv = NULL; - int size, mask, pos, s; - - if (glyph->info.width > GLYPH_MAX_SIZE - || glyph->info.height > GLYPH_MAX_SIZE) - return NULL; - - for (size = GLYPH_MIN_SIZE; size <= GLYPH_MAX_SIZE; size *= 2) - if (glyph->info.width <= size && glyph->info.height <= size) - break; - - s = glamor_glyph_size_to_count(size); - mask = glamor_glyph_count_to_mask(s); - pos = (cache->count + s - 1) & mask; - - priv = glamor_glyph_get_private(screen, glyph); - if (pos < GLYPH_CACHE_SIZE) { - cache->count = pos + s; - } - else { - for (s = size; s <= GLYPH_MAX_SIZE; s *= 2) { - int i = cache->evict & glamor_glyph_size_to_mask(s); - GlyphPtr evicted = cache->glyphs[i]; - - if (evicted == NULL) - continue; - - evicted_priv = glamor_glyph_get_private(screen, evicted); - assert(evicted_priv->pos == i); - if (evicted_priv->size >= s) { - cache->glyphs[i] = NULL; - evicted_priv->cached = FALSE; - pos = cache->evict & glamor_glyph_size_to_mask(size); - } - else - evicted_priv = NULL; - break; - } - if (evicted_priv == NULL) { - int count = glamor_glyph_size_to_count(size); - - mask = glamor_glyph_count_to_mask(count); - pos = cache->evict & mask; - for (s = 0; s < count; s++) { - GlyphPtr evicted = cache->glyphs[pos + s]; - - if (evicted != NULL) { - - evicted_priv = glamor_glyph_get_private(screen, evicted); - - assert(evicted_priv->pos == pos + s); - evicted_priv->cached = FALSE; - cache->glyphs[pos + s] = NULL; - } - } - - } - /* And pick a new eviction position */ - cache->evict = rand() % GLYPH_CACHE_SIZE; - } - - cache->glyphs[pos] = glyph; - - priv->cache = cache; - priv->size = size; - priv->pos = pos; - s = pos / ((GLYPH_MAX_SIZE / GLYPH_MIN_SIZE) * - (GLYPH_MAX_SIZE / GLYPH_MIN_SIZE)); - priv->x = s % (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE) * GLYPH_MAX_SIZE; - priv->y = (s / (CACHE_PICTURE_SIZE / GLYPH_MAX_SIZE)) * GLYPH_MAX_SIZE; - for (s = GLYPH_MIN_SIZE; s < GLYPH_MAX_SIZE; s *= 2) { - if (pos & 1) - priv->x += s; - if (pos & 2) - priv->y += s; - pos >>= 2; - } - - glamor_glyph_cache_upload_glyph(screen, cache, glyph, priv->x, priv->y); -#ifndef GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK - if (priv->has_edge_map == FALSE && glyph->info.width >= 2) - glamor_glyph_priv_get_edge_map(glyph, priv, glyph_picture); -#endif - priv->cached = TRUE; - - *out_x = priv->x; - *out_y = priv->y; - return cache->picture; -} - -typedef void (*glyphs_flush_func) (void *arg); -struct glyphs_flush_dst_arg { - CARD8 op; - PicturePtr src; - PicturePtr dst; - glamor_glyph_buffer_t *buffer; - int x_src, y_src; - int x_dst, y_dst; -}; - -static struct glyphs_flush_dst_arg dst_arg; -static struct glyphs_flush_mask_arg mask_arg; -static glamor_glyph_buffer_t dst_buffer; -static glamor_glyph_buffer_t mask_buffer; -unsigned long long mask_glyphs_cnt = 0; -unsigned long long dst_glyphs_cnt = 0; - -#define GLYPHS_DST_MODE_VIA_MASK 0 -#define GLYPHS_DST_MODE_VIA_MASK_CACHE 1 -#define GLYPHS_DST_MODE_TO_DST 2 -#define GLYPHS_DST_MODE_MASK_TO_DST 3 - -struct glyphs_flush_mask_arg { - PicturePtr mask; - glamor_glyph_buffer_t *buffer; - glamor_glyph_mask_cache_t *maskcache; - unsigned int used_bitmap; -}; - -static void -glamor_glyphs_flush_mask(struct glyphs_flush_mask_arg *arg) -{ - if (arg->buffer->count > 0) { - glamor_composite_glyph_rects(PictOpAdd, arg->buffer->source, - NULL, arg->mask, - arg->buffer->count, arg->buffer->rects); - } - arg->buffer->count = 0; - arg->buffer->source = NULL; - -} - -static void -glamor_glyphs_flush_dst(struct glyphs_flush_dst_arg *arg) -{ - if (!arg->buffer) - return; - - if (mask_buffer.count > 0) { - glamor_glyphs_flush_mask(&mask_arg); - } - if (mask_arg.used_bitmap) { - put_mask_cache_bitmap(mask_arg.maskcache, mask_arg.used_bitmap); - mask_arg.used_bitmap = 0; - } - - if (arg->buffer->count > 0) { - glamor_composite_glyph_rects(arg->op, arg->src, - arg->buffer->source, arg->dst, - arg->buffer->count, - &arg->buffer->rects[0]); - arg->buffer->count = 0; - arg->buffer->source = NULL; - } -} - -static glamor_glyph_cache_result_t -glamor_buffer_glyph(glamor_screen_private *glamor_priv, - glamor_glyph_buffer_t *buffer, - PictFormatShort format, - GlyphPtr glyph, struct glamor_glyph *priv, - int x_glyph, int y_glyph, - int dx, int dy, int w, int h, - int glyphs_dst_mode, - glyphs_flush_func glyphs_flush, void *flush_arg) -{ - ScreenPtr screen = glamor_priv->screen; - glamor_composite_rect_t *rect; - PicturePtr source; - int x, y; - glamor_glyph_cache_t *cache; - - if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST) - priv = glamor_glyph_get_private(screen, glyph); - - if (PICT_FORMAT_BPP(format) == 1) - format = PICT_a8; - - cache = &glamor_priv->glyphCaches[PICT_FORMAT_RGB(format) != 0]; - - if (buffer->source && buffer->source != cache->picture && glyphs_flush) { - (*glyphs_flush) (flush_arg); - glyphs_flush = NULL; - } - - if (buffer->count == GLYPH_BUFFER_SIZE && glyphs_flush) { - (*glyphs_flush) (flush_arg); - glyphs_flush = NULL; - } - - if (priv && priv->cached) { - rect = &buffer->rects[buffer->count++]; - rect->x_src = priv->x + dx; - rect->y_src = priv->y + dy; - if (buffer->source == NULL) - buffer->source = priv->cache->picture; - if (glyphs_dst_mode <= GLYPHS_DST_MODE_VIA_MASK_CACHE) - assert(priv->cache->glyphs[priv->pos] == glyph); - } - else { - assert(glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST); - if (glyphs_flush) - (*glyphs_flush) (flush_arg); - source = glamor_glyph_cache(glamor_priv, glyph, &x, &y); - - if (source != NULL) { - rect = &buffer->rects[buffer->count++]; - rect->x_src = x + dx; - rect->y_src = y + dy; - if (buffer->source == NULL) - buffer->source = source; - if (glyphs_dst_mode == GLYPHS_DST_MODE_VIA_MASK_CACHE) { - /* mode 1 means we are using global mask cache, - * thus we have to composite from the cache picture - * to the cache picture, we need a flush here to make - * sure latter we get the corret glyphs data.*/ - glamor_make_current(glamor_priv); - glFlush(); - } - } - else { - /* Couldn't find the glyph in the cache, use the glyph picture directly */ - source = GlyphPicture(glyph)[screen->myNum]; - if (buffer->source && buffer->source != source && glyphs_flush) - (*glyphs_flush) (flush_arg); - buffer->source = source; - - rect = &buffer->rects[buffer->count++]; - rect->x_src = 0 + dx; - rect->y_src = 0 + dy; - } - priv = glamor_glyph_get_private(screen, glyph); - } - - rect->x_dst = x_glyph; - rect->y_dst = y_glyph; - if (glyphs_dst_mode != GLYPHS_DST_MODE_MASK_TO_DST) { - rect->x_dst -= glyph->info.x; - rect->y_dst -= glyph->info.y; - } - rect->width = w; - rect->height = h; - if (glyphs_dst_mode > GLYPHS_DST_MODE_VIA_MASK_CACHE) { - rect->x_mask = rect->x_src; - rect->y_mask = rect->y_src; - rect->x_src = dst_arg.x_src + rect->x_dst - dst_arg.x_dst; - rect->y_src = dst_arg.y_src + rect->y_dst - dst_arg.y_dst; - } - - return GLAMOR_GLYPH_SUCCESS; -} - -static void -glamor_buffer_glyph_clip(glamor_screen_private *glamor_priv, - BoxPtr rects, - int nrect, PictFormatShort format, - GlyphPtr glyph, struct glamor_glyph *priv, - int glyph_x, int glyph_y, - int glyph_dx, int glyph_dy, - int width, int height, - int glyphs_mode, - glyphs_flush_func flush_func, void *arg) -{ - int i; - - for (i = 0; i < nrect; i++) { - int dst_x, dst_y; - int dx, dy; - int x2, y2; - - dst_x = glyph_x - glyph_dx; - dst_y = glyph_y - glyph_dy; - x2 = dst_x + width; - y2 = dst_y + height; - dx = dy = 0; - if (rects[i].y1 >= y2) - break; - - if (dst_x < rects[i].x1) - dx = rects[i].x1 - dst_x, dst_x = rects[i].x1; - if (x2 > rects[i].x2) - x2 = rects[i].x2; - if (dst_y < rects[i].y1) - dy = rects[i].y1 - dst_y, dst_y = rects[i].y1; - if (y2 > rects[i].y2) - y2 = rects[i].y2; - if (dst_x < x2 && dst_y < y2) { - - glamor_buffer_glyph(glamor_priv, - &dst_buffer, - format, - glyph, priv, - dst_x + glyph_dx, - dst_y + glyph_dy, - dx, dy, - x2 - dst_x, y2 - dst_y, - glyphs_mode, flush_func, arg); - } - } -} - -static void -glamor_glyphs_via_mask(CARD8 op, - PicturePtr src, - PicturePtr dst, - PictFormatPtr mask_format, - INT16 x_src, - INT16 y_src, - int nlist, GlyphListPtr list, GlyphPtr *glyphs, - Bool use_mask_cache) -{ - PixmapPtr mask_pixmap = 0; - PicturePtr mask; - ScreenPtr screen = dst->pDrawable->pScreen; - int width = 0, height = 0; - int x, y; - int x_dst = list->xOff, y_dst = list->yOff; - int n; - GlyphPtr glyph; - int error; - BoxRec extents = { 0, 0, 0, 0 }; - XID component_alpha; - glamor_screen_private *glamor_priv; - int need_free_mask = FALSE; - glamor_glyph_buffer_t buffer; - struct glyphs_flush_mask_arg arg; - glamor_glyph_buffer_t *pmask_buffer; - struct glyphs_flush_mask_arg *pmask_arg; - struct glamor_glyph_mask_cache_entry *mce = NULL; - glamor_glyph_mask_cache_t *maskcache; - glamor_glyph_cache_t *cache; - int glyphs_dst_mode; - - glamor_glyph_extents(nlist, list, glyphs, &extents); - - if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) - return; - glamor_priv = glamor_get_screen_private(screen); - width = extents.x2 - extents.x1; - height = extents.y2 - extents.y1; - - if (mask_format->depth == 1) { - PictFormatPtr a8Format = PictureMatchFormat(screen, 8, PICT_a8); - - if (a8Format) - mask_format = a8Format; - } - - cache = &glamor_priv->glyphCaches - [PICT_FORMAT_RGB(mask_format->format) != 0]; - maskcache = glamor_priv->mask_cache[PICT_FORMAT_RGB(mask_format->format) != 0]; - - x = -extents.x1; - y = -extents.y1; - if (!use_mask_cache || width > (CACHE_PICTURE_SIZE / 4) - || height > MASK_CACHE_MAX_SIZE) { - new_mask_pixmap: - mask_pixmap = glamor_create_pixmap(screen, width, height, - mask_format->depth, - CREATE_PIXMAP_USAGE_SCRATCH); - if (!mask_pixmap) { - glamor_destroy_pixmap(mask_pixmap); - return; - } - glamor_solid(mask_pixmap, 0, 0, width, height, 0); - component_alpha = NeedsComponent(mask_format->format); - mask = CreatePicture(0, &mask_pixmap->drawable, - mask_format, CPComponentAlpha, - &component_alpha, serverClient, &error); - if (!mask) - return; - need_free_mask = TRUE; - pmask_arg = &arg; - pmask_buffer = &buffer; - pmask_buffer->count = 0; - pmask_buffer->source = NULL; - pmask_arg->used_bitmap = 0; - glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK; - } - else { - int retry_cnt = 0; - - retry: - mce = get_mask_cache(maskcache, - (width + MASK_CACHE_MAX_SIZE - - 1) / MASK_CACHE_MAX_SIZE); - - if (mce == NULL) { - glamor_glyphs_flush_dst(&dst_arg); - retry_cnt++; - if (retry_cnt > 2) { - assert(0); - goto new_mask_pixmap; - } - goto retry; - } - - mask = cache->picture; - x += mce->x; - y += mce->y; - mce->width = (width + MASK_CACHE_MAX_SIZE - 1) / MASK_CACHE_MAX_SIZE; - mce->height = 1; - if (mask_arg.mask && mask_arg.mask != mask && mask_buffer.count != 0) - glamor_glyphs_flush_dst(&dst_arg); - pmask_arg = &mask_arg; - pmask_buffer = &mask_buffer; - pmask_arg->maskcache = maskcache; - glyphs_dst_mode = GLYPHS_DST_MODE_VIA_MASK_CACHE; - } - pmask_arg->mask = mask; - pmask_arg->buffer = pmask_buffer; - while (nlist--) { - x += list->xOff; - y += list->yOff; - n = list->len; - mask_glyphs_cnt += n; - while (n--) { - glyph = *glyphs++; - if (glyph->info.width > 0 && glyph->info.height > 0) { - glyphs_flush_func flush_func; - void *temp_arg; - - if (need_free_mask) { - if (pmask_buffer->count) - flush_func = - (glyphs_flush_func) glamor_glyphs_flush_mask; - else - flush_func = NULL; - temp_arg = pmask_arg; - } - else { - /* If we are using global mask cache, then we need to - * flush dst instead of mask. As some dst depends on the - * previous mask result. Just flush mask can't get all previous's - * overlapped glyphs.*/ - if (dst_buffer.count || mask_buffer.count) - flush_func = - (glyphs_flush_func) glamor_glyphs_flush_dst; - else - flush_func = NULL; - temp_arg = &dst_arg; - } - glamor_buffer_glyph(glamor_priv, pmask_buffer, - mask_format->format, - glyph, NULL, x, y, - 0, 0, - glyph->info.width, glyph->info.height, - glyphs_dst_mode, - flush_func, (void *) temp_arg); - } - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - } - - x = extents.x1; - y = extents.y1; - if (need_free_mask) { - glamor_glyphs_flush_mask(pmask_arg); - CompositePicture(op, - src, - mask, - dst, - x_src + x - x_dst, - y_src + y - y_dst, 0, 0, x, y, width, height); - FreePicture(mask, 0); - glamor_destroy_pixmap(mask_pixmap); - } - else { - struct glamor_glyph priv; - glyphs_flush_func flush_func; - BoxPtr rects; - int nrect; - - priv.cache = cache; - priv.x = mce->x; - priv.y = mce->y; - priv.cached = TRUE; - rects = REGION_RECTS(dst->pCompositeClip); - nrect = REGION_NUM_RECTS(dst->pCompositeClip); - - pmask_arg->used_bitmap |= ((1 << mce->width) - 1) << mce->idx; - dst_arg.op = op; - dst_arg.src = src; - dst_arg.dst = dst; - dst_arg.buffer = &dst_buffer; - dst_arg.x_src = x_src; - dst_arg.y_src = y_src; - dst_arg.x_dst = x_dst; - dst_arg.y_dst = y_dst; - - if (dst_buffer.source == NULL) { - dst_buffer.source = cache->picture; - } - else if (dst_buffer.source != cache->picture) { - glamor_glyphs_flush_dst(&dst_arg); - dst_buffer.source = cache->picture; - } - - x += dst->pDrawable->x; - y += dst->pDrawable->y; - - if (dst_buffer.count || mask_buffer.count) - flush_func = (glyphs_flush_func) glamor_glyphs_flush_dst; - else - flush_func = NULL; - - glamor_buffer_glyph_clip(glamor_priv, - rects, nrect, - mask_format->format, - NULL, &priv, - x, y, - 0, 0, - width, height, - GLYPHS_DST_MODE_MASK_TO_DST, - flush_func, (void *) &dst_arg); - } -} - -static void -glamor_glyphs_to_dst(CARD8 op, - PicturePtr src, - PicturePtr dst, - INT16 x_src, - INT16 y_src, - int nlist, GlyphListPtr list, GlyphPtr *glyphs) -{ - ScreenPtr screen = dst->pDrawable->pScreen; - int x = 0, y = 0; - int x_dst = list->xOff, y_dst = list->yOff; - int n; - GlyphPtr glyph; - BoxPtr rects; - int nrect; - glamor_screen_private *glamor_priv; - - rects = REGION_RECTS(dst->pCompositeClip); - nrect = REGION_NUM_RECTS(dst->pCompositeClip); - - glamor_priv = glamor_get_screen_private(screen); - - dst_arg.op = op; - dst_arg.src = src; - dst_arg.dst = dst; - dst_arg.buffer = &dst_buffer; - dst_arg.x_src = x_src; - dst_arg.y_src = y_src; - dst_arg.x_dst = x_dst; - dst_arg.y_dst = y_dst; - - x = dst->pDrawable->x; - y = dst->pDrawable->y; - - while (nlist--) { - x += list->xOff; - y += list->yOff; - n = list->len; - dst_glyphs_cnt += n; - while (n--) { - glyph = *glyphs++; - - if (glyph->info.width > 0 && glyph->info.height > 0) { - glyphs_flush_func flush_func; - - if (dst_buffer.count || mask_buffer.count) - flush_func = (glyphs_flush_func) glamor_glyphs_flush_dst; - else - flush_func = NULL; - glamor_buffer_glyph_clip(glamor_priv, - rects, nrect, - (GlyphPicture(glyph)[screen->myNum])-> - format, glyph, NULL, x, y, - glyph->info.x, glyph->info.y, - glyph->info.width, glyph->info.height, - GLYPHS_DST_MODE_TO_DST, flush_func, - (void *) &dst_arg); - } - - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - } -} - -#define MAX_FIXED_SIZE -static void -glamor_glyphs_reset_buffer(glamor_glyph_buffer_t *buffer) -{ - buffer->count = 0; - buffer->source = NULL; -} - -static Bool -_glamor_glyphs(CARD8 op, - PicturePtr src, - PicturePtr dst, - PictFormatPtr mask_format, - INT16 x_src, - INT16 y_src, int nlist, GlyphListPtr list, - GlyphPtr *glyphs, Bool fallback) -{ - PictFormatShort format; - int fixed_size, fixed_cnt = 0; - struct glamor_glyph_list *fixed_list = NULL; - Bool need_free_list = FALSE; - -#ifndef GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK - Bool check_fake_overlap = TRUE; - - if (!(op == PictOpOver || op == PictOpAdd || op == PictOpXor)) { - /* C = (0,0,0,0) D = glyphs , SRC = A, DEST = B (faked overlapped glyphs, overlapped with (0,0,0,0)). - * For those op, (A IN (C ADD D)) OP B != (A IN D) OP ((A IN C) OP B) - * or (A IN (D ADD C)) OP B != (A IN C) OP ((A IN D) OP B) - * We need to split the faked regions to three or two, and composite the disoverlapped small - * boxes one by one. For other Ops, it's safe to composite the whole box. */ - check_fake_overlap = FALSE; - } -#else - Bool check_fake_overlap = FALSE; -#endif - if (mask_format) - format = mask_format->depth << 24 | mask_format->format; - else - format = 0; - - fixed_size = 32; - glamor_glyphs_reset_buffer(&dst_buffer); - - if (!mask_format || (((nlist == 1 && list->len == 1) || op == PictOpAdd) - && (dst->format == - ((mask_format->depth << 24) | mask_format-> - format)))) { - glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist, list, glyphs); - goto last_flush; - } - - glamor_glyphs_reset_buffer(&mask_buffer); - - /* We have mask_format. Need to check the real overlap or not. */ - format = mask_format->depth << 24 | mask_format->format; - - fixed_list = calloc(fixed_size, sizeof(*fixed_list)); - if (_X_UNLIKELY(fixed_list == NULL)) - fixed_size = 0; - fixed_cnt = glamor_glyphs_intersect(nlist, list, glyphs, - format, dst->pDrawable->pScreen, - check_fake_overlap, - fixed_list, fixed_size); - if (fixed_cnt == 0) - mask_format = NULL; - need_free_list = TRUE; - - if (fixed_cnt <= 0) { - if (mask_format == NULL) { - glamor_glyphs_to_dst(op, src, dst, x_src, y_src, nlist, - list, glyphs); - goto last_flush; - } - else { - glamor_glyphs_via_mask(op, src, dst, mask_format, - x_src, y_src, nlist, list, glyphs, FALSE); - goto free_fixed_list; - } - } - else { - - /* We have splitted the original list to serval list, some are overlapped - * and some are non-overlapped. For the non-overlapped, we render it to - * dst directly. For the overlapped, we render it to mask picture firstly, - * then render the mask to dst. If we can use mask cache which is in the - * glyphs cache's last row, we can accumulate the rendering of mask to dst - * with the other dst_buffer's rendering operations thus can reduce the call - * of glDrawElements. - * - * */ - struct glamor_glyph_list *saved_list; - - saved_list = fixed_list; - mask_arg.used_bitmap = 0; - while (fixed_cnt--) { - if (fixed_list->type == NON_INTERSECTED) { - glamor_glyphs_to_dst(op, src, dst, - x_src, y_src, - fixed_list->nlist, - fixed_list->list, fixed_list->glyphs); - } - else - glamor_glyphs_via_mask(op, src, dst, - mask_format, x_src, y_src, - fixed_list->nlist, - fixed_list->list, - fixed_list->glyphs, TRUE); - - free(fixed_list->list); - fixed_list++; - } - free(saved_list); - need_free_list = FALSE; - } - - last_flush: - if (dst_buffer.count || mask_buffer.count) - glamor_glyphs_flush_dst(&dst_arg); - free_fixed_list: - if (need_free_list) { - assert(fixed_cnt <= 0); - free(fixed_list); - } - return TRUE; -} - -void -glamor_glyphs(CARD8 op, - PicturePtr src, - PicturePtr dst, - PictFormatPtr mask_format, - INT16 x_src, - INT16 y_src, int nlist, GlyphListPtr list, GlyphPtr *glyphs) -{ - _glamor_glyphs(op, src, dst, mask_format, x_src, - y_src, nlist, list, glyphs, TRUE); -} diff --git a/xorg-server/glamor/glamor_gradient.c b/xorg-server/glamor/glamor_gradient.c index 8ea645efc..d34131d35 100644 --- a/xorg-server/glamor/glamor_gradient.c +++ b/xorg-server/glamor/glamor_gradient.c @@ -997,13 +997,13 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen, /* Set all the stops and colors to shader. */ if (stops_count > RADIAL_SMALL_STOPS) { - stop_colors = malloc(4 * stops_count * sizeof(float)); + stop_colors = xallocarray(stops_count, 4 * sizeof(float)); if (stop_colors == NULL) { ErrorF("Failed to allocate stop_colors memory.\n"); goto GRADIENT_FAIL; } - n_stops = malloc(stops_count * sizeof(float)); + n_stops = xallocarray(stops_count, sizeof(float)); if (n_stops == NULL) { ErrorF("Failed to allocate n_stops memory.\n"); goto GRADIENT_FAIL; @@ -1338,13 +1338,13 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen, /* Set all the stops and colors to shader. */ if (stops_count > LINEAR_SMALL_STOPS) { - stop_colors = malloc(4 * stops_count * sizeof(float)); + stop_colors = xallocarray(stops_count, 4 * sizeof(float)); if (stop_colors == NULL) { ErrorF("Failed to allocate stop_colors memory.\n"); goto GRADIENT_FAIL; } - n_stops = malloc(stops_count * sizeof(float)); + n_stops = xallocarray(stops_count, sizeof(float)); if (n_stops == NULL) { ErrorF("Failed to allocate n_stops memory.\n"); goto GRADIENT_FAIL; diff --git a/xorg-server/glamor/glamor_image.c b/xorg-server/glamor/glamor_image.c index 5633da647..a272d5eaf 100644 --- a/xorg-server/glamor/glamor_image.c +++ b/xorg-server/glamor/glamor_image.c @@ -49,7 +49,7 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, if (gc->alu != GXcopy) goto bail; - if (!glamor_pm_is_solid(&pixmap->drawable, gc->planemask)) + if (!glamor_pm_is_solid(gc->depth, gc->planemask)) goto bail; if (format == XYPixmap && drawable->depth == 1 && leftPad == 0) @@ -116,7 +116,7 @@ glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h, if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) goto bail; - if (format != ZPixmap || !glamor_pm_is_solid(drawable, plane_mask)) + if (format != ZPixmap || !glamor_pm_is_solid(drawable->depth, plane_mask)) goto bail; glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); diff --git a/xorg-server/glamor/glamor_pixmap.c b/xorg-server/glamor/glamor_pixmap.c index 89b4c366b..4e8737172 100644 --- a/xorg-server/glamor/glamor_pixmap.c +++ b/xorg-server/glamor/glamor_pixmap.c @@ -109,9 +109,9 @@ glamor_set_destination_pixmap(PixmapPtr pixmap) } Bool -glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask) +glamor_set_planemask(int depth, unsigned long planemask) { - if (glamor_pm_is_solid(&pixmap->drawable, planemask)) { + if (glamor_pm_is_solid(depth, planemask)) { return GL_TRUE; } @@ -775,7 +775,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format, if (pixmap->drawable.depth == 1) stride = (((w * 8 + 7) / 8) + 3) & ~3; - converted_bits = malloc(h * stride); + converted_bits = xallocarray(h, stride); if (converted_bits == NULL) return FALSE; @@ -966,7 +966,7 @@ glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, void *sub_bits; int i, j; - sub_bits = malloc(h * stride); + sub_bits = xallocarray(h, stride); if (sub_bits == NULL) return FALSE; box.x1 = x; diff --git a/xorg-server/glamor/glamor_points.c b/xorg-server/glamor/glamor_points.c index df7e5a23f..3ba4a6927 100644 --- a/xorg-server/glamor/glamor_points.c +++ b/xorg-server/glamor/glamor_points.c @@ -60,7 +60,8 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint if (!prog->prog) { if (!glamor_build_program(screen, prog, &glamor_facet_point, - &glamor_fill_solid)) + &glamor_fill_solid, + NULL, NULL)) goto bail; } diff --git a/xorg-server/glamor/glamor_prepare.c b/xorg-server/glamor/glamor_prepare.c index 83ba7f16f..9bfc557e1 100644 --- a/xorg-server/glamor/glamor_prepare.c +++ b/xorg-server/glamor/glamor_prepare.c @@ -91,8 +91,8 @@ glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box) pixmap->devKind * pixmap->drawable.height, NULL, gl_usage); } else { - pixmap->devPrivate.ptr = malloc(pixmap->devKind * - pixmap->drawable.height); + pixmap->devPrivate.ptr = xallocarray(pixmap->devKind, + pixmap->drawable.height); if (!pixmap->devPrivate.ptr) return FALSE; } diff --git a/xorg-server/glamor/glamor_priv.h b/xorg-server/glamor/glamor_priv.h index 898a9348a..480d13bfe 100644 --- a/xorg-server/glamor/glamor_priv.h +++ b/xorg-server/glamor/glamor_priv.h @@ -154,41 +154,8 @@ enum glamor_gl_flavor { GLAMOR_GL_ES2 // OPENGL ES2.0 API }; -#define GLAMOR_NUM_GLYPH_CACHE_FORMATS 2 - #define GLAMOR_COMPOSITE_VBO_VERT_CNT (64*1024) -typedef struct { - PicturePtr picture; /* Where the glyphs of the cache are stored */ - GlyphPtr *glyphs; - uint16_t count; - uint16_t evict; -} glamor_glyph_cache_t; - -#define CACHE_PICTURE_SIZE 1024 -#define GLYPH_MIN_SIZE 8 -#define GLYPH_MAX_SIZE 64 -#define GLYPH_CACHE_SIZE ((CACHE_PICTURE_SIZE) * CACHE_PICTURE_SIZE / (GLYPH_MIN_SIZE * GLYPH_MIN_SIZE)) - -#define MASK_CACHE_MAX_SIZE 32 -#define MASK_CACHE_WIDTH (CACHE_PICTURE_SIZE / MASK_CACHE_MAX_SIZE) -#define MASK_CACHE_MASK ((1LL << (MASK_CACHE_WIDTH)) - 1) - -struct glamor_glyph_mask_cache_entry { - int idx; - int width; - int height; - int x; - int y; -}; - -typedef struct { - PixmapPtr pixmap; - struct glamor_glyph_mask_cache_entry mcache[MASK_CACHE_WIDTH]; - unsigned int free_bitmap; - unsigned int cleared_bitmap; -} glamor_glyph_mask_cache_t; - struct glamor_saved_procs { CloseScreenProcPtr close_screen; CreateScreenResourcesProcPtr create_screen_resources; @@ -208,7 +175,6 @@ struct glamor_saved_procs { AddTrapsProcPtr addtraps; CreatePictureProcPtr create_picture; DestroyPictureProcPtr destroy_picture; - UnrealizeGlyphProcPtr unrealize_glyph; SetWindowPixmapProcPtr set_window_pixmap; #if XSYNC SyncScreenFuncsRec sync_screen_funcs; @@ -274,6 +240,14 @@ typedef struct glamor_screen_private { glamor_program_fill on_off_dash_line_progs; glamor_program double_dash_line_prog; + /* glamor composite_glyphs shaders */ + glamor_program_render glyphs_program; + struct glamor_glyph_atlas *glyph_atlas_a; + struct glamor_glyph_atlas *glyph_atlas_argb; + int glyph_atlas_dim; + int glyph_max_dim; + char *glyph_defines; + /* vertext/elment_index buffer object for render */ GLuint vbo, ebo; /** Next offset within the VBO that glamor_get_vbo_space() will use. */ @@ -292,9 +266,6 @@ typedef struct glamor_screen_private { glamor_composite_shader composite_shader[SHADER_SOURCE_COUNT] [SHADER_MASK_COUNT] [SHADER_IN_COUNT]; - glamor_glyph_cache_t glyphCaches[GLAMOR_NUM_GLYPH_CACHE_FORMATS]; - glamor_glyph_mask_cache_t *mask_cache[GLAMOR_NUM_GLYPH_CACHE_FORMATS]; - Bool glyph_caches_realized; /* shaders to restore a texture to another texture. */ GLint finish_access_prog[2]; @@ -638,10 +609,10 @@ glamor_get_gc_private(GCPtr gc) * pixel values for pDrawable. */ static inline Bool -glamor_pm_is_solid(DrawablePtr drawable, unsigned long planemask) +glamor_pm_is_solid(int depth, unsigned long planemask) { - return (planemask & FbFullMask(drawable->depth)) == - FbFullMask(drawable->depth); + return (planemask & FbFullMask(depth)) == + FbFullMask(depth); } extern int glamor_debug_level; @@ -676,7 +647,7 @@ glamor_pixmap_fbo *glamor_create_fbo_array(glamor_screen_private *glamor_priv, void glamor_init_finish_access_shaders(ScreenPtr screen); void glamor_fini_finish_access_shaders(ScreenPtr screen); -const Bool glamor_get_drawable_location(const DrawablePtr drawable); +Bool glamor_get_drawable_location(const DrawablePtr drawable); void glamor_get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int *x, int *y); GLint glamor_compile_glsl_prog(GLenum type, const char *source); @@ -701,23 +672,12 @@ glamor_pixmap_fbo *glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int swap_rb); Bool glamor_set_alu(ScreenPtr screen, unsigned char alu); -Bool glamor_set_planemask(PixmapPtr pixmap, unsigned long planemask); +Bool glamor_set_planemask(int depth, unsigned long planemask); RegionPtr glamor_bitmap_to_region(PixmapPtr pixmap); void glamor_track_stipple(GCPtr gc); -/* glamor_glyphs.c */ -Bool glamor_realize_glyph_caches(ScreenPtr screen); -void glamor_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph); -void glamor_glyphs_fini(ScreenPtr screen); -void glamor_glyphs(CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr *glyphs); - /* glamor_render.c */ Bool glamor_composite_clipped_region(CARD8 op, PicturePtr source, @@ -744,10 +704,6 @@ void glamor_composite(CARD8 op, void glamor_init_composite_shaders(ScreenPtr screen); void glamor_fini_composite_shaders(ScreenPtr screen); -void glamor_composite_glyph_rects(CARD8 op, - PicturePtr src, PicturePtr mask, - PicturePtr dst, int nrect, - glamor_composite_rect_t *rects); void glamor_composite_rects(CARD8 op, PicturePtr pDst, xRenderColor *color, int nRect, xRectangle *rects); @@ -994,6 +950,22 @@ void glamor_composite_rectangles(CARD8 op, xRenderColor *color, int num_rects, xRectangle *rects); +/* glamor_composite_glyphs.c */ +Bool +glamor_composite_glyphs_init(ScreenPtr pScreen); + +void +glamor_composite_glyphs_fini(ScreenPtr pScreen); + +void +glamor_composite_glyphs(CARD8 op, + PicturePtr src, + PicturePtr dst, + PictFormatPtr mask_format, + INT16 x_src, + INT16 y_src, int nlist, + GlyphListPtr list, GlyphPtr *glyphs); + /* glamor_sync.c */ Bool glamor_sync_init(ScreenPtr screen); @@ -1077,8 +1049,6 @@ void glamor_xv_render(glamor_port_private *port_priv); #if 0 #define MAX_FBO_SIZE 32 /* For test purpose only. */ #endif -//#define GLYPHS_NO_EDEGEMAP_OVERLAP_CHECK -#define GLYPHS_EDEGE_OVERLAP_LOOSE_CHECK #include "glamor_font.h" diff --git a/xorg-server/glamor/glamor_program.c b/xorg-server/glamor/glamor_program.c index 8aab53f4f..1dc5f1983 100644 --- a/xorg-server/glamor/glamor_program.c +++ b/xorg-server/glamor/glamor_program.c @@ -47,7 +47,7 @@ static const glamor_facet glamor_fill_tile = { .name = "tile", .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n", .fs_exec = " gl_FragColor = texture2D(sampler, fill_pos);\n", - .locations = glamor_program_location_fill, + .locations = glamor_program_location_fillsamp | glamor_program_location_fillpos, .use = use_tile, }; @@ -66,7 +66,7 @@ static const glamor_facet glamor_fill_stipple = { " if (a == 0.0)\n" " discard;\n" " gl_FragColor = fg;\n"), - .locations = glamor_program_location_fg | glamor_program_location_fill, + .locations = glamor_program_location_fg | glamor_program_location_fillsamp | glamor_program_location_fillpos, .use = use_stipple, }; @@ -87,7 +87,7 @@ static const glamor_facet glamor_fill_opaque_stipple = { " gl_FragColor = bg;\n" " else\n" " gl_FragColor = fg;\n"), - .locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fill, + .locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_fillsamp | glamor_program_location_fillpos, .use = use_opaque_stipple }; @@ -114,12 +114,15 @@ static glamor_location_var location_vars[] = { .fs_vars = "uniform vec4 bg;\n" }, { - .location = glamor_program_location_fill, + .location = glamor_program_location_fillsamp, + .fs_vars = "uniform sampler2D sampler;\n" + }, + { + .location = glamor_program_location_fillpos, .vs_vars = ("uniform vec2 fill_offset;\n" "uniform vec2 fill_size_inv;\n" "varying vec2 fill_pos;\n"), - .fs_vars = ("uniform sampler2D sampler;\n" - "uniform vec2 fill_size_inv;\n" + .fs_vars = ("uniform vec2 fill_size_inv;\n" "varying vec2 fill_pos;\n") }, { @@ -136,6 +139,10 @@ static glamor_location_var location_vars[] = { .vs_vars = "uniform float dash_length;\n", .fs_vars = "uniform sampler2D dash;\n", }, + { + .location = glamor_program_location_atlas, + .fs_vars = "uniform sampler2D atlas;\n", + }, }; #define NUM_LOCATION_VARS (sizeof location_vars / sizeof location_vars[0]) @@ -183,6 +190,7 @@ fs_location_vars(glamor_program_location locations) static const char vs_template[] = "%s" /* version */ + "%s" /* defines */ "%s" /* prim vs_vars */ "%s" /* fill vs_vars */ "%s" /* location vs_vars */ @@ -195,12 +203,14 @@ static const char vs_template[] = static const char fs_template[] = "%s" /* version */ GLAMOR_DEFAULT_PRECISION + "%s" /* defines */ "%s" /* prim fs_vars */ "%s" /* fill fs_vars */ "%s" /* location fs_vars */ "void main() {\n" "%s" /* prim fs_exec */ "%s" /* fill fs_exec */ + "%s" /* combine */ "}\n"; static const char * @@ -236,7 +246,9 @@ Bool glamor_build_program(ScreenPtr screen, glamor_program *prog, const glamor_facet *prim, - const glamor_facet *fill) + const glamor_facet *fill, + const char *combine, + const char *defines) { glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); @@ -282,6 +294,7 @@ glamor_build_program(ScreenPtr screen, if (asprintf(&vs_prog_string, vs_template, str(version_string), + str(defines), str(prim->vs_vars), str(fill->vs_vars), vs_vars, @@ -292,26 +305,30 @@ glamor_build_program(ScreenPtr screen, if (asprintf(&fs_prog_string, fs_template, str(version_string), + str(defines), str(prim->fs_vars), str(fill->fs_vars), fs_vars, str(prim->fs_exec), - str(fill->fs_exec)) < 0) + str(fill->fs_exec), + str(combine)) < 0) fs_prog_string = NULL; if (!vs_prog_string || !fs_prog_string) goto fail; + prog->prog = glCreateProgram(); #if DBG - ErrorF("\nPrograms for %s %s\nVertex shader:\n\n%s\n\nFragment Shader:\n\n%s", - prim->name, fill->name, vs_prog_string, fs_prog_string); + ErrorF("\n\tProgram %d for %s %s\n\tVertex shader:\n\n\t================\n%s\n\n\tFragment Shader:\n\n%s\t================\n", + prog->prog, prim->name, fill->name, vs_prog_string, fs_prog_string); #endif - prog->prog = glCreateProgram(); prog->flags = flags; prog->locations = locations; prog->prim_use = prim->use; + prog->prim_use_render = prim->use_render; prog->fill_use = fill->use; + prog->fill_use_render = fill->use_render; vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, vs_prog_string); fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, fs_prog_string); @@ -335,13 +352,14 @@ glamor_build_program(ScreenPtr screen, prog->matrix_uniform = glamor_get_uniform(prog, glamor_program_location_none, "v_matrix"); prog->fg_uniform = glamor_get_uniform(prog, glamor_program_location_fg, "fg"); prog->bg_uniform = glamor_get_uniform(prog, glamor_program_location_bg, "bg"); - prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_offset"); - prog->fill_size_inv_uniform = glamor_get_uniform(prog, glamor_program_location_fill, "fill_size_inv"); + prog->fill_offset_uniform = glamor_get_uniform(prog, glamor_program_location_fillpos, "fill_offset"); + prog->fill_size_inv_uniform = glamor_get_uniform(prog, glamor_program_location_fillpos, "fill_size_inv"); prog->font_uniform = glamor_get_uniform(prog, glamor_program_location_font, "font"); prog->bitplane_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitplane"); prog->bitmul_uniform = glamor_get_uniform(prog, glamor_program_location_bitplane, "bitmul"); prog->dash_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash"); prog->dash_length_uniform = glamor_get_uniform(prog, glamor_program_location_dash, "dash_length"); + prog->atlas_uniform = glamor_get_uniform(prog, glamor_program_location_atlas, "atlas"); free(version_string); free(fs_vars); @@ -396,7 +414,7 @@ glamor_use_program_fill(PixmapPtr pixmap, if (!fill) return NULL; - if (!glamor_build_program(screen, prog, prim, fill)) + if (!glamor_build_program(screen, prog, prim, fill, NULL, NULL)) return NULL; } @@ -405,3 +423,238 @@ glamor_use_program_fill(PixmapPtr pixmap, return prog; } + +static struct blendinfo composite_op_info[] = { + [PictOpClear] = {0, 0, GL_ZERO, GL_ZERO}, + [PictOpSrc] = {0, 0, GL_ONE, GL_ZERO}, + [PictOpDst] = {0, 0, GL_ZERO, GL_ONE}, + [PictOpOver] = {0, 1, GL_ONE, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpOverReverse] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ONE}, + [PictOpIn] = {1, 0, GL_DST_ALPHA, GL_ZERO}, + [PictOpInReverse] = {0, 1, GL_ZERO, GL_SRC_ALPHA}, + [PictOpOut] = {1, 0, GL_ONE_MINUS_DST_ALPHA, GL_ZERO}, + [PictOpOutReverse] = {0, 1, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpAtop] = {1, 1, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpAtopReverse] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA}, + [PictOpXor] = {1, 1, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA}, + [PictOpAdd] = {0, 0, GL_ONE, GL_ONE}, +}; + +static void +glamor_set_blend(CARD8 op, glamor_program_alpha alpha, PicturePtr dst) +{ + GLenum src_blend, dst_blend; + struct blendinfo *op_info; + + switch (alpha) { + case glamor_program_alpha_ca_first: + op = PictOpOutReverse; + break; + case glamor_program_alpha_ca_second: + op = PictOpAdd; + break; + default: + break; + } + + if (op == PictOpSrc) + return; + + op_info = &composite_op_info[op]; + + src_blend = op_info->source_blend; + dst_blend = op_info->dest_blend; + + /* If there's no dst alpha channel, adjust the blend op so that we'll treat + * it as always 1. + */ + if (PICT_FORMAT_A(dst->format) == 0 && op_info->dest_alpha) { + if (src_blend == GL_DST_ALPHA) + src_blend = GL_ONE; + else if (src_blend == GL_ONE_MINUS_DST_ALPHA) + src_blend = GL_ZERO; + } + + /* Set up the source alpha value for blending in component alpha mode. */ + if (alpha != glamor_program_alpha_normal && op_info->source_alpha) { + if (dst_blend == GL_SRC_ALPHA) + dst_blend = GL_SRC_COLOR; + else if (dst_blend == GL_ONE_MINUS_SRC_ALPHA) + dst_blend = GL_ONE_MINUS_SRC_COLOR; + } + + glEnable(GL_BLEND); + glBlendFunc(src_blend, dst_blend); +} + +static Bool +use_source_solid(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog) +{ + + glamor_set_blend(op, prog->alpha, dst); + + glamor_set_color(glamor_get_drawable_pixmap(dst->pDrawable), + src->pSourcePict->solidFill.color, + prog->fg_uniform); + return TRUE; +} + +const glamor_facet glamor_source_solid = { + .name = "render_solid", + .fs_exec = " vec4 source = fg;\n", + .locations = glamor_program_location_fg, + .use_render = use_source_solid, +}; + +static Bool +use_source_picture(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog) +{ + glamor_set_blend(op, prog->alpha, dst); + + return glamor_set_texture((PixmapPtr) src->pDrawable, + 0, 0, + prog->fill_offset_uniform, + prog->fill_size_inv_uniform); +} + +const glamor_facet glamor_source_picture = { + .name = "render_picture", + .vs_exec = " fill_pos = (fill_offset + primitive.xy + pos) * fill_size_inv;\n", + .fs_exec = " vec4 source = texture2D(sampler, fill_pos);\n", + .locations = glamor_program_location_fillsamp | glamor_program_location_fillpos, + .use_render = use_source_picture, +}; + +static Bool +use_source_1x1_picture(CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog) +{ + glamor_set_blend(op, prog->alpha, dst); + + return glamor_set_texture_pixmap((PixmapPtr) src->pDrawable); +} + +const glamor_facet glamor_source_1x1_picture = { + .name = "render_picture", + .fs_exec = " vec4 source = texture2D(sampler, vec2(0.5));\n", + .locations = glamor_program_location_fillsamp, + .use_render = use_source_1x1_picture, +}; + +const glamor_facet *glamor_facet_source[glamor_program_source_count] = { + [glamor_program_source_solid] = &glamor_source_solid, + [glamor_program_source_picture] = &glamor_source_picture, + [glamor_program_source_1x1_picture] = &glamor_source_1x1_picture, +}; + +static const char *glamor_combine[] = { + [glamor_program_alpha_normal] = " gl_FragColor = source * mask.a;\n", + [glamor_program_alpha_ca_first] = " gl_FragColor = source.a * mask;\n", + [glamor_program_alpha_ca_second] = " gl_FragColor = source * mask;\n" +}; + +static Bool +glamor_setup_one_program_render(ScreenPtr screen, + glamor_program *prog, + glamor_program_source source_type, + glamor_program_alpha alpha, + const glamor_facet *prim, + const char *defines) +{ + if (prog->failed) + return FALSE; + + if (!prog->prog) { + const glamor_facet *fill = glamor_facet_source[source_type]; + + if (!fill) + return FALSE; + + if (!glamor_build_program(screen, prog, prim, fill, glamor_combine[alpha], defines)) + return FALSE; + prog->alpha = alpha; + } + + return TRUE; +} + +glamor_program * +glamor_setup_program_render(CARD8 op, + PicturePtr src, + PicturePtr mask, + PicturePtr dst, + glamor_program_render *program_render, + const glamor_facet *prim, + const char *defines) +{ + ScreenPtr screen = dst->pDrawable->pScreen; + glamor_program_alpha alpha; + glamor_program_source source_type; + glamor_program *prog; + + if (op > ARRAY_SIZE(composite_op_info)) + return NULL; + + if (glamor_is_component_alpha(mask)) { + /* This only works for PictOpOver */ + if (op != PictOpOver) + return NULL; + alpha = glamor_program_alpha_ca_first; + } else + alpha = glamor_program_alpha_normal; + + if (src->pDrawable) { + + /* Can't do transforms, alphamaps or sourcing from non-pixmaps yet */ + if (src->transform || src->alphaMap || src->pDrawable->type != DRAWABLE_PIXMAP) + return NULL; + + if (src->pDrawable->width == 1 && src->pDrawable->height == 1 && src->repeat) + source_type = glamor_program_source_1x1_picture; + else + source_type = glamor_program_source_picture; + } else { + SourcePictPtr sp = src->pSourcePict; + if (!sp) + return NULL; + switch (sp->type) { + case SourcePictTypeSolidFill: + source_type = glamor_program_source_solid; + break; + default: + return NULL; + } + } + + prog = &program_render->progs[source_type][alpha]; + if (!glamor_setup_one_program_render(screen, prog, source_type, alpha, prim, defines)) + return NULL; + + if (alpha == glamor_program_alpha_ca_first) { + + /* Make sure we can also build the second program before + * deciding to use this path. + */ + if (!glamor_setup_one_program_render(screen, + &program_render->progs[source_type][glamor_program_alpha_ca_second], + source_type, glamor_program_alpha_ca_second, prim, + defines)) + return NULL; + } + return prog; +} + +Bool +glamor_use_program_render(glamor_program *prog, + CARD8 op, + PicturePtr src, + PicturePtr dst) +{ + glUseProgram(prog->prog); + + if (prog->prim_use_render && !prog->prim_use_render(op, src, dst, prog)) + return FALSE; + + if (prog->fill_use_render && !prog->fill_use_render(op, src, dst, prog)) + return FALSE; + return TRUE; +} diff --git a/xorg-server/glamor/glamor_program.h b/xorg-server/glamor/glamor_program.h index fa3877c5d..9e561cd92 100644 --- a/xorg-server/glamor/glamor_program.h +++ b/xorg-server/glamor/glamor_program.h @@ -27,23 +27,36 @@ typedef enum { glamor_program_location_none = 0, glamor_program_location_fg = 1, glamor_program_location_bg = 2, - glamor_program_location_fill = 4, - glamor_program_location_font = 8, - glamor_program_location_bitplane = 16, - glamor_program_location_dash = 32, + glamor_program_location_fillsamp = 4, + glamor_program_location_fillpos = 8, + glamor_program_location_font = 16, + glamor_program_location_bitplane = 32, + glamor_program_location_dash = 64, + glamor_program_location_atlas = 128, } glamor_program_location; typedef enum { glamor_program_flag_none = 0, } glamor_program_flag; +typedef enum { + glamor_program_alpha_normal, + glamor_program_alpha_ca_first, + glamor_program_alpha_ca_second, + glamor_program_alpha_count +} glamor_program_alpha; + typedef struct _glamor_program glamor_program; typedef Bool (*glamor_use) (PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg); +typedef Bool (*glamor_use_render) (CARD8 op, PicturePtr src, PicturePtr dst, glamor_program *prog); + typedef struct { const char *name; const int version; + char *vs_defines; + char *fs_defines; const char *vs_vars; const char *vs_exec; const char *fs_vars; @@ -52,6 +65,7 @@ typedef struct { const glamor_program_flag flags; const char *source_name; glamor_use use; + glamor_use_render use_render; } glamor_facet; struct _glamor_program { @@ -67,10 +81,14 @@ struct _glamor_program { GLint bitmul_uniform; GLint dash_uniform; GLint dash_length_uniform; + GLint atlas_uniform; glamor_program_location locations; glamor_program_flag flags; glamor_use prim_use; glamor_use fill_use; + glamor_program_alpha alpha; + glamor_use_render prim_use_render; + glamor_use_render fill_use_render; }; typedef struct { @@ -83,7 +101,9 @@ Bool glamor_build_program(ScreenPtr screen, glamor_program *prog, const glamor_facet *prim, - const glamor_facet *fill); + const glamor_facet *fill, + const char *combine, + const char *defines); Bool glamor_use_program(PixmapPtr pixmap, @@ -97,4 +117,37 @@ glamor_use_program_fill(PixmapPtr pixmap, glamor_program_fill *program_fill, const glamor_facet *prim); +typedef enum { + glamor_program_source_solid, + glamor_program_source_picture, + glamor_program_source_1x1_picture, + glamor_program_source_count, +} glamor_program_source; + +typedef struct { + glamor_program progs[glamor_program_source_count][glamor_program_alpha_count]; +} glamor_program_render; + +static inline Bool +glamor_is_component_alpha(PicturePtr mask) { + if (mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) + return TRUE; + return FALSE; +} + +glamor_program * +glamor_setup_program_render(CARD8 op, + PicturePtr src, + PicturePtr mask, + PicturePtr dst, + glamor_program_render *program_render, + const glamor_facet *prim, + const char *defines); + +Bool +glamor_use_program_render(glamor_program *prog, + CARD8 op, + PicturePtr src, + PicturePtr dst); + #endif /* _GLAMOR_PROGRAM_H_ */ diff --git a/xorg-server/glamor/glamor_render.c b/xorg-server/glamor/glamor_render.c index 27c09fd48..efca36744 100644 --- a/xorg-server/glamor/glamor_render.c +++ b/xorg-server/glamor/glamor_render.c @@ -1701,139 +1701,3 @@ glamor_composite(CARD8 op, glamor_finish_access_picture(source); glamor_finish_access_picture(dest); } - -static void -glamor_get_src_rect_extent(int nrect, - glamor_composite_rect_t *rects, BoxPtr extent) -{ - extent->x1 = MAXSHORT; - extent->y1 = MAXSHORT; - extent->x2 = MINSHORT; - extent->y2 = MINSHORT; - - while (nrect--) { - if (extent->x1 > rects->x_src) - extent->x1 = rects->x_src; - if (extent->y1 > rects->y_src) - extent->y1 = rects->y_src; - if (extent->x2 < rects->x_src + rects->width) - extent->x2 = rects->x_src + rects->width; - if (extent->y2 < rects->y_src + rects->height) - extent->y2 = rects->y_src + rects->height; - rects++; - } -} - -static void -glamor_composite_src_rect_translate(int nrect, - glamor_composite_rect_t *rects, - int x, int y) -{ - while (nrect--) { - rects->x_src += x; - rects->y_src += y; - rects++; - } -} - -void -glamor_composite_glyph_rects(CARD8 op, - PicturePtr src, PicturePtr mask, PicturePtr dst, - int nrect, glamor_composite_rect_t *rects) -{ - int n; - PicturePtr temp_src = NULL; - glamor_composite_rect_t *r; - - ValidatePicture(src); - ValidatePicture(dst); - if (!(glamor_is_large_picture(src) - || (mask && glamor_is_large_picture(mask)) - || glamor_is_large_picture(dst))) { - PixmapPtr src_pixmap = NULL; - PixmapPtr mask_pixmap = NULL; - PixmapPtr dst_pixmap = NULL; - PixmapPtr temp_src_pixmap = NULL; - glamor_pixmap_private *src_pixmap_priv = NULL; - glamor_pixmap_private *mask_pixmap_priv = NULL; - glamor_pixmap_private *dst_pixmap_priv; - glamor_pixmap_private *temp_src_priv = NULL; - BoxRec src_extent; - - dst_pixmap = glamor_get_drawable_pixmap(dst->pDrawable); - dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); - - if (mask && mask->pDrawable) { - mask_pixmap = glamor_get_drawable_pixmap(mask->pDrawable); - mask_pixmap_priv = glamor_get_pixmap_private(mask_pixmap); - } - if (src->pDrawable) { - src_pixmap = glamor_get_drawable_pixmap(src->pDrawable); - src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); - } - - if (!src->pDrawable - && (src->pSourcePict->type != SourcePictTypeSolidFill)) { - glamor_get_src_rect_extent(nrect, rects, &src_extent); - temp_src = glamor_convert_gradient_picture(dst->pDrawable->pScreen, - src, - src_extent.x1, - src_extent.y1, - src_extent.x2 - - src_extent.x1, - src_extent.y2 - - src_extent.y1); - if (!temp_src) - goto fallback; - - temp_src_pixmap = (PixmapPtr) (temp_src->pDrawable); - temp_src_priv = glamor_get_pixmap_private(temp_src_pixmap); - glamor_composite_src_rect_translate(nrect, rects, - -src_extent.x1, -src_extent.y1); - } - else { - temp_src = src; - temp_src_pixmap = src_pixmap; - temp_src_priv = src_pixmap_priv; - } - - if (mask && mask->componentAlpha) { - if (op == PictOpOver) { - if (glamor_composite_with_shader(PictOpOutReverse, - temp_src, mask, dst, - temp_src_pixmap, mask_pixmap, dst_pixmap, - temp_src_priv, - mask_pixmap_priv, - dst_pixmap_priv, nrect, rects, - TRUE)) - goto done; - } - } - else { - if (glamor_composite_with_shader - (op, temp_src, mask, dst, - temp_src_pixmap, mask_pixmap, dst_pixmap, - temp_src_priv, mask_pixmap_priv, - dst_pixmap_priv, nrect, rects, FALSE)) - goto done; - } - } - fallback: - n = nrect; - r = rects; - - while (n--) { - CompositePicture(op, - temp_src ? temp_src : src, - mask, - dst, - r->x_src, r->y_src, - r->x_mask, r->y_mask, - r->x_dst, r->y_dst, r->width, r->height); - r++; - } - - done: - if (temp_src && temp_src != src) - FreePicture(temp_src, 0); -} diff --git a/xorg-server/glamor/glamor_spans.c b/xorg-server/glamor/glamor_spans.c index b358c60bd..58da3edf7 100644 --- a/xorg-server/glamor/glamor_spans.c +++ b/xorg-server/glamor/glamor_spans.c @@ -279,7 +279,7 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src, if (gc->alu != GXcopy) goto bail; - if (!glamor_pm_is_solid(&pixmap->drawable, gc->planemask)) + if (!glamor_pm_is_solid(gc->depth, gc->planemask)) goto bail; glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); diff --git a/xorg-server/glamor/glamor_text.c b/xorg-server/glamor/glamor_text.c index c7c1ab738..81a22a5af 100644 --- a/xorg-server/glamor/glamor_text.c +++ b/xorg-server/glamor/glamor_text.c @@ -417,7 +417,7 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc, fill_facet = &glamor_facet_image_fill; } - if (!glamor_build_program(screen, prog, prim_facet, fill_facet)) + if (!glamor_build_program(screen, prog, prim_facet, fill_facet, NULL, NULL)) goto bail; } @@ -431,7 +431,7 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc, /* Check planemask before drawing background to * bail early if it's not OK */ - if (!glamor_set_planemask(pixmap, gc->planemask)) + if (!glamor_set_planemask(gc->depth, gc->planemask)) goto bail; for (c = 0; c < count; c++) if (charinfo[c]) diff --git a/xorg-server/glamor/glamor_transform.c b/xorg-server/glamor/glamor_transform.c index 6d29e9eb6..f476a99b7 100644 --- a/xorg-server/glamor/glamor_transform.c +++ b/xorg-server/glamor/glamor_transform.c @@ -129,7 +129,7 @@ glamor_set_solid(PixmapPtr pixmap, CARD32 pixel; int alu = use_alu ? gc->alu : GXcopy; - if (!glamor_set_planemask(pixmap, gc->planemask)) + if (!glamor_set_planemask(gc->depth, gc->planemask)) return FALSE; pixel = gc->fgPixel; @@ -155,12 +155,7 @@ glamor_set_solid(PixmapPtr pixmap, } Bool -glamor_set_texture(PixmapPtr pixmap, - PixmapPtr texture, - int off_x, - int off_y, - GLint offset_uniform, - GLint size_inv_uniform) +glamor_set_texture_pixmap(PixmapPtr texture) { glamor_pixmap_private *texture_priv; @@ -175,6 +170,23 @@ glamor_set_texture(PixmapPtr pixmap, glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture_priv->fbo->tex); + /* we're not setting the sampler uniform here as we always use + * GL_TEXTURE0, and the default value for uniforms is zero. So, + * save a bit of CPU time by taking advantage of that. + */ + return TRUE; +} + +Bool +glamor_set_texture(PixmapPtr texture, + int off_x, + int off_y, + GLint offset_uniform, + GLint size_inv_uniform) +{ + if (!glamor_set_texture_pixmap(texture)) + return FALSE; + glUniform2f(offset_uniform, off_x, off_y); glUniform2f(size_inv_uniform, 1.0f/texture->drawable.width, 1.0f/texture->drawable.height); return TRUE; @@ -189,11 +201,10 @@ glamor_set_tiled(PixmapPtr pixmap, if (!glamor_set_alu(pixmap->drawable.pScreen, gc->alu)) return FALSE; - if (!glamor_set_planemask(pixmap, gc->planemask)) + if (!glamor_set_planemask(gc->depth, gc->planemask)) return FALSE; - return glamor_set_texture(pixmap, - gc->tile.pixmap, + return glamor_set_texture(gc->tile.pixmap, -gc->patOrg.x, -gc->patOrg.y, offset_uniform, @@ -274,8 +285,7 @@ glamor_set_stippled(PixmapPtr pixmap, if (!glamor_set_solid(pixmap, gc, TRUE, fg_uniform)) return FALSE; - return glamor_set_texture(pixmap, - stipple, + return glamor_set_texture(stipple, -gc->patOrg.x, -gc->patOrg.y, offset_uniform, diff --git a/xorg-server/glamor/glamor_transform.h b/xorg-server/glamor/glamor_transform.h index 36b789af8..dca6a26ab 100644 --- a/xorg-server/glamor/glamor_transform.h +++ b/xorg-server/glamor/glamor_transform.h @@ -39,8 +39,10 @@ glamor_set_color(PixmapPtr pixmap, GLint uniform); Bool -glamor_set_texture(PixmapPtr pixmap, - PixmapPtr texture, +glamor_set_texture_pixmap(PixmapPtr texture); + +Bool +glamor_set_texture(PixmapPtr texture, int off_x, int off_y, GLint offset_uniform, diff --git a/xorg-server/glamor/glamor_utils.c b/xorg-server/glamor/glamor_utils.c index f06896096..d3e6fd3ff 100644 --- a/xorg-server/glamor/glamor_utils.c +++ b/xorg-server/glamor/glamor_utils.c @@ -31,7 +31,7 @@ glamor_solid_boxes(PixmapPtr pixmap, xRectangle *rect; int n; - rect = malloc(nbox * sizeof (xRectangle)); + rect = xallocarray(nbox, sizeof(xRectangle)); if (!rect) return; for (n = 0; n < nbox; n++) { diff --git a/xorg-server/glx/single2.c b/xorg-server/glx/single2.c index a6ea614fd..acc66ac07 100644 --- a/xorg-server/glx/single2.c +++ b/xorg-server/glx/single2.c @@ -62,9 +62,8 @@ __glXDisp_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) size = *(GLsizei *) (pc + 0); type = *(GLenum *) (pc + 4); if (cx->feedbackBufSize < size) { - cx->feedbackBuf = (GLfloat *) realloc(cx->feedbackBuf, - (size_t) size - * __GLX_SIZE_FLOAT32); + cx->feedbackBuf = reallocarray(cx->feedbackBuf, + (size_t) size, __GLX_SIZE_FLOAT32); if (!cx->feedbackBuf) { cl->client->errorValue = size; return BadAlloc; @@ -94,8 +93,8 @@ __glXDisp_SelectBuffer(__GLXclientState * cl, GLbyte * pc) pc += __GLX_SINGLE_HDR_SIZE; size = *(GLsizei *) (pc + 0); if (cx->selectBufSize < size) { - cx->selectBuf = (GLuint *) realloc(cx->selectBuf, - (size_t) size * __GLX_SIZE_CARD32); + cx->selectBuf = reallocarray(cx->selectBuf, + (size_t) size, __GLX_SIZE_CARD32); if (!cx->selectBuf) { cl->client->errorValue = size; return BadAlloc; diff --git a/xorg-server/glx/single2swap.c b/xorg-server/glx/single2swap.c index 53490694b..d5bb1c03c 100644 --- a/xorg-server/glx/single2swap.c +++ b/xorg-server/glx/single2swap.c @@ -63,9 +63,8 @@ __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) size = *(GLsizei *) (pc + 0); type = *(GLenum *) (pc + 4); if (cx->feedbackBufSize < size) { - cx->feedbackBuf = (GLfloat *) realloc(cx->feedbackBuf, - (size_t) size - * __GLX_SIZE_FLOAT32); + cx->feedbackBuf = reallocarray(cx->feedbackBuf, + (size_t) size, __GLX_SIZE_FLOAT32); if (!cx->feedbackBuf) { cl->client->errorValue = size; return BadAlloc; @@ -99,8 +98,8 @@ __glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc) __GLX_SWAP_INT(pc + 0); size = *(GLsizei *) (pc + 0); if (cx->selectBufSize < size) { - cx->selectBuf = (GLuint *) realloc(cx->selectBuf, - (size_t) size * __GLX_SIZE_CARD32); + cx->selectBuf = reallocarray(cx->selectBuf, + (size_t) size, __GLX_SIZE_CARD32); if (!cx->selectBuf) { cl->client->errorValue = size; return BadAlloc; diff --git a/xorg-server/hw/dmx/config/dmxconfig.c b/xorg-server/hw/dmx/config/dmxconfig.c index 2cc9ab396..1d10ec018 100644 --- a/xorg-server/hw/dmx/config/dmxconfig.c +++ b/xorg-server/hw/dmx/config/dmxconfig.c @@ -204,8 +204,8 @@ dmxConfigAddDisplay(const char *name, { DMXScreenInfo *dmxScreen; - if (!(dmxScreens = realloc(dmxScreens, - (dmxNumScreens + 1) * sizeof(*dmxScreens)))) + if (!(dmxScreens = reallocarray(dmxScreens, dmxNumScreens + 1, + sizeof(*dmxScreens)))) dmxLog(dmxFatal, "dmxConfigAddDisplay: realloc failed for screen %d (%s)\n", dmxNumScreens, name); @@ -234,8 +234,8 @@ dmxConfigAddInput(const char *name, int core) { DMXInputInfo *dmxInput; - if (!(dmxInputs = realloc(dmxInputs, - (dmxNumInputs + 1) * sizeof(*dmxInputs)))) + if (!(dmxInputs = reallocarray(dmxInputs, dmxNumInputs + 1, + sizeof(*dmxInputs)))) dmxLog(dmxFatal, "dmxConfigAddInput: realloc failed for input %d (%s)\n", dmxNumInputs, name); @@ -341,7 +341,7 @@ dmxConfigCopyFromOption(DMXConfigOptionPtr o) for (pt = o->option; pt; pt = pt->next) { if (pt->string) { ++argc; - argv = realloc(argv, (argc + 1) * sizeof(*argv)); + argv = reallocarray(argv, argc + 1, sizeof(*argv)); argv[argc] = (char *) pt->string; } } diff --git a/xorg-server/hw/dmx/dmx.c b/xorg-server/hw/dmx/dmx.c index 2988df33a..9729963da 100644 --- a/xorg-server/hw/dmx/dmx.c +++ b/xorg-server/hw/dmx/dmx.c @@ -427,7 +427,7 @@ ProcDMXChangeScreensAttributes(ClientPtr client) if (!_DMXXineramaActive()) goto noxinerama; - if (!(attribs = malloc(stuff->screenCount * sizeof(*attribs)))) + if (!(attribs = xallocarray(stuff->screenCount, sizeof(*attribs)))) return BadAlloc; for (i = 0; i < stuff->screenCount; i++) { @@ -624,18 +624,18 @@ ProcDMXGetWindowAttributes(ClientPtr client) REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq); - if (!(screens = malloc(count * sizeof(*screens)))) + if (!(screens = xallocarray(count, sizeof(*screens)))) return BadAlloc; - if (!(windows = malloc(count * sizeof(*windows)))) { + if (!(windows = xallocarray(count, sizeof(*windows)))) { free(screens); return BadAlloc; } - if (!(pos = malloc(count * sizeof(*pos)))) { + if (!(pos = xallocarray(count, sizeof(*pos)))) { free(windows); free(screens); return BadAlloc; } - if (!(vis = malloc(count * sizeof(*vis)))) { + if (!(vis = xallocarray(count, sizeof(*vis)))) { free(pos); free(windows); free(screens); diff --git a/xorg-server/hw/dmx/dmxcmap.c b/xorg-server/hw/dmx/dmxcmap.c index 450627b40..7a87a9864 100644 --- a/xorg-server/hw/dmx/dmxcmap.c +++ b/xorg-server/hw/dmx/dmxcmap.c @@ -177,7 +177,7 @@ dmxStoreColors(ColormapPtr pColormap, int ndef, xColorItem * pdef) dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap); if (dmxScreen->beDisplay && (pColormap->pVisual->class & DynamicClass)) { - XColor *color = malloc(sizeof(*color) * ndef); + XColor *color = xallocarray(ndef, sizeof(*color)); int i; if (color) { diff --git a/xorg-server/hw/dmx/dmxcursor.c b/xorg-server/hw/dmx/dmxcursor.c index 70f2bc4b4..0ef800e39 100644 --- a/xorg-server/hw/dmx/dmxcursor.c +++ b/xorg-server/hw/dmx/dmxcursor.c @@ -203,7 +203,7 @@ miPointerScreenFuncRec dmxPointerCursorFuncs = { static int * dmxSLCreate(void) { - int *list = malloc(dmxNumScreens * sizeof(*list)); + int *list = xallocarray(dmxNumScreens, sizeof(*list)); int i; for (i = 0; i < dmxNumScreens; i++) diff --git a/xorg-server/hw/dmx/dmxextension.c b/xorg-server/hw/dmx/dmxextension.c index fcc97e3df..75d7166f3 100644 --- a/xorg-server/hw/dmx/dmxextension.c +++ b/xorg-server/hw/dmx/dmxextension.c @@ -1188,8 +1188,8 @@ dmxBERestoreRenderGlyph(void *value, XID id, void *n) /* Now allocate the memory we need */ images = calloc(len_images, sizeof(char)); - gids = malloc(glyphSet->hash.tableEntries * sizeof(Glyph)); - glyphs = malloc(glyphSet->hash.tableEntries * sizeof(XGlyphInfo)); + gids = xallocarray(glyphSet->hash.tableEntries, sizeof(Glyph)); + glyphs = xallocarray(glyphSet->hash.tableEntries, sizeof(XGlyphInfo)); pos = images; ctr = 0; diff --git a/xorg-server/hw/dmx/dmxfont.c b/xorg-server/hw/dmx/dmxfont.c index 115422d41..25a04a6f0 100644 --- a/xorg-server/hw/dmx/dmxfont.c +++ b/xorg-server/hw/dmx/dmxfont.c @@ -72,7 +72,7 @@ dmxGetFontPath(int *npaths) newfp = malloc(*npaths + len); c = (unsigned char *) newfp; - fp = malloc(*npaths * sizeof(*fp)); + fp = xallocarray(*npaths, sizeof(*fp)); memmove(newfp, paths + 1, *npaths + len - 1); l = *paths; @@ -306,7 +306,7 @@ dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont) if (!dmxFontPath) dmxLog(dmxWarning, "No default font path is set.\n"); - goodfps = malloc(npaths * sizeof(*goodfps)); + goodfps = xallocarray(npaths, sizeof(*goodfps)); dmxLog(dmxError, "The DMX server failed to set the following font paths on " @@ -354,7 +354,7 @@ dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont) return FALSE; } - newfp = malloc(len * sizeof(*newfp)); + newfp = xallocarray(len, sizeof(*newfp)); for (i = 0; i < npaths; i++) { if (goodfps[i]) { int n = strlen(fp[i]); diff --git a/xorg-server/hw/dmx/dmxgc.c b/xorg-server/hw/dmx/dmxgc.c index ec15d27aa..c4789a607 100644 --- a/xorg-server/hw/dmx/dmxgc.c +++ b/xorg-server/hw/dmx/dmxgc.c @@ -397,7 +397,7 @@ dmxChangeClip(GCPtr pGC, int type, void *pvalue, int nrects) } else { if (dmxScreen->beDisplay) { nRects = RegionNumRects((RegionPtr) pGC->clientClip); - pRects = malloc(nRects * sizeof(*pRects)); + pRects = xallocarray(nRects, sizeof(*pRects)); pBox = RegionRects((RegionPtr) pGC->clientClip); for (i = 0; i < nRects; i++) { diff --git a/xorg-server/hw/dmx/dmxinit.c b/xorg-server/hw/dmx/dmxinit.c index 025dc8637..3d394c52b 100644 --- a/xorg-server/hw/dmx/dmxinit.c +++ b/xorg-server/hw/dmx/dmxinit.c @@ -438,7 +438,7 @@ dmxGetColormaps(DMXScreenInfo * dmxScreen) int i; dmxScreen->beNumDefColormaps = dmxScreen->beNumVisuals; - dmxScreen->beDefColormaps = malloc(dmxScreen->beNumDefColormaps * + dmxScreen->beDefColormaps = xallocarray(dmxScreen->beNumDefColormaps, sizeof(*dmxScreen->beDefColormaps)); for (i = 0; i < dmxScreen->beNumDefColormaps; i++) @@ -793,7 +793,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[]) nconfigs = dmxScreen->numGlxVisuals; } - configprivs = malloc(nconfigs * sizeof(dmxGlxVisualPrivate *)); + configprivs = xallocarray(nconfigs, sizeof(dmxGlxVisualPrivate *)); if (configs != NULL && configprivs != NULL) { int j; diff --git a/xorg-server/hw/dmx/dmxpict.c b/xorg-server/hw/dmx/dmxpict.c index aaca178b9..1f1022ee6 100644 --- a/xorg-server/hw/dmx/dmxpict.c +++ b/xorg-server/hw/dmx/dmxpict.c @@ -390,7 +390,7 @@ dmxProcRenderAddGlyphs(ClientPtr client) sizeof(xRenderAddGlyphsReq) - (sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs); - gidsCopy = malloc(sizeof(*gidsCopy) * nglyphs); + gidsCopy = xallocarray(nglyphs, sizeof(*gidsCopy)); for (i = 0; i < nglyphs; i++) gidsCopy[i] = gids[i]; @@ -434,7 +434,7 @@ dmxProcRenderFreeGlyphs(ClientPtr client) nglyphs = ((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq)) >> 2; if (nglyphs) { - gids = malloc(sizeof(*gids) * nglyphs); + gids = xallocarray(nglyphs, sizeof(*gids)); for (i = 0; i < nglyphs; i++) gids[i] = ((CARD32 *) (stuff + 1))[i]; @@ -569,11 +569,11 @@ dmxProcRenderCompositeGlyphs(ClientPtr client) /* The following only works for Render version > 0.2 */ /* All of the XGlyphElt* structure sizes are identical */ - elts = malloc(nelt * sizeof(XGlyphElt8)); + elts = xallocarray(nelt, sizeof(XGlyphElt8)); if (!elts) return BadAlloc; - glyphs = malloc(nglyph * size); + glyphs = xallocarray(nglyph, size); if (!glyphs) { free(elts); return BadAlloc; @@ -925,7 +925,7 @@ dmxChangePictureClip(PicturePtr pPicture, int clipType, void *value, int n) int nRects; nRects = nBox; - pRects = pRect = malloc(nRects * sizeof(*pRect)); + pRects = pRect = xallocarray(nRects, sizeof(*pRect)); while (nBox--) { pRect->x = pBox->x1; diff --git a/xorg-server/hw/dmx/dmxprop.c b/xorg-server/hw/dmx/dmxprop.c index 5e306d286..4c85268b7 100644 --- a/xorg-server/hw/dmx/dmxprop.c +++ b/xorg-server/hw/dmx/dmxprop.c @@ -171,7 +171,7 @@ dmxPropertyCheckOtherServers(DMXScreenInfo * dmxScreen, Atom atom) dmxLogOutputWarning(dmxScreen, "%s also running on %s\n", tp.value, dmxScreen->name); - list = realloc(list, ++count * sizeof(*list)); + list = reallocarray(list, ++count, sizeof(*list)); list[count - 1] = malloc(tp.nitems + 2); strncpy(list[count - 1], (char *) tp.value, tp.nitems + 1); } diff --git a/xorg-server/hw/dmx/dmxwindow.c b/xorg-server/hw/dmx/dmxwindow.c index c157e1099..dcdb9ac60 100644 --- a/xorg-server/hw/dmx/dmxwindow.c +++ b/xorg-server/hw/dmx/dmxwindow.c @@ -969,7 +969,7 @@ dmxDoSetShape(WindowPtr pWindow) if (wBoundingShape(pWindow)) { pBox = RegionRects(wBoundingShape(pWindow)); nRect = nBox = RegionNumRects(wBoundingShape(pWindow)); - pRectFirst = pRect = malloc(nRect * sizeof(*pRect)); + pRectFirst = pRect = xallocarray(nRect, sizeof(*pRect)); while (nBox--) { pRect->x = pBox->x1; pRect->y = pBox->y1; @@ -992,7 +992,7 @@ dmxDoSetShape(WindowPtr pWindow) if (wClipShape(pWindow)) { pBox = RegionRects(wClipShape(pWindow)); nRect = nBox = RegionNumRects(wClipShape(pWindow)); - pRectFirst = pRect = malloc(nRect * sizeof(*pRect)); + pRectFirst = pRect = xallocarray(nRect, sizeof(*pRect)); while (nBox--) { pRect->x = pBox->x1; pRect->y = pBox->y1; diff --git a/xorg-server/hw/dmx/glxProxy/glxcmds.c b/xorg-server/hw/dmx/glxProxy/glxcmds.c index 4c500c93d..ddcb98135 100644 --- a/xorg-server/hw/dmx/glxProxy/glxcmds.c +++ b/xorg-server/hw/dmx/glxProxy/glxcmds.c @@ -284,11 +284,11 @@ CreateContext(__GLXclientState * cl, * allocate memory for back-end servers info */ num_be_screens = to_screen - from_screen + 1; - glxc->real_ids = (XID *) malloc(sizeof(XID) * num_be_screens); + glxc->real_ids = xallocarray(num_be_screens, sizeof(XID)); if (!glxc->real_ids) { return BadAlloc; } - glxc->real_vids = (XID *) malloc(sizeof(XID) * num_be_screens); + glxc->real_vids = xallocarray(num_be_screens, sizeof(XID)); if (!glxc->real_vids) { return BadAlloc; } @@ -685,22 +685,16 @@ AddCurrentContext(__GLXclientState * cl, __GLXcontext * glxc, DrawablePtr pDraw) if (!num) { table = (__GLXcontext **) malloc(sizeof(__GLXcontext *)); cl->currentDrawables = (DrawablePtr *) malloc(sizeof(DrawablePtr)); - cl->be_currentCTag = - (GLXContextTag *) malloc(screenInfo.numScreens * - sizeof(GLXContextTag)); + cl->be_currentCTag = xallocarray(screenInfo.numScreens, + sizeof(GLXContextTag)); } else { - table = (__GLXcontext **) realloc(table, - (num + 1) * sizeof(__GLXcontext *)); - cl->currentDrawables = (DrawablePtr *) realloc(cl->currentDrawables, - (num + - 1) * - sizeof(DrawablePtr)); - cl->be_currentCTag = - (GLXContextTag *) realloc(cl->be_currentCTag, - (num + - 1) * screenInfo.numScreens * - sizeof(GLXContextTag)); + table = reallocarray(table, num + 1, sizeof(__GLXcontext *)); + cl->currentDrawables = reallocarray(cl->currentDrawables, num + 1, + sizeof(DrawablePtr)); + cl->be_currentCTag = reallocarray(cl->be_currentCTag, + (num + 1) * screenInfo.numScreens, + sizeof(GLXContextTag)); } table[num] = glxc; cl->currentDrawables[num] = pDraw; @@ -1896,7 +1890,7 @@ CreateGLXPixmap(__GLXclientState * cl, if (!pGlxPixmap) { return BadAlloc; } - pGlxPixmap->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens); + pGlxPixmap->be_xids = xallocarray(screenInfo.numScreens, sizeof(XID)); if (!pGlxPixmap->be_xids) { free(pGlxPixmap); return BadAlloc; @@ -3356,7 +3350,7 @@ __glXCreatePbuffer(__GLXclientState * cl, GLbyte * pc) return BadAlloc; } - pGlxPbuffer->be_xids = (XID *) malloc(sizeof(XID) * screenInfo.numScreens); + pGlxPbuffer->be_xids = xallocarray(screenInfo.numScreens, sizeof(XID)); if (!pGlxPbuffer->be_xids) { free(pGlxPbuffer); return BadAlloc; @@ -3617,13 +3611,13 @@ __glXGetDrawableAttributes(__GLXclientState * cl, GLbyte * pc) } if (reply.numAttribs) { - attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32; - attribs = (CARD32 *) malloc(attribs_size); + attribs = xallocarray(reply.numAttribs, 2 * __GLX_SIZE_CARD32); if (attribs == NULL) { UnlockDisplay(dpy); SyncHandle(); return BadAlloc; } + attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32; _XRead(dpy, (char *) attribs, attribs_size); } diff --git a/xorg-server/hw/dmx/glxProxy/glxscreens.c b/xorg-server/hw/dmx/glxProxy/glxscreens.c index 15bb1e862..508e67ed4 100644 --- a/xorg-server/hw/dmx/glxProxy/glxscreens.c +++ b/xorg-server/hw/dmx/glxProxy/glxscreens.c @@ -129,7 +129,7 @@ CalcServerVersionAndExtensions(void) /* * read extensions strings of all back-end servers */ - be_extensions = (char **) malloc(__glXNumActiveScreens * sizeof(char *)); + be_extensions = xallocarray(__glXNumActiveScreens, sizeof(char *)); if (!be_extensions) return; @@ -237,10 +237,9 @@ __glXScreenInit(GLint numscreens) // find the set of FBConfigs that are present on all back-end // servers - only those configs will be supported */ - __glXFBConfigs = (__GLXFBConfig **) malloc(dmxScreen0->numFBConfigs * - (numscreens + - 1) * - sizeof(__GLXFBConfig *)); + __glXFBConfigs = + xallocarray(dmxScreen0->numFBConfigs * (numscreens + 1), + sizeof(__GLXFBConfig *)); __glXNumFBConfigs = 0; for (c = 0; c < dmxScreen0->numFBConfigs; c++) { diff --git a/xorg-server/hw/dmx/input/dmxarg.c b/xorg-server/hw/dmx/input/dmxarg.c index 4a74b4c9e..6c21ae959 100644 --- a/xorg-server/hw/dmx/input/dmxarg.c +++ b/xorg-server/hw/dmx/input/dmxarg.c @@ -86,7 +86,7 @@ void dmxArgAdd(dmxArg a, const char *string) { if (a->argm <= a->argc + 2) - a->argv = realloc(a->argv, sizeof(*a->argv) * (a->argm *= 2)); + a->argv = reallocarray(a->argv, (a->argm *= 2), sizeof(*a->argv)); a->argv[a->argc++] = strdup(string); a->argv[a->argc] = NULL; } diff --git a/xorg-server/hw/dmx/input/dmxinputinit.c b/xorg-server/hw/dmx/input/dmxinputinit.c index 56a39df8c..cdefd9ae0 100644 --- a/xorg-server/hw/dmx/input/dmxinputinit.c +++ b/xorg-server/hw/dmx/input/dmxinputinit.c @@ -814,8 +814,8 @@ dmxInputCopyLocal(DMXInputInfo * dmxInput, DMXLocalInputInfoPtr s) dmxLocal->deviceId = -1; ++dmxInput->numDevs; - dmxInput->devs = realloc(dmxInput->devs, - dmxInput->numDevs * sizeof(*dmxInput->devs)); + dmxInput->devs = reallocarray(dmxInput->devs, + dmxInput->numDevs, sizeof(*dmxInput->devs)); dmxInput->devs[dmxInput->numDevs - 1] = dmxLocal; return dmxLocal; diff --git a/xorg-server/hw/dmx/input/dmxmotion.c b/xorg-server/hw/dmx/input/dmxmotion.c index 1642894a2..7f2cb8ed9 100644 --- a/xorg-server/hw/dmx/input/dmxmotion.c +++ b/xorg-server/hw/dmx/input/dmxmotion.c @@ -113,9 +113,8 @@ dmxPointerPutMotionEvent(DeviceIntPtr pDevice, int i; if (!dmxLocal->history) { - dmxLocal->history = malloc(sizeof(*dmxLocal->history) - * (numAxes + 1) - * DMX_MOTION_SIZE); + dmxLocal->history = xallocarray(numAxes + 1, + sizeof(*dmxLocal->history) * DMX_MOTION_SIZE); dmxLocal->head = 0; dmxLocal->tail = 0; dmxLocal->valuators = calloc(sizeof(*dmxLocal->valuators), numAxes); diff --git a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c index 3d5cf7721..748b608c2 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c @@ -431,8 +431,8 @@ EphyrDuplicateVisual(unsigned int a_screen, * extend the list of visual IDs in that entry, * so to add a_new_id in there. */ - vids = realloc(cur_depth->vids, - (cur_depth->numVids + 1) * sizeof(VisualID)); + vids = reallocarray(cur_depth->vids, + cur_depth->numVids + 1, sizeof(VisualID)); if (!vids) { EPHYR_LOG_ERROR("failed to realloc numids\n"); goto out; diff --git a/xorg-server/hw/kdrive/ephyr/ephyrinit.c b/xorg-server/hw/kdrive/ephyr/ephyrinit.c index 897aa1955..8fbaf1d44 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrinit.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrinit.c @@ -52,6 +52,13 @@ void processScreenOrOutputArg(const char *screen_size, const char *output, char void processOutputArg(const char *output, char *parent_id); void processScreenArg(const char *screen_size, char *parent_id); +int +main(int argc, char *argv[], char *envp[]) +{ + hostx_use_resname(basename(argv[0]), 0); + return dix_main(argc, argv, envp); +} + void InitCard(char *name) { @@ -209,10 +216,6 @@ ddxProcessArgument(int argc, char **argv, int i) EPHYR_DBG("mark argv[%d]='%s'", i, argv[i]); - if (i == 1) { - hostx_use_resname(basename(argv[0]), 0); - } - if (!strcmp(argv[i], "-parent")) { if (i + 1 < argc) { int j; diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c index c67ff60d3..dc265d545 100644 --- a/xorg-server/hw/kdrive/ephyr/hostx.c +++ b/xorg-server/hw/kdrive/ephyr/hostx.c @@ -129,8 +129,8 @@ hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num, Boo int index = HostX.n_screens; HostX.n_screens += 1; - HostX.screens = realloc(HostX.screens, - HostX.n_screens * sizeof(HostX.screens[0])); + HostX.screens = reallocarray(HostX.screens, + HostX.n_screens, sizeof(HostX.screens[0])); HostX.screens[index] = screen; scrpriv->screen = screen; @@ -177,7 +177,7 @@ hostx_set_win_title(KdScreenInfo *screen, const char *extra_text) memset(buf, 0, BUF_LEN + 1); snprintf(buf, BUF_LEN, "Xephyr on %s.%d %s", - HostX.server_dpy_name, + HostX.server_dpy_name ? HostX.server_dpy_name : ":0", scrpriv->mynum, (extra_text != NULL) ? extra_text : ""); xcb_icccm_set_wm_name(HostX.conn, @@ -798,7 +798,7 @@ hostx_screen_init(KdScreenInfo *screen, } EPHYR_DBG("host_screen=%p x=%d, y=%d, wxh=%dx%d, buffer_height=%d", - host_screen, x, y, width, height, buffer_height); + screen, x, y, width, height, buffer_height); if (scrpriv->ximg != NULL) { /* Free up the image data if previously used @@ -866,8 +866,13 @@ hostx_screen_init(KdScreenInfo *screen, ~0, NULL); + /* Match server byte order so that the image can be converted to + * the native byte order by xcb_image_put() before drawing */ + if (host_depth_matches_server(scrpriv)) + scrpriv->ximg->byte_order = IMAGE_BYTE_ORDER; + scrpriv->ximg->data = - malloc(scrpriv->ximg->stride * buffer_height); + xallocarray(scrpriv->ximg->stride, buffer_height); } { @@ -933,7 +938,7 @@ hostx_screen_init(KdScreenInfo *screen, *bits_per_pixel = scrpriv->server_depth; EPHYR_DBG("server bpp %i", bytes_per_pixel); - scrpriv->fb_data = malloc (stride * buffer_height); + scrpriv->fb_data = xallocarray (stride, buffer_height); return scrpriv->fb_data; } } @@ -1034,8 +1039,11 @@ hostx_paint_rect(KdScreenInfo *screen, sx, sy, dx, dy, width, height, FALSE); } else { - xcb_image_put(HostX.conn, scrpriv->win, HostX.gc, scrpriv->ximg, - dx, dy, 0); + /* This is slow and could be done better */ + xcb_image_t *img = xcb_image_native (HostX.conn, scrpriv->ximg, 1); + xcb_image_put(HostX.conn, scrpriv->win, HostX.gc, img, 0, 0, 0); + if (scrpriv->ximg != img) + xcb_image_destroy(img); } xcb_aux_sync(HostX.conn); @@ -1148,9 +1156,9 @@ hostx_get_visuals_info(EphyrHostVisualInfo ** a_visuals, int *a_num_entries) for (; depths.rem; xcb_depth_next(&depths)) { xcb_visualtype_t *visuals = xcb_depth_visuals(depths.data); EphyrHostVisualInfo *tmp_visuals = - realloc(host_visuals, - (nb_items + depths.data->visuals_len) - * sizeof(EphyrHostVisualInfo)); + reallocarray(host_visuals, + nb_items + depths.data->visuals_len, + sizeof(EphyrHostVisualInfo)); if (!tmp_visuals) { goto out; } diff --git a/xorg-server/hw/kdrive/fake/Makefile.am b/xorg-server/hw/kdrive/fake/Makefile.am index 14c99c3cc..d28bd2752 100644 --- a/xorg-server/hw/kdrive/fake/Makefile.am +++ b/xorg-server/hw/kdrive/fake/Makefile.am @@ -18,6 +18,7 @@ Xfake_SOURCES = \ Xfake_LDADD = \ libfake.la \ + @KDRIVE_MAIN_LIB@ \ @KDRIVE_LIBS@ Xfake_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) diff --git a/xorg-server/hw/kdrive/fake/fake.c b/xorg-server/hw/kdrive/fake/fake.c index 90e3ec9a6..04a727897 100644 --- a/xorg-server/hw/kdrive/fake/fake.c +++ b/xorg-server/hw/kdrive/fake/fake.c @@ -158,7 +158,7 @@ fakeMapFramebuffer(KdScreenInfo * screen) priv->bytes_per_line = ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2; free(priv->base); - priv->base = malloc(priv->bytes_per_line * screen->height); + priv->base = xallocarray(priv->bytes_per_line, screen->height); if (scrpriv->shadow) { if (!KdShadowFbAlloc diff --git a/xorg-server/hw/kdrive/fbdev/Makefile.am b/xorg-server/hw/kdrive/fbdev/Makefile.am index 7e8ba024c..d550c1391 100644 --- a/xorg-server/hw/kdrive/fbdev/Makefile.am +++ b/xorg-server/hw/kdrive/fbdev/Makefile.am @@ -16,6 +16,7 @@ Xfbdev_SOURCES = \ Xfbdev_LDADD = \ libfbdev.la \ + @KDRIVE_MAIN_LIB@ \ @KDRIVE_LIBS@ Xfbdev_DEPENDENCIES = \ diff --git a/xorg-server/hw/kdrive/fbdev/fbdev.c b/xorg-server/hw/kdrive/fbdev/fbdev.c index 95f64cbef..23f750924 100644 --- a/xorg-server/hw/kdrive/fbdev/fbdev.c +++ b/xorg-server/hw/kdrive/fbdev/fbdev.c @@ -677,7 +677,7 @@ fbdevCreateColormap(ColormapPtr pmap) case FB_VISUAL_STATIC_PSEUDOCOLOR: pVisual = pmap->pVisual; nent = pVisual->ColormapEntries; - pdefs = malloc(nent * sizeof(xColorItem)); + pdefs = xallocarray(nent, sizeof(xColorItem)); if (!pdefs) return FALSE; for (i = 0; i < nent; i++) diff --git a/xorg-server/hw/kdrive/src/kshadow.c b/xorg-server/hw/kdrive/src/kshadow.c index 828ea19a6..7f1e2ee19 100644 --- a/xorg-server/hw/kdrive/src/kshadow.c +++ b/xorg-server/hw/kdrive/src/kshadow.c @@ -36,7 +36,7 @@ KdShadowFbAlloc(KdScreenInfo * screen, Bool rotate) /* use fb computation for width */ paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits); - buf = malloc(paddedWidth * height); + buf = xallocarray(paddedWidth, height); if (!buf) return FALSE; if (screen->fb.shadow) diff --git a/xorg-server/hw/kdrive/src/kxv.c b/xorg-server/hw/kdrive/src/kxv.c index 369db3332..844deca0d 100644 --- a/xorg-server/hw/kdrive/src/kxv.c +++ b/xorg-server/hw/kdrive/src/kxv.c @@ -327,8 +327,8 @@ KdXVInitAdaptors(ScreenPtr pScreen, KdVideoAdaptorPtr infoPtr, int number) void *moreSpace; totFormat *= 2; - moreSpace = realloc(pFormat, - totFormat * sizeof(XvFormatRec)); + moreSpace = reallocarray(pFormat, totFormat, + sizeof(XvFormatRec)); if (!moreSpace) break; pFormat = moreSpace; diff --git a/xorg-server/hw/vfb/InitOutput.c b/xorg-server/hw/vfb/InitOutput.c index bcaaa85e4..8b867e3b9 100644 --- a/xorg-server/hw/vfb/InitOutput.c +++ b/xorg-server/hw/vfb/InitOutput.c @@ -292,7 +292,7 @@ ddxProcessArgument(int argc, char *argv[], int i) if (vfbNumScreens <= screenNum) { vfbScreens = - realloc(vfbScreens, sizeof(*vfbScreens) * (screenNum + 1)); + reallocarray(vfbScreens, screenNum + 1, sizeof(*vfbScreens)); if (!vfbScreens) FatalError("Not enough memory for screen %d\n", screenNum); for (; vfbNumScreens <= screenNum; ++vfbNumScreens) @@ -407,9 +407,9 @@ vfbInstallColormap(ColormapPtr pmap) swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue); swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries); - ppix = (Pixel *) malloc(entries * sizeof(Pixel)); - prgb = (xrgb *) malloc(entries * sizeof(xrgb)); - defs = (xColorItem *) malloc(entries * sizeof(xColorItem)); + ppix = xallocarray(entries, sizeof(Pixel)); + prgb = xallocarray(entries, sizeof(xrgb)); + defs = xallocarray(entries, sizeof(xColorItem)); for (i = 0; i < entries; i++) ppix[i] = i; diff --git a/xorg-server/hw/xfree86/common/xf86AutoConfig.c b/xorg-server/hw/xfree86/common/xf86AutoConfig.c index 1450afbfc..6b8d0eb89 100644 --- a/xorg-server/hw/xfree86/common/xf86AutoConfig.c +++ b/xorg-server/hw/xfree86/common/xf86AutoConfig.c @@ -105,7 +105,7 @@ AppendToList(const char *s, const char ***list, int *lines) str = xnfstrdup(s); for (p = strtok(str, "\n"); p; p = strtok(NULL, "\n")) { (*lines)++; - *list = xnfrealloc(*list, (*lines + 1) * sizeof(**list)); + *list = xnfreallocarray(*list, *lines + 1, sizeof(**list)); newstr = xnfalloc(strlen(p) + 2); strcpy(newstr, p); strcat(newstr, "\n"); diff --git a/xorg-server/hw/xfree86/common/xf86Bus.c b/xorg-server/hw/xfree86/common/xf86Bus.c index 889294fe7..bd36fc5ab 100644 --- a/xorg-server/hw/xfree86/common/xf86Bus.c +++ b/xorg-server/hw/xfree86/common/xf86Bus.c @@ -256,11 +256,11 @@ int xf86AllocateEntity(void) { xf86NumEntities++; - xf86Entities = xnfrealloc(xf86Entities, - sizeof(EntityPtr) * xf86NumEntities); + xf86Entities = xnfreallocarray(xf86Entities, + xf86NumEntities, sizeof(EntityPtr)); xf86Entities[xf86NumEntities - 1] = xnfcalloc(1, sizeof(EntityRec)); xf86Entities[xf86NumEntities - 1]->entityPrivates = - xnfcalloc(sizeof(DevUnion) * xf86EntityPrivateCount, 1); + xnfcalloc(xf86EntityPrivateCount, sizeof(DevUnion)); return xf86NumEntities - 1; } @@ -326,12 +326,13 @@ xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex) } pScrn->numEntities++; - pScrn->entityList = xnfrealloc(pScrn->entityList, - pScrn->numEntities * sizeof(int)); + pScrn->entityList = xnfreallocarray(pScrn->entityList, + pScrn->numEntities, sizeof(int)); pScrn->entityList[pScrn->numEntities - 1] = entityIndex; xf86Entities[entityIndex]->inUse = TRUE; - pScrn->entityInstanceList = xnfrealloc(pScrn->entityInstanceList, - pScrn->numEntities * sizeof(int)); + pScrn->entityInstanceList = xnfreallocarray(pScrn->entityInstanceList, + pScrn->numEntities, + sizeof(int)); pScrn->entityInstanceList[pScrn->numEntities - 1] = 0; } @@ -427,8 +428,8 @@ xf86AddDevToEntity(int entityIndex, GDevPtr dev) pEnt = xf86Entities[entityIndex]; pEnt->numInstances++; - pEnt->devices = xnfrealloc(pEnt->devices, - pEnt->numInstances * sizeof(GDevPtr)); + pEnt->devices = xnfreallocarray(pEnt->devices, + pEnt->numInstances, sizeof(GDevPtr)); pEnt->devices[pEnt->numInstances - 1] = dev; dev->claimed = TRUE; } @@ -670,8 +671,8 @@ xf86AllocateEntityPrivateIndex(void) idx = xf86EntityPrivateCount++; for (i = 0; i < xf86NumEntities; i++) { pEnt = xf86Entities[i]; - nprivs = xnfrealloc(pEnt->entityPrivates, - xf86EntityPrivateCount * sizeof(DevUnion)); + nprivs = xnfreallocarray(pEnt->entityPrivates, + xf86EntityPrivateCount, sizeof(DevUnion)); /* Zero the new private */ memset(&nprivs[idx], 0, sizeof(DevUnion)); pEnt->entityPrivates = nprivs; diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c index d42572f38..b8ec8a0ef 100644 --- a/xorg-server/hw/xfree86/common/xf86Config.c +++ b/xorg-server/hw/xfree86/common/xf86Config.c @@ -126,7 +126,7 @@ static Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum, MessageType from); static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor); static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, - Bool active); + Bool active, Bool gpu); static Bool configInput(InputInfoPtr pInfo, XF86ConfInputPtr conf_input, MessageType from); static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display); @@ -363,8 +363,8 @@ xf86ModulelistFromConfig(void ***optlist) /* * allocate the memory and walk the list again to fill in the pointers */ - modulearray = xnfalloc((count + 1) * sizeof(char *)); - optarray = xnfalloc((count + 1) * sizeof(void *)); + modulearray = xnfallocarray(count + 1, sizeof(char *)); + optarray = xnfallocarray(count + 1, sizeof(void *)); count = 0; if (xf86configptr->conf_modules) { modp = xf86configptr->conf_modules->mod_load_lst; @@ -390,7 +390,7 @@ const char ** xf86DriverlistFromConfig(void) { int count = 0; - int j; + int j, k; const char **modulearray; screenLayoutPtr slp; @@ -411,8 +411,10 @@ xf86DriverlistFromConfig(void) */ if (xf86ConfigLayout.screens) { slp = xf86ConfigLayout.screens; - while ((slp++)->screen) { + while (slp->screen) { count++; + count += slp->screen->num_gpu_devices; + slp++; } } @@ -429,12 +431,16 @@ xf86DriverlistFromConfig(void) /* * allocate the memory and walk the list again to fill in the pointers */ - modulearray = xnfalloc((count + 1) * sizeof(char *)); + modulearray = xnfallocarray(count + 1, sizeof(char *)); count = 0; slp = xf86ConfigLayout.screens; while (slp->screen) { modulearray[count] = slp->screen->device->driver; count++; + for (k = 0; k < slp->screen->num_gpu_devices; k++) { + modulearray[count] = slp->screen->gpu_devices[k]->driver; + count++; + } slp++; } @@ -493,7 +499,7 @@ xf86InputDriverlistFromConfig(void) /* * allocate the memory and walk the list again to fill in the pointers */ - modulearray = xnfalloc((count + 1) * sizeof(char *)); + modulearray = xnfallocarray(count + 1, sizeof(char *)); count = 0; idp = xf86ConfigLayout.inputs; while (idp && *idp) { @@ -1086,7 +1092,7 @@ addDevice(InputInfoPtr * list, InputInfoPtr pInfo) for (devs = list; devs && *devs; devs++) count++; - list = xnfrealloc(list, (count + 1) * sizeof(InputInfoPtr)); + list = xnfreallocarray(list, count + 1, sizeof(InputInfoPtr)); list[count] = NULL; list[count - 1] = pInfo; @@ -1502,7 +1508,7 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout, if (!count) /* alloc enough storage even if no screen is specified */ count = 1; - slp = xnfcalloc(1, (count + 1) * sizeof(screenLayoutRec)); + slp = xnfcalloc((count + 1), sizeof(screenLayoutRec)); slp[count].screen = NULL; /* * now that we have storage, loop over the list again and fill in our @@ -1626,12 +1632,12 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout, } DebugF("Found %d inactive devices in the layout section %s\n", count, conf_layout->lay_identifier); - gdp = xnfalloc((count + 1) * sizeof(GDevRec)); + gdp = xnfallocarray(count + 1, sizeof(GDevRec)); gdp[count].identifier = NULL; idp = conf_layout->lay_inactive_lst; count = 0; while (idp) { - if (!configDevice(&gdp[count], idp->inactive_device, FALSE)) + if (!configDevice(&gdp[count], idp->inactive_device, FALSE, FALSE)) goto bail; count++; idp = (XF86ConfInactivePtr) idp->list.next; @@ -1746,7 +1752,7 @@ configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor) count++; conf_port = (XF86ConfVideoPortPtr) conf_port->list.next; } - adaptor->ports = xnfalloc((count) * sizeof(confXvPortRec)); + adaptor->ports = xnfallocarray(count, sizeof(confXvPortRec)); adaptor->numports = count; count = 0; conf_port = conf_adaptor->va_port_lst; @@ -1769,6 +1775,7 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum, XF86ConfAdaptorLinkPtr conf_adaptor; Bool defaultMonitor = FALSE; XF86ConfScreenRec local_conf_screen; + int i; if (!conf_screen) { memset(&local_conf_screen, 0, sizeof(local_conf_screen)); @@ -1811,12 +1818,41 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum, xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n" "\tUsing the first device section listed.\n", screenp->id); } - if (configDevice(screenp->device, conf_screen->scrn_device, TRUE)) { + if (configDevice(screenp->device, conf_screen->scrn_device, TRUE, FALSE)) { screenp->device->myScreenSection = screenp; } else { screenp->device = NULL; } + + if (conf_screen->num_gpu_devices == 0 && xf86configptr->conf_device_lst) { + XF86ConfDevicePtr sdevice = xf86configptr->conf_device_lst->list.next; + + for (i = 0; i < MAX_GPUDEVICES; i++) { + if (!sdevice) + break; + + FIND_SUITABLE (XF86ConfDevicePtr, sdevice, conf_screen->scrn_gpu_devices[i]); + if (!conf_screen->scrn_gpu_devices[i]) + break; + screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec)); + if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) { + screenp->gpu_devices[i]->myScreenSection = screenp; + } + sdevice = conf_screen->scrn_gpu_devices[i]->list.next; + } + screenp->num_gpu_devices = i; + + } else { + for (i = 0; i < conf_screen->num_gpu_devices; i++) { + screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec)); + if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) { + screenp->gpu_devices[i]->myScreenSection = screenp; + } + } + screenp->num_gpu_devices = conf_screen->num_gpu_devices; + } + screenp->options = conf_screen->scrn_option_lst; /* @@ -1827,7 +1863,7 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum, count++; dispptr = (XF86ConfDisplayPtr) dispptr->list.next; } - screenp->displays = xnfalloc((count) * sizeof(DispRec)); + screenp->displays = xnfallocarray(count, sizeof(DispRec)); screenp->numdisplays = count; /* Fill in the default Virtual size, if any */ @@ -1857,7 +1893,7 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum, count++; conf_adaptor = (XF86ConfAdaptorLinkPtr) conf_adaptor->list.next; } - screenp->xvadaptors = xnfalloc((count) * sizeof(confXvAdaptorRec)); + screenp->xvadaptors = xnfallocarray(count, sizeof(confXvAdaptorRec)); screenp->numxvadaptors = 0; conf_adaptor = conf_screen->scrn_adaptor_lst; while (conf_adaptor) { @@ -2096,7 +2132,7 @@ configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display) count++; modep = (XF86ModePtr) modep->list.next; } - displayp->modes = xnfalloc((count + 1) * sizeof(char *)); + displayp->modes = xnfallocarray(count + 1, sizeof(char *)); modep = conf_display->disp_mode_lst; count = 0; while (modep) { @@ -2110,7 +2146,7 @@ configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display) } static Bool -configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active) +configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active, Bool gpu) { int i; @@ -2118,10 +2154,14 @@ configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active) return FALSE; } - if (active) - xf86Msg(X_CONFIG, "| |-->Device \"%s\"\n", - conf_device->dev_identifier); - else + if (active) { + if (gpu) + xf86Msg(X_CONFIG, "| |-->GPUDevice \"%s\"\n", + conf_device->dev_identifier); + else + xf86Msg(X_CONFIG, "| |-->Device \"%s\"\n", + conf_device->dev_identifier); + } else xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n", conf_device->dev_identifier); diff --git a/xorg-server/hw/xfree86/common/xf86Configure.c b/xorg-server/hw/xfree86/common/xf86Configure.c index cc7ff1bb5..1271010fa 100644 --- a/xorg-server/hw/xfree86/common/xf86Configure.c +++ b/xorg-server/hw/xfree86/common/xf86Configure.c @@ -109,7 +109,7 @@ xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, /* Allocate new structure occurrence */ i = nDevToConfig++; DevToConfig = - xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec)); + xnfreallocarray(DevToConfig, nDevToConfig, sizeof(DevToConfigRec)); memset(DevToConfig + i, 0, sizeof(DevToConfigRec)); DevToConfig[i].GDev.chipID = @@ -645,10 +645,10 @@ DoConfigure(void) xf86DoConfigurePass1 = FALSE; - dev2screen = xnfcalloc(1, xf86NumDrivers * sizeof(int)); + dev2screen = xnfcalloc(xf86NumDrivers, sizeof(int)); { - Bool *driverProbed = xnfcalloc(1, xf86NumDrivers * sizeof(Bool)); + Bool *driverProbed = xnfcalloc(xf86NumDrivers, sizeof(Bool)); for (screennum = 0; screennum < nDevToConfig; screennum++) { int k, l, n, oldNumScreens; diff --git a/xorg-server/hw/xfree86/common/xf86DGA.c b/xorg-server/hw/xfree86/common/xf86DGA.c index b9e1e3f88..9533e1c52 100644 --- a/xorg-server/hw/xfree86/common/xf86DGA.c +++ b/xorg-server/hw/xfree86/common/xf86DGA.c @@ -1349,7 +1349,7 @@ ProcXDGAQueryModes(ClientPtr client) return Success; } - if (!(mode = (XDGAModePtr) malloc(num * sizeof(XDGAModeRec)))) + if (!(mode = xallocarray(num, sizeof(XDGAModeRec)))) return BadAlloc; for (i = 0; i < num; i++) diff --git a/xorg-server/hw/xfree86/common/xf86Helper.c b/xorg-server/hw/xfree86/common/xf86Helper.c index e2b32a074..359bac762 100644 --- a/xorg-server/hw/xfree86/common/xf86Helper.c +++ b/xorg-server/hw/xfree86/common/xf86Helper.c @@ -77,8 +77,8 @@ xf86AddDriver(DriverPtr driver, void *module, int flags) xf86NumDrivers = 0; xf86NumDrivers++; - xf86DriverList = xnfrealloc(xf86DriverList, - xf86NumDrivers * sizeof(DriverPtr)); + xf86DriverList = xnfreallocarray(xf86DriverList, + xf86NumDrivers, sizeof(DriverPtr)); xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec)); if (flags & HaveDriverFuncs) *xf86DriverList[xf86NumDrivers - 1] = *driver; @@ -117,9 +117,9 @@ xf86AddInputDriver(InputDriverPtr driver, void *module, int flags) xf86NumInputDrivers = 0; xf86NumInputDrivers++; - xf86InputDriverList = xnfrealloc(xf86InputDriverList, - xf86NumInputDrivers * - sizeof(InputDriverPtr)); + xf86InputDriverList = xnfreallocarray(xf86InputDriverList, + xf86NumInputDrivers, + sizeof(InputDriverPtr)); xf86InputDriverList[xf86NumInputDrivers - 1] = xnfalloc(sizeof(InputDriverRec)); *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver; @@ -173,7 +173,8 @@ xf86AllocateScreen(DriverPtr drv, int flags) if (xf86GPUScreens == NULL) xf86NumGPUScreens = 0; i = xf86NumGPUScreens++; - xf86GPUScreens = xnfrealloc(xf86GPUScreens, xf86NumGPUScreens * sizeof(ScrnInfoPtr)); + xf86GPUScreens = xnfreallocarray(xf86GPUScreens, xf86NumGPUScreens, + sizeof(ScrnInfoPtr)); xf86GPUScreens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1); pScrn = xf86GPUScreens[i]; pScrn->scrnIndex = i + GPU_SCREEN_OFFSET; /* Changes when a screen is removed */ @@ -183,7 +184,8 @@ xf86AllocateScreen(DriverPtr drv, int flags) xf86NumScreens = 0; i = xf86NumScreens++; - xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr)); + xf86Screens = xnfreallocarray(xf86Screens, xf86NumScreens, + sizeof(ScrnInfoPtr)); xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1); pScrn = xf86Screens[i]; @@ -293,16 +295,16 @@ xf86AllocateScrnInfoPrivateIndex(void) idx = xf86ScrnInfoPrivateCount++; for (i = 0; i < xf86NumScreens; i++) { pScr = xf86Screens[i]; - nprivs = xnfrealloc(pScr->privates, - xf86ScrnInfoPrivateCount * sizeof(DevUnion)); + nprivs = xnfreallocarray(pScr->privates, + xf86ScrnInfoPrivateCount, sizeof(DevUnion)); /* Zero the new private */ memset(&nprivs[idx], 0, sizeof(DevUnion)); pScr->privates = nprivs; } for (i = 0; i < xf86NumGPUScreens; i++) { pScr = xf86GPUScreens[i]; - nprivs = xnfrealloc(pScr->privates, - xf86ScrnInfoPrivateCount * sizeof(DevUnion)); + nprivs = xnfreallocarray(pScr->privates, + xf86ScrnInfoPrivateCount, sizeof(DevUnion)); /* Zero the new private */ memset(&nprivs[idx], 0, sizeof(DevUnion)); pScr->privates = nprivs; @@ -636,8 +638,8 @@ xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp, if (i == scrp->confScreen->numdisplays) { scrp->confScreen->numdisplays++; scrp->confScreen->displays = - xnfrealloc(scrp->confScreen->displays, - scrp->confScreen->numdisplays * sizeof(DispRec)); + xnfreallocarray(scrp->confScreen->displays, + scrp->confScreen->numdisplays, sizeof(DispRec)); xf86DrvMsg(scrp->scrnIndex, X_INFO, "Creating default Display subsection in Screen section\n" "\t\"%s\" for depth/fbbpp %d/%d\n", @@ -1367,7 +1369,7 @@ xf86MatchDevice(const char *drivername, GDevPtr ** sectlist) { GDevPtr gdp, *pgdp = NULL; confScreenPtr screensecptr; - int i, j; + int i, j, k; if (sectlist) *sectlist = NULL; @@ -1408,9 +1410,20 @@ xf86MatchDevice(const char *drivername, GDevPtr ** sectlist) /* * we have a matching driver that wasn't claimed, yet */ - pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr)); + pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr)); pgdp[i++] = screensecptr->device; } + for (k = 0; k < screensecptr->num_gpu_devices; k++) { + if ((screensecptr->gpu_devices[k]->driver != NULL) + && (xf86NameCmp(screensecptr->gpu_devices[k]->driver, drivername) == 0) + && (!screensecptr->gpu_devices[k]->claimed)) { + /* + * we have a matching driver that wasn't claimed, yet + */ + pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr)); + pgdp[i++] = screensecptr->gpu_devices[k]; + } + } } /* Then handle the inactive devices */ @@ -1420,7 +1433,7 @@ xf86MatchDevice(const char *drivername, GDevPtr ** sectlist) if (gdp->driver && !gdp->claimed && !xf86NameCmp(gdp->driver, drivername)) { /* we have a matching driver that wasn't claimed yet */ - pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr)); + pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr)); pgdp[i++] = gdp; } j++; diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c index 9fa3dc43c..55bf2bbe4 100644 --- a/xorg-server/hw/xfree86/common/xf86Xinput.c +++ b/xorg-server/hw/xfree86/common/xf86Xinput.c @@ -867,8 +867,9 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable) if (fd != -1) { if (paused) { /* Put on new_input_devices list for delayed probe */ - new_input_devices = xnfrealloc(new_input_devices, - sizeof(pInfo) * (new_input_devices_count + 1)); + new_input_devices = xnfreallocarray(new_input_devices, + new_input_devices_count + 1, + sizeof(pInfo)); new_input_devices[new_input_devices_count] = pInfo; new_input_devices_count++; systemd_logind_release_fd(pInfo->major, pInfo->minor, fd); diff --git a/xorg-server/hw/xfree86/common/xf86cmap.c b/xorg-server/hw/xfree86/common/xf86cmap.c index ab51f9603..704e35358 100644 --- a/xorg-server/hw/xfree86/common/xf86cmap.c +++ b/xorg-server/hw/xfree86/common/xf86cmap.c @@ -166,10 +166,10 @@ xf86HandleColormaps(ScreenPtr pScreen, elements = 1 << sigRGBbits; - if (!(gamma = malloc(elements * sizeof(LOCO)))) + if (!(gamma = xallocarray(elements, sizeof(LOCO)))) return FALSE; - if (!(indices = malloc(maxColors * sizeof(int)))) { + if (!(indices = xallocarray(maxColors, sizeof(int)))) { free(gamma); return FALSE; } @@ -270,7 +270,7 @@ CMapAllocateColormapPrivate(ColormapPtr pmap) else numColors = 1 << pmap->pVisual->nplanes; - if (!(colors = malloc(numColors * sizeof(LOCO)))) + if (!(colors = xallocarray(numColors, sizeof(LOCO)))) return FALSE; if (!(pColPriv = malloc(sizeof(CMapColormapRec)))) { diff --git a/xorg-server/hw/xfree86/common/xf86fbman.c b/xorg-server/hw/xfree86/common/xf86fbman.c index 1b2cb5704..91ddedc29 100644 --- a/xorg-server/hw/xfree86/common/xf86fbman.c +++ b/xorg-server/hw/xfree86/common/xf86fbman.c @@ -317,16 +317,17 @@ localRegisterFreeBoxCallback(ScreenPtr pScreen, offman = (FBManagerPtr) dixLookupPrivate(&pScreen->devPrivates, xf86FBScreenKey); - newCallbacks = realloc(offman->FreeBoxesUpdateCallback, - sizeof(FreeBoxCallbackProcPtr) * - (offman->NumCallbacks + 1)); + newCallbacks = reallocarray(offman->FreeBoxesUpdateCallback, + offman->NumCallbacks + 1, + sizeof(FreeBoxCallbackProcPtr)); if (!newCallbacks) return FALSE; else offman->FreeBoxesUpdateCallback = newCallbacks; - newPrivates = realloc(offman->devPrivates, - sizeof(DevUnion) * (offman->NumCallbacks + 1)); + newPrivates = reallocarray(offman->devPrivates, + offman->NumCallbacks + 1, + sizeof(DevUnion)); if (!newPrivates) return FALSE; else diff --git a/xorg-server/hw/xfree86/common/xf86pciBus.c b/xorg-server/hw/xfree86/common/xf86pciBus.c index e86ecb9d4..8158c2b62 100644 --- a/xorg-server/hw/xfree86/common/xf86pciBus.c +++ b/xorg-server/hw/xfree86/common/xf86pciBus.c @@ -103,9 +103,9 @@ xf86PciProbe(void) while ((info = pci_device_next(iter)) != NULL) { if (PCIINFOCLASSES(info->device_class)) { num++; - xf86PciVideoInfo = xnfrealloc(xf86PciVideoInfo, - (sizeof(struct pci_device *) - * (num + 1))); + xf86PciVideoInfo = xnfreallocarray(xf86PciVideoInfo, + num + 1, + sizeof(struct pci_device *)); xf86PciVideoInfo[num] = NULL; xf86PciVideoInfo[num - 1] = info; @@ -679,7 +679,7 @@ xf86MatchPciInstances(const char *driverName, int vendorID, } pci_iterator_destroy(iter); - instances = xnfalloc(max_entries * sizeof(struct Inst)); + instances = xnfallocarray(max_entries, sizeof(struct Inst)); } iter = pci_slot_match_iterator_create(NULL); @@ -976,7 +976,7 @@ xf86MatchPciInstances(const char *driverName, int vendorID, /* Allocate an entry in the lists to be returned */ numFound++; - retEntities = xnfrealloc(retEntities, numFound * sizeof(int)); + retEntities = xnfreallocarray(retEntities, numFound, sizeof(int)); retEntities[numFound - 1] = xf86ClaimPciSlot(pPci, drvp, instances[i].chip, instances[i].dev, diff --git a/xorg-server/hw/xfree86/common/xf86platformBus.c b/xorg-server/hw/xfree86/common/xf86platformBus.c index c1aaba41a..f1e942378 100644 --- a/xorg-server/hw/xfree86/common/xf86platformBus.c +++ b/xorg-server/hw/xfree86/common/xf86platformBus.c @@ -59,9 +59,9 @@ struct xf86_platform_device *xf86_platform_devices; int xf86_add_platform_device(struct OdevAttributes *attribs, Bool unowned) { - xf86_platform_devices = xnfrealloc(xf86_platform_devices, - (sizeof(struct xf86_platform_device) - * (xf86_num_platform_devices + 1))); + xf86_platform_devices = xnfreallocarray(xf86_platform_devices, + xf86_num_platform_devices + 1, + sizeof(struct xf86_platform_device)); xf86_platform_devices[xf86_num_platform_devices].attribs = attribs; xf86_platform_devices[xf86_num_platform_devices].pdev = NULL; diff --git a/xorg-server/hw/xfree86/common/xf86sbusBus.c b/xorg-server/hw/xfree86/common/xf86sbusBus.c index 07eb71ed8..119211dc5 100644 --- a/xorg-server/hw/xfree86/common/xf86sbusBus.c +++ b/xorg-server/hw/xfree86/common/xf86sbusBus.c @@ -68,7 +68,7 @@ CheckSbusDevice(const char *device, int fbNum) if (!sbusDeviceTable[i].devId) return; xf86SbusInfo = - xnfrealloc(xf86SbusInfo, sizeof(psdp) * (++xf86nSbusInfo + 1)); + xnfreallocarray(xf86SbusInfo, ++xf86nSbusInfo + 1, sizeof(psdp)); xf86SbusInfo[xf86nSbusInfo] = NULL; xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof(sbusDevice), 1); psdp->devId = sbusDeviceTable[i].devId; @@ -406,8 +406,8 @@ xf86MatchSbusInstances(const char *driverName, int sbusDevId, if (psdp->fd == -2) continue; ++allocatedInstances; - instances = xnfrealloc(instances, - allocatedInstances * sizeof(struct Inst)); + instances = xnfreallocarray(instances, + allocatedInstances, sizeof(struct Inst)); instances[allocatedInstances - 1].sbus = psdp; instances[allocatedInstances - 1].dev = NULL; instances[allocatedInstances - 1].claimed = FALSE; @@ -532,7 +532,7 @@ xf86MatchSbusInstances(const char *driverName, int sbusDevId, /* Allocate an entry in the lists to be returned */ numFound++; - retEntities = xnfrealloc(retEntities, numFound * sizeof(int)); + retEntities = xnfreallocarray(retEntities, numFound, sizeof(int)); retEntities[numFound - 1] = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev, instances[i].dev->active ? TRUE : FALSE); @@ -648,7 +648,7 @@ xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, return; fbcmap.count = 0; fbcmap.index = indices[0]; - fbcmap.red = data = malloc(numColors * 3); + fbcmap.red = data = xallocarray(numColors, 3); if (!data) return; fbcmap.green = data + numColors; diff --git a/xorg-server/hw/xfree86/common/xf86str.h b/xorg-server/hw/xfree86/common/xf86str.h index 643a65db1..a58fafebd 100644 --- a/xorg-server/hw/xfree86/common/xf86str.h +++ b/xorg-server/hw/xfree86/common/xf86str.h @@ -440,6 +440,7 @@ typedef struct _confxvadaptrec { void *options; } confXvAdaptorRec, *confXvAdaptorPtr; +#define MAX_GPUDEVICES 4 typedef struct _confscreenrec { const char *id; int screennum; @@ -453,6 +454,9 @@ typedef struct _confscreenrec { int numxvadaptors; confXvAdaptorPtr xvadaptors; void *options; + + int num_gpu_devices; + GDevPtr gpu_devices[MAX_GPUDEVICES]; } confScreenRec, *confScreenPtr; typedef enum { @@ -512,6 +516,9 @@ typedef struct _confdrirec { #define NUM_RESERVED_POINTERS 14 #define NUM_RESERVED_FUNCS 10 +/* let clients know they can use this */ +#define XF86_SCRN_HAS_PREFER_CLONE 1 + typedef void *(*funcPointer) (void); /* flags for depth 24 pixmap options */ @@ -768,6 +775,9 @@ typedef struct _ScrnInfoRec { ClockRangePtr clockRanges; int adjustFlags; + /* initial rightof support disable */ + int preferClone; + /* * These can be used when the minor ABI version is incremented. * The NUM_* parameters must be reduced appropriately to keep the diff --git a/xorg-server/hw/xfree86/common/xf86vmode.c b/xorg-server/hw/xfree86/common/xf86vmode.c index 0ce58e365..818e7dc45 100644 --- a/xorg-server/hw/xfree86/common/xf86vmode.c +++ b/xorg-server/hw/xfree86/common/xf86vmode.c @@ -1240,11 +1240,11 @@ ProcXF86VidModeGetMonitor(ClientPtr client) pad_to_int32(rep.modelLength)); rep.nhsync = nHsync; rep.nvsync = nVrefresh; - hsyncdata = malloc(nHsync * sizeof(CARD32)); + hsyncdata = xallocarray(nHsync, sizeof(CARD32)); if (!hsyncdata) { return BadAlloc; } - vsyncdata = malloc(nVrefresh * sizeof(CARD32)); + vsyncdata = xallocarray(nVrefresh, sizeof(CARD32)); if (!vsyncdata) { free(hsyncdata); @@ -1512,9 +1512,9 @@ ProcXF86VidModeGetGammaRamp(ClientPtr client) length = (stuff->size + 1) & ~1; if (stuff->size) { - ramplen = length * 3 * sizeof(CARD16); - if (!(ramp = malloc(ramplen))) + if (!(ramp = xallocarray(length, 3 * sizeof(CARD16)))) return BadAlloc; + ramplen = length * 3 * sizeof(CARD16); if (!VidModeGetGammaRamp(stuff->screen, stuff->size, ramp, ramp + length, ramp + (length * 2))) { diff --git a/xorg-server/hw/xfree86/common/xf86xv.c b/xorg-server/hw/xfree86/common/xf86xv.c index b974cd212..d613d712c 100644 --- a/xorg-server/hw/xfree86/common/xf86xv.c +++ b/xorg-server/hw/xfree86/common/xf86xv.c @@ -131,8 +131,8 @@ xf86XVRegisterGenericAdaptorDriver(xf86XVInitGenericAdaptorPtr InitFunc) { xf86XVInitGenericAdaptorPtr *newdrivers; - newdrivers = realloc(GenDrivers, sizeof(xf86XVInitGenericAdaptorPtr) * - (1 + NumGenDrivers)); + newdrivers = reallocarray(GenDrivers, 1 + NumGenDrivers, + sizeof(xf86XVInitGenericAdaptorPtr)); if (!newdrivers) return 0; GenDrivers = newdrivers; @@ -159,7 +159,7 @@ xf86XVListGenericAdaptors(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr ** adaptors) n = (*GenDrivers[i]) (pScrn, &DrivAdap); if (0 == n) continue; - new = realloc(*adaptors, sizeof(XF86VideoAdaptorPtr) * (num + n)); + new = reallocarray(*adaptors, num + n, sizeof(XF86VideoAdaptorPtr)); if (NULL == new) continue; *adaptors = new; @@ -436,8 +436,8 @@ xf86XVInitAdaptors(ScreenPtr pScreen, XF86VideoAdaptorPtr * infoPtr, int number) void *moreSpace; totFormat *= 2; - moreSpace = realloc(pFormat, - totFormat * sizeof(XvFormatRec)); + moreSpace = reallocarray(pFormat, totFormat, + sizeof(XvFormatRec)); if (!moreSpace) break; pFormat = moreSpace; diff --git a/xorg-server/hw/xfree86/common/xf86xvmc.c b/xorg-server/hw/xfree86/common/xf86xvmc.c index 3169c054c..a0a94c74b 100644 --- a/xorg-server/hw/xfree86/common/xf86xvmc.c +++ b/xorg-server/hw/xfree86/common/xf86xvmc.c @@ -155,7 +155,7 @@ xf86XvMCScreenInit(ScreenPtr pScreen, if (noXvExtension) return FALSE; - if (!(pAdapt = malloc(sizeof(XvMCAdaptorRec) * num_adaptors))) + if (!(pAdapt = xallocarray(num_adaptors, sizeof(XvMCAdaptorRec)))) return FALSE; if (!dixRegisterPrivateKey(&XF86XvMCScreenKeyRec, PRIVATE_SCREEN, 0)) { diff --git a/xorg-server/hw/xfree86/ddc/ddc.c b/xorg-server/hw/xfree86/ddc/ddc.c index 29185ad8b..ee533db1c 100644 --- a/xorg-server/hw/xfree86/ddc/ddc.c +++ b/xorg-server/hw/xfree86/ddc/ddc.c @@ -437,7 +437,7 @@ xf86DoEEDID(ScrnInfoPtr pScrn, I2CBusPtr pBus, Bool complete) int i, n = EDID_block[0x7e]; if (complete && n) { - EDID_block = realloc(EDID_block, EDID1_LEN * (1 + n)); + EDID_block = reallocarray(EDID_block, 1 + n, EDID1_LEN); for (i = 0; i < n; i++) DDC2Read(dev, i + 1, EDID_block + (EDID1_LEN * (1 + i))); diff --git a/xorg-server/hw/xfree86/dri/xf86dri.c b/xorg-server/hw/xfree86/dri/xf86dri.c index 086e833ed..68f8b7e72 100644 --- a/xorg-server/hw/xfree86/dri/xf86dri.c +++ b/xorg-server/hw/xfree86/dri/xf86dri.c @@ -422,7 +422,7 @@ ProcXF86DRIGetDrawableInfo(register ClientPtr client) if (rep.numClipRects) { /* Clip cliprects to screen dimensions (redirected windows) */ - pClippedRects = malloc(rep.numClipRects * sizeof(drm_clip_rect_t)); + pClippedRects = xallocarray(rep.numClipRects, sizeof(drm_clip_rect_t)); if (pClippedRects) { ScreenPtr pScreen = screenInfo.screens[stuff->screen]; diff --git a/xorg-server/hw/xfree86/dri2/dri2.c b/xorg-server/hw/xfree86/dri2/dri2.c index 0c038b3d1..60ea6dd93 100644 --- a/xorg-server/hw/xfree86/dri2/dri2.c +++ b/xorg-server/hw/xfree86/dri2/dri2.c @@ -1577,7 +1577,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) if (info->version == 3 || info->numDrivers == 0) { /* Driver too old: use the old-style driverName field */ ds->numDrivers = info->driverName ? 1 : 2; - ds->driverNames = malloc(ds->numDrivers * sizeof(*ds->driverNames)); + ds->driverNames = xallocarray(ds->numDrivers, sizeof(*ds->driverNames)); if (!ds->driverNames) goto err_out; @@ -1591,7 +1591,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) } else { ds->numDrivers = info->numDrivers; - ds->driverNames = malloc(info->numDrivers * sizeof(*ds->driverNames)); + ds->driverNames = xallocarray(info->numDrivers, sizeof(*ds->driverNames)); if (!ds->driverNames) goto err_out; memcpy(ds->driverNames, info->driverNames, diff --git a/xorg-server/hw/xfree86/drivers/modesetting/driver.c b/xorg-server/hw/xfree86/drivers/modesetting/driver.c index e2f3846ca..e90e4b842 100644 --- a/xorg-server/hw/xfree86/drivers/modesetting/driver.c +++ b/xorg-server/hw/xfree86/drivers/modesetting/driver.c @@ -451,7 +451,7 @@ dispatch_dirty_region(ScrnInfoPtr scrn, int ret = 0; if (num_cliprects) { - drmModeClip *clip = malloc(num_cliprects * sizeof(drmModeClip)); + drmModeClip *clip = xallocarray(num_cliprects, sizeof(drmModeClip)); BoxPtr rect = REGION_RECTS(dirty); int i; diff --git a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c index 1ea799b3a..f3c9909ef 100644 --- a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -326,6 +326,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, continue; drmmode_output = output->driver_private; + if (drmmode_output->output_id == -1) + continue; output_ids[output_count] = drmmode_output->mode_output->connector_id; output_count++; @@ -366,10 +368,14 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, /* go through all the outputs and force DPMS them back on? */ for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; + drmmode_output_private_ptr drmmode_output; if (output->crtc != crtc) continue; + drmmode_output = output->driver_private; + if (drmmode_output->output_id == -1) + continue; output->funcs->dpms(output, DPMSModeOn); } } @@ -427,10 +433,10 @@ drmmode_set_cursor(xf86CrtcPtr crtc) drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, ms->cursor_width, ms->cursor_height, cursor->bits->xhot, cursor->bits->yhot); + if (!ret) + return; if (ret == -EINVAL) use_set_cursor2 = FALSE; - else - return; } ret = drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, @@ -687,7 +693,7 @@ drmmode_crtc_vblank_pipe(int crtc_id) } static void -drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) +drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num) { xf86CrtcPtr crtc; drmmode_crtc_private_ptr drmmode_crtc; @@ -698,7 +704,7 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); drmmode_crtc->mode_crtc = - drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]); + drmModeGetCrtc(drmmode->fd, mode_res->crtcs[num]); drmmode_crtc->drmmode = drmmode; drmmode_crtc->vblank_pipe = drmmode_crtc_vblank_pipe(num); crtc->driver_private = drmmode_crtc; @@ -712,6 +718,9 @@ drmmode_output_detect(xf86OutputPtr output) drmmode_ptr drmmode = drmmode_output->drmmode; xf86OutputStatus status; + if (drmmode_output->output_id == -1) + return XF86OutputStatusDisconnected; + drmModeFreeConnector(drmmode_output->mode_output); drmmode_output->mode_output = @@ -740,6 +749,46 @@ drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) return MODE_OK; } +static void +drmmode_output_attach_tile(xf86OutputPtr output) +{ + drmmode_output_private_ptr drmmode_output = output->driver_private; + drmModeConnectorPtr koutput = drmmode_output->mode_output; + drmmode_ptr drmmode = drmmode_output->drmmode; + int i; + struct xf86CrtcTileInfo tile_info, *set = NULL; + + if (!koutput) { + xf86OutputSetTile(output, NULL); + return; + } + + /* look for a TILE property */ + for (i = 0; i < koutput->count_props; i++) { + drmModePropertyPtr props; + props = drmModeGetProperty(drmmode->fd, koutput->props[i]); + if (!props) + continue; + + if (!(props->flags & DRM_MODE_PROP_BLOB)) { + drmModeFreeProperty(props); + continue; + } + + if (!strcmp(props->name, "TILE")) { + drmModeFreePropertyBlob(drmmode_output->tile_blob); + drmmode_output->tile_blob = + drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); + } + drmModeFreeProperty(props); + } + if (drmmode_output->tile_blob) { + if (xf86OutputParseKMSTile(drmmode_output->tile_blob->data, drmmode_output->tile_blob->length, &tile_info) == TRUE) + set = &tile_info; + } + xf86OutputSetTile(output, set); +} + static Bool has_panel_fitter(xf86OutputPtr output) { @@ -848,6 +897,8 @@ drmmode_output_get_modes(xf86OutputPtr output) } xf86OutputSetEDID(output, mon); + drmmode_output_attach_tile(output); + /* modes should already be available */ for (i = 0; i < koutput->count_modes; i++) { Mode = xnfalloc(sizeof(DisplayModeRec)); @@ -873,11 +924,13 @@ drmmode_output_destroy(xf86OutputPtr output) free(drmmode_output->props[i].atoms); } free(drmmode_output->props); - for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) { - drmModeFreeEncoder(drmmode_output->mode_encoders[i]); + if (drmmode_output->mode_output) { + for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) { + drmModeFreeEncoder(drmmode_output->mode_encoders[i]); + } + drmModeFreeConnector(drmmode_output->mode_output); } free(drmmode_output->mode_encoders); - drmModeFreeConnector(drmmode_output->mode_output); free(drmmode_output); output->driver_private = NULL; } @@ -1111,22 +1164,134 @@ static const char *const output_names[] = { "DSI", }; +static xf86OutputPtr find_output(ScrnInfoPtr pScrn, int id) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + drmmode_output_private_ptr drmmode_output; + + drmmode_output = output->driver_private; + if (drmmode_output->output_id == id) + return output; + } + return NULL; +} + +static int parse_path_blob(drmModePropertyBlobPtr path_blob, int *conn_base_id, char **path) +{ + char *conn; + char conn_id[5]; + int id, len; + char *blob_data; + + if (!path_blob) + return -1; + + blob_data = path_blob->data; + /* we only handle MST paths for now */ + if (strncmp(blob_data, "mst:", 4)) + return -1; + + conn = strchr(blob_data + 4, '-'); + if (!conn) + return -1; + len = conn - (blob_data + 4); + if (len + 1> 5) + return -1; + memcpy(conn_id, blob_data + 4, len); + conn_id[len + 1] = '\0'; + id = strtoul(conn_id, NULL, 10); + + *conn_base_id = id; + + *path = conn + 1; + return 0; +} + +static void +drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name, + drmModePropertyBlobPtr path_blob) +{ + int ret; + char *extra_path; + int conn_id; + xf86OutputPtr output; + + ret = parse_path_blob(path_blob, &conn_id, &extra_path); + if (ret == -1) + goto fallback; + + output = find_output(pScrn, conn_id); + if (!output) + goto fallback; + + snprintf(name, 32, "%s-%s", output->name, extra_path); + return; + + fallback: + if (koutput->connector_type >= MS_ARRAY_SIZE(output_names)) + snprintf(name, 32, "Unknown-%d", koutput->connector_type_id - 1); +#ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT + else if (pScrn->is_gpu) + snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type], pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, koutput->connector_type_id - 1); +#endif + else + snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id - 1); +} + static void -drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) +drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, Bool dynamic) { xf86OutputPtr output; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); drmModeConnectorPtr koutput; drmModeEncoderPtr *kencoders = NULL; drmmode_output_private_ptr drmmode_output; drmModePropertyPtr props; char name[32]; int i; + drmModePropertyBlobPtr path_blob = NULL; koutput = - drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]); + drmModeGetConnector(drmmode->fd, mode_res->connectors[num]); if (!koutput) return; + for (i = 0; i < koutput->count_props; i++) { + props = drmModeGetProperty(drmmode->fd, koutput->props[i]); + if (props && (props->flags & DRM_MODE_PROP_BLOB)) { + if (!strcmp(props->name, "PATH")) { + path_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); + drmModeFreeProperty(props); + break; + } + drmModeFreeProperty(props); + } + } + + drmmode_create_name(pScrn, koutput, name, path_blob); + + if (path_blob) + drmModeFreePropertyBlob(path_blob); + + if (path_blob && dynamic) { + /* see if we have an output with this name already + and hook stuff up */ + for (i = 0; i < xf86_config->num_output; i++) { + output = xf86_config->output[i]; + + if (strncmp(output->name, name, 32)) + continue; + + drmmode_output = output->driver_private; + drmmode_output->output_id = mode_res->connectors[num]; + drmmode_output->mode_output = koutput; + return; + } + } + kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders); if (!kencoders) { goto out_free_encoders; @@ -1139,17 +1304,6 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) } } - /* need to do smart conversion here for compat with non-kms ATI driver */ - if (koutput->connector_type >= MS_ARRAY_SIZE(output_names)) - snprintf(name, 32, "Unknown-%d", koutput->connector_type_id - 1); - else if (pScrn->is_gpu) - snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type], - pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, - koutput->connector_type_id - 1); - else - snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], - koutput->connector_type_id - 1); - output = xf86OutputCreate(pScrn, &drmmode_output_funcs, name); if (!output) { goto out_free_encoders; @@ -1161,7 +1315,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) goto out_free_encoders; } - drmmode_output->output_id = drmmode->mode_res->connectors[num]; + drmmode_output->output_id = mode_res->connectors[num]; drmmode_output->mode_output = koutput; drmmode_output->mode_encoders = kencoders; drmmode_output->drmmode = drmmode; @@ -1192,6 +1346,8 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num) } } + if (dynamic) + output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output); return; out_free_encoders: if (kencoders) { @@ -1231,7 +1387,7 @@ find_clones(ScrnInfoPtr scrn, xf86OutputPtr output) } static void -drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode) +drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, drmModeResPtr mode_res) { int i, j; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); @@ -1246,8 +1402,8 @@ drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode) for (j = 0; j < drmmode_output->mode_output->count_encoders; j++) { int k; - for (k = 0; k < drmmode->mode_res->count_encoders; k++) { - if (drmmode->mode_res->encoders[k] == + for (k = 0; k < mode_res->count_encoders; k++) { + if (mode_res->encoders[k] == drmmode_output->mode_encoders[j]->encoder_id) drmmode_output->enc_mask |= (1 << k); } @@ -1425,6 +1581,7 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) int i; int ret; uint64_t value = 0; + drmModeResPtr mode_res; /* check for dumb capability */ ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_BUFFER, &value); @@ -1438,23 +1595,24 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) drmmode->scrn = pScrn; drmmode->cpp = cpp; - drmmode->mode_res = drmModeGetResources(drmmode->fd); - if (!drmmode->mode_res) + mode_res = drmModeGetResources(drmmode->fd); + if (!mode_res) return FALSE; - xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, - drmmode->mode_res->max_height); - for (i = 0; i < drmmode->mode_res->count_crtcs; i++) + xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width, + mode_res->max_height); + for (i = 0; i < mode_res->count_crtcs; i++) if (!xf86IsEntityShared(pScrn->entityList[0]) || pScrn->confScreen->device->screen == i) - drmmode_crtc_init(pScrn, drmmode, i); + drmmode_crtc_init(pScrn, drmmode, mode_res, i); - for (i = 0; i < drmmode->mode_res->count_connectors; i++) - drmmode_output_init(pScrn, drmmode, i); + for (i = 0; i < mode_res->count_connectors; i++) + drmmode_output_init(pScrn, drmmode, mode_res, i, FALSE); /* workout clones */ - drmmode_clones_init(pScrn, drmmode); + drmmode_clones_init(pScrn, drmmode, mode_res); + drmModeFreeResources(mode_res); #if XF86_CRTC_VERSION >= 5 xf86ProviderSetup(pScrn, NULL, "modesetting"); #endif @@ -1618,11 +1776,78 @@ drmmode_handle_uevents(int fd, void *closure) drmmode_ptr drmmode = closure; ScrnInfoPtr scrn = drmmode->scrn; struct udev_device *dev; + drmModeResPtr mode_res; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int i, j; + Bool found; + Bool changed = FALSE; dev = udev_monitor_receive_device(drmmode->uevent_monitor); if (!dev) return; + mode_res = drmModeGetResources(drmmode->fd); + if (!mode_res) + goto out; + + if (mode_res->count_crtcs != config->num_crtc) { + ErrorF("number of CRTCs changed - failed to handle, %d vs %d\n", mode_res->count_crtcs, config->num_crtc); + goto out_free_res; + } + + /* figure out if we have gotten rid of any connectors + traverse old output list looking for outputs */ + for (i = 0; i < config->num_output; i++) { + xf86OutputPtr output = config->output[i]; + drmmode_output_private_ptr drmmode_output; + + drmmode_output = output->driver_private; + found = FALSE; + for (j = 0; j < mode_res->count_connectors; j++) { + if (mode_res->connectors[j] == drmmode_output->output_id) { + found = TRUE; + break; + } + } + if (found) + continue; + + drmModeFreeConnector(drmmode_output->mode_output); + drmmode_output->mode_output = NULL; + drmmode_output->output_id = -1; + + changed = TRUE; + } + + /* find new output ids we don't have outputs for */ + for (i = 0; i < mode_res->count_connectors; i++) { + found = FALSE; + + for (j = 0; j < config->num_output; j++) { + xf86OutputPtr output = config->output[j]; + drmmode_output_private_ptr drmmode_output; + + drmmode_output = output->driver_private; + if (mode_res->connectors[i] == drmmode_output->output_id) { + found = TRUE; + break; + } + } + if (found) + continue; + + changed = TRUE; + drmmode_output_init(scrn, drmmode, mode_res, i, 1); + } + + if (changed) { + RRSetChanged(xf86ScrnToScreen(scrn)); + RRTellChanged(xf86ScrnToScreen(scrn)); + } + +out_free_res: + drmModeFreeResources(mode_res); +out: RRGetInfo(xf86ScrnToScreen(scrn), TRUE); udev_device_unref(dev); } diff --git a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h index 3a8959ac3..b0e45b6e0 100644 --- a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -47,7 +47,6 @@ typedef struct { int fd; unsigned fb_id; unsigned old_fb_id; - drmModeResPtr mode_res; drmModeFBPtr mode_fb; int cpp; ScrnInfoPtr scrn; @@ -121,6 +120,7 @@ typedef struct { drmModeConnectorPtr mode_output; drmModeEncoderPtr *mode_encoders; drmModePropertyBlobPtr edid_blob; + drmModePropertyBlobPtr tile_blob; int dpms_enum_id; int num_props; drmmode_prop_ptr props; diff --git a/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.c b/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.c index 58d420e07..cf13f0a9c 100644 --- a/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.c +++ b/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.c @@ -25,6 +25,10 @@ * */ +#ifdef HAVE_DIX_CONFIG_H +#include "dix-config.h" +#endif + #include "dumb_bo.h" #include <errno.h> diff --git a/xorg-server/hw/xfree86/i2c/xf86i2c.c b/xorg-server/hw/xfree86/i2c/xf86i2c.c index cf2cd0971..2a8b8df22 100644 --- a/xorg-server/hw/xfree86/i2c/xf86i2c.c +++ b/xorg-server/hw/xfree86/i2c/xf86i2c.c @@ -872,7 +872,7 @@ xf86I2CGetScreenBuses(int scrnIndex, I2CBusPtr ** pppI2CBus) if (!pppI2CBus) continue; - *pppI2CBus = xnfrealloc(*pppI2CBus, n * sizeof(I2CBusPtr)); + *pppI2CBus = xnfreallocarray(*pppI2CBus, n, sizeof(I2CBusPtr)); (*pppI2CBus)[n - 1] = pI2CBus; } diff --git a/xorg-server/hw/xfree86/loader/loadmod.c b/xorg-server/hw/xfree86/loader/loadmod.c index fdf5bd8c9..73dc1b8dc 100644 --- a/xorg-server/hw/xfree86/loader/loadmod.c +++ b/xorg-server/hw/xfree86/loader/loadmod.c @@ -142,7 +142,7 @@ InitPathList(const char *path) if (addslash) len++; save = list; - list = realloc(list, (n + 2) * sizeof(char *)); + list = reallocarray(list, n + 2, sizeof(char *)); if (!list) { if (save) { save[n] = NULL; @@ -244,7 +244,7 @@ InitPatterns(const char **patternlist) for (i = 0, s = patternlist; *s; i++, s++) if (*s == DEFAULT_LIST) i += sizeof(stdPatterns) / sizeof(stdPatterns[0]) - 1 - 1; - patterns = malloc((i + 1) * sizeof(PatternRec)); + patterns = xallocarray(i + 1, sizeof(PatternRec)); if (!patterns) { return NULL; } @@ -323,7 +323,7 @@ InitSubdirs(const char **subdirlist) } } } - subdirs = malloc((i * 2 + 1) * sizeof(char *)); + subdirs = xallocarray(i * 2 + 1, sizeof(char *)); if (!subdirs) { free(tmp_subdirlist); return NULL; @@ -530,8 +530,8 @@ LoaderListDirs(const char **subdirlist, const char **patternlist) match[1].rm_so != -1) { len = match[1].rm_eo - match[1].rm_so; save = listing; - listing = realloc(listing, - (n + 2) * sizeof(char *)); + listing = reallocarray(listing, n + 2, + sizeof(char *)); if (!listing) { if (save) { save[n] = NULL; diff --git a/xorg-server/hw/xfree86/man/xorg.conf.man b/xorg-server/hw/xfree86/man/xorg.conf.man index d26c3cc4d..e9b6d9990 100644 --- a/xorg-server/hw/xfree86/man/xorg.conf.man +++ b/xorg-server/hw/xfree86/man/xorg.conf.man @@ -1906,6 +1906,7 @@ sections have the following format: .B "Section \*qScreen\*q" .BI " Identifier \*q" name \*q .BI " Device \*q" devid \*q +.BI " GPUDevice \*q" devid \*q .BI " Monitor \*q" monid \*q .I " entries" .I " ..." @@ -1949,6 +1950,18 @@ of a .B Device section in the config file. .TP 7 +.BI "GPUDevice \*q" device\-id \*q +This entry specifies the +.B Device +section to be used as a secondary GPU device for this screen. When multiple graphics cards are +present, this is what ties a specific secondary card to a screen. The +.I device\-id +must match the +.B Identifier +of a +.B Device +section in the config file. This can be specified up to 4 times for a single screen. +.TP 7 .BI "Monitor \*q" monitor\-id \*q specifies which monitor description is to be used for this screen. If a diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c index a1947241b..38bc58cbc 100644 --- a/xorg-server/hw/xfree86/modes/xf86Crtc.c +++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c @@ -118,7 +118,7 @@ xf86CrtcCreate(ScrnInfoPtr scrn, const xf86CrtcFuncsRec * funcs) /* Preallocate gamma at a sensible size. */ crtc->gamma_size = 256; - crtc->gamma_red = malloc(3 * crtc->gamma_size * sizeof(CARD16)); + crtc->gamma_red = xallocarray(crtc->gamma_size, 3 * sizeof(CARD16)); if (!crtc->gamma_red) { free(crtc); return NULL; @@ -127,10 +127,10 @@ xf86CrtcCreate(ScrnInfoPtr scrn, const xf86CrtcFuncsRec * funcs) crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size; if (xf86_config->crtc) - crtcs = realloc(xf86_config->crtc, - (xf86_config->num_crtc + 1) * sizeof(xf86CrtcPtr)); + crtcs = reallocarray(xf86_config->crtc, + xf86_config->num_crtc + 1, sizeof(xf86CrtcPtr)); else - crtcs = malloc((xf86_config->num_crtc + 1) * sizeof(xf86CrtcPtr)); + crtcs = xallocarray(xf86_config->num_crtc + 1, sizeof(xf86CrtcPtr)); if (!crtcs) { free(crtc->gamma_red); free(crtc); @@ -620,11 +620,12 @@ xf86OutputCreate(ScrnInfoPtr scrn, } if (xf86_config->output) - outputs = realloc(xf86_config->output, - (xf86_config->num_output + - 1) * sizeof(xf86OutputPtr)); + outputs = reallocarray(xf86_config->output, + xf86_config->num_output + 1, + sizeof(xf86OutputPtr)); else - outputs = malloc((xf86_config->num_output + 1) * sizeof(xf86OutputPtr)); + outputs = xallocarray(xf86_config->num_output + 1, + sizeof(xf86OutputPtr)); if (!outputs) { free(output); return NULL; @@ -942,7 +943,7 @@ xf86PickCrtcs(ScrnInfoPtr scrn, if (modes[n] == NULL) return best_score; - crtcs = malloc(config->num_output * sizeof(xf86CrtcPtr)); + crtcs = xallocarray(config->num_output, sizeof(xf86CrtcPtr)); if (!crtcs) return best_score; @@ -1123,6 +1124,15 @@ xf86InitialOutputPositions(ScrnInfoPtr scrn, DisplayModePtr * modes) int o; int min_x, min_y; + /* check for initial right-of heuristic */ + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + if (output->initial_x || output->initial_y) + return TRUE; + } + for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; @@ -2102,6 +2112,118 @@ bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect) return match; } +static int +numEnabledOutputs(xf86CrtcConfigPtr config, Bool *enabled) +{ + int i = 0, p; + + for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ; + + return i; +} + +static Bool +xf86TargetRightOf(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, + DisplayModePtr *modes, Bool *enabled, + int width, int height) +{ + int o; + int w = 0; + Bool has_tile = FALSE; + uint32_t configured_outputs; + + if (scrn->preferClone) + return FALSE; + + if (numEnabledOutputs(config, enabled) < 2) + return FALSE; + + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + DisplayModePtr mode = + xf86OutputHasPreferredMode(config->output[o], width, height); + + if (!mode) + return FALSE; + + w += mode->HDisplay; + } + + if (w > width) + return FALSE; + + w = 0; + configured_outputs = 0; + + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + DisplayModePtr mode = + xf86OutputHasPreferredMode(config->output[o], width, height); + + if (configured_outputs & (1 << o)) + continue; + + if (config->output[o]->tile_info.group_id) { + has_tile = TRUE; + continue; + } + + config->output[o]->initial_x = w; + w += mode->HDisplay; + + configured_outputs |= (1 << o); + modes[o] = mode; + } + + if (has_tile) { + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + int ht, vt, ot; + int add_x, cur_x = w; + struct xf86CrtcTileInfo *tile_info = &config->output[o]->tile_info, *this_tile; + if (configured_outputs & (1 << o)) + continue; + if (!tile_info->group_id) + continue; + + if (tile_info->tile_h_loc != 0 && tile_info->tile_v_loc != 0) + continue; + + for (ht = 0; ht < tile_info->num_h_tile; ht++) { + int cur_y = 0; + add_x = 0; + for (vt = 0; vt < tile_info->num_v_tile; vt++) { + + for (ot = -1; nextEnabledOutput(config, enabled, &ot); ) { + + DisplayModePtr mode = + xf86OutputHasPreferredMode(config->output[ot], width, height); + if (!config->output[ot]->tile_info.group_id) + continue; + + this_tile = &config->output[ot]->tile_info; + if (this_tile->group_id != tile_info->group_id) + continue; + + if (this_tile->tile_h_loc != ht || + this_tile->tile_v_loc != vt) + continue; + + config->output[ot]->initial_x = cur_x; + config->output[ot]->initial_y = cur_y; + + if (vt == 0) + add_x = this_tile->tile_h_size; + cur_y += this_tile->tile_v_size; + configured_outputs |= (1 << ot); + modes[ot] = mode; + } + } + cur_x += add_x; + } + w = cur_x; + } + } + return TRUE; +} + static Bool xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, DisplayModePtr * modes, Bool *enabled, @@ -2178,14 +2300,10 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, */ if (!ret) do { - int i = 0; float aspect = 0.0; DisplayModePtr a = NULL, b = NULL; - /* count the number of enabled outputs */ - for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++); - - if (i != 1) + if (numEnabledOutputs(config, enabled) != 1) break; p = -1; @@ -2334,7 +2452,7 @@ xf86CrtcSetInitialGamma(xf86CrtcPtr crtc, float gamma_red, float gamma_green, int i, size = 256; CARD16 *red, *green, *blue; - red = malloc(3 * size * sizeof(CARD16)); + red = xallocarray(size, 3 * sizeof(CARD16)); green = red + size; blue = green + size; @@ -2491,6 +2609,8 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow) else { if (xf86TargetUserpref(scrn, config, modes, enabled, width, height)) xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n"); + else if (xf86TargetRightOf(scrn, config, modes, enabled, width, height)) + xf86DrvMsg(i, X_INFO, "Using spanning desktop for initial modes\n"); else if (xf86TargetPreferred (scrn, config, modes, enabled, width, height)) xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n"); @@ -2510,9 +2630,11 @@ xf86InitialConfiguration(ScrnInfoPtr scrn, Bool canGrow) "Output %s enabled but has no modes\n", config->output[o]->name); else - xf86DrvMsg(scrn->scrnIndex, X_INFO, - "Output %s using initial mode %s\n", - config->output[o]->name, modes[o]->name); + xf86DrvMsg (scrn->scrnIndex, X_INFO, + "Output %s using initial mode %s +%d+%d\n", + config->output[o]->name, modes[o]->name, + config->output[o]->initial_x, + config->output[o]->initial_y); } /* diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.h b/xorg-server/hw/xfree86/modes/xf86Crtc.h index 3c5bbcfd5..8b0160845 100644 --- a/xorg-server/hw/xfree86/modes/xf86Crtc.h +++ b/xorg-server/hw/xfree86/modes/xf86Crtc.h @@ -745,6 +745,8 @@ xf86CompatOutput(ScrnInfoPtr pScrn) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + if (config->compat_output < 0) + return NULL; return config->output[config->compat_output]; } diff --git a/xorg-server/hw/xfree86/modes/xf86DiDGA.c b/xorg-server/hw/xfree86/modes/xf86DiDGA.c index 3f1a3309f..645727441 100644 --- a/xorg-server/hw/xfree86/modes/xf86DiDGA.c +++ b/xorg-server/hw/xfree86/modes/xf86DiDGA.c @@ -60,7 +60,7 @@ xf86_dga_get_modes(ScreenPtr pScreen) if (!num) return FALSE; - modes = malloc(num * sizeof(DGAModeRec)); + modes = xallocarray(num, sizeof(DGAModeRec)); if (!modes) return FALSE; diff --git a/xorg-server/hw/xfree86/modes/xf86RandR12.c b/xorg-server/hw/xfree86/modes/xf86RandR12.c index b1c306a88..0d446da64 100644 --- a/xorg-server/hw/xfree86/modes/xf86RandR12.c +++ b/xorg-server/hw/xfree86/modes/xf86RandR12.c @@ -1058,7 +1058,7 @@ xf86RandR12CrtcNotify(RRCrtcPtr randr_crtc) DisplayModePtr mode = &crtc->mode; Bool ret; - randr_outputs = malloc(config->num_output * sizeof(RROutputPtr)); + randr_outputs = xallocarray(config->num_output, sizeof(RROutputPtr)); if (!randr_outputs) return FALSE; x = crtc->x; @@ -1150,7 +1150,7 @@ xf86RandR12CrtcSet(ScreenPtr pScreen, if (!crtc->scrn->vtSema) return FALSE; - save_crtcs = malloc(config->num_output * sizeof(xf86CrtcPtr)); + save_crtcs = xallocarray(config->num_output, sizeof(xf86CrtcPtr)); if ((randr_mode != NULL) != crtc->enabled) changed = TRUE; else if (randr_mode && !xf86RandRModeMatches(randr_mode, &crtc->mode)) @@ -1255,9 +1255,8 @@ xf86RandR12CrtcSetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc) if (randr_crtc->gammaSize != crtc->gamma_size) { CARD16 *tmp_ptr; - tmp_ptr = - realloc(crtc->gamma_red, - 3 * randr_crtc->gammaSize * sizeof(CARD16)); + tmp_ptr = reallocarray(crtc->gamma_red, + randr_crtc->gammaSize, 3 * sizeof(CARD16)); if (!tmp_ptr) return FALSE; crtc->gamma_red = tmp_ptr; @@ -1298,9 +1297,8 @@ xf86RandR12CrtcGetGamma(ScreenPtr pScreen, RRCrtcPtr randr_crtc) if (randr_crtc->gammaSize != crtc->gamma_size) { CARD16 *tmp_ptr; - tmp_ptr = - realloc(randr_crtc->gammaRed, - 3 * crtc->gamma_size * sizeof(CARD16)); + tmp_ptr = reallocarray(randr_crtc->gammaRed, + crtc->gamma_size, 3 * sizeof(CARD16)); if (!tmp_ptr) return FALSE; randr_crtc->gammaRed = tmp_ptr; @@ -1394,7 +1392,7 @@ xf86RROutputSetModes(RROutputPtr randr_output, DisplayModePtr modes) nmode++; if (nmode) { - rrmodes = malloc(nmode * sizeof(RRModePtr)); + rrmodes = xallocarray(nmode, sizeof(RRModePtr)); if (!rrmodes) return FALSE; @@ -1449,8 +1447,8 @@ xf86RandR12SetInfo12(ScreenPtr pScreen) int o, c, l; int nclone; - clones = malloc(config->num_output * sizeof(RROutputPtr)); - crtcs = malloc(config->num_crtc * sizeof(RRCrtcPtr)); + clones = xallocarray(config->num_output, sizeof(RROutputPtr)); + crtcs = xallocarray(config->num_crtc, sizeof(RRCrtcPtr)); for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; @@ -1564,6 +1562,70 @@ xf86RandR12CreateObjects12(ScreenPtr pScreen) return TRUE; } +static void +xf86RandR12CreateMonitors(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int o, ot; + int ht, vt; + int ret; + char buf[25]; + + for (o = 0; o < config->num_output; o++) { + xf86OutputPtr output = config->output[o]; + struct xf86CrtcTileInfo *tile_info = &output->tile_info, *this_tile; + RRMonitorPtr monitor; + int output_num, num_outputs; + if (!tile_info->group_id) + continue; + + if (tile_info->tile_h_loc || + tile_info->tile_v_loc) + continue; + + num_outputs = tile_info->num_h_tile * tile_info->num_v_tile; + + monitor = RRMonitorAlloc(num_outputs); + if (!monitor) + return; + monitor->pScreen = pScreen; + snprintf(buf, 25, "Auto-Monitor-%d", tile_info->group_id); + monitor->name = MakeAtom(buf, strlen(buf), TRUE); + monitor->primary = 0; + monitor->automatic = TRUE; + memset(&monitor->geometry.box, 0, sizeof(monitor->geometry.box)); + + output_num = 0; + for (ht = 0; ht < tile_info->num_h_tile; ht++) { + for (vt = 0; vt < tile_info->num_v_tile; vt++) { + + for (ot = 0; ot < config->num_output; ot++) { + this_tile = &config->output[ot]->tile_info; + + if (this_tile->group_id != tile_info->group_id) + continue; + + if (this_tile->tile_h_loc != ht || + this_tile->tile_v_loc != vt) + continue; + + monitor->outputs[output_num] = config->output[ot]->randr_output->id; + output_num++; + + } + + } + } + + ret = RRMonitorAdd(serverClient, pScreen, monitor); + if (ret) { + RRMonitorFree(monitor); + return; + } + } +} + static Bool xf86RandR12CreateScreenResources12(ScreenPtr pScreen) { @@ -1579,6 +1641,8 @@ xf86RandR12CreateScreenResources12(ScreenPtr pScreen) RRScreenSetSizeRange(pScreen, config->minWidth, config->minHeight, config->maxWidth, config->maxHeight); + + xf86RandR12CreateMonitors(pScreen); return TRUE; } diff --git a/xorg-server/hw/xfree86/os-support/bus/Sbus.c b/xorg-server/hw/xfree86/os-support/bus/Sbus.c index 16ce5b58a..86b4d685a 100644 --- a/xorg-server/hw/xfree86/os-support/bus/Sbus.c +++ b/xorg-server/hw/xfree86/os-support/bus/Sbus.c @@ -440,7 +440,7 @@ sparcPromAssignNodes(void) for (i = 0, j = 0; i < 32; i++) if (devicePtrs[i] && devicePtrs[i]->fbNum == -1) j++; - xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (n + j + 1)); + xf86SbusInfo = xnfreallocarray(xf86SbusInfo, n + j + 1, sizeof(psdp)); for (i = 0, psdpp = xf86SbusInfo; i < 32; i++) if (devicePtrs[i]) { if (devicePtrs[i]->fbNum == -1) { diff --git a/xorg-server/hw/xfree86/os-support/solaris/Makefile.am b/xorg-server/hw/xfree86/os-support/solaris/Makefile.am index 6cda4b361..e534bc8dc 100644 --- a/xorg-server/hw/xfree86/os-support/solaris/Makefile.am +++ b/xorg-server/hw/xfree86/os-support/solaris/Makefile.am @@ -33,5 +33,4 @@ AM_CFLAGS = -DUSESTDRES -DHAVE_SYSV_IPC $(XORG_CFLAGS) $(DIX_CFLAGS) AM_CPPFLAGS = $(XORG_INCS) -EXTRA_DIST = solaris-amd64.S solaris-ia32.S solaris-sparcv8plus.S \ - apSolaris.shar sun_inout.s +EXTRA_DIST = solaris-amd64.S solaris-ia32.S solaris-sparcv8plus.S sun_inout.s diff --git a/xorg-server/hw/xfree86/os-support/solaris/apSolaris.shar b/xorg-server/hw/xfree86/os-support/solaris/apSolaris.shar deleted file mode 100644 index a3548f7b4..000000000 --- a/xorg-server/hw/xfree86/os-support/solaris/apSolaris.shar +++ /dev/null @@ -1,806 +0,0 @@ -#!/bin/sh -# -# This is a shell archive. Save it in a file, remove anything before -# this line, and then unpack it by entering "sh file". Note, it may -# create directories; files and directories will be owned by you and -# have default permissions. -# Made on Sun Jun 25 20:24:59 CEST 2006 by Martin Bochnig at martux.org -# -# This archive contains: -# -# ./aperture -# -# ./aperture/Makefile -# ./aperture/Makefile.amd64 -# ./aperture/Makefile.sparcv9 -# ./aperture/README -# ./aperture/aperture.c -# ./aperture/aperture.conf -# ./aperture/devlink.tab -# -echo c - ./aperture -mkdir -p ./aperture > /dev/null 2>&1 -# -echo x - ./aperture/Makefile -sed 's/^X//' >./aperture/Makefile << 'END-of-./aperture/Makefile' -X# -X# File: makefile for aperture Framebuffer Driver -X# Author: Doug Anson (danson@lgc.com) -X# Date: 2/15/94 -X# Modified: David Holland (davidh@use.com) -X# Date: 2/23/94 -X# - Changed name, and debugging structure -X# Modified: Marc Aurele La France (tsi@xfree86.org) -X# Date: 2001.06.08 -X# - SPARC support, cleanup and turf aptest. -X# -X# >>NOTE<< Have a look at Makefile.sparcv9 for specifics. -X# -X# Modified: Martin Bochnig (martin@martux.org) -X# Date: 2006.06.24 -X# - Slightly modified to also build on Solaris 10 and 11. -X# - amd64 64 bit kernel support -X# - cosmetical changes to also support sun4v, not only sun4u -X# -X# >>NOTE<< Have a look at Makefile.amd64 for amd64 specifics. -X# -X# GNU gcc compiler -XCC=gcc -XCFLGS=-fno-builtin -Wall -O3 -X -X# -X# SUNWspro compiler -X#CC=/opt/SUNWspro/bin/cc -X#CFLGS=-Xa -xnolib -xO3 -X -X# -X# Debug error reporting -X#DEBUG_FLG= -X#DEBUG_FLG=-DAPERTURE_DEBUG -X -X# -X# Files and object declarations -XKERNEL_FLGS=-D_KERNEL -DSUNDDI -XCFLAGS= $(CFLGS) $(KERNEL_FLGS) $(DEBUG_FLG) -XCFILES= aperture.c -XOBJS= aperture.o -XDRIVER= aperture -X -X# -X# Make rules -Xall: $(DRIVER) -X -X$(DRIVER): $(OBJS) -X @if [ -f "Makefile.`isainfo -k`" ]; then \ -X make -f Makefile.`isainfo -k` $(DRIVER); \ -X else \ -X rm -f $(DRIVER); \ -X ld -r -o $(DRIVER) $(OBJS); \ -X fi -X -Xinstall: $(DRIVER) -X @if [ -f "Makefile.`isainfo -k`" ]; then \ -X make -f Makefile.`isainfo -k` install; \ -X else \ -X cp aperture.conf /kernel/drv; \ -X cp $(DRIVER) /kernel/drv; \ -X fi -X -Xadd_drv: -X @if [ -f "Makefile.`isainfo -k`" ]; then \ -X make -f Makefile.`isainfo -k` add_drv; \ -X else \ -X add_drv aperture; \ -X fi -X -Xclean: -X rm -f *% *.BAK $(OBJS) $(DRIVER) core -X -X.SUFFIXES: .i -X -X.c.i: -X $(CC) -E $(CFLAGS) $*.c > $@ -X -X.c.o: -X @if [ -f "Makefile.`isainfo -k`" ]; then \ -X make -f Makefile.`isainfo -k` $@; \ -X else \ -X rm -f $@; \ -X $(CC) -c $(CFLAGS) $*.c -o $@; \ -X fi -END-of-./aperture/Makefile -echo x - ./aperture/Makefile.amd64 -sed 's/^X//' >./aperture/Makefile.amd64 << 'END-of-./aperture/Makefile.amd64' -X# -X# File: Makefile for aperture Framebuffer Driver -X# Author: Doug Anson (danson@lgc.com) -X# Date: 2/15/94 -X# Modified: David Holland (davidh@use.com) -X# Date: 2/23/94 -X# - Changed name, and debugging structure -X# Modified: Marc Aurele La France (tsi@xfree86.org) -X# Date: 2001.06.08 -X# - SPARC support, cleanup and turf aptest. -X# Modified: Martin Bochnig (martin@martux.org) -X# - amd64 64 bit kernel support, cosmetics and also -X# supporting sun4v (and arbitrary sparcv9) platforms -X# as well as SunOS 5.10 or higher now -X# - Changed name -X# -X -X# -X# GNU gcc compiler, version 3.2 or later -X# -XCC=gcc -XCFLGS=-fno-builtin -Wall -O3 -m64 -mcmodel=kernel -X -X# -X# SUNWspro compiler (untested, might not properly work for amd64 here) -X#CC=/opt/SUNWspro/bin/cc -X#CFLGS=-Xa -xarch=v9 -xnolib -xO3 -X -X# -X# Debug error reporting -X#DEBUG_FLG= -X#DEBUG_FLG=-DAPERTURE_DEBUG -X -X# -X# Files and object declarations -XKERNEL_FLGS=-D_KERNEL -DSUNDDI -XCFLAGS= $(CFLGS) $(KERNEL_FLGS) $(DEBUG_FLG) -XCFILES= aperture.c -XOBJS= aperture.o -XDRIVER= aperture -X -X# -X# Make rules -Xall: $(DRIVER) -X -X$(DRIVER): $(OBJS) -X rm -f $(DRIVER) -X ld -r -o $(DRIVER) $(OBJS) -X -Xinstall: $(DRIVER) -X cp aperture.conf /kernel/drv -X cp $(DRIVER) /kernel/drv/amd64 -X -Xadd_drv: -X add_drv aperture -X -Xclean: -X rm -f *% *.BAK $(OBJS) $(DRIVER) core -X -X.SUFFIXES: .i -X -X.c.i: -X $(CC) -E $(CFLAGS) $*.c > $@ -END-of-./aperture/Makefile.amd64 -echo x - ./aperture/Makefile.sparcv9 -sed 's/^X//' >./aperture/Makefile.sparcv9 << 'END-of-./aperture/Makefile.sparcv9' -X# -X# File: makefile for aperture Framebuffer Driver -X# Author: Doug Anson (danson@lgc.com) -X# Date: 2/15/94 -X# Modified: David Holland (davidh@use.com) -X# Date: 2/23/94 -X# - Changed name, and debugging structure -X# Modified: Marc Aurele La France (tsi@xfree86.org) -X# Date: 2001.06.08 -X# - SPARC support, cleanup and turf aptest. -X# Modified: Martin Bochnig (martin@martux.org) -X# Date: 2006.06.24 -X# - Changed name for generic sparcv9 support -X# - updated to better work with Solaris 10 and 11 -X# -X -X# -X# GNU gcc compiler, version 3.2 or later -X# -XCC=gcc -XCFLGS=-fno-builtin -Wall -O3 -m64 -X -X# -X# SUNWspro compiler -X#CC=/opt/SUNWspro/bin/cc -X#CFLGS=-Xa -xarch=v9 -xnolib -xO3 -X -X# -X# Debug error reporting -X#DEBUG_FLG= -X#DEBUG_FLG=-DAPERTURE_DEBUG -X -X# -X# Files and object declarations -XKERNEL_FLGS=-D_KERNEL -DSUNDDI -XCFLAGS= $(CFLGS) $(KERNEL_FLGS) $(DEBUG_FLG) -XCFILES= aperture.c -XOBJS= aperture.o -XDRIVER= aperture -X -X# -X# Make rules -Xall: $(DRIVER) -X -X$(DRIVER): $(OBJS) -X rm -f $(DRIVER) -X ld -r -o $(DRIVER) $(OBJS) -X -Xinstall: $(DRIVER) -X cp aperture.conf /kernel/drv -X cp $(DRIVER) /kernel/drv/sparcv9 -X -Xadd_drv: -X add_drv aperture -X -Xclean: -X rm -f *% *.BAK $(OBJS) $(DRIVER) core -X -X.SUFFIXES: .i -X -X.c.i: -X $(CC) -E $(CFLAGS) $*.c > $@ -END-of-./aperture/Makefile.sparcv9 -echo x - ./aperture/README -sed 's/^X//' >./aperture/README << 'END-of-./aperture/README' -XFramebuffer aperture driver. -X -XThis driver was written to provide a device that, unlike /dev/mem, allows -Xmmap()'ing of ranges beyond installed memory. -X -XThe original x86-based version of this driver was the collaborative work of -XDoug Anson (danson@lgc.com), and David Holland (davidh@use.com). It has since -Xbeen rewritten to also work on sparc machines and - later on - also on sparcv9 -Xand recently amd64 64 bit kernels. -XIt flawlessly compiles and installs on Solaris 10 and 11 now. -X -X -XInstallation instructions: -X -X1) Check the Makefile, for appropriate CC, and CFLAGS definitions. Compiling -X with APERTURE_DEBUG defined means the driver will generate reams of -X debugging output. You'll probably want to leave this off... -X -X2) Type 'make' (or 'gmake'). Both the driver and test program should compile -X without any problems. No warning messages should be generated. -X -X3) Become 'root'. -X -X4) Type 'make install' and 'make add_drv'. The screen should look something -X like this: -X -X # make install -X cp aperture aperture.conf /kernel/drv -X # make add_drv -X add_drv aperture -X -X On a sparcv9 machine this will mention the /kernel/drv/sparcv9 directory -X instead of /kernel/drv. Similarily /kernel/drv/amd64 should be used on amd64. -X -X This installs the driver to the system. -X -X5) While as root modify the file /etc/devlink.tab, adding these lines: -X -X# The following entry is for the framebuffer driver -Xtype=ddi_pseudo;name=aperture fbs/\M0 -X -X Add that line exactly as shown. You may also simply add the -X contents of the devlink.tab file supplied to /etc/devlink.tab. -X It contains the lines as well. (Yes, that is a tab between -X aperture and fbs, not spaces - very important) -X -X6) Perform a reconfiguration boot of the system. -X -X # touch /reconfigure -X # init 6 -X -XBug reports, questions, suggestions, etc can be sent to xfree86@xfree86.org. -END-of-./aperture/README -echo x - ./aperture/aperture.c -sed 's/^X//' >./aperture/aperture.c << 'END-of-./aperture/aperture.c' -X/* -X * Copyright (C) 2001 The XFree86 Project, Inc. All Rights Reserved. -X * -X * Permission is hereby granted, free of charge, to any person obtaining a copy -X * of this software and associated documentation files (the "Software"), to -X * deal in the Software without restriction, including without limitation the -X * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -X * sell copies of the Software, and to permit persons to whom the Software is -X * furnished to do so, subject to the following conditions: -X * -X * The above copyright notice and this permission notice shall be included in -X * all copies or substantial portions of the Software. -X * -X * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -X * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -X * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -X * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -X * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -X * -X * Except as contained in this notice, the name of the XFree86 Project shall -X * not be used in advertising or otherwise to promote the sale, use or other -X * dealings in this Software without prior written authorization from the -X * XFree86 Project. -X */ -X -X/* -X * Aperture driver for Solaris. -X */ -X -X/* -X * Modified: Martin Bochnig (martin@martux.org) -X * Log: Commented out obsolete kernel interfaces DDI_IDENTIFIED and DDI_NOT_IDENTIFIED -X * not supported by SunOS 5.10 or higher anymore, -X * see http://docs.sun.com/app/docs/doc/819-2255/6n4ibnffr?a=view -X */ -X -X#include <sys/conf.h> -X#include <sys/ddi.h> -X#include <sys/modctl.h> -X#include <sys/open.h> -X#include <sys/stat.h> -X#include <sys/sunddi.h> -X -X#define DEV_IDENT "aperture" -X#define DEV_BANNER "XFree86 aperture driver" -X -X#ifndef D_64BIT -X#define D_64BIT 0 -X#endif -X -X#ifndef NULL -X#define NULL ((void *)0) -X#endif -X -X/* -X * open(9E) -X */ -X/*ARGSUSED*/ -Xstatic int -Xaperture_open -X( -X#ifdef __STDC__ -X dev_t *devp, -X int flag, -X int typ, -X struct cred *cred -X#endif -X) -X#ifndef __STDC__ -X dev_t *devp; -X int flag; -X int typ; -X struct cred *cred; -X#endif -X{ -X int error; -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": entering open()\n"); -X -X#endif -X -X if ((typ != OTYP_CHR) || (getminor(*devp))) -X error = EINVAL; -X else -X error = 0; -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": leaving open() = %d\n", error); -X -X#endif -X -X return error; -X} -X -X/* -X * mmap(9E) -X */ -X/*ARGSUSED*/ -Xstatic int -Xaperture_mmap -X( -X#ifdef __STDC__ -X dev_t dev, -X off_t off, -X int prot -X#endif -X) -X#ifndef __STDC__ -X dev_t dev; -X off_t off; -X int prot; -X#endif -X{ -X pfn_t pf; -X int error; -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": entering mmap(0x%016lx)\n", off); -X -X#endif -X -X pf = btop((unsigned long)off); -X -X /* Deal with mmap(9E) interface limits */ -X error = (int)pf; -X if ((error < 0) || (pf != (pfn_t)error)) -X error = -1; -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": leaving mmap() = 0x%08lx", error); -X -X#endif -X -X return error; -X} -X -Xstatic struct cb_ops aperture_cb_ops = -X{ -X aperture_open, /* open */ -X nulldev, /* close */ -X nodev, /* strategy */ -X nodev, /* print */ -X nodev, /* dump */ -X nodev, /* read */ -X nodev, /* write */ -X nodev, /* ioctl */ -X nodev, /* devmap */ -X aperture_mmap, /* mmap */ -X ddi_segmap, /* segmap */ -X nochpoll, /* poll */ -X ddi_prop_op, /* cb_prop_op */ -X 0, /* streamtab */ -X D_NEW | D_MP | D_64BIT /* Driver compatibility flag */ -X}; -X -X -Xstatic dev_info_t *aperture_dip; /* private copy of devinfo pointer */ -X -X/* -X * getinfo(9E) -X */ -X/*ARGSUSED*/ -Xstatic int -Xaperture_getinfo -X( -X#ifdef __STDC__ -X dev_info_t *dip, -X ddi_info_cmd_t infocmd, -X void *arg, -X void **result -X#endif -X) -X#ifndef __STDC__ -X dev_info_t *dip; -X ddi_info_cmd_t infocmd; -X void *arg; -X void **result; -X#endif -X{ -X int error; -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": entering getinfo()\n"); -X -X#endif -X -X switch (infocmd) { -X case DDI_INFO_DEVT2DEVINFO: -X *result = aperture_dip; -X error = DDI_SUCCESS; -X break; -X case DDI_INFO_DEVT2INSTANCE: -X *result = NULL; -X error = DDI_SUCCESS; -X break; -X default: -X error = DDI_FAILURE; -X } -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": leaving getinfo() = %d\n", error); -X -X#endif -X -X return error; -X} -X -X/* -X * identify(9E) -X */ -X/*ARGSUSED*/ -Xstatic int -Xaperture_identify -X( -X#ifdef __STDC__ -X dev_info_t *dip -X#endif -X) -X#ifndef __STDC__ -X dev_info_t *dip; -X#endif -X{ -X int error; -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": entering identify()\n"); -X -X#endif -X -X if (strcmp(ddi_get_name(dip), DEV_IDENT)) -X error = 1 /* DDI_NOT_IDENTIFIED obsolete since SunOS 5.10 */ ; -X else -X error = 2 /* DDI_IDENTIFIED obsolete since SunOS 5.10 */ ; -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": leaving identify() = %d\n", error); -X -X#endif -X -X return error; -X} -X -X/* -X * attach(9E) -X */ -X/*ARGSUSED*/ -Xstatic int -Xaperture_attach -X( -X#ifdef __STDC__ -X dev_info_t *dip, -X ddi_attach_cmd_t cmd -X#endif -X) -X#ifndef __STDC__ -X dev_info_t *dip; -X ddi_attach_cmd_t cmd; -X#endif -X{ -X int error; -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": entering attach()\n"); -X -X#endif -X -X if (cmd != DDI_ATTACH) -X { -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": not attach(, DDI_ATTACH)\n"); -X -X#endif -X -X error = DDI_FAILURE; -X } -X else -X { -X error = ddi_create_minor_node(dip, ddi_get_name(dip), S_IFCHR, -X (minor_t)ddi_get_instance(dip), -X NULL, 0 /* NODESPECIFIC_DEV obsolete since SunOS 5.10 */ ); -X -X if (error == DDI_SUCCESS) -X { -X aperture_dip = dip; -X ddi_report_dev(dip); -X } -X } -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": leaving attach() = %d\n", error); -X -X#endif -X -X return error; -X} -X -X/* -X * detach(9E) -X */ -Xstatic int -Xaperture_detach -X( -X#ifdef __STDC__ -X dev_info_t *dip, -X ddi_detach_cmd_t cmd -X#endif -X) -X#ifndef __STDC__ -X dev_info_t *dip; -X ddi_detach_cmd_t cmd; -X#endif -X{ -X int error; -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": entering detach()\n"); -X -X#endif -X -X if (cmd != DDI_DETACH) -X { -X error = DDI_FAILURE; -X } -X else -X { -X ddi_remove_minor_node(dip, NULL); -X aperture_dip = NULL; -X error = DDI_SUCCESS; -X } -X -X#if APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": leaving detach() = %d\n", error); -X -X#endif -X -X return error; -X} -X -X -Xstatic struct dev_ops aperture_ops = -X{ -X DEVO_REV, /* revision */ -X 0, /* refcnt */ -X aperture_getinfo, /* getinfo */ -X aperture_identify, /* identify */ -X nulldev, /* probe */ -X aperture_attach, /* attach */ -X aperture_detach, /* detach */ -X nodev, /* reset */ -X &aperture_cb_ops, /* driver operations */ -X NULL /* bus operations */ -X}; -X -X -Xstatic struct modldrv modldrv = -X{ -X &mod_driverops, /* mod_ops structure pointer */ -X DEV_BANNER, /* driver banner string */ -X &aperture_ops, /* dev_ops structure pointer */ -X}; -X -X -Xstatic struct modlinkage modlinkage = -X{ -X MODREV_1, /* module API revision */ -X { -X &modldrv, /* module driver structure pointer */ -X NULL /* list termination */ -X } -X}; -X -X -X/* -X * _init(9E) -X */ -Xint -X_init -X( -X#ifdef __STDC__ -X void -X#endif -X) -X{ -X int error; -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": entering _init()\n"); -X -X#endif -X -X error = mod_install(&modlinkage); -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": leaving _init() = %d\n", error); -X -X#endif -X -X return error; -X} -X -X/* -X * _info(9E) -X */ -Xint -X_info -X( -X#ifdef __STDC__ -X struct modinfo *modinfop -X#endif -X) -X#ifndef __STDC__ -X struct modinfo *modinfop; -X#endif -X{ -X int error; -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": entering _info()\n"); -X -X#endif -X -X error = mod_info(&modlinkage, modinfop); -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": leaving _info() = %d\n", error); -X -X#endif -X -X return error; -X} -X -X/* -X * _fini(9E) -X */ -Xint -X_fini -X( -X#ifdef __STDC__ -X void -X#endif -X) -X{ -X int error; -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": entering _fini()\n"); -X -X#endif -X -X error = mod_remove(&modlinkage); -X -X#ifdef APERTURE_DEBUG -X -X cmn_err(CE_CONT, DEV_IDENT ": leaving _fini() = %d\n", error); -X -X#endif -X -X return error; -X} -END-of-./aperture/aperture.c -echo x - ./aperture/aperture.conf -sed 's/^X//' >./aperture/aperture.conf << 'END-of-./aperture/aperture.conf' -X# -X# Copyright 1994 Doug Anson, danson@lgc.com & David Holland, davidh@use.com -X# -X# File: aperture.conf -X# Author: Doug Anson (danson@lgc.com) -X# -X# Modified: David Holland (davidh@use.com) -X# Log: Change comments 02/23/94 -X# Change defaults/comments 09/25/94 -X# -X# Modified: Marc Aurele La France (tsi@xfree86.org) -X# Log: SPARC changes 2001.09 -X# -X# Purpose: This conf file is used by the aperture driver. -X# -Xname="aperture" parent="pseudo"; -END-of-./aperture/aperture.conf -echo x - ./aperture/devlink.tab -sed 's/^X//' >./aperture/devlink.tab << 'END-of-./aperture/devlink.tab' -X# The following entry is for the aperture driver -Xtype=ddi_pseudo;name=aperture fbs/\M0 -END-of-./aperture/devlink.tab -exit - diff --git a/xorg-server/hw/xfree86/parser/Configint.h b/xorg-server/hw/xfree86/parser/Configint.h index 31035ae2d..e5fa6cec2 100644 --- a/xorg-server/hw/xfree86/parser/Configint.h +++ b/xorg-server/hw/xfree86/parser/Configint.h @@ -204,6 +204,8 @@ else\ "Multiple \"%s\" lines." #define MUST_BE_OCTAL_MSG \ "The number \"%d\" given in this section must be in octal (0xxx) format." +#define GPU_DEVICE_TOO_MANY \ +"More than %d GPU devices defined." /* Warning messages */ #define OBSOLETE_MSG \ diff --git a/xorg-server/hw/xfree86/parser/Screen.c b/xorg-server/hw/xfree86/parser/Screen.c index 9d8eda277..b5b454ff4 100644 --- a/xorg-server/hw/xfree86/parser/Screen.c +++ b/xorg-server/hw/xfree86/parser/Screen.c @@ -211,6 +211,7 @@ static xf86ConfigSymTabRec ScreenTab[] = { {DEFAULTFBBPP, "defaultfbbpp"}, {VIRTUAL, "virtual"}, {OPTION, "option"}, + {GDEVICE, "gpudevice"}, {-1, ""}, }; @@ -270,6 +271,13 @@ xf86parseScreenSection(void) Error(QUOTE_MSG, "Device"); ptr->scrn_device_str = xf86_lex_val.str; break; + case GDEVICE: + if (xf86getSubToken(&(ptr->scrn_comment)) != STRING) + Error(QUOTE_MSG, "GPUDevice"); + if (ptr->num_gpu_devices == CONF_MAXGPUDEVICES) + Error(GPU_DEVICE_TOO_MANY, CONF_MAXGPUDEVICES); + ptr->scrn_gpu_device_str[ptr->num_gpu_devices++] = xf86_lex_val.str; + break; case MONITOR: if (xf86getSubToken(&(ptr->scrn_comment)) != STRING) Error(QUOTE_MSG, "Monitor"); @@ -342,7 +350,7 @@ xf86printScreenSection(FILE * cf, XF86ConfScreenPtr ptr) XF86ConfAdaptorLinkPtr aptr; XF86ConfDisplayPtr dptr; XF86ModePtr mptr; - + int i; while (ptr) { fprintf(cf, "Section \"Screen\"\n"); if (ptr->scrn_comment) @@ -353,6 +361,9 @@ xf86printScreenSection(FILE * cf, XF86ConfScreenPtr ptr) fprintf(cf, "\tDriver \"%s\"\n", ptr->scrn_obso_driver); if (ptr->scrn_device_str) fprintf(cf, "\tDevice \"%s\"\n", ptr->scrn_device_str); + for (i = 0; i < ptr->num_gpu_devices; i++) + if (ptr->scrn_gpu_device_str[i]) + fprintf(cf, "\tGPUDevice \"%s\"\n", ptr->scrn_gpu_device_str[i]); if (ptr->scrn_monitor_str) fprintf(cf, "\tMonitor \"%s\"\n", ptr->scrn_monitor_str); if (ptr->scrn_defaultdepth) @@ -426,11 +437,13 @@ void xf86freeScreenList(XF86ConfScreenPtr ptr) { XF86ConfScreenPtr prev; - + int i; while (ptr) { TestFree(ptr->scrn_identifier); TestFree(ptr->scrn_monitor_str); TestFree(ptr->scrn_device_str); + for (i = 0; i < ptr->num_gpu_devices; i++) + TestFree(ptr->scrn_gpu_device_str[i]); TestFree(ptr->scrn_comment); xf86optionListFree(ptr->scrn_option_lst); xf86freeAdaptorLinkList(ptr->scrn_adaptor_lst); @@ -487,6 +500,7 @@ xf86validateScreen(XF86ConfigPtr p) XF86ConfScreenPtr screen = p->conf_screen_lst; XF86ConfMonitorPtr monitor; XF86ConfAdaptorLinkPtr adaptor; + int i; while (screen) { if (screen->scrn_obso_driver && !screen->scrn_identifier) @@ -505,6 +519,10 @@ xf86validateScreen(XF86ConfigPtr p) screen->scrn_device = xf86findDevice(screen->scrn_device_str, p->conf_device_lst); + for (i = 0; i < screen->num_gpu_devices; i++) { + screen->scrn_gpu_devices[i] = + xf86findDevice(screen->scrn_gpu_device_str[i], p->conf_device_lst); + } adaptor = screen->scrn_adaptor_lst; while (adaptor) { adaptor->al_adaptor = diff --git a/xorg-server/hw/xfree86/parser/xf86Parser.h b/xorg-server/hw/xfree86/parser/xf86Parser.h index 43e17550c..b3a50e52f 100644 --- a/xorg-server/hw/xfree86/parser/xf86Parser.h +++ b/xorg-server/hw/xfree86/parser/xf86Parser.h @@ -259,6 +259,7 @@ typedef struct { XF86ConfVideoAdaptorPtr al_adaptor; } XF86ConfAdaptorLinkRec, *XF86ConfAdaptorLinkPtr; +#define CONF_MAXGPUDEVICES 4 typedef struct { GenericListRec list; const char *scrn_identifier; @@ -276,6 +277,10 @@ typedef struct { char *scrn_comment; int scrn_virtualX, scrn_virtualY; char *match_seat; + + int num_gpu_devices; + const char *scrn_gpu_device_str[CONF_MAXGPUDEVICES]; + XF86ConfDevicePtr scrn_gpu_devices[CONF_MAXGPUDEVICES]; } XF86ConfScreenRec, *XF86ConfScreenPtr; typedef struct { diff --git a/xorg-server/hw/xfree86/parser/xf86tokens.h b/xorg-server/hw/xfree86/parser/xf86tokens.h index 9c44970ea..bbd6b90d1 100644 --- a/xorg-server/hw/xfree86/parser/xf86tokens.h +++ b/xorg-server/hw/xfree86/parser/xf86tokens.h @@ -143,6 +143,7 @@ typedef enum { /* Screen tokens */ OBSDRIVER, MDEVICE, + GDEVICE, MONITOR, SCREENNO, DEFAULTDEPTH, diff --git a/xorg-server/hw/xfree86/utils/cvt/cvt.c b/xorg-server/hw/xfree86/utils/cvt/cvt.c index d5df17fd9..9413c20fa 100644 --- a/xorg-server/hw/xfree86/utils/cvt/cvt.c +++ b/xorg-server/hw/xfree86/utils/cvt/cvt.c @@ -54,11 +54,11 @@ XNFalloc(unsigned long n) /* xnfcalloc implementation used by the server code we built in */ void * -XNFcalloc(unsigned long n) +XNFcallocarray(size_t nmemb, size_t size) { void *r; - r = calloc(1, n); + r = calloc(nmemb, size); if (!r) { perror("calloc failed"); exit(1); diff --git a/xorg-server/hw/xfree86/vbe/vbe.c b/xorg-server/hw/xfree86/vbe/vbe.c index 5ea019733..ef12cb805 100644 --- a/xorg-server/hw/xfree86/vbe/vbe.c +++ b/xorg-server/hw/xfree86/vbe/vbe.c @@ -397,7 +397,7 @@ VBEGetVBEInfo(vbeInfoPtr pVbe) i = 0; while (modes[i] != 0xffff) i++; - block->VideoModePtr = malloc(sizeof(CARD16) * (i + 1)); + block->VideoModePtr = xallocarray(i + 1, sizeof(CARD16)); memcpy(block->VideoModePtr, modes, sizeof(CARD16) * i); block->VideoModePtr[i] = 0xffff; @@ -825,7 +825,7 @@ VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num, if (set) return data; - data = malloc(num * sizeof(CARD32)); + data = xallocarray(num, sizeof(CARD32)); memcpy(data, pVbe->memory, num * sizeof(CARD32)); return data; diff --git a/xorg-server/hw/xnest/Color.c b/xorg-server/hw/xnest/Color.c index 8d9d35621..3a9e42203 100644 --- a/xorg-server/hw/xnest/Color.c +++ b/xorg-server/hw/xnest/Color.c @@ -62,7 +62,7 @@ xnestCreateColormap(ColormapPtr pCmap) switch (pVisual->class) { case StaticGray: /* read only */ - colors = (XColor *) malloc(ncolors * sizeof(XColor)); + colors = xallocarray(ncolors, sizeof(XColor)); for (i = 0; i < ncolors; i++) colors[i].pixel = i; XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors); @@ -75,7 +75,7 @@ xnestCreateColormap(ColormapPtr pCmap) break; case StaticColor: /* read only */ - colors = (XColor *) malloc(ncolors * sizeof(XColor)); + colors = xallocarray(ncolors, sizeof(XColor)); for (i = 0; i < ncolors; i++) colors[i].pixel = i; XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors); @@ -88,7 +88,7 @@ xnestCreateColormap(ColormapPtr pCmap) break; case TrueColor: /* read only */ - colors = (XColor *) malloc(ncolors * sizeof(XColor)); + colors = xallocarray(ncolors, sizeof(XColor)); red = green = blue = 0L; redInc = lowbit(pVisual->redMask); greenInc = lowbit(pVisual->greenMask); @@ -194,14 +194,12 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen) xnestInstalledColormapWindows icws; int numWindows; - icws.cmapIDs = (Colormap *) malloc(pScreen->maxInstalledCmaps * - sizeof(Colormap)); + icws.cmapIDs = xallocarray(pScreen->maxInstalledCmaps, sizeof(Colormap)); icws.numCmapIDs = xnestListInstalledColormaps(pScreen, icws.cmapIDs); icws.numWindows = 0; WalkTree(pScreen, xnestCountInstalledColormapWindows, (void *) &icws); if (icws.numWindows) { - icws.windows = - (Window *) malloc((icws.numWindows + 1) * sizeof(Window)); + icws.windows = xallocarray(icws.numWindows + 1, sizeof(Window)); icws.index = 0; WalkTree(pScreen, xnestGetInstalledColormapWindows, (void *) &icws); icws.windows[icws.numWindows] = xnestDefaultWindows[pScreen->myNum]; @@ -220,8 +218,7 @@ xnestSetInstalledColormapWindows(ScreenPtr pScreen) #ifdef _XSERVER64 { int i; - Window64 *windows = - (Window64 *) malloc(numWindows * sizeof(Window64)); + Window64 *windows = xallocarray(numWindows, sizeof(Window64)); for (i = 0; i < numWindows; ++i) windows[i] = icws.windows[i]; @@ -393,7 +390,7 @@ xnestStoreColors(ColormapPtr pCmap, int nColors, xColorItem * pColors) #ifdef _XSERVER64 { int i; - XColor *pColors64 = (XColor *) malloc(nColors * sizeof(XColor)); + XColor *pColors64 = xallocarray(nColors, sizeof(XColor)); for (i = 0; i < nColors; ++i) { pColors64[i].pixel = pColors[i].pixel; diff --git a/xorg-server/hw/xnest/Display.c b/xorg-server/hw/xnest/Display.c index a2f8acbaa..e6d07dfd1 100644 --- a/xorg-server/hw/xnest/Display.c +++ b/xorg-server/hw/xnest/Display.c @@ -121,8 +121,8 @@ xnestOpenDisplay(int argc, char *argv[]) } xnestNumDefaultColormaps = xnestNumVisuals; - xnestDefaultColormaps = (Colormap *) malloc(xnestNumDefaultColormaps * - sizeof(Colormap)); + xnestDefaultColormaps = xallocarray(xnestNumDefaultColormaps, + sizeof(Colormap)); for (i = 0; i < xnestNumDefaultColormaps; i++) xnestDefaultColormaps[i] = XCreateColormap(xnestDisplay, DefaultRootWindow diff --git a/xorg-server/hw/xnest/GC.c b/xorg-server/hw/xnest/GC.c index 96af6eb91..ecfa61e39 100644 --- a/xorg-server/hw/xnest/GC.c +++ b/xorg-server/hw/xnest/GC.c @@ -190,7 +190,7 @@ xnestDestroyGC(GCPtr pGC) void xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects) { - int i, size; + int i; BoxPtr pBox; XRectangle *pRects; @@ -204,8 +204,7 @@ xnestChangeClip(GCPtr pGC, int type, void *pValue, int nRects) case CT_REGION: nRects = RegionNumRects((RegionPtr) pValue); - size = nRects * sizeof(*pRects); - pRects = (XRectangle *) malloc(size); + pRects = xallocarray(nRects, sizeof(*pRects)); pBox = RegionRects((RegionPtr) pValue); for (i = nRects; i-- > 0;) { pRects[i].x = pBox[i].x1; diff --git a/xorg-server/hw/xnest/Keyboard.c b/xorg-server/hw/xnest/Keyboard.c index ee3f68e3f..7ee7a7c3c 100644 --- a/xorg-server/hw/xnest/Keyboard.c +++ b/xorg-server/hw/xnest/Keyboard.c @@ -16,6 +16,10 @@ is" without express or implied warranty. #include <xnest-config.h> #endif +#ifdef WIN32 +#include <X11/Xwindows.h> +#endif + #include <X11/X.h> #include <X11/Xproto.h> #include <xcb/xcb_keysyms.h> @@ -134,7 +138,7 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff) max_keycode - min_keycode + 1, &mapWidth); len = (max_keycode - min_keycode + 1) * mapWidth; - keymap = (KeySym *) malloc(len * sizeof(KeySym)); + keymap = xallocarray(len, sizeof(KeySym)); for (i = 0; i < len; ++i) keymap[i] = keymap64[i]; XFree(keymap64); diff --git a/xorg-server/hw/xnest/Screen.c b/xorg-server/hw/xnest/Screen.c index abb4d372d..214b55015 100644 --- a/xorg-server/hw/xnest/Screen.c +++ b/xorg-server/hw/xnest/Screen.c @@ -158,7 +158,7 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[]) if (!dixRegisterPrivateKey(&xnestCursorScreenKeyRec, PRIVATE_SCREEN, 0)) return FALSE; - visuals = (VisualPtr) malloc(xnestNumVisuals * sizeof(VisualRec)); + visuals = xallocarray(xnestNumVisuals, sizeof(VisualRec)); numVisuals = 0; depths = (DepthPtr) malloc(MAXDEPTH * sizeof(DepthRec)); @@ -224,7 +224,7 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[]) numVisuals++; } - visuals = (VisualPtr) realloc(visuals, numVisuals * sizeof(VisualRec)); + visuals = reallocarray(visuals, numVisuals, sizeof(VisualRec)); defaultVisual = visuals[xnestDefaultVisualIndex].vid; rootDepth = visuals[xnestDefaultVisualIndex].nplanes; diff --git a/xorg-server/hw/xwayland/xwayland-glamor.c b/xorg-server/hw/xwayland/xwayland-glamor.c index d06006c70..6b6e59756 100644 --- a/xorg-server/hw/xwayland/xwayland-glamor.c +++ b/xorg-server/hw/xwayland/xwayland-glamor.c @@ -310,7 +310,7 @@ xwl_drm_init_egl(struct xwl_screen *xwl_screen) } if (!epoxy_has_gl_extension("GL_OES_EGL_image")) { - ErrorF("GL_OES_EGL_image no available"); + ErrorF("GL_OES_EGL_image not available\n"); return; } @@ -329,7 +329,7 @@ xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device) xwl_screen->drm_fd = open(xwl_screen->device_name, O_RDWR | O_CLOEXEC); if (xwl_screen->drm_fd == -1) { - ErrorF("wayland-egl: could not open %s (%s)", + ErrorF("wayland-egl: could not open %s (%s)\n", xwl_screen->device_name, strerror(errno)); return; } diff --git a/xorg-server/hw/xwayland/xwayland-input.c b/xorg-server/hw/xwayland/xwayland-input.c index cc3bc53c8..78d9702ac 100644 --- a/xorg-server/hw/xwayland/xwayland-input.c +++ b/xorg-server/hw/xwayland/xwayland-input.c @@ -43,7 +43,7 @@ static int xwl_pointer_proc(DeviceIntPtr device, int what) { #define NBUTTONS 10 -#define NAXES 2 +#define NAXES 4 BYTE map[NBUTTONS + 1]; int i = 0; Atom btn_labels[NBUTTONS] = { 0 }; @@ -67,8 +67,10 @@ xwl_pointer_proc(DeviceIntPtr device, int what) axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X); axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y); + axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL); + axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL); - if (!InitValuatorClassDeviceStruct(device, 2, btn_labels, + if (!InitValuatorClassDeviceStruct(device, NAXES, btn_labels, GetMotionHistorySize(), Absolute)) return BadValue; @@ -77,6 +79,13 @@ xwl_pointer_proc(DeviceIntPtr device, int what) 0, 0xFFFF, 10000, 0, 10000, Absolute); InitValuatorAxisStruct(device, 1, axes_labels[1], 0, 0xFFFF, 10000, 0, 10000, Absolute); + InitValuatorAxisStruct(device, 2, axes_labels[2], + NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative); + InitValuatorAxisStruct(device, 3, axes_labels[3], + NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative); + + SetScrollValuator(device, 2, SCROLL_TYPE_HORIZONTAL, 1.0, SCROLL_FLAG_NONE); + SetScrollValuator(device, 3, SCROLL_TYPE_VERTICAL, 1.0, SCROLL_FLAG_PREFERRED); if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control)) return BadValue; @@ -259,54 +268,24 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value) { struct xwl_seat *xwl_seat = data; - int index, count; - int i, val; + int index; const int divisor = 10; ValuatorMask mask; - if (time - xwl_seat->scroll_time > 2000) { - xwl_seat->vertical_scroll = 0; - xwl_seat->horizontal_scroll = 0; - } - xwl_seat->scroll_time = time; - - /* FIXME: Need to do proper smooth scrolling here! */ switch (axis) { case WL_POINTER_AXIS_VERTICAL_SCROLL: - xwl_seat->vertical_scroll += value / divisor; - val = wl_fixed_to_int(xwl_seat->vertical_scroll); - xwl_seat->vertical_scroll -= wl_fixed_from_int(val); - - if (val <= -1) - index = 4; - else if (val >= 1) - index = 5; - else - return; + index = 3; break; case WL_POINTER_AXIS_HORIZONTAL_SCROLL: - xwl_seat->horizontal_scroll += value / divisor; - val = wl_fixed_to_int(xwl_seat->horizontal_scroll); - xwl_seat->horizontal_scroll -= wl_fixed_from_int(val); - - if (val <= -1) - index = 6; - else if (val >= 1) - index = 7; - else - return; + index = 2; break; default: return; } valuator_mask_zero(&mask); - - count = abs(val); - for (i = 0; i < count; i++) { - QueuePointerEvents(xwl_seat->pointer, ButtonPress, index, 0, &mask); - QueuePointerEvents(xwl_seat->pointer, ButtonRelease, index, 0, &mask); - } + valuator_mask_set_double(&mask, index, wl_fixed_to_double(value) / divisor); + QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0, POINTER_RELATIVE, &mask); } static const struct wl_pointer_listener pointer_listener = { @@ -561,7 +540,7 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id) xwl_seat = calloc(sizeof *xwl_seat, 1); if (xwl_seat == NULL) { - ErrorF("create_input ENOMEM"); + ErrorF("create_input ENOMEM\n"); return; } diff --git a/xorg-server/hw/xwayland/xwayland-output.c b/xorg-server/hw/xwayland/xwayland-output.c index 778914c61..155cbc109 100644 --- a/xorg-server/hw/xwayland/xwayland-output.c +++ b/xorg-server/hw/xwayland/xwayland-output.c @@ -159,7 +159,7 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id) xwl_output = calloc(sizeof *xwl_output, 1); if (xwl_output == NULL) { - ErrorF("create_output ENOMEM"); + ErrorF("create_output ENOMEM\n"); return NULL; } @@ -168,7 +168,7 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id) wl_output_add_listener(xwl_output->output, &output_listener, xwl_output); if (snprintf(name, sizeof name, "XWAYLAND%d", serial++) < 0) { - ErrorF("create_output ENOMEM"); + ErrorF("create_output ENOMEM\n"); free(xwl_output); return NULL; } diff --git a/xorg-server/hw/xwayland/xwayland.h b/xorg-server/hw/xwayland/xwayland.h index bfffa712f..cfb343d36 100644 --- a/xorg-server/hw/xwayland/xwayland.h +++ b/xorg-server/hw/xwayland/xwayland.h @@ -122,10 +122,6 @@ struct xwl_seat { struct xorg_list link; CursorPtr x_cursor; - wl_fixed_t horizontal_scroll; - wl_fixed_t vertical_scroll; - uint32_t scroll_time; - size_t keymap_size; char *keymap; struct wl_surface *keyboard_focus; diff --git a/xorg-server/hw/xwin/winclipboard/Makefile.am b/xorg-server/hw/xwin/winclipboard/Makefile.am index b1c95f4ef..a1079aec6 100644 --- a/xorg-server/hw/xwin/winclipboard/Makefile.am +++ b/xorg-server/hw/xwin/winclipboard/Makefile.am @@ -19,7 +19,7 @@ xwinclip_SOURCES = xwinclip.c debug.c xwinclip_CFLAGS = $(XWINMODULES_CFLAGS) -xwinclip_LDADD = libXWinclipboard.la $(XWINMODULES_LIBS) -lgdi32 +xwinclip_LDADD = libXWinclipboard.la $(XWINMODULES_LIBS) -lgdi32 -lpthread include $(top_srcdir)/manpages.am appman_PRE = xwinclip.man diff --git a/xorg-server/include/dix-config.h.in b/xorg-server/include/dix-config.h.in index 1aa77a5eb..76f45f535 100644 --- a/xorg-server/include/dix-config.h.in +++ b/xorg-server/include/dix-config.h.in @@ -149,6 +149,9 @@ /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */ #undef HAVE_NDIR_H +/* Define to 1 if you have the `reallocarray' function. */ +#undef HAVE_REALLOCARRAY + /* Define to 1 if you have the <rpcsvc/dbm.h> header file. */ #undef HAVE_RPCSVC_DBM_H @@ -388,9 +391,15 @@ /* Vendor name */ #undef XVENDORNAME +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + /* Enable GNU and other extensions to the C environment for GLIBC */ #undef _GNU_SOURCE +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + /* Define to empty if `const' does not conform to ANSI C. */ #undef const @@ -454,9 +463,6 @@ /* Define to __typeof__ if your compiler spells it that way. */ #undef typeof -/* The compiler supported TLS storage class, prefering initial-exec if tls_model is supported */ -#undef TLS - /* Correctly set _XSERVER64 for OSX fat binaries */ #ifdef __APPLE__ #include "dix-config-apple-verbatim.h" diff --git a/xorg-server/include/os.h b/xorg-server/include/os.h index 3e68c4933..6638c8443 100644 --- a/xorg-server/include/os.h +++ b/xorg-server/include/os.h @@ -69,11 +69,15 @@ typedef struct _NewClientRec *NewClientPtr; #ifndef xnfalloc #define xnfalloc(size) XNFalloc((unsigned long)(size)) -#define xnfcalloc(_num, _size) XNFcalloc((unsigned long)(_num)*(unsigned long)(_size)) +#define xnfcalloc(_num, _size) XNFcallocarray((_num), (_size)) #define xnfrealloc(ptr, size) XNFrealloc((void *)(ptr), (unsigned long)(size)) #define xstrdup(s) Xstrdup(s) #define xnfstrdup(s) XNFstrdup(s) + +#define xallocarray(num, size) reallocarray(NULL, (num), (size)) +#define xnfallocarray(num, size) XNFreallocarray(NULL, (num), (size)) +#define xnfreallocarray(ptr, num, size) XNFreallocarray((ptr), (num), (size)) #endif #include <stdio.h> @@ -222,7 +226,14 @@ XNFalloc(unsigned long /*amount */ ); * enough memory. */ extern _X_EXPORT void * -XNFcalloc(unsigned long /*amount */ ); +XNFcalloc(unsigned long /*amount */ ) _X_DEPRECATED; + +/* + * This function calloc(3)s buffer, terminating the server if there is not + * enough memory or the arguments overflow when multiplied + */ +extern _X_EXPORT void * +XNFcallocarray(size_t nmemb, size_t size); /* * This function realloc(3)s passed buffer, terminating the server if there is @@ -232,6 +243,13 @@ extern _X_EXPORT void * XNFrealloc(void * /*ptr */ , unsigned long /*amount */ ); /* + * This function reallocarray(3)s passed buffer, terminating the server if + * there is not enough memory or the arguments overflow when multiplied. + */ +extern _X_EXPORT void * +XNFreallocarray(void *ptr, size_t nmemb, size_t size); + +/* * This function strdup(3)s passed string. The only difference from the library * function that it is safe to pass NULL, as NULL will be returned. */ @@ -510,7 +528,14 @@ ddxGiveUp(enum ExitCode error); extern _X_EXPORT int TimeSinceLastInputEvent(void); -/* strcasecmp.c */ +/* Function fallbacks provided by AC_REPLACE_FUNCS in configure.ac */ + +#ifndef HAVE_REALLOCARRAY +#define reallocarray xreallocarray +extern _X_EXPORT void * +reallocarray(void *optr, size_t nmemb, size_t size); +#endif + #ifndef HAVE_STRCASECMP #define strcasecmp xstrcasecmp extern _X_EXPORT int diff --git a/xorg-server/include/servermd.h b/xorg-server/include/servermd.h index a3b5c3af3..087826f48 100644 --- a/xorg-server/include/servermd.h +++ b/xorg-server/include/servermd.h @@ -52,6 +52,8 @@ SOFTWARE. #error xserver code must include dix-config.h before any other headers #endif +#include <X11/Xarch.h> /* for X_LITTLE_ENDIAN/X_BIG_ENDIAN */ + #if X_BYTE_ORDER == X_LITTLE_ENDIAN #define IMAGE_BYTE_ORDER LSBFirst #define BITMAP_BIT_ORDER LSBFirst diff --git a/xorg-server/include/xorg-server.h.in b/xorg-server/include/xorg-server.h.in index 4cb94875c..3152dbd68 100644 --- a/xorg-server/include/xorg-server.h.in +++ b/xorg-server/include/xorg-server.h.in @@ -47,6 +47,9 @@ /* Define to 1 if you have the `ffs' function. */ #undef HAVE_FFS +/* Define to 1 if you have the `reallocarray' function. */ +#undef HAVE_REALLOCARRAY + /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP diff --git a/xorg-server/m4/xorg-tls.m4 b/xorg-server/m4/xorg-tls.m4 deleted file mode 100644 index 57687758f..000000000 --- a/xorg-server/m4/xorg-tls.m4 +++ /dev/null @@ -1,55 +0,0 @@ -dnl Copyright © 2011 Apple Inc. -dnl -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 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 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: Jeremy Huddleston <jeremyhu@apple.com> - -AC_DEFUN([XORG_TLS], [ - AC_REQUIRE([XORG_STRICT_OPTION]) - AC_MSG_CHECKING(for thread local storage (TLS) support) - AC_CACHE_VAL(ac_cv_tls, [ - ac_cv_tls=none - keywords="__thread __declspec(thread)" - for kw in $keywords ; do - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int $kw test;]], [])], ac_cv_tls=$kw ; break ;) - done - ]) - AC_MSG_RESULT($ac_cv_tls) - - if test "$ac_cv_tls" != "none"; then - AC_MSG_CHECKING(for tls_model attribute support) - AC_CACHE_VAL(ac_cv_tls_model, [ - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $STRICT_CFLAGS" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int $ac_cv_tls __attribute__((tls_model("initial-exec"))) test;]], [])], - ac_cv_tls_model=yes, ac_cv_tls_model=no) - CFLAGS="$save_CFLAGS" - ]) - AC_MSG_RESULT($ac_cv_tls_model) - - if test "x$ac_cv_tls_model" = "xyes" ; then - xorg_tls=$ac_cv_tls' __attribute__((tls_model("initial-exec")))' - else - xorg_tls=$ac_cv_tls - fi - - AC_DEFINE_UNQUOTED([TLS], $xorg_tls, [The compiler supported TLS storage class, prefering initial-exec if tls_model is supported]) - fi -]) diff --git a/xorg-server/mi/miarc.c b/xorg-server/mi/miarc.c index e8bc87e3e..5e854b329 100644 --- a/xorg-server/mi/miarc.c +++ b/xorg-server/mi/miarc.c @@ -1187,9 +1187,9 @@ miFillSppPoly(DrawablePtr dst, GCPtr pgc, int count, /* number of points */ y = ymax - ymin + 1; if ((count < 3) || (y <= 0)) return; - ptsOut = FirstPoint = malloc(sizeof(DDXPointRec) * y); - width = FirstWidth = malloc(sizeof(int) * y); - Marked = malloc(sizeof(int) * count); + ptsOut = FirstPoint = xallocarray(y, sizeof(DDXPointRec)); + width = FirstWidth = xallocarray(y, sizeof(int)); + Marked = xallocarray(count, sizeof(int)); if (!ptsOut || !width || !Marked) { free(Marked); @@ -1679,8 +1679,7 @@ miGetArcPts(SppArcPtr parc, /* points to an arc */ count++; cdt = 2 * miDcos(dt); - if (!(poly = (SppPointPtr) realloc((void *) *ppPts, - (cpt + count) * sizeof(SppPointRec)))) + if (!(poly = reallocarray(*ppPts, cpt + count, sizeof(SppPointRec)))) return 0; *ppPts = poly; @@ -1737,7 +1736,7 @@ addCap(miArcCapPtr * capsp, int *ncapsp, int *sizep, int end, int arcIndex) if (*ncapsp == *sizep) { newsize = *sizep + ADD_REALLOC_STEP; - cap = (miArcCapPtr) realloc(*capsp, newsize * sizeof(**capsp)); + cap = reallocarray(*capsp, newsize, sizeof(**capsp)); if (!cap) return; *sizep = newsize; @@ -1760,7 +1759,7 @@ addJoin(miArcJoinPtr * joinsp, if (*njoinsp == *sizep) { newsize = *sizep + ADD_REALLOC_STEP; - join = (miArcJoinPtr) realloc(*joinsp, newsize * sizeof(**joinsp)); + join = reallocarray(*joinsp, newsize, sizeof(**joinsp)); if (!join) return; *sizep = newsize; @@ -1784,7 +1783,7 @@ addArc(miArcDataPtr * arcsp, int *narcsp, int *sizep, xArc * xarc) if (*narcsp == *sizep) { newsize = *sizep + ADD_REALLOC_STEP; - arc = (miArcDataPtr) realloc(*arcsp, newsize * sizeof(**arcsp)); + arc = reallocarray(*arcsp, newsize, sizeof(**arcsp)); if (!arc) return NULL; *sizep = newsize; @@ -1890,10 +1889,10 @@ miComputeArcs(xArc * parcs, int narcs, GCPtr pGC) isDoubleDash = (pGC->lineStyle == LineDoubleDash); dashOffset = pGC->dashOffset; - data = malloc(narcs * sizeof(struct arcData)); + data = xallocarray(narcs, sizeof(struct arcData)); if (!data) return NULL; - arcs = malloc(sizeof(*arcs) * (isDoubleDash ? 2 : 1)); + arcs = xallocarray(isDoubleDash ? 2 : 1, sizeof(*arcs)); if (!arcs) { free(data); return NULL; @@ -3081,8 +3080,8 @@ fillSpans(DrawablePtr pDrawable, GCPtr pGC) if (nspans == 0) return; - xSpan = xSpans = malloc(nspans * sizeof(DDXPointRec)); - xWidth = xWidths = malloc(nspans * sizeof(int)); + xSpan = xSpans = xallocarray(nspans, sizeof(DDXPointRec)); + xWidth = xWidths = xallocarray(nspans, sizeof(int)); if (xSpans && xWidths) { i = 0; f = finalSpans; @@ -3136,7 +3135,7 @@ realFindSpan(int y) else change = SPAN_REALLOC; newSize = finalSize + change; - newSpans = malloc(newSize * sizeof(struct finalSpan *)); + newSpans = xallocarray(newSize, sizeof(struct finalSpan *)); if (!newSpans) return NULL; newMiny = finalMiny; diff --git a/xorg-server/mi/mibitblt.c b/xorg-server/mi/mibitblt.c index 724396333..28296a449 100644 --- a/xorg-server/mi/mibitblt.c +++ b/xorg-server/mi/mibitblt.c @@ -136,11 +136,11 @@ miCopyArea(DrawablePtr pSrcDrawable, dsty += pDstDrawable->y; } - pptFirst = ppt = malloc(heightSrc * sizeof(DDXPointRec)); - pwidthFirst = pwidth = malloc(heightSrc * sizeof(unsigned int)); + pptFirst = ppt = xallocarray(heightSrc, sizeof(DDXPointRec)); + pwidthFirst = pwidth = xallocarray(heightSrc, sizeof(unsigned int)); numRects = RegionNumRects(prgnSrcClip); boxes = RegionRects(prgnSrcClip); - ordering = malloc(numRects * sizeof(unsigned int)); + ordering = xallocarray(numRects, sizeof(unsigned int)); if (!pptFirst || !pwidthFirst || !ordering) { free(ordering); free(pwidthFirst); @@ -221,7 +221,7 @@ miCopyArea(DrawablePtr pSrcDrawable, ppt++->y = y++; *pwidth++ = width; } - pbits = malloc(height * PixmapBytePad(width, pSrcDrawable->depth)); + pbits = xallocarray(height, PixmapBytePad(width, pSrcDrawable->depth)); if (pbits) { (*pSrcDrawable->pScreen->GetSpans) (pSrcDrawable, width, pptFirst, (int *) pwidthFirst, height, @@ -398,8 +398,8 @@ miOpqStipDrawable(DrawablePtr pDraw, GCPtr pGC, RegionPtr prgnSrc, ChangeGC(NullClient, pGCT, GCBackground, gcv); ValidateGC((DrawablePtr) pPixmap, pGCT); miClearDrawable((DrawablePtr) pPixmap, pGCT); - ppt = pptFirst = malloc(h * sizeof(DDXPointRec)); - pwidth = pwidthFirst = malloc(h * sizeof(int)); + ppt = pptFirst = xallocarray(h, sizeof(DDXPointRec)); + pwidth = pwidthFirst = xallocarray(h, sizeof(int)); if (!pptFirst || !pwidthFirst) { free(pwidthFirst); free(pptFirst); @@ -746,8 +746,8 @@ miPutImage(DrawablePtr pDraw, GCPtr pGC, int depth, break; case ZPixmap: - ppt = pptFirst = malloc(h * sizeof(DDXPointRec)); - pwidth = pwidthFirst = malloc(h * sizeof(int)); + ppt = pptFirst = xallocarray(h, sizeof(DDXPointRec)); + pwidth = pwidthFirst = xallocarray(h, sizeof(int)); if (!pptFirst || !pwidthFirst) { free(pwidthFirst); free(pptFirst); diff --git a/xorg-server/mi/micmap.c b/xorg-server/mi/micmap.c index 1aeb359ba..5743adb19 100644 --- a/xorg-server/mi/micmap.c +++ b/xorg-server/mi/micmap.c @@ -458,9 +458,9 @@ miInitVisuals(VisualPtr * visualp, DepthPtr * depthp, int *nvisualp, ndepth++; nvisual += visuals->count; } - depth = malloc(ndepth * sizeof(DepthRec)); - visual = malloc(nvisual * sizeof(VisualRec)); - preferredCVCs = malloc(ndepth * sizeof(int)); + depth = xallocarray(ndepth, sizeof(DepthRec)); + visual = xallocarray(nvisual, sizeof(VisualRec)); + preferredCVCs = xallocarray(ndepth, sizeof(int)); if (!depth || !visual || !preferredCVCs) { free(depth); free(visual); @@ -481,7 +481,7 @@ miInitVisuals(VisualPtr * visualp, DepthPtr * depthp, int *nvisualp, prefp++; vid = NULL; if (nvtype) { - vid = malloc(nvtype * sizeof(VisualID)); + vid = xallocarray(nvtype, sizeof(VisualID)); if (!vid) { free(depth); free(visual); diff --git a/xorg-server/mi/micopy.c b/xorg-server/mi/micopy.c index 2409c7880..12cdad4ad 100644 --- a/xorg-server/mi/micopy.c +++ b/xorg-server/mi/micopy.c @@ -62,7 +62,7 @@ miCopyRegion(DrawablePtr pSrcDrawable, if (nbox > 1) { /* keep ordering in each band, reverse order of bands */ - pboxNew1 = (BoxPtr) malloc(sizeof(BoxRec) * nbox); + pboxNew1 = xallocarray(nbox, sizeof(BoxRec)); if (!pboxNew1) return; pboxBase = pboxNext = pbox + nbox - 1; @@ -93,7 +93,7 @@ miCopyRegion(DrawablePtr pSrcDrawable, if (nbox > 1) { /* reverse order of rects in each band */ - pboxNew2 = (BoxPtr) malloc(sizeof(BoxRec) * nbox); + pboxNew2 = xallocarray(nbox, sizeof(BoxRec)); if (!pboxNew2) { free(pboxNew1); return; diff --git a/xorg-server/mi/miexpose.c b/xorg-server/mi/miexpose.c index fc4dbc071..c4118f16a 100644 --- a/xorg-server/mi/miexpose.c +++ b/xorg-server/mi/miexpose.c @@ -535,7 +535,7 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what) gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin; } - prect = malloc(RegionNumRects(prgn) * sizeof(xRectangle)); + prect = xallocarray(RegionNumRects(prgn), sizeof(xRectangle)); if (!prect) return; diff --git a/xorg-server/mi/mifillrct.c b/xorg-server/mi/mifillrct.c index 28f2322e6..eb98a779e 100644 --- a/xorg-server/mi/mifillrct.c +++ b/xorg-server/mi/mifillrct.c @@ -100,8 +100,8 @@ miPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrectFill, /* number of rec maxheight = max(maxheight, prect->height); } - pptFirst = malloc(maxheight * sizeof(DDXPointRec)); - pwFirst = malloc(maxheight * sizeof(int)); + pptFirst = xallocarray(maxheight, sizeof(DDXPointRec)); + pwFirst = xallocarray(maxheight, sizeof(int)); if (!pptFirst || !pwFirst) { free(pwFirst); free(pptFirst); diff --git a/xorg-server/mi/miglblt.c b/xorg-server/mi/miglblt.c index 0183e998b..e9d3a1af0 100644 --- a/xorg-server/mi/miglblt.c +++ b/xorg-server/mi/miglblt.c @@ -131,7 +131,7 @@ miPolyGlyphBlt(DrawablePtr pDrawable, GC * pGC, int x, int y, unsigned int nglyp gcvals); nbyLine = BitmapBytePad(width); - pbits = malloc(height * nbyLine); + pbits = xallocarray(height, nbyLine); if (!pbits) { (*pDrawable->pScreen->DestroyPixmap) (pPixmap); FreeScratchGC(pGCtmp); diff --git a/xorg-server/mi/miinitext.c b/xorg-server/mi/miinitext.c index 086d2c3fb..5fc44e3f4 100644 --- a/xorg-server/mi/miinitext.c +++ b/xorg-server/mi/miinitext.c @@ -352,8 +352,8 @@ NewExtensionModuleList(int size) numExtensionModules = 0; n = numExtensionModules + size; - ExtensionModuleList = realloc(ExtensionModuleList, - n * sizeof(ExtensionModule)); + ExtensionModuleList = reallocarray(ExtensionModuleList, n, + sizeof(ExtensionModule)); if (ExtensionModuleList == NULL) { ExtensionModuleList = save; return NULL; diff --git a/xorg-server/mi/mipoly.c b/xorg-server/mi/mipoly.c index a332376d1..a97e2bb64 100644 --- a/xorg-server/mi/mipoly.c +++ b/xorg-server/mi/mipoly.c @@ -412,8 +412,8 @@ miFillConvexPoly(DrawablePtr dst, GCPtr pgc, int count, DDXPointPtr ptsIn) dy = ymax - ymin + 1; if ((count < 3) || (dy < 0)) return TRUE; - ptsOut = FirstPoint = malloc(sizeof(DDXPointRec) * dy); - width = FirstWidth = malloc(sizeof(int) * dy); + ptsOut = FirstPoint = xallocarray(dy, sizeof(DDXPointRec)); + width = FirstWidth = xallocarray(dy, sizeof(int)); if (!FirstPoint || !FirstWidth) { free(FirstWidth); free(FirstPoint); diff --git a/xorg-server/mi/mipolypnt.c b/xorg-server/mi/mipolypnt.c index 4fa521d07..1c4150dfb 100644 --- a/xorg-server/mi/mipolypnt.c +++ b/xorg-server/mi/mipolypnt.c @@ -67,7 +67,7 @@ miPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, /* Origin or Previous */ int i; xPoint *ppt; - if (!(pwidthInit = malloc(npt * sizeof(int)))) + if (!(pwidthInit = xallocarray(npt, sizeof(int)))) return; /* make pointlist origin relative */ diff --git a/xorg-server/mi/mipolyrect.c b/xorg-server/mi/mipolyrect.c index 830822513..7ebf9db8d 100644 --- a/xorg-server/mi/mipolyrect.c +++ b/xorg-server/mi/mipolyrect.c @@ -88,7 +88,7 @@ miPolyRectangle(DrawablePtr pDraw, GCPtr pGC, int nrects, xRectangle *pRects) offset2 = pGC->lineWidth; offset1 = offset2 >> 1; offset3 = offset2 - offset1; - tmp = malloc(ntmp * sizeof(xRectangle)); + tmp = xallocarray(ntmp, sizeof(xRectangle)); if (!tmp) return; t = tmp; diff --git a/xorg-server/mi/miwideline.c b/xorg-server/mi/miwideline.c index 452d74fc1..3baa99bfb 100644 --- a/xorg-server/mi/miwideline.c +++ b/xorg-server/mi/miwideline.c @@ -189,19 +189,16 @@ miSubtractSpans(SpanGroup * spanGroup, Spans * sub) int *newwid; #define EXTRA 8 - newPt = - (DDXPointPtr) realloc(spans->points, - (spans->count + - EXTRA) * - sizeof(DDXPointRec)); + newPt = reallocarray(spans->points, + spans->count + EXTRA, + sizeof(DDXPointRec)); if (!newPt) break; spansPt = newPt + (spansPt - spans->points); spans->points = newPt; - newwid = - (int *) realloc(spans->widths, - (spans->count + - EXTRA) * sizeof(int)); + newwid = reallocarray(spans->widths, + spans->count + EXTRA, + sizeof(int)); if (!newwid) break; spansWid = newwid + (spansWid - spans->widths); @@ -240,8 +237,8 @@ miAppendSpans(SpanGroup * spanGroup, SpanGroup * otherGroup, Spans * spans) if (spansCount > 0) { if (spanGroup->size == spanGroup->count) { spanGroup->size = (spanGroup->size + 8) * 2; - spanGroup->group = (Spans *) - realloc(spanGroup->group, sizeof(Spans) * spanGroup->size); + spanGroup->group = + reallocarray(spanGroup->group, sizeof(Spans), spanGroup->size); } spanGroup->group[spanGroup->count] = *spans; @@ -456,8 +453,8 @@ miFillUniqueSpanGroup(DrawablePtr pDraw, GCPtr pGC, SpanGroup * spanGroup) ylength = spanGroup->ymax - ymin + 1; /* Allocate Spans for y buckets */ - yspans = malloc(ylength * sizeof(Spans)); - ysizes = malloc(ylength * sizeof(int)); + yspans = xallocarray(ylength, sizeof(Spans)); + ysizes = xallocarray(ylength, sizeof(int)); if (!yspans || !ysizes) { free(yspans); @@ -491,12 +488,11 @@ miFillUniqueSpanGroup(DrawablePtr pDraw, GCPtr pGC, SpanGroup * spanGroup) int *newwidths; ysizes[index] = (ysizes[index] + 8) * 2; - newpoints = (DDXPointPtr) realloc(newspans->points, - ysizes[index] * - sizeof(DDXPointRec)); - newwidths = - (int *) realloc(newspans->widths, - ysizes[index] * sizeof(int)); + newpoints = reallocarray(newspans->points, + ysizes[index], + sizeof(DDXPointRec)); + newwidths = reallocarray(newspans->widths, + ysizes[index], sizeof(int)); if (!newpoints || !newwidths) { for (i = 0; i < ylength; i++) { free(yspans[i].points); @@ -525,8 +521,8 @@ miFillUniqueSpanGroup(DrawablePtr pDraw, GCPtr pGC, SpanGroup * spanGroup) } /* for i thorough Spans */ /* Now sort by x and uniquify each bucket into the final array */ - points = malloc(count * sizeof(DDXPointRec)); - widths = malloc(count * sizeof(int)); + points = xallocarray(count, sizeof(DDXPointRec)); + widths = xallocarray(count, sizeof(int)); if (!points || !widths) { for (i = 0; i < ylength; i++) { free(yspans[i].points); @@ -573,10 +569,10 @@ miFillUniqueSpanGroup(DrawablePtr pDraw, GCPtr pGC, SpanGroup * spanGroup) static Bool InitSpans(Spans * spans, size_t nspans) { - spans->points = malloc(nspans * sizeof(*spans->points)); + spans->points = xallocarray(nspans, sizeof(*spans->points)); if (!spans->points) return FALSE; - spans->widths = malloc(nspans * sizeof(*spans->widths)); + spans->widths = xallocarray(nspans, sizeof(*spans->widths)); if (!spans->widths) { free(spans->points); return FALSE; diff --git a/xorg-server/mi/miwindow.c b/xorg-server/mi/miwindow.c index a1af3a770..7574239f5 100644 --- a/xorg-server/mi/miwindow.c +++ b/xorg-server/mi/miwindow.c @@ -777,9 +777,9 @@ miSpriteTrace(SpritePtr pSprite, int x, int y) ) { if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize) { pSprite->spriteTraceSize += 10; - pSprite->spriteTrace = realloc(pSprite->spriteTrace, - pSprite->spriteTraceSize * - sizeof(WindowPtr)); + pSprite->spriteTrace = reallocarray(pSprite->spriteTrace, + pSprite->spriteTraceSize, + sizeof(WindowPtr)); } pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin; pWin = pWin->firstChild; diff --git a/xorg-server/mi/mizerarc.c b/xorg-server/mi/mizerarc.c index b216cf43d..e1b5f0c18 100644 --- a/xorg-server/mi/mizerarc.c +++ b/xorg-server/mi/mizerarc.c @@ -671,7 +671,7 @@ miZeroPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs) numPts = maxPts << 2; dospans = (pGC->fillStyle != FillSolid); if (dospans) { - widths = malloc(sizeof(int) * numPts); + widths = xallocarray(numPts, sizeof(int)); if (!widths) return; maxw = 0; @@ -687,7 +687,7 @@ miZeroPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs) (unsigned char *) pGC->dash, (int) pGC->numInDashList, &dinfo.dashOffsetInit); } - points = malloc(sizeof(DDXPointRec) * numPts); + points = xallocarray(numPts, sizeof(DDXPointRec)); if (!points) { if (dospans) { free(widths); diff --git a/xorg-server/mi/mizerline.c b/xorg-server/mi/mizerline.c index 5a2447014..2f22d2309 100644 --- a/xorg-server/mi/mizerline.c +++ b/xorg-server/mi/mizerline.c @@ -150,8 +150,8 @@ miZeroLine(DrawablePtr pDraw, GCPtr pGC, int mode, /* Origin or Previous */ width = xright - xleft + 1; height = ybottom - ytop + 1; list_len = (height >= width) ? height : width; - pspanInit = malloc(list_len * sizeof(DDXPointRec)); - pwidthInit = malloc(list_len * sizeof(int)); + pspanInit = xallocarray(list_len, sizeof(DDXPointRec)); + pwidthInit = xallocarray(list_len, sizeof(int)); if (!pspanInit || !pwidthInit) { free(pspanInit); free(pwidthInit); diff --git a/xorg-server/miext/damage/damage.c b/xorg-server/miext/damage/damage.c index 6ef7f9dfc..ce20169d4 100644 --- a/xorg-server/miext/damage/damage.c +++ b/xorg-server/miext/damage/damage.c @@ -1293,7 +1293,7 @@ damageText(DrawablePtr pDrawable, if (!checkGCDamage(pDrawable, pGC)) return; - charinfo = malloc(count * sizeof(CharInfoPtr)); + charinfo = xallocarray(count, sizeof(CharInfoPtr)); if (!charinfo) return; diff --git a/xorg-server/miext/rootless/rootlessWindow.c b/xorg-server/miext/rootless/rootlessWindow.c index a8f296a39..1f78e3f6c 100644 --- a/xorg-server/miext/rootless/rootlessWindow.c +++ b/xorg-server/miext/rootless/rootlessWindow.c @@ -949,7 +949,7 @@ StartFrameResize(WindowPtr pWin, Bool gravity, copy_rect_width = copy_rect.x2 - copy_rect.x1; copy_rect_height = copy_rect.y2 - copy_rect.y1; copy_rowbytes = ((copy_rect_width * Bpp) + 31) & ~31; - gResizeDeathBits = malloc(copy_rowbytes * copy_rect_height); + gResizeDeathBits = xallocarray(copy_rowbytes, copy_rect_height); if (copy_rect_width * copy_rect_height > rootless_CopyBytes_threshold && @@ -998,7 +998,7 @@ StartFrameResize(WindowPtr pWin, Bool gravity, RootlessStartDrawing(pWin); - gResizeDeathBits = malloc(winRec->bytesPerRow * winRec->height); + gResizeDeathBits = xallocarray(winRec->bytesPerRow, winRec->height); memcpy(gResizeDeathBits, winRec->pixelData, winRec->bytesPerRow * winRec->height); diff --git a/xorg-server/miext/shadow/shalloc.c b/xorg-server/miext/shadow/shalloc.c index e555135b9..6a79085c4 100644 --- a/xorg-server/miext/shadow/shalloc.c +++ b/xorg-server/miext/shadow/shalloc.c @@ -44,6 +44,6 @@ shadowAlloc(int width, int height, int bpp) /* Cant use PixmapBytePad -- the structure is probably not initialized yet */ stride = BitmapBytePad(width * bpp); - fb = malloc(stride * height); + fb = xallocarray(stride, height); return fb; } diff --git a/xorg-server/os/connection.c b/xorg-server/os/connection.c index 7ff44e175..c36b125fe 100644 --- a/xorg-server/os/connection.c +++ b/xorg-server/os/connection.c @@ -309,7 +309,7 @@ InitConnectionLimits(void) #if !defined(WIN32) if (!ConnectionTranslation) - ConnectionTranslation = (int *) xnfalloc(sizeof(int) * (lastfdesc + 1)); + ConnectionTranslation = xnfallocarray(lastfdesc + 1, sizeof(int)); #else InitConnectionTranslation(); #endif @@ -429,7 +429,9 @@ CreateWellKnownSockets(void) display = dynamic_display; } - ListenTransFds = malloc(ListenTransCount * sizeof (int)); + ListenTransFds = xallocarray(ListenTransCount, sizeof (int)); + if (ListenTransFds == NULL) + FatalError ("Failed to create listening socket array"); for (i = 0; i < ListenTransCount; i++) { int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]); @@ -1291,11 +1293,10 @@ ListenOnOpenFD(int fd, int noxauth) /* Allocate space to store it */ ListenTransFds = - (int *) realloc(ListenTransFds, (ListenTransCount + 1) * sizeof(int)); + xnfreallocarray(ListenTransFds, ListenTransCount + 1, sizeof(int)); ListenTransConns = - (XtransConnInfo *) realloc(ListenTransConns, - (ListenTransCount + - 1) * sizeof(XtransConnInfo)); + xnfreallocarray(ListenTransConns, ListenTransCount + 1, + sizeof(XtransConnInfo)); /* Store it */ ListenTransConns[ListenTransCount] = ciptr; diff --git a/xorg-server/os/reallocarray.c b/xorg-server/os/reallocarray.c new file mode 100644 index 000000000..c415e09af --- /dev/null +++ b/xorg-server/os/reallocarray.c @@ -0,0 +1,43 @@ +/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */ +/* + * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <sys/types.h> +#include <errno.h> +#include <stdint.h> +#include <stdlib.h> +#include "os.h" + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) + +void * +reallocarray(void *optr, size_t nmemb, size_t size) +{ + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && SIZE_MAX / nmemb < size) { + errno = ENOMEM; + return NULL; + } + return realloc(optr, size * nmemb); +} diff --git a/xorg-server/os/utils.c b/xorg-server/os/utils.c index 75769f17c..7fd395b2a 100644 --- a/xorg-server/os/utils.c +++ b/xorg-server/os/utils.c @@ -1128,10 +1128,20 @@ XNFalloc(unsigned long amount) return ptr; } +/* The original XNFcalloc was used with the xnfcalloc macro which multiplied + * the arguments at the call site without allowing calloc to check for overflow. + * XNFcallocarray was added to fix that without breaking ABI. + */ void * XNFcalloc(unsigned long amount) { - void *ret = calloc(1, amount); + return XNFcallocarray(1, amount); +} + +void * +XNFcallocarray(size_t nmemb, size_t size) +{ + void *ret = calloc(nmemb, size); if (!ret) FatalError("XNFcalloc: Out of memory"); @@ -1148,6 +1158,16 @@ XNFrealloc(void *ptr, unsigned long amount) return ret; } +void * +XNFreallocarray(void *ptr, size_t nmemb, size_t size) +{ + void *ret = reallocarray(ptr, nmemb, size); + + if (!ret) + FatalError("XNFreallocarray: Out of memory"); + return ret; +} + char * Xstrdup(const char *s) { @@ -1640,7 +1660,7 @@ Fclose(void *iop) #include <X11/Xwindows.h> const char * -Win32TempDir() +Win32TempDir(void) { static char buffer[PATH_MAX]; @@ -1981,7 +2001,7 @@ xstrtokenize(const char *str, const char *separators) if (!tmp) goto error; for (tok = strtok(tmp, separators); tok; tok = strtok(NULL, separators)) { - nlist = realloc(list, (num + 2) * sizeof(*list)); + nlist = reallocarray(list, num + 2, sizeof(*list)); if (!nlist) goto error; list = nlist; @@ -2091,6 +2111,7 @@ FormatUInt64Hex(uint64_t num, char *string) string[len] = '\0'; } +#if !defined(WIN32) || defined(__CYGWIN__) /* Move a file descriptor out of the way of our select mask; this * is useful for file descriptors which will never appear in the * select mask to avoid reducing the number of clients that can @@ -2114,3 +2135,4 @@ os_move_fd(int fd) close(fd); return newfd; } +#endif diff --git a/xorg-server/os/xdmcp.c b/xorg-server/os/xdmcp.c index bc5a70706..b265db338 100644 --- a/xorg-server/os/xdmcp.c +++ b/xorg-server/os/xdmcp.c @@ -19,6 +19,10 @@ #ifdef WIN32 #include <X11/Xwinsock.h> +#define XSERV_t +#define TRANS_SERVER +#define TRANS_REOPEN +#include <X11/Xtrans/Xtrans.h> #endif #include <X11/Xos.h> diff --git a/xorg-server/pseudoramiX/pseudoramiX.c b/xorg-server/pseudoramiX/pseudoramiX.c index e59ca1312..d8b259341 100644 --- a/xorg-server/pseudoramiX/pseudoramiX.c +++ b/xorg-server/pseudoramiX/pseudoramiX.c @@ -140,9 +140,9 @@ PseudoramiXAddScreen(int x, int y, int w, int h) if (pseudoramiXNumScreens == pseudoramiXScreensAllocated) { pseudoramiXScreensAllocated += pseudoramiXScreensAllocated + 1; - pseudoramiXScreens = realloc(pseudoramiXScreens, - pseudoramiXScreensAllocated * - sizeof(PseudoramiXScreenRec)); + pseudoramiXScreens = reallocarray(pseudoramiXScreens, + pseudoramiXScreensAllocated, + sizeof(PseudoramiXScreenRec)); } DEBUG_LOG("x: %d, y: %d, w: %d, h: %d\n", x, y, w, h); diff --git a/xorg-server/randr/randrstr.h b/xorg-server/randr/randrstr.h index 438a52aeb..03974fd4f 100644 --- a/xorg-server/randr/randrstr.h +++ b/xorg-server/randr/randrstr.h @@ -1016,6 +1016,15 @@ RRMonitorFreeList(RRMonitorPtr monitors, int nmon); void RRMonitorClose(ScreenPtr screen); +RRMonitorPtr +RRMonitorAlloc(int noutput); + +int +RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor); + +void +RRMonitorFree(RRMonitorPtr monitor); + int ProcRRGetMonitors(ClientPtr client); diff --git a/xorg-server/randr/rrcrtc.c b/xorg-server/randr/rrcrtc.c index 69b3ecf0f..e95b049df 100644 --- a/xorg-server/randr/rrcrtc.c +++ b/xorg-server/randr/rrcrtc.c @@ -65,8 +65,8 @@ RRCrtcCreate(ScreenPtr pScreen, void *devPrivate) /* make space for the crtc pointer */ if (pScrPriv->numCrtcs) - crtcs = realloc(pScrPriv->crtcs, - (pScrPriv->numCrtcs + 1) * sizeof(RRCrtcPtr)); + crtcs = reallocarray(pScrPriv->crtcs, + pScrPriv->numCrtcs + 1, sizeof(RRCrtcPtr)); else crtcs = malloc(sizeof(RRCrtcPtr)); if (!crtcs) @@ -176,10 +176,10 @@ RRCrtcNotify(RRCrtcPtr crtc, if (numOutputs) { if (crtc->numOutputs) - newoutputs = realloc(crtc->outputs, - numOutputs * sizeof(RROutputPtr)); + newoutputs = reallocarray(crtc->outputs, + numOutputs, sizeof(RROutputPtr)); else - newoutputs = malloc(numOutputs * sizeof(RROutputPtr)); + newoutputs = xallocarray(numOutputs, sizeof(RROutputPtr)); if (!newoutputs) return FALSE; } @@ -394,7 +394,7 @@ rrCreateSharedPixmap(RRCrtcPtr crtc, int width, int height, Bool ret; int depth; PixmapPtr mscreenpix; - PixmapPtr protopix = crtc->pScreen->current_master->GetScreenPixmap(crtc->pScreen->current_master); + PixmapPtr protopix = master->GetScreenPixmap(master); rrScrPriv(crtc->pScreen); /* create a pixmap on the master screen, @@ -428,7 +428,7 @@ rrCreateSharedPixmap(RRCrtcPtr crtc, int width, int height, ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, spix); if (ret == FALSE) { - ErrorF("failed to set shadow slave pixmap\n"); + ErrorF("randr: failed to set shadow slave pixmap\n"); return FALSE; } @@ -457,18 +457,20 @@ rrCheckPixmapBounding(ScreenPtr pScreen, /* have to iterate all the crtcs of the attached gpu masters and all their output slaves */ for (c = 0; c < pScrPriv->numCrtcs; c++) { - if (pScrPriv->crtcs[c] == rr_crtc) { + RRCrtcPtr crtc = pScrPriv->crtcs[c]; + + if (crtc == rr_crtc) { newbox.x1 = x; newbox.x2 = x + w; newbox.y1 = y; newbox.y2 = y + h; } else { - if (!pScrPriv->crtcs[c]->mode) + if (!crtc->mode) continue; - newbox.x1 = pScrPriv->crtcs[c]->x; - newbox.x2 = pScrPriv->crtcs[c]->x + pScrPriv->crtcs[c]->mode->mode.width; - newbox.y1 = pScrPriv->crtcs[c]->y; - newbox.y2 = pScrPriv->crtcs[c]->y + pScrPriv->crtcs[c]->mode->mode.height; + newbox.x1 = crtc->x; + newbox.x2 = crtc->x + crtc->mode->mode.width; + newbox.y1 = crtc->y; + newbox.y2 = crtc->y + crtc->mode->mode.height; } RegionInit(&new_crtc_region, &newbox, 1); RegionUnion(&total_region, &total_region, &new_crtc_region); @@ -477,19 +479,21 @@ rrCheckPixmapBounding(ScreenPtr pScreen, xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) { rrScrPrivPtr slave_priv = rrGetScrPriv(slave); for (c = 0; c < slave_priv->numCrtcs; c++) { - if (slave_priv->crtcs[c] == rr_crtc) { + RRCrtcPtr slave_crtc = slave_priv->crtcs[c]; + + if (slave_crtc == rr_crtc) { newbox.x1 = x; newbox.x2 = x + w; newbox.y1 = y; newbox.y2 = y + h; } else { - if (!slave_priv->crtcs[c]->mode) + if (!slave_crtc->mode) continue; - newbox.x1 = slave_priv->crtcs[c]->x; - newbox.x2 = slave_priv->crtcs[c]->x + slave_priv->crtcs[c]->mode->mode.width; - newbox.y1 = slave_priv->crtcs[c]->y; - newbox.y2 = slave_priv->crtcs[c]->y + slave_priv->crtcs[c]->mode->mode.height; + newbox.x1 = slave_crtc->x; + newbox.x2 = slave_crtc->x + slave_crtc->mode->mode.width; + newbox.y1 = slave_crtc->y; + newbox.y2 = slave_crtc->y + slave_crtc->mode->mode.height; } RegionInit(&new_crtc_region, &newbox, 1); RegionUnion(&total_region, &total_region, &new_crtc_region); @@ -502,7 +506,6 @@ rrCheckPixmapBounding(ScreenPtr pScreen, if (new_width == screen_pixmap->drawable.width && new_height == screen_pixmap->drawable.height) { - ErrorF("adjust shatters %d %d\n", newsize->x1, newsize->x2); } else { pScrPriv->rrScreenSetSize(pScreen, new_width, new_height, 0, 0); } @@ -557,7 +560,6 @@ RRCrtcSet(RRCrtcPtr crtc, width = mode->mode.width; height = mode->mode.height; } - ErrorF("have a master to look out for\n"); ret = rrCheckPixmapBounding(master, crtc, x, y, width, height); if (!ret) @@ -565,8 +567,6 @@ RRCrtcSet(RRCrtcPtr crtc, if (pScreen->current_master) { ret = rrCreateSharedPixmap(crtc, width, height, x, y); - ErrorF("need to create shared pixmap %d", ret); - } } #if RANDR_12_INTERFACE @@ -798,7 +798,7 @@ RRCrtcGammaSetSize(RRCrtcPtr crtc, int size) if (size == crtc->gammaSize) return TRUE; if (size) { - gamma = malloc(size * 3 * sizeof(CARD16)); + gamma = xallocarray(size, 3 * sizeof(CARD16)); if (!gamma) return FALSE; } @@ -1027,7 +1027,7 @@ ProcRRSetCrtcConfig(ClientPtr client) return BadMatch; } if (numOutputs) { - outputs = malloc(numOutputs * sizeof(RROutputPtr)); + outputs = xallocarray(numOutputs, sizeof(RROutputPtr)); if (!outputs) return BadAlloc; } @@ -1575,7 +1575,8 @@ ProcRRGetCrtcTransform(ClientPtr client) return Success; } -static Bool check_all_screen_crtcs(ScreenPtr pScreen, int *x, int *y) +static Bool +check_all_screen_crtcs(ScreenPtr pScreen, int *x, int *y) { rrScrPriv(pScreen); int i; @@ -1595,7 +1596,8 @@ static Bool check_all_screen_crtcs(ScreenPtr pScreen, int *x, int *y) return FALSE; } -static Bool constrain_all_screen_crtcs(DeviceIntPtr pDev, ScreenPtr pScreen, int *x, int *y) +static Bool +constrain_all_screen_crtcs(DeviceIntPtr pDev, ScreenPtr pScreen, int *x, int *y) { rrScrPriv(pScreen); int i; diff --git a/xorg-server/randr/rrinfo.c b/xorg-server/randr/rrinfo.c index fc57bd408..24245b7b6 100644 --- a/xorg-server/randr/rrinfo.c +++ b/xorg-server/randr/rrinfo.c @@ -55,8 +55,8 @@ RROldModeAdd(RROutputPtr output, RRScreenSizePtr size, int refresh) } if (output->numModes) - modes = realloc(output->modes, - (output->numModes + 1) * sizeof(RRModePtr)); + modes = reallocarray(output->modes, + output->numModes + 1, sizeof(RRModePtr)); else modes = malloc(sizeof(RRModePtr)); if (!modes) { @@ -266,8 +266,8 @@ RRRegisterSize(ScreenPtr pScreen, for (i = 0; i < pScrPriv->nSizes; i++) if (RRScreenSizeMatches(&tmp, &pScrPriv->pSizes[i])) return &pScrPriv->pSizes[i]; - pNew = realloc(pScrPriv->pSizes, - (pScrPriv->nSizes + 1) * sizeof(RRScreenSize)); + pNew = reallocarray(pScrPriv->pSizes, + pScrPriv->nSizes + 1, sizeof(RRScreenSize)); if (!pNew) return 0; pNew[pScrPriv->nSizes++] = tmp; @@ -289,7 +289,7 @@ RRRegisterRate(ScreenPtr pScreen, RRScreenSizePtr pSize, int rate) if (pSize->pRates[i].rate == rate) return TRUE; - pNew = realloc(pSize->pRates, (pSize->nRates + 1) * sizeof(RRScreenRate)); + pNew = reallocarray(pSize->pRates, pSize->nRates + 1, sizeof(RRScreenRate)); if (!pNew) return FALSE; pRate = &pNew[pSize->nRates++]; diff --git a/xorg-server/randr/rrmode.c b/xorg-server/randr/rrmode.c index befac4741..a7aa43320 100644 --- a/xorg-server/randr/rrmode.c +++ b/xorg-server/randr/rrmode.c @@ -79,7 +79,7 @@ RRModeCreate(xRRModeInfo * modeInfo, const char *name, ScreenPtr userScreen) mode->userScreen = userScreen; if (num_modes) - newModes = realloc(modes, (num_modes + 1) * sizeof(RRModePtr)); + newModes = reallocarray(modes, num_modes + 1, sizeof(RRModePtr)); else newModes = malloc(sizeof(RRModePtr)); @@ -166,7 +166,7 @@ RRModesForScreen(ScreenPtr pScreen, int *num_ret) RRModePtr *screen_modes; int num_screen_modes = 0; - screen_modes = malloc((num_modes ? num_modes : 1) * sizeof(RRModePtr)); + screen_modes = xallocarray((num_modes ? num_modes : 1), sizeof(RRModePtr)); if (!screen_modes) return NULL; diff --git a/xorg-server/randr/rrmonitor.c b/xorg-server/randr/rrmonitor.c index fbdd352f6..05285ddfd 100644 --- a/xorg-server/randr/rrmonitor.c +++ b/xorg-server/randr/rrmonitor.c @@ -389,13 +389,13 @@ RRMonitorCountList(ScreenPtr screen) return nmon; } -static void +void RRMonitorFree(RRMonitorPtr monitor) { free(monitor); } -static RRMonitorPtr +RRMonitorPtr RRMonitorAlloc(int noutput) { RRMonitorPtr monitor; @@ -451,7 +451,7 @@ RRMonitorMatchesOutputName(ScreenPtr screen, Atom name) return FALSE; } -static int +int RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor) { rrScrPrivPtr pScrPriv = rrGetScrPriv(screen); @@ -494,8 +494,9 @@ RRMonitorAdd(ClientPtr client, ScreenPtr screen, RRMonitorPtr monitor) * needs to not have any side-effects on failure */ if (pScrPriv->numMonitors) - monitors = realloc(pScrPriv->monitors, - (pScrPriv->numMonitors + 1) * sizeof (RRMonitorPtr)); + monitors = reallocarray(pScrPriv->monitors, + pScrPriv->numMonitors + 1, + sizeof (RRMonitorPtr)); else monitors = malloc(sizeof (RRMonitorPtr)); diff --git a/xorg-server/randr/rroutput.c b/xorg-server/randr/rroutput.c index 548e07d1d..10df4da95 100644 --- a/xorg-server/randr/rroutput.c +++ b/xorg-server/randr/rroutput.c @@ -60,8 +60,8 @@ RROutputCreate(ScreenPtr pScreen, pScrPriv = rrGetScrPriv(pScreen); if (pScrPriv->numOutputs) - outputs = realloc(pScrPriv->outputs, - (pScrPriv->numOutputs + 1) * sizeof(RROutputPtr)); + outputs = reallocarray(pScrPriv->outputs, + pScrPriv->numOutputs + 1, sizeof(RROutputPtr)); else outputs = malloc(sizeof(RROutputPtr)); if (!outputs) @@ -124,7 +124,7 @@ RROutputSetClones(RROutputPtr output, RROutputPtr * clones, int numClones) return TRUE; } if (numClones) { - newClones = malloc(numClones * sizeof(RROutputPtr)); + newClones = xallocarray(numClones, sizeof(RROutputPtr)); if (!newClones) return FALSE; } @@ -157,7 +157,7 @@ RROutputSetModes(RROutputPtr output, } if (numModes) { - newModes = malloc(numModes * sizeof(RRModePtr)); + newModes = xallocarray(numModes, sizeof(RRModePtr)); if (!newModes) return FALSE; } @@ -200,8 +200,8 @@ RROutputAddUserMode(RROutputPtr output, RRModePtr mode) return BadMatch; if (output->userModes) - newModes = realloc(output->userModes, - (output->numUserModes + 1) * sizeof(RRModePtr)); + newModes = reallocarray(output->userModes, + output->numUserModes + 1, sizeof(RRModePtr)); else newModes = malloc(sizeof(RRModePtr)); if (!newModes) @@ -256,7 +256,7 @@ RROutputSetCrtcs(RROutputPtr output, RRCrtcPtr * crtcs, int numCrtcs) return TRUE; } if (numCrtcs) { - newCrtcs = malloc(numCrtcs * sizeof(RRCrtcPtr)); + newCrtcs = xallocarray(numCrtcs, sizeof(RRCrtcPtr)); if (!newCrtcs) return FALSE; } diff --git a/xorg-server/randr/rrproperty.c b/xorg-server/randr/rrproperty.c index e385e15ab..e56626cd2 100644 --- a/xorg-server/randr/rrproperty.c +++ b/xorg-server/randr/rrproperty.c @@ -140,7 +140,6 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type, RRPropertyPtr prop; rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen); int size_in_bytes; - int total_size; unsigned long total_len; RRPropertyValuePtr prop_value; RRPropertyValueRec new_value; @@ -180,9 +179,8 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type, if (mode == PropModeReplace || len > 0) { void *new_data = NULL, *old_data = NULL; - total_size = total_len * size_in_bytes; - new_value.data = (void *) malloc(total_size); - if (!new_value.data && total_size) { + new_value.data = xallocarray(total_len, size_in_bytes); + if (!new_value.data && total_len && size_in_bytes) { if (add) RRDestroyOutputProperty(prop); return BadAlloc; @@ -350,7 +348,7 @@ RRConfigureOutputProperty(RROutputPtr output, Atom property, return BadMatch; } - new_values = malloc(num_values * sizeof(INT32)); + new_values = xallocarray(num_values, sizeof(INT32)); if (!new_values && num_values) { if (add) RRDestroyOutputProperty(prop); @@ -400,7 +398,7 @@ ProcRRListOutputProperties(ClientPtr client) for (prop = output->properties; prop; prop = prop->next) numProps++; if (numProps) - if (!(pAtoms = (Atom *) malloc(numProps * sizeof(Atom)))) + if (!(pAtoms = xallocarray(numProps, sizeof(Atom)))) return BadAlloc; rep = (xRRListOutputPropertiesReply) { @@ -447,7 +445,7 @@ ProcRRQueryOutputProperty(ClientPtr client) return BadName; if (prop->num_valid) { - extra = malloc(prop->num_valid * sizeof(INT32)); + extra = xallocarray(prop->num_valid, sizeof(INT32)); if (!extra) return BadAlloc; } diff --git a/xorg-server/randr/rrproviderproperty.c b/xorg-server/randr/rrproviderproperty.c index ff2c614d0..b79c17f9b 100644 --- a/xorg-server/randr/rrproviderproperty.c +++ b/xorg-server/randr/rrproviderproperty.c @@ -350,7 +350,7 @@ RRConfigureProviderProperty(RRProviderPtr provider, Atom property, return BadMatch; } - new_values = malloc(num_values * sizeof(INT32)); + new_values = xallocarray(num_values, sizeof(INT32)); if (!new_values && num_values) { if (add) RRDestroyProviderProperty(prop); @@ -400,7 +400,7 @@ ProcRRListProviderProperties(ClientPtr client) for (prop = provider->properties; prop; prop = prop->next) numProps++; if (numProps) - if (!(pAtoms = (Atom *) malloc(numProps * sizeof(Atom)))) + if (!(pAtoms = xallocarray(numProps, sizeof(Atom)))) return BadAlloc; rep = (xRRListProviderPropertiesReply) { @@ -445,7 +445,7 @@ ProcRRQueryProviderProperty(ClientPtr client) return BadName; if (prop->num_valid) { - extra = malloc(prop->num_valid * sizeof(INT32)); + extra = xallocarray(prop->num_valid, sizeof(INT32)); if (!extra) return BadAlloc; } diff --git a/xorg-server/randr/rrscreen.c b/xorg-server/randr/rrscreen.c index e7ea49ddf..d0ca91e0e 100644 --- a/xorg-server/randr/rrscreen.c +++ b/xorg-server/randr/rrscreen.c @@ -400,8 +400,6 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen) update_totals(iter, pScrPriv); } - ErrorF("reporting %d %d %d %d\n", total_crtcs, total_outputs, total_modes, total_name_len); - pScrPriv = rrGetScrPriv(pScreen); rep = (xRRGetScreenResourcesReply) { .type = X_Reply, @@ -415,8 +413,9 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen) .nbytesNames = total_name_len }; - rep.length = (total_crtcs + total_outputs + total_modes * bytes_to_int32(SIZEOF(xRRModeInfo)) + - bytes_to_int32(rep.nbytesNames)); + rep.length = (total_crtcs + total_outputs + + total_modes * bytes_to_int32(SIZEOF(xRRModeInfo)) + + bytes_to_int32(total_name_len)); extraLen = rep.length << 2; if (extraLen) { diff --git a/xorg-server/randr/rrtransform.c b/xorg-server/randr/rrtransform.c index c8a27498f..6137f8587 100644 --- a/xorg-server/randr/rrtransform.c +++ b/xorg-server/randr/rrtransform.c @@ -70,7 +70,7 @@ RRTransformSetFilter(RRTransformPtr dst, xFixed *new_params; if (nparams) { - new_params = malloc(nparams * sizeof(xFixed)); + new_params = xallocarray(nparams, sizeof(xFixed)); if (!new_params) return FALSE; memcpy(new_params, params, nparams * sizeof(xFixed)); diff --git a/xorg-server/record/record.c b/xorg-server/record/record.c index 0a466e279..1caf3f1db 100644 --- a/xorg-server/record/record.c +++ b/xorg-server/record/record.c @@ -1074,19 +1074,19 @@ RecordAddClientToRCAP(RecordClientsAndProtocolPtr pRCAP, XID clientspec) { if (pRCAP->numClients == pRCAP->sizeClients) { if (pRCAP->clientIDsSeparatelyAllocated) { - XID *pNewIDs = (XID *) realloc(pRCAP->pClientIDs, - (pRCAP->sizeClients + - CLIENT_ARRAY_GROWTH_INCREMENT) * - sizeof(XID)); + XID *pNewIDs = + reallocarray(pRCAP->pClientIDs, + pRCAP->sizeClients + CLIENT_ARRAY_GROWTH_INCREMENT, + sizeof(XID)); if (!pNewIDs) return; pRCAP->pClientIDs = pNewIDs; pRCAP->sizeClients += CLIENT_ARRAY_GROWTH_INCREMENT; } else { - XID *pNewIDs = (XID *) malloc((pRCAP->sizeClients + - CLIENT_ARRAY_GROWTH_INCREMENT) * - sizeof(XID)); + XID *pNewIDs = + xallocarray(pRCAP->sizeClients + CLIENT_ARRAY_GROWTH_INCREMENT, + sizeof(XID)); if (!pNewIDs) return; memcpy(pNewIDs, pRCAP->pClientIDs, pRCAP->numClients * sizeof(XID)); @@ -1217,7 +1217,7 @@ RecordCanonicalizeClientSpecifiers(XID *pClientspecs, int *pNumClientspecs, for (i = 0; i < numClients; i++) { if (pClientspecs[i] == XRecordAllClients || pClientspecs[i] == XRecordCurrentClients) { /* expand All/Current */ int j, nc; - XID *pCanon = (XID *) malloc(sizeof(XID) * (currentMaxClients + 1)); + XID *pCanon = xallocarray(currentMaxClients + 1, sizeof(XID)); if (!pCanon) return NULL; @@ -1421,8 +1421,7 @@ static int RecordAllocIntervals(SetInfoPtr psi, int nIntervals) { assert(!psi->intervals); - psi->intervals = (RecordSetInterval *) - malloc(nIntervals * sizeof(RecordSetInterval)); + psi->intervals = xallocarray(nIntervals, sizeof(RecordSetInterval)); if (!psi->intervals) return BadAlloc; memset(psi->intervals, 0, nIntervals * sizeof(RecordSetInterval)); @@ -1584,7 +1583,7 @@ RecordRegisterClients(RecordContextPtr pContext, ClientPtr client, * range for extension replies. */ maxSets = PREDEFSETS + 2 * stuff->nRanges; - si = (SetInfoPtr) malloc(sizeof(SetInfoRec) * maxSets); + si = xallocarray(maxSets, sizeof(SetInfoRec)); if (!si) { err = BadAlloc; goto bailout; @@ -1853,8 +1852,8 @@ ProcRecordCreateContext(ClientPtr client) /* make sure there is room in ppAllContexts to store the new context */ - ppNewAllContexts = (RecordContextPtr *) - realloc(ppAllContexts, sizeof(RecordContextPtr) * (numContexts + 1)); + ppNewAllContexts = + reallocarray(ppAllContexts, numContexts + 1, sizeof(RecordContextPtr)); if (!ppNewAllContexts) goto bailout; ppAllContexts = ppNewAllContexts; @@ -1971,8 +1970,7 @@ RecordAllocRanges(GetContextRangeInfoPtr pri, int nRanges) #define SZINCR 8 newsize = max(pri->size + SZINCR, nRanges); - pNewRange = (xRecordRange *) realloc(pri->pRanges, - newsize * sizeof(xRecordRange)); + pNewRange = reallocarray(pri->pRanges, newsize, sizeof(xRecordRange)); if (!pNewRange) return BadAlloc; @@ -2150,9 +2148,7 @@ ProcRecordGetContext(ClientPtr client) /* allocate and initialize space for record range info */ - pRangeInfo = - (GetContextRangeInfoPtr) malloc(nRCAPs * - sizeof(GetContextRangeInfoRec)); + pRangeInfo = xallocarray(nRCAPs, sizeof(GetContextRangeInfoRec)); if (!pRangeInfo && nRCAPs > 0) return BadAlloc; for (i = 0; i < nRCAPs; i++) { @@ -2733,7 +2729,8 @@ RecordAClientStateChange(CallbackListPtr *pcbl, void *nulldata, /* RecordDisableContext modifies contents of ppAllContexts. */ numContextsCopy = numContexts; - ppAllContextsCopy = malloc(numContextsCopy * sizeof(RecordContextPtr)); + ppAllContextsCopy = xallocarray(numContextsCopy, + sizeof(RecordContextPtr)); assert(ppAllContextsCopy); memcpy(ppAllContextsCopy, ppAllContexts, numContextsCopy * sizeof(RecordContextPtr)); diff --git a/xorg-server/record/set.c b/xorg-server/record/set.c index 34faa617e..e0db385b9 100644 --- a/xorg-server/record/set.c +++ b/xorg-server/record/set.c @@ -303,9 +303,7 @@ IntervalListCreateSet(RecordSetInterval * pIntervals, int nIntervals, CARD16 first; if (nIntervals > 0) { - stackIntervals = - (RecordSetInterval *) malloc(sizeof(RecordSetInterval) * - nIntervals); + stackIntervals = xallocarray(nIntervals, sizeof(RecordSetInterval)); if (!stackIntervals) return NULL; diff --git a/xorg-server/render/filter.c b/xorg-server/render/filter.c index 019ea7f94..2741f406c 100644 --- a/xorg-server/render/filter.c +++ b/xorg-server/render/filter.c @@ -67,7 +67,7 @@ PictureGetFilterId(const char *filter, int len, Bool makeit) memcpy(name, filter, len); name[len] = '\0'; if (filterNames) - names = realloc(filterNames, (nfilterNames + 1) * sizeof(char *)); + names = reallocarray(filterNames, nfilterNames + 1, sizeof(char *)); else names = malloc(sizeof(char *)); if (!names) { @@ -145,7 +145,7 @@ PictureAddFilter(ScreenPtr pScreen, return -1; if (ps->filters) filters = - realloc(ps->filters, (ps->nfilters + 1) * sizeof(PictFilterRec)); + reallocarray(ps->filters, ps->nfilters + 1, sizeof(PictFilterRec)); else filters = malloc(sizeof(PictFilterRec)); if (!filters) @@ -177,9 +177,9 @@ PictureSetFilterAlias(ScreenPtr pScreen, const char *filter, const char *alias) PictFilterAliasPtr aliases; if (ps->filterAliases) - aliases = realloc(ps->filterAliases, - (ps->nfilterAliases + 1) * - sizeof(PictFilterAliasRec)); + aliases = reallocarray(ps->filterAliases, + ps->nfilterAliases + 1, + sizeof(PictFilterAliasRec)); else aliases = malloc(sizeof(PictFilterAliasRec)); if (!aliases) @@ -336,7 +336,7 @@ SetPicturePictFilter(PicturePtr pPicture, PictFilterPtr pFilter, return BadMatch; if (nparams != pPicture->filter_nparams) { - xFixed *new_params = malloc(nparams * sizeof(xFixed)); + xFixed *new_params = xallocarray(nparams, sizeof(xFixed)); if (!new_params && nparams) return BadAlloc; diff --git a/xorg-server/render/miindex.c b/xorg-server/render/miindex.c index 0375e8f88..4119eef66 100644 --- a/xorg-server/render/miindex.c +++ b/xorg-server/render/miindex.c @@ -254,7 +254,7 @@ miInitIndexed(ScreenPtr pScreen, PictFormatPtr pFormat) return FALSE; pFormat->index.nvalues = num; - pFormat->index.pValues = malloc(num * sizeof(xIndexValue)); + pFormat->index.pValues = xallocarray(num, sizeof(xIndexValue)); if (!pFormat->index.pValues) { free(pIndexed); return FALSE; diff --git a/xorg-server/render/mipict.c b/xorg-server/render/mipict.c index a72510480..2571fda17 100644 --- a/xorg-server/render/mipict.c +++ b/xorg-server/render/mipict.c @@ -510,7 +510,7 @@ miTriStrip(CARD8 op, int ntri; ntri = npoints - 2; - tris = malloc(ntri * sizeof(xTriangle)); + tris = xallocarray(ntri, sizeof(xTriangle)); if (!tris) return; @@ -535,7 +535,7 @@ miTriFan(CARD8 op, int ntri; ntri = npoints - 2; - tris = malloc(ntri * sizeof(xTriangle)); + tris = xallocarray(ntri, sizeof(xTriangle)); if (!tris) return; diff --git a/xorg-server/render/picture.c b/xorg-server/render/picture.c index 6ff31ba02..60517a4ee 100644 --- a/xorg-server/render/picture.c +++ b/xorg-server/render/picture.c @@ -837,7 +837,7 @@ initGradient(SourcePictPtr pGradient, int stopCount, dpos = stopPoints[i]; } - pGradient->gradient.stops = malloc(stopCount * sizeof(PictGradientStop)); + pGradient->gradient.stops = xallocarray(stopCount, sizeof(PictGradientStop)); if (!pGradient->gradient.stops) { *error = BadAlloc; return; diff --git a/xorg-server/render/render.c b/xorg-server/render/render.c index 723f380c2..88d8a2669 100644 --- a/xorg-server/render/render.c +++ b/xorg-server/render/render.c @@ -1318,14 +1318,14 @@ ProcRenderCompositeGlyphs(ClientPtr client) if (nglyph <= NLOCALGLYPH) glyphsBase = glyphsLocal; else { - glyphsBase = (GlyphPtr *) malloc(nglyph * sizeof(GlyphPtr)); + glyphsBase = xallocarray(nglyph, sizeof(GlyphPtr)); if (!glyphsBase) return BadAlloc; } if (nlist <= NLOCALDELTA) listsBase = listsLocal; else { - listsBase = (GlyphListPtr) malloc(nlist * sizeof(GlyphListRec)); + listsBase = xallocarray(nlist, sizeof(GlyphListRec)); if (!listsBase) { rc = BadAlloc; goto bail; @@ -1793,7 +1793,7 @@ ProcRenderCreateAnimCursor(ClientPtr client) ncursor = (client->req_len - (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1; - cursors = malloc(ncursor * (sizeof(CursorPtr) + sizeof(CARD32))); + cursors = xallocarray(ncursor, sizeof(CursorPtr) + sizeof(CARD32)); if (!cursors) return BadAlloc; deltas = (CARD32 *) (cursors + ncursor); diff --git a/xorg-server/xfixes/region.c b/xorg-server/xfixes/region.c index 4492f1267..dd74d7f7e 100644 --- a/xorg-server/xfixes/region.c +++ b/xorg-server/xfixes/region.c @@ -777,7 +777,7 @@ ProcXFixesExpandRegion(ClientPtr client) nBoxes = RegionNumRects(pSource); pSrc = RegionRects(pSource); if (nBoxes) { - pTmp = malloc(nBoxes * sizeof(BoxRec)); + pTmp = xallocarray(nBoxes, sizeof(BoxRec)); if (!pTmp) return BadAlloc; for (i = 0; i < nBoxes; i++) { diff --git a/xorg-server/xkb/XKBAlloc.c b/xorg-server/xkb/XKBAlloc.c index 78c98371d..18557b804 100644 --- a/xorg-server/xkb/XKBAlloc.c +++ b/xorg-server/xkb/XKBAlloc.c @@ -56,8 +56,8 @@ XkbAllocCompatMap(XkbDescPtr xkb, unsigned which, unsigned nSI) if (compat->sym_interpret == NULL) compat->num_si = 0; prev_interpret = compat->sym_interpret; - compat->sym_interpret = realloc(compat->sym_interpret, - nSI * sizeof(XkbSymInterpretRec)); + compat->sym_interpret = reallocarray(compat->sym_interpret, + nSI, sizeof(XkbSymInterpretRec)); if (compat->sym_interpret == NULL) { free(prev_interpret); compat->size_si = compat->num_si = 0; @@ -159,9 +159,9 @@ XkbAllocNames(XkbDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases) else if (nTotalAliases > names->num_key_aliases) { XkbKeyAliasRec *prev_aliases = names->key_aliases; - names->key_aliases = realloc(names->key_aliases, - nTotalAliases * - sizeof(XkbKeyAliasRec)); + names->key_aliases = reallocarray(names->key_aliases, + nTotalAliases, + sizeof(XkbKeyAliasRec)); if (names->key_aliases != NULL) { memset(&names->key_aliases[names->num_key_aliases], 0, (nTotalAliases - @@ -184,8 +184,8 @@ XkbAllocNames(XkbDescPtr xkb, unsigned which, int nTotalRG, int nTotalAliases) else if (nTotalRG > names->num_rg) { Atom *prev_radio_groups = names->radio_groups; - names->radio_groups = realloc(names->radio_groups, - nTotalRG * sizeof(Atom)); + names->radio_groups = reallocarray(names->radio_groups, + nTotalRG, sizeof(Atom)); if (names->radio_groups != NULL) { memset(&names->radio_groups[names->num_rg], 0, (nTotalRG - names->num_rg) * sizeof(Atom)); diff --git a/xorg-server/xkb/XKBGAlloc.c b/xorg-server/xkb/XKBGAlloc.c index 25917d304..e9f55fa43 100644 --- a/xorg-server/xkb/XKBGAlloc.c +++ b/xorg-server/xkb/XKBGAlloc.c @@ -409,7 +409,7 @@ XkbGeomRealloc(void **buffer, int szItems, int nrItems, return FALSE; /* Check if there is need to resize. */ if (nrItems != szItems) - if (!(items = realloc(items, nrItems * itemSize))) + if (!(items = reallocarray(items, nrItems, itemSize))) return FALSE; /* Clear specified items to zero. */ switch (clearance) { diff --git a/xorg-server/xkb/XKBMAlloc.c b/xorg-server/xkb/XKBMAlloc.c index 37ed1a725..dbc1389e6 100644 --- a/xorg-server/xkb/XKBMAlloc.c +++ b/xorg-server/xkb/XKBMAlloc.c @@ -80,7 +80,7 @@ XkbAllocClientMap(XkbDescPtr xkb, unsigned which, unsigned nTotalTypes) XkbKeyTypeRec *prev_types = map->types; map->types = - realloc(map->types, nTotalTypes * sizeof(XkbKeyTypeRec)); + reallocarray(map->types, nTotalTypes, sizeof(XkbKeyTypeRec)); if (map->types == NULL) { free(prev_types); map->num_types = map->size_types = 0; @@ -177,7 +177,7 @@ XkbAllocServerMap(XkbDescPtr xkb, unsigned which, unsigned nNewActions) XkbAction *prev_acts = map->acts; need = map->num_acts + nNewActions; - map->acts = realloc(map->acts, need * sizeof(XkbAction)); + map->acts = reallocarray(map->acts, need, sizeof(XkbAction)); if (map->acts == NULL) { free(prev_acts); map->num_acts = map->size_acts = 0; @@ -309,7 +309,7 @@ XkbResizeKeyType(XkbDescPtr xkb, if ((map_count > type->map_count) || (type->map == NULL)) type->map = - realloc(type->map, map_count * sizeof(XkbKTMapEntryRec)); + reallocarray(type->map, map_count, sizeof(XkbKTMapEntryRec)); if (!type->map) { free(prev_map); return BadAlloc; @@ -318,8 +318,8 @@ XkbResizeKeyType(XkbDescPtr xkb, XkbModsRec *prev_preserve = type->preserve; if ((map_count > type->map_count) || (type->preserve == NULL)) { - type->preserve = realloc(type->preserve, - map_count * sizeof(XkbModsRec)); + type->preserve = reallocarray(type->preserve, + map_count, sizeof(XkbModsRec)); } if (!type->preserve) { free(prev_preserve); @@ -336,8 +336,8 @@ XkbResizeKeyType(XkbDescPtr xkb, if ((new_num_lvls > type->num_levels) || (type->level_names == NULL)) { Atom *prev_level_names = type->level_names; - type->level_names = realloc(type->level_names, - new_num_lvls * sizeof(Atom)); + type->level_names = reallocarray(type->level_names, + new_num_lvls, sizeof(Atom)); if (!type->level_names) { free(prev_level_names); return BadAlloc; @@ -659,9 +659,9 @@ XkbChangeKeycodeRange(XkbDescPtr xkb, if (xkb->map->key_sym_map) { XkbSymMapRec *prev_key_sym_map = xkb->map->key_sym_map; - xkb->map->key_sym_map = realloc(xkb->map->key_sym_map, - (maxKC + - 1) * sizeof(XkbSymMapRec)); + xkb->map->key_sym_map = reallocarray(xkb->map->key_sym_map, + maxKC + 1, + sizeof(XkbSymMapRec)); if (!xkb->map->key_sym_map) { free(prev_key_sym_map); return BadAlloc; @@ -680,8 +680,9 @@ XkbChangeKeycodeRange(XkbDescPtr xkb, if (xkb->map->modmap) { unsigned char *prev_modmap = xkb->map->modmap; - xkb->map->modmap = realloc(xkb->map->modmap, - (maxKC + 1) * sizeof(unsigned char)); + xkb->map->modmap = reallocarray(xkb->map->modmap, + maxKC + 1, + sizeof(unsigned char)); if (!xkb->map->modmap) { free(prev_modmap); return BadAlloc; @@ -702,9 +703,9 @@ XkbChangeKeycodeRange(XkbDescPtr xkb, if (xkb->server->behaviors) { XkbBehavior *prev_behaviors = xkb->server->behaviors; - xkb->server->behaviors = realloc(xkb->server->behaviors, - (maxKC + - 1) * sizeof(XkbBehavior)); + xkb->server->behaviors = reallocarray(xkb->server->behaviors, + maxKC + 1, + sizeof(XkbBehavior)); if (!xkb->server->behaviors) { free(prev_behaviors); return BadAlloc; @@ -724,9 +725,9 @@ XkbChangeKeycodeRange(XkbDescPtr xkb, if (xkb->server->key_acts) { unsigned short *prev_key_acts = xkb->server->key_acts; - xkb->server->key_acts = realloc(xkb->server->key_acts, - (maxKC + - 1) * sizeof(unsigned short)); + xkb->server->key_acts = reallocarray(xkb->server->key_acts, + maxKC + 1, + sizeof(unsigned short)); if (!xkb->server->key_acts) { free(prev_key_acts); return BadAlloc; @@ -746,9 +747,9 @@ XkbChangeKeycodeRange(XkbDescPtr xkb, if (xkb->server->vmodmap) { unsigned short *prev_vmodmap = xkb->server->vmodmap; - xkb->server->vmodmap = realloc(xkb->server->vmodmap, - (maxKC + - 1) * sizeof(unsigned short)); + xkb->server->vmodmap = reallocarray(xkb->server->vmodmap, + maxKC + 1, + sizeof(unsigned short)); if (!xkb->server->vmodmap) { free(prev_vmodmap); return BadAlloc; @@ -769,8 +770,8 @@ XkbChangeKeycodeRange(XkbDescPtr xkb, if ((xkb->names) && (xkb->names->keys)) { XkbKeyNameRec *prev_keys = xkb->names->keys; - xkb->names->keys = realloc(xkb->names->keys, - (maxKC + 1) * sizeof(XkbKeyNameRec)); + xkb->names->keys = reallocarray(xkb->names->keys, + maxKC + 1, sizeof(XkbKeyNameRec)); if (!xkb->names->keys) { free(prev_keys); return BadAlloc; diff --git a/xorg-server/xkb/maprules.c b/xorg-server/xkb/maprules.c index 28148d9a5..8e2277969 100644 --- a/xorg-server/xkb/maprules.c +++ b/xorg-server/xkb/maprules.c @@ -89,11 +89,11 @@ InputLineAddChar(InputLine * line, int ch) { if (line->num_line >= line->sz_line) { if (line->line == line->buf) { - line->line = malloc(line->sz_line * 2); + line->line = xallocarray(line->sz_line, 2); memcpy(line->line, line->buf, line->sz_line); } else { - line->line = realloc((char *) line->line, line->sz_line * 2); + line->line = reallocarray(line->line, line->sz_line, 2); } line->sz_line *= 2; } @@ -897,8 +897,8 @@ XkbRF_AddRule(XkbRF_RulesPtr rules) } else if (rules->num_rules >= rules->sz_rules) { rules->sz_rules *= 2; - rules->rules = realloc(rules->rules, - rules->sz_rules * sizeof(XkbRF_RuleRec)); + rules->rules = reallocarray(rules->rules, + rules->sz_rules, sizeof(XkbRF_RuleRec)); } if (!rules->rules) { rules->sz_rules = rules->num_rules = 0; @@ -919,8 +919,8 @@ XkbRF_AddGroup(XkbRF_RulesPtr rules) } else if (rules->num_groups >= rules->sz_groups) { rules->sz_groups *= 2; - rules->groups = realloc(rules->groups, - rules->sz_groups * sizeof(XkbRF_GroupRec)); + rules->groups = reallocarray(rules->groups, + rules->sz_groups, sizeof(XkbRF_GroupRec)); } if (!rules->groups) { rules->sz_groups = rules->num_groups = 0; diff --git a/xorg-server/xkb/xkb.c b/xorg-server/xkb/xkb.c index f3988f9a7..294cdf8a3 100644 --- a/xorg-server/xkb/xkb.c +++ b/xorg-server/xkb/xkb.c @@ -2216,12 +2216,11 @@ SetKeyBehaviors(XkbSrvInfoPtr xkbi, } if (maxRG > (int) xkbi->nRadioGroups) { - int sz = maxRG * sizeof(XkbRadioGroupRec); - if (xkbi->radioGroups) - xkbi->radioGroups = realloc(xkbi->radioGroups, sz); + xkbi->radioGroups = reallocarray(xkbi->radioGroups, maxRG, + sizeof(XkbRadioGroupRec)); else - xkbi->radioGroups = calloc(1, sz); + xkbi->radioGroups = calloc(maxRG, sizeof(XkbRadioGroupRec)); if (xkbi->radioGroups) { if (xkbi->nRadioGroups) memset(&xkbi->radioGroups[xkbi->nRadioGroups], 0, @@ -2700,15 +2699,16 @@ XkbSendCompatMap(ClientPtr client, char *data; int size; - size = rep->length * 4; - if (size > 0) { - data = malloc(size); + if (rep->length > 0) { + data = xallocarray(rep->length, 4); if (data) { register unsigned i, bit; xkbModsWireDesc *grp; XkbSymInterpretPtr sym = &compat->sym_interpret[rep->firstSI]; xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *) data; + size = rep->length * 4; + for (i = 0; i < rep->nSI; i++, sym++, wire++) { wire->sym = sym->sym; wire->mods = sym->mods; @@ -2856,9 +2856,9 @@ _XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev, if ((unsigned) (req->firstSI + req->nSI) > compat->num_si) { compat->num_si = req->firstSI + req->nSI; - compat->sym_interpret = realloc(compat->sym_interpret, - compat->num_si * - sizeof(XkbSymInterpretRec)); + compat->sym_interpret = reallocarray(compat->sym_interpret, + compat->num_si, + sizeof(XkbSymInterpretRec)); if (!compat->sym_interpret) { compat->num_si = 0; return BadAlloc; @@ -3086,14 +3086,15 @@ XkbSendIndicatorMap(ClientPtr client, register int i; register unsigned bit; - length = rep->length * 4; - if (length > 0) { + if (rep->length > 0) { CARD8 *to; - to = map = malloc(length); + to = map = xallocarray(rep->length, 4); if (map) { xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *) to; + length = rep->length * 4; + for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { if (rep->which & bit) { wire->flags = indicators->maps[i].flags; @@ -4863,7 +4864,6 @@ XkbComputeGetGeometryReplySize(XkbGeometryPtr geom, } return Success; } - static int XkbSendGeometry(ClientPtr client, XkbGeometryPtr geom, xkbGetGeometryReply * rep, Bool freeGeom) @@ -4872,10 +4872,10 @@ XkbSendGeometry(ClientPtr client, int len; if (geom != NULL) { - len = rep->length * 4; - start = desc = malloc(len); + start = desc = xallocarray(rep->length, 4); if (!start) return BadAlloc; + len = rep->length * 4; desc = XkbWriteCountedString(desc, geom->label_font, client->swapped); if (rep->nProperties > 0) desc = XkbWriteGeomProperties(desc, geom, client->swapped); diff --git a/xorg-server/xkb/xkbActions.c b/xorg-server/xkb/xkbActions.c index 2a196f151..9dd1cbd3b 100644 --- a/xorg-server/xkb/xkbActions.c +++ b/xorg-server/xkb/xkbActions.c @@ -1103,8 +1103,8 @@ _XkbNextFreeFilter(XkbSrvInfoPtr xkbi) } } xkbi->szFilters *= 2; - xkbi->filters = realloc(xkbi->filters, - xkbi->szFilters * sizeof(XkbFilterRec)); + xkbi->filters = reallocarray(xkbi->filters, + xkbi->szFilters, sizeof(XkbFilterRec)); /* 6/21/93 (ef) -- XXX! deal with allocation failure */ memset(&xkbi->filters[xkbi->szFilters / 2], 0, (xkbi->szFilters / 2) * sizeof(XkbFilterRec)); diff --git a/xorg-server/xkb/xkbUtils.c b/xorg-server/xkb/xkbUtils.c index 6019f0f31..25b5a364e 100644 --- a/xorg-server/xkb/xkbUtils.c +++ b/xorg-server/xkb/xkbUtils.c @@ -946,8 +946,8 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst) if (src->map->syms) { if (src->map->size_syms != dst->map->size_syms) { - tmp = realloc(dst->map->syms, - src->map->size_syms * sizeof(KeySym)); + tmp = reallocarray(dst->map->syms, + src->map->size_syms, sizeof(KeySym)); if (!tmp) return FALSE; dst->map->syms = tmp; @@ -965,8 +965,8 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst) if (src->map->key_sym_map) { if (src->max_key_code != dst->max_key_code) { - tmp = realloc(dst->map->key_sym_map, - (src->max_key_code + 1) * sizeof(XkbSymMapRec)); + tmp = reallocarray(dst->map->key_sym_map, + src->max_key_code + 1, sizeof(XkbSymMapRec)); if (!tmp) return FALSE; dst->map->key_sym_map = tmp; @@ -983,8 +983,8 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst) if (src->map->num_types > dst->map->size_types || !dst->map->types || !dst->map->size_types) { if (dst->map->types && dst->map->size_types) { - tmp = realloc(dst->map->types, - src->map->num_types * sizeof(XkbKeyTypeRec)); + tmp = reallocarray(dst->map->types, src->map->num_types, + sizeof(XkbKeyTypeRec)); if (!tmp) return FALSE; dst->map->types = tmp; @@ -1020,8 +1020,8 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst) if (stype->num_levels != dtype->num_levels && dtype->num_levels && dtype->level_names && i < dst->map->num_types) { - tmp = realloc(dtype->level_names, - stype->num_levels * sizeof(Atom)); + tmp = reallocarray(dtype->level_names, + stype->num_levels, sizeof(Atom)); if (!tmp) continue; dtype->level_names = tmp; @@ -1053,17 +1053,17 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst) if (stype->map_count != dtype->map_count && dtype->map_count && dtype->map && i < dst->map->num_types) { - tmp = realloc(dtype->map, - stype->map_count * - sizeof(XkbKTMapEntryRec)); + tmp = reallocarray(dtype->map, + stype->map_count, + sizeof(XkbKTMapEntryRec)); if (!tmp) return FALSE; dtype->map = tmp; } else if (!dtype->map_count || !dtype->map || i >= dst->map->num_types) { - tmp = malloc(stype->map_count * - sizeof(XkbKTMapEntryRec)); + tmp = xallocarray(stype->map_count, + sizeof(XkbKTMapEntryRec)); if (!tmp) return FALSE; dtype->map = tmp; @@ -1082,16 +1082,17 @@ _XkbCopyClientMap(XkbDescPtr src, XkbDescPtr dst) if (stype->map_count != dtype->map_count && dtype->map_count && dtype->preserve && i < dst->map->num_types) { - tmp = realloc(dtype->preserve, - stype->map_count * - sizeof(XkbModsRec)); + tmp = reallocarray(dtype->preserve, + stype->map_count, + sizeof(XkbModsRec)); if (!tmp) return FALSE; dtype->preserve = tmp; } else if (!dtype->preserve || !dtype->map_count || i >= dst->map->num_types) { - tmp = malloc(stype->map_count * sizeof(XkbModsRec)); + tmp = xallocarray(stype->map_count, + sizeof(XkbModsRec)); if (!tmp) return FALSE; dtype->preserve = tmp; @@ -1192,8 +1193,8 @@ _XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst) if (src->server->acts) { if (src->server->size_acts != dst->server->size_acts) { - tmp = realloc(dst->server->acts, - src->server->size_acts * sizeof(XkbAction)); + tmp = reallocarray(dst->server->acts, + src->server->size_acts, sizeof(XkbAction)); if (!tmp) return FALSE; dst->server->acts = tmp; @@ -1210,8 +1211,8 @@ _XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst) if (src->server->key_acts) { if (src->max_key_code != dst->max_key_code) { - tmp = realloc(dst->server->key_acts, - (src->max_key_code + 1) * sizeof(unsigned short)); + tmp = reallocarray(dst->server->key_acts, + src->max_key_code + 1, sizeof(unsigned short)); if (!tmp) return FALSE; dst->server->key_acts = tmp; @@ -1226,8 +1227,8 @@ _XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst) if (src->server->behaviors) { if (src->max_key_code != dst->max_key_code) { - tmp = realloc(dst->server->behaviors, - (src->max_key_code + 1) * sizeof(XkbBehavior)); + tmp = reallocarray(dst->server->behaviors, + src->max_key_code + 1, sizeof(XkbBehavior)); if (!tmp) return FALSE; dst->server->behaviors = tmp; @@ -1244,8 +1245,8 @@ _XkbCopyServerMap(XkbDescPtr src, XkbDescPtr dst) if (src->server->vmodmap) { if (src->max_key_code != dst->max_key_code) { - tmp = realloc(dst->server->vmodmap, - (src->max_key_code + 1) * sizeof(unsigned short)); + tmp = reallocarray(dst->server->vmodmap, + src->max_key_code + 1, sizeof(unsigned short)); if (!tmp) return FALSE; dst->server->vmodmap = tmp; @@ -1281,8 +1282,8 @@ _XkbCopyNames(XkbDescPtr src, XkbDescPtr dst) if (src->names->keys) { if (src->max_key_code != dst->max_key_code) { - tmp = realloc(dst->names->keys, - (src->max_key_code + 1) * sizeof(XkbKeyNameRec)); + tmp = reallocarray(dst->names->keys, src->max_key_code + 1, + sizeof(XkbKeyNameRec)); if (!tmp) return FALSE; dst->names->keys = tmp; @@ -1297,9 +1298,9 @@ _XkbCopyNames(XkbDescPtr src, XkbDescPtr dst) if (src->names->num_key_aliases) { if (src->names->num_key_aliases != dst->names->num_key_aliases) { - tmp = realloc(dst->names->key_aliases, - src->names->num_key_aliases * - sizeof(XkbKeyAliasRec)); + tmp = reallocarray(dst->names->key_aliases, + src->names->num_key_aliases, + sizeof(XkbKeyAliasRec)); if (!tmp) return FALSE; dst->names->key_aliases = tmp; @@ -1315,8 +1316,8 @@ _XkbCopyNames(XkbDescPtr src, XkbDescPtr dst) if (src->names->num_rg) { if (src->names->num_rg != dst->names->num_rg) { - tmp = realloc(dst->names->radio_groups, - src->names->num_rg * sizeof(Atom)); + tmp = reallocarray(dst->names->radio_groups, + src->names->num_rg, sizeof(Atom)); if (!tmp) return FALSE; dst->names->radio_groups = tmp; @@ -1366,8 +1367,9 @@ _XkbCopyCompat(XkbDescPtr src, XkbDescPtr dst) if (src->compat->sym_interpret && src->compat->num_si) { if (src->compat->num_si != dst->compat->size_si) { - tmp = realloc(dst->compat->sym_interpret, - src->compat->num_si * sizeof(XkbSymInterpretRec)); + tmp = reallocarray(dst->compat->sym_interpret, + src->compat->num_si, + sizeof(XkbSymInterpretRec)); if (!tmp) return FALSE; dst->compat->sym_interpret = tmp; @@ -1582,8 +1584,8 @@ _XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst) j < sshape->num_outlines; j++, soutline++, doutline++) { if (soutline->num_points) { - tmp = malloc(soutline->num_points * - sizeof(XkbPointRec)); + tmp = xallocarray(soutline->num_points, + sizeof(XkbPointRec)); if (!tmp) return FALSE; doutline->points = tmp; @@ -1710,7 +1712,7 @@ _XkbCopyGeom(XkbDescPtr src, XkbDescPtr dst) for (j = 0, srow = ssection->rows, drow = dsection->rows; j < ssection->num_rows; j++, srow++, drow++) { if (srow->num_keys) { - tmp = malloc(srow->num_keys * sizeof(XkbKeyRec)); + tmp = xallocarray(srow->num_keys, sizeof(XkbKeyRec)); if (!tmp) return FALSE; drow->keys = tmp; diff --git a/xorg-server/xkb/xkmread.c b/xorg-server/xkb/xkmread.c index 0b9f0ef6d..1666e3216 100644 --- a/xorg-server/xkb/xkmread.c +++ b/xorg-server/xkb/xkmread.c @@ -64,7 +64,7 @@ XkmInsureSize(void *oldPtr, int oldCount, int *newCountRtrn, int elemSize) oldPtr = calloc(newCount, elemSize); } else if (oldCount < newCount) { - oldPtr = realloc(oldPtr, newCount * elemSize); + oldPtr = reallocarray(oldPtr, newCount, elemSize); if (oldPtr != NULL) { char *tmp = (char *) oldPtr; diff --git a/xorg-server/xkeyboard-config/rules/base.xml.in b/xorg-server/xkeyboard-config/rules/base.xml.in index a75f02942..c700972d2 100644 --- a/xorg-server/xkeyboard-config/rules/base.xml.in +++ b/xorg-server/xkeyboard-config/rules/base.xml.in @@ -4938,6 +4938,13 @@ </languageList> </configItem> </variant> + <variant> + <configItem> + <name>us</name> + <shortDescription>us</shortDescription> + <_description>Singhala (US keyboard with Singhala letters)</_description> + </configItem> + </variant> </variantList> </layout> <layout> diff --git a/xorg-server/xkeyboard-config/symbols/eu b/xorg-server/xkeyboard-config/symbols/eu index 0a4d31a21..5b767f1da 100644 --- a/xorg-server/xkeyboard-config/symbols/eu +++ b/xorg-server/xkeyboard-config/symbols/eu @@ -1,6 +1,5 @@ // Based on <http://eurkey.steffen.bruentjen.eu/> // Copyright: Copyright 2012 Steffen Bruentjen (eurkey (at) steffen dot bruentjen dot de) -// License: GPLv3 <http://www.gnu.org/licenses/gpl-3.0.html> // modified by Christoph Roeper <spam (at) roeper dot biz> (use firstName to mail) default partial alphanumeric_keys modifier_keys diff --git a/xorg-server/xkeyboard-config/symbols/lk b/xorg-server/xkeyboard-config/symbols/lk index 9f3b7c7b7..017029dfb 100644 --- a/xorg-server/xkeyboard-config/symbols/lk +++ b/xorg-server/xkeyboard-config/symbols/lk @@ -88,3 +88,97 @@ xkb_symbols "tam_TAB" { name[Group1]= "Tamil (Sri Lanka, TAB Typewriter)"; }; +// SINGHALA - US, SUBSTITUTES SOME AND ADDS SOME +// ============================================= +// +// This started as an upgrade to the first romanized version of +// Singhala called PTS Pali created in the 1860s. PTS requires +// dots and bars on letters that are rare in fonts, and impossible +// to type. Its singular purpose was to print Tripitaka, the +// collection of Buddhist discourses. +// +// This version covers the entire newer Singhala phoneme chart +// (Hodiya) that became standard just before the end of the 19th +// century. All the phonemes map to the SBCS. It is easy and +// faster than English to type. It overcomes the setback of +// Unicode Sinhala that it is not compatible with Pali and +// Sanskrit because it encodes two ligatures as base letters and +// the SLS1134 specification matching shape and morpheme sets +// violating Sanskrit orthography. +// +// Most importantly, this romanized version of Singhala has a +// companion orthographic font that displays the text in the +// native script and a JavaScript converts it to Unicode Sinhala +// and back dramatically increasing Singhala seen on the web due +// to its ease of use +// +// Dedication: +// Thomas William Rhys Davids, Ven. Udagama Sumangala +// Rev. Fr. A. M. Gunasekara, Rev. Fr. Theodore G. Perera +// Ven. Mettavihari +// +// Maintainer: +// JC Ahangama - sing@ahangama.com +// +partial alphanumeric_keys modifier_keys +xkb_symbols "us" { + include "us(basic)" + name[Group1]= "Singhala (US keyboard with Singhala letters)"; +// +// UNSHIFTED, SHIFT, ALT +// -------------------------------------------- +// + key <AB01> { [ z, VoidSymbol, VoidSymbol ] }; + key <AB02> { [ x, VoidSymbol, VoidSymbol ] }; + key <AB03> { [ c, ccedilla, VoidSymbol ] }; + key <AB04> { [ v, VoidSymbol, VoidSymbol ] }; + key <AB05> { [ b, B, VoidSymbol ] }; + key <AB06> { [ n, N, ntilde ] }; + key <AB07> { [ m, VoidSymbol, VoidSymbol ] }; + key <AB08> { [ comma, less, UAB ] }; + key <AB09> { [ period, greater, UBB ] }; + key <AB10> { [ slash, question, U200C ] }; + + key <AC01> { [ a, aacute, adiaeresis ] }; + key <AC02> { [ s, VoidSymbol, VoidSymbol ] }; + key <AC03> { [ d, D, VoidSymbol ] }; + key <AC04> { [ thorn, f, VoidSymbol ] }; + key <AC05> { [ g, G, VoidSymbol ] }; + key <AC06> { [ h, VoidSymbol, VoidSymbol ] }; + key <AC07> { [ j, ccedilla, VoidSymbol ] }; + key <AC08> { [ k, VoidSymbol, VoidSymbol ] }; + key <AC09> { [ l, L, ocircumflex ] }; + key <AC10> { [ semicolon, colon, VoidSymbol ] }; + key <AC11> { [ apostrophe, quotedbl, VoidSymbol ] }; + + key <AD01> { [ eth, ETH, q ] }; + key <AD02> { [ ae, acute, VoidSymbol ] }; + key <AD03> { [ e, eacute, ediaeresis ] }; + key <AD04> { [ r, ucircumflex, VoidSymbol ] }; + key <AD05> { [ t, VoidSymbol, VoidSymbol ] }; + key <AD06> { [ y, VoidSymbol, VoidSymbol ] }; + key <AD07> { [ u, uacute, udiaeresis ] }; + key <AD08> { [ i, iacute, idiaeresis ] }; + key <AD09> { [ o, oacute, odiaeresis ] }; + key <AD10> { [ p, VoidSymbol, VoidSymbol ] }; + key <AD11> { [ bracketleft, braceleft, VoidSymbol ] }; + key <AD12> { [ bracketright, braceright, VoidSymbol ] }; + + key <AE01> { [ one, exclam, dead_macron ] }; + key <AE02> { [ two, at, dead_belowdot ] }; + key <AE03> { [ three, numbersign, dead_abovedot ] }; + key <AE04> { [ four, dollar, currency ] }; + key <AE05> { [ five, percent, UB0 ] }; + key <AE06> { [ six, asciicircum, onequarter ] }; + key <AE07> { [ seven, ampersand, onehalf ] }; + key <AE08> { [ eight, asterisk, threequarters ] }; + key <AE09> { [ nine, parenleft, VoidSymbol ] }; + key <AE10> { [ zero, parenright, VoidSymbol ] }; + key <AE11> { [ minus, underscore, U2014 ] }; + key <AE12> { [ equal, plus, VoidSymbol ] }; + + key <BKSL> { [ backslash, bar, VoidSymbol ] }; + key <SPCE> { [ space, nobreakspace, VoidSymbol ] }; + key <TLDE> { [ grave, asciitilde, VoidSymbol ] }; + include "level3(alt_switch)" +}; |