diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c index ac2393c3b..4a77b3ee6 100644 --- a/GL/glx/glxcmds.c +++ b/GL/glx/glxcmds.c @@ -190,7 +190,6 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, __GLXscreen *pGlxScreen, GLboolean isDirect) { ClientPtr client = cl->client; - VisualPtr pVisual; __GLXcontext *glxc, *shareglxc; LEGAL_NEW_RESOURCE(gcId, client); @@ -250,7 +249,6 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, */ glxc->pScreen = pGlxScreen->pScreen; glxc->pGlxScreen = pGlxScreen; - glxc->pVisual = pVisual; glxc->modes = config; /* @@ -1215,6 +1213,11 @@ static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type) return __glXError(GLXBadPbuffer); } } + + if (type == GLX_DRAWABLE_PIXMAP) { + ((PixmapPtr) pGlxDraw->pDraw)->refcnt--; + } + FreeResource(glxdrawable, FALSE); return Success; @@ -1465,7 +1468,7 @@ DoQueryContext(__GLXclientState *cl, GLXContextID gcId) *pSendBuf++ = GLX_SHARE_CONTEXT_EXT; *pSendBuf++ = (int)(ctx->share_id); *pSendBuf++ = GLX_VISUAL_ID_EXT; - *pSendBuf++ = (int)(ctx->pVisual->vid); + *pSendBuf++ = (int)(ctx->modes->visualID); *pSendBuf++ = GLX_SCREEN_EXT; *pSendBuf++ = (int)(ctx->pScreen->myNum); diff --git a/GL/glx/glxcontext.h b/GL/glx/glxcontext.h index 712264729..cf944a174 100644 --- a/GL/glx/glxcontext.h +++ b/GL/glx/glxcontext.h @@ -88,11 +88,6 @@ struct __GLXcontext { ScreenPtr pScreen; __GLXscreen *pGlxScreen; - /* - ** This context is created with respect to this visual. - */ - VisualRec *pVisual; - /* ** The XID of this context. */ diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c index 3688d50a8..5c45cd190 100644 --- a/GL/glx/glxdri.c +++ b/GL/glx/glxdri.c @@ -185,10 +185,14 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable) (*private->driDrawable.destroyDrawable)(&private->driDrawable); - __glXenterServer(GL_FALSE); - DRIDestroyDrawable(drawable->pDraw->pScreen, - serverClient, drawable->pDraw); - __glXleaveServer(GL_FALSE); + /* If the X window was destroyed, the dri DestroyWindow hook will + * aready have taken care of this, so only call if pDraw isn't NULL. */ + if (drawable->pDraw != NULL) { + __glXenterServer(GL_FALSE); + DRIDestroyDrawable(drawable->pDraw->pScreen, + serverClient, drawable->pDraw); + __glXleaveServer(GL_FALSE); + } xfree(private); } @@ -668,11 +672,16 @@ getDrawableInfo(__DRIdrawable *driDrawable, { __GLXDRIdrawable *drawable = containerOf(driDrawable, __GLXDRIdrawable, driDrawable); - ScreenPtr pScreen = drawable->base.pDraw->pScreen; + ScreenPtr pScreen; drm_clip_rect_t *pClipRects, *pBackClipRects; GLboolean retval; size_t size; + /* If the X window has been destroyed, give up here. */ + if (drawable->base.pDraw == NULL) + return GL_FALSE; + + pScreen = drawable->base.pDraw->pScreen; __glXenterServer(GL_FALSE); retval = DRIGetDrawableInfo(pScreen, drawable->base.pDraw, index, stamp, x, y, width, height, diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c index 4d6bfd7c6..772538940 100644 --- a/GL/glx/glxext.c +++ b/GL/glx/glxext.c @@ -122,6 +122,8 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid) cx->pendingState |= __GLX_PENDING_DESTROY; } + glxPriv->pDraw = NULL; + glxPriv->drawId = 0; __glXUnrefDrawable(glxPriv); return True; @@ -393,7 +395,7 @@ void glxSuspendClients(void) int i; for (i = 1; i < currentMaxClients; i++) { - if (glxGetClient(clients[i])->inUse) + if (clients[i] && glxGetClient(clients[i])->inUse) IgnoreClient(clients[i]); } @@ -408,7 +410,7 @@ void glxResumeClients(void) glxBlockClients = FALSE; for (i = 1; i < currentMaxClients; i++) { - if (glxGetClient(clients[i])->inUse) + if (clients[i] && glxGetClient(clients[i])->inUse) AttendClient(clients[i]); } diff --git a/configure.ac b/configure.ac index bcaf21e06..4f581e486 100644 --- a/configure.ac +++ b/configure.ac @@ -464,6 +464,10 @@ APPLE_APPLICATIONS_DIR="${bindir}/Applications" AC_ARG_WITH(apple-applications-dir,AS_HELP_STRING([--with-apple-applications-dir=PATH], [Path to the Applications directory (default: ${bindir}/Applications)]), [ APPLE_APPLICATIONS_DIR="${withval}" ]. [ APPLE_APPLICATIONS_DIR="${bindir}/Applications" ]) +AC_ARG_WITH(pci-txt-ids-dir, AS_HELP_STRING([--with-pci-txt-ids-dir=PATH], +[Path to pci id directory (default: ${datadir}/X11/pci)]), + [ PCI_TXT_IDS_DIR="$withval" ], + [ PCI_TXT_IDS_DIR="${datadir}/X11/pci" ]) AC_ARG_ENABLE(builddocs, AS_HELP_STRING([--enable-builddocs], [Build docs (default: disabled)]), [BUILDDOCS=$enableval], [BUILDDOCS=no]) @@ -1011,6 +1015,7 @@ fi AC_DEFINE_DIR(COMPILEDDEFAULTFONTPATH, FONTPATH, [Default font path]) AC_DEFINE_DIR(RGB_DB, RGBPATH, [Default RGB path]) +AC_DEFINE_DIR(PCI_TXT_IDS_PATH, PCI_TXT_IDS_DIR, [Default PCI text file ID path]) AC_DEFINE_DIR(SERVERCONFIGdir, SERVERCONFIG, [Server config path]) AC_DEFINE_DIR(BASE_FONT_PATH, FONTDIR, [Default base font path]) AC_DEFINE_DIR(DRI_DRIVER_PATH, DRI_DRIVER_PATH, [Default DRI driver path]) @@ -1091,7 +1096,7 @@ PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS]) # XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}" XSERVER_LIBS="$DIX_LIB $CONFIG_LIB $MI_LIB $OS_LIB" -XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}" +XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS} -lcrypto" AC_SUBST([XSERVER_LIBS]) AC_SUBST([XSERVER_SYS_LIBS]) @@ -1899,7 +1904,7 @@ if test "$KDRIVE" = yes; then KDRIVE_LOCAL_LIBS="$TSLIB_LIBS $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB" KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS" KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB" - KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVERLIBS_LIBS $XV_LIBS" + KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $XV_LIBS" # check if we can build Xephyr PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"]) diff --git a/dix/getevents.c b/dix/getevents.c index a6e246ac7..ffcdf174e 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -95,7 +95,14 @@ set_key_up(DeviceIntPtr pDev, int key_code) static Bool key_is_down(DeviceIntPtr pDev, int key_code) { - return pDev->key->postdown[key_code >> 3] >> (key_code & 7); + return !!(pDev->key->postdown[key_code >> 3] & (1 << (key_code & 7))); +} + +static Bool +key_autorepeats(DeviceIntPtr pDev, int key_code) +{ + return !!(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] & + (1 << (key_code & 7))); } /** @@ -444,10 +451,11 @@ GetKeyboardValuatorEvents(xEvent *events, DeviceIntPtr pDev, int type, * FIXME: In theory, if you're repeating with two keyboards in non-XKB, * you could get unbalanced events here. */ if (type == KeyPress && key_is_down(pDev, key_code)) { + /* If autorepeating is disabled either globally or just for that key, + * or we have a modifier, don't generate a repeat event. */ if (!pDev->kbdfeed->ctrl.autoRepeat || - pDev->key->modifierMap[key_code] || - !(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] - & (1 << (key_code & 7)))) + !key_autorepeats(pDev, key_code) || + pDev->key->modifierMap[key_code]) return 0; #ifdef XKB diff --git a/exa/exa.c b/exa/exa.c index 7ad226fba..6d6c0549f 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -291,7 +291,9 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth) pExaPixmap->fb_ptr = NULL; } else { pExaPixmap->driverPriv = NULL; - /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */ + /* Scratch pixmaps may have w/h equal to zero, and may not be + * migrated. + */ if (!w || !h) pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; else @@ -696,7 +698,6 @@ exaCloseScreen(int i, ScreenPtr pScreen) #ifdef RENDER if (ps) { ps->Composite = pExaScr->SavedComposite; - ps->Glyphs = pExaScr->SavedGlyphs; ps->Trapezoids = pExaScr->SavedTrapezoids; } #endif @@ -865,9 +866,6 @@ exaDriverInit (ScreenPtr pScreen, pExaScr->SavedTriangles = ps->Triangles; ps->Triangles = exaTriangles; - pExaScr->SavedGlyphs = ps->Glyphs; - ps->Glyphs = exaGlyphs; - pExaScr->SavedTrapezoids = ps->Trapezoids; ps->Trapezoids = exaTrapezoids; } diff --git a/exa/exa_accel.c b/exa/exa_accel.c index 52cc5c40a..5fb72d71b 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -658,7 +658,7 @@ exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, x1 = ppt[0].x; y1 = ppt[0].y; /* If we have any non-horizontal/vertical, fall back. */ - for (i = 0; i < npt; i++) { + for (i = 0; i < npt - 1; i++) { if (mode == CoordModePrevious) { x2 = x1 + ppt[i + 1].x; y2 = y1 + ppt[i + 1].y; diff --git a/exa/exa_priv.h b/exa/exa_priv.h index 523a76f60..a69536372 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -53,6 +53,7 @@ #include "fboverlay.h" #ifdef RENDER #include "fbpict.h" +#include "glyphstr.h" #endif #include "damage.h" diff --git a/exa/exa_render.c b/exa/exa_render.c index cc2f59d6d..6a9e53f3e 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -997,356 +997,3 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst, exaTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris); } } - -/** - * 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. - */ -static Bool -exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs) -{ - int x1, x2, y1, y2; - int n; - GlyphPtr glyph; - int x, y; - BoxRec extents; - Bool first = TRUE; - - x = 0; - y = 0; - while (nlist--) { - x += list->xOff; - y += list->yOff; - n = list->len; - list++; - while (n--) { - glyph = *glyphs++; - - if (glyph->info.width == 0 || glyph->info.height == 0) { - x += glyph->info.xOff; - y += glyph->info.yOff; - continue; - } - - x1 = x - glyph->info.x; - if (x1 < MINSHORT) - x1 = MINSHORT; - y1 = y - glyph->info.y; - if (y1 < MINSHORT) - y1 = MINSHORT; - x2 = x1 + glyph->info.width; - if (x2 > MAXSHORT) - x2 = MAXSHORT; - y2 = y1 + glyph->info.height; - if (y2 > MAXSHORT) - y2 = MAXSHORT; - - if (first) { - extents.x1 = x1; - extents.y1 = y1; - extents.x2 = x2; - extents.y2 = y2; - first = FALSE; - } else { - if (x1 < extents.x2 && x2 > extents.x1 && - y1 < extents.y2 && y2 > extents.y1) - { - return TRUE; - } - - 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; - } - } - - return FALSE; -} - -#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) - -/* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The - * issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to - * migrate these pixmaps. So, instead we create a pixmap at the beginning of - * the loop and upload each glyph into the pixmap before compositing. - * - * This is now used even when Composite can't be accelerated for better - * migration control. - */ -void -exaGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs) -{ - ExaScreenPriv (pDst->pDrawable->pScreen); - PixmapPtr pPixmap = NULL; - PicturePtr pPicture; - PixmapPtr pMaskPixmap = NULL; - PicturePtr pMask; - ScreenPtr pScreen = pDst->pDrawable->pScreen; - int width = 0, height = 0; - int x, y, x1, y1; - int xDst = list->xOff, yDst = list->yOff; - int n; - int error; - BoxRec extents; - CARD32 component_alpha; - - /* If we have a mask format but it's the same as all the glyphs and - * the glyphs don't intersect, we can avoid accumulating the glyphs in the - * temporary picture. - */ - if (maskFormat != NULL) { - Bool sameFormat = TRUE; - int i; - - for (i = 0; i < nlist; i++) { - if (maskFormat->format != list[i].format->format) { - sameFormat = FALSE; - break; - } - } - if (sameFormat) { - if (!exaGlyphsIntersect(nlist, list, glyphs)) { - maskFormat = NULL; - } - } - } - - if (maskFormat) - { - GCPtr pGC; - xRectangle rect; - - miGlyphExtents (nlist, list, glyphs, &extents); - - extents.x1 = max(extents.x1, 0); - extents.y1 = max(extents.y1, 0); - extents.x2 = min(extents.x2, pDst->pDrawable->width); - extents.y2 = min(extents.y2, pDst->pDrawable->height); - - if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) - return; - width = extents.x2 - extents.x1; - height = extents.y2 - extents.y1; - pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, - maskFormat->depth); - if (!pMaskPixmap) - return; - component_alpha = NeedsComponent(maskFormat->format); - pMask = CreatePicture (0, &pMaskPixmap->drawable, - maskFormat, CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pMask) - { - (*pScreen->DestroyPixmap) (pMaskPixmap); - return; - } - ValidatePicture(pMask); - pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); - ValidateGC (&pMaskPixmap->drawable, pGC); - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - ExaCheckPolyFillRect (&pMaskPixmap->drawable, pGC, 1, &rect); - if (pExaScr->info->PrepareComposite) - (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); - else - exaPixmapDirty(pMaskPixmap, 0, 0, width, height); - FreeScratchGC (pGC); - x = -extents.x1; - y = -extents.y1; - } - else - { - pMask = pDst; - x = 0; - y = 0; - } - - while (nlist--) - { - GCPtr pGC = NULL; - int maxwidth = 0, maxheight = 0, i; - ExaMigrationRec pixmaps[1]; - PixmapPtr pScratchPixmap = NULL; - - x += list->xOff; - y += list->yOff; - n = list->len; - for (i = 0; i < n; i++) { - if (glyphs[i]->info.width > maxwidth) - maxwidth = glyphs[i]->info.width; - if (glyphs[i]->info.height > maxheight) - maxheight = glyphs[i]->info.height; - } - if (maxwidth == 0 || maxheight == 0) { - while (n--) - { - GlyphPtr glyph; - - glyph = *glyphs++; - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - continue; - } - - /* Create the (real) temporary pixmap to store the current glyph in */ - pPixmap = (*pScreen->CreatePixmap) (pScreen, maxwidth, maxheight, - list->format->depth); - if (!pPixmap) - return; - - /* Create a temporary picture to wrap the temporary pixmap, so it can be - * used as a source for Composite. - */ - component_alpha = NeedsComponent(list->format->format); - pPicture = CreatePicture (0, &pPixmap->drawable, list->format, - CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pPicture) { - (*pScreen->DestroyPixmap) (pPixmap); - return; - } - ValidatePicture(pPicture); - - /* Give the temporary pixmap an initial kick towards the screen, so - * it'll stick there. - */ - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pPixmap; - pixmaps[0].pReg = NULL; - exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL); - - while (n--) - { - GlyphPtr glyph = *glyphs++; - pointer glyphdata = (pointer) (glyph + 1); - DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable; - - x1 = x - glyph->info.x; - y1 = y - glyph->info.y; - - if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height || - glyph->info.width == 0 || glyph->info.height == 0 || - (x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0) - goto nextglyph; - - (*pScreen->ModifyPixmapHeader) (pScratchPixmap, - glyph->info.width, - glyph->info.height, - 0, 0, -1, glyphdata); - - /* Copy the glyph data into the proper pixmap instead of a fake. - * First we try to use UploadToScreen, if we can, then we fall back - * to a plain exaCopyArea in case of failure. - */ - if (pExaScr->info->UploadToScreen && - exaPixmapIsOffscreen(pPixmap) && - (*pExaScr->info->UploadToScreen) (pPixmap, 0, 0, - glyph->info.width, - glyph->info.height, - glyphdata, - PixmapBytePad(glyph->info.width, - list->format->depth))) - { - exaMarkSync (pScreen); - } else { - /* Set up the scratch pixmap/GC for doing a CopyArea. */ - if (pScratchPixmap == NULL) { - /* Get a scratch pixmap to wrap the original glyph data */ - pScratchPixmap = GetScratchPixmapHeader (pScreen, - glyph->info.width, - glyph->info.height, - list->format->depth, - list->format->depth, - -1, glyphdata); - if (!pScratchPixmap) { - FreePicture(pPicture, 0); - (*pScreen->DestroyPixmap) (pPixmap); - return; - } - - /* Get a scratch GC with which to copy the glyph data from - * scratch to temporary - */ - pGC = GetScratchGC (list->format->depth, pScreen); - ValidateGC (&pPixmap->drawable, pGC); - } else { - (*pScreen->ModifyPixmapHeader) (pScratchPixmap, - glyph->info.width, - glyph->info.height, - 0, 0, -1, glyphdata); - pScratchPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - } - -#ifdef MITSHM - if (pExaScr->info->PrepareComposite) - exaShmPutImage(&pPixmap->drawable, pGC, - pPixmap->drawable.depth, ZPixmap, - glyph->info.width, glyph->info.height, 0, 0, - glyph->info.width, glyph->info.height, 0, 0, - glyphdata); - else -#endif - exaCopyArea (&pScratchPixmap->drawable, &pPixmap->drawable, pGC, - 0, 0, glyph->info.width, glyph->info.height, 0, 0); - } - - exaPixmapDirty (pPixmap, 0, 0, - glyph->info.width, glyph->info.height); - - if (maskFormat) - { - exaComposite (PictOpAdd, pPicture, NULL, pMask, 0, 0, 0, 0, - x1, y1, glyph->info.width, glyph->info.height); - exaPixmapDirty(pMaskPixmap, x1, y1, x1 + glyph->info.width, - y1 + glyph->info.height); - } - else - { - exaComposite (op, pSrc, pPicture, pDst, - xSrc + x1 - xDst, ySrc + y1 - yDst, - 0, 0, x1, y1, glyph->info.width, - glyph->info.height); - } -nextglyph: - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - if (pGC != NULL) - FreeScratchGC (pGC); - FreePicture ((pointer) pPicture, 0); - (*pScreen->DestroyPixmap) (pPixmap); - if (pScratchPixmap != NULL) - FreeScratchPixmapHeader (pScratchPixmap); - } - if (maskFormat) - { - x = extents.x1; - y = extents.y1; - exaComposite (op, pSrc, pMask, pDst, xSrc + x - xDst, ySrc + y - yDst, - 0, 0, x, y, width, height); - FreePicture ((pointer) pMask, (XID) 0); - (*pScreen->DestroyPixmap) (pMaskPixmap); - } -} diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index a6bfc0190..c5998bfb8 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -329,6 +329,11 @@ autoConfigDevice(GDevPtr preconf_device) return ptr; } +#ifdef __linux__ +/* This function is used to provide a workaround for binary drivers that + * don't export their PCI ID's properly. If distros don't end up using this + * feature it can and should be removed because the symbol-based resolution + * scheme should be the primary one */ static void matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip) { @@ -341,9 +346,10 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip char path_name[256], vendor_str[5], chip_str[5]; uint16_t vendor, chip; int i, j; - idsdir = opendir("/usr/share/xserver-xorg/pci"); + idsdir = opendir(PCI_TXT_IDS_PATH); if (idsdir) { + xf86Msg(X_INFO, "Scanning %s directory for additional PCI ID's supported by the drivers\n", PCI_TXT_IDS_PATH); direntry = readdir(idsdir); /* Read the directory */ while (direntry) { @@ -355,15 +361,20 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip /* A tiny bit of sanity checking. We should probably do better */ if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) { /* We need the full path name to open the file */ - strncpy(path_name, "/usr/share/xserver-xorg/pci/", 256); - strncat(path_name, direntry->d_name, (256 - strlen(path_name))); + strncpy(path_name, PCI_TXT_IDS_PATH, 256); + strncat(path_name, "/", 1); + strncat(path_name, direntry->d_name, (256 - strlen(path_name) - 1)); fp = fopen(path_name, "r"); if (fp == NULL) { xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name); goto end; } /* Read the file */ + #ifdef __GLIBC__ while ((read = getline(&line, &len, fp)) != -1) { + #else + while ((line = fgetln(fp, &len)) != (char *)NULL) { + #endif /* __GLIBC __ */ xchomp(line); if (isdigit(line[0])) { strncpy(vendor_str, line, 4); @@ -405,8 +416,7 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip matches[i][j] = direntry->d_name[j]; } } - xf86Msg(X_INFO, "Matched %s from file name %s in autoconfig\n", matches[i], direntry->d_name); - + xf86Msg(X_INFO, "Matched %s from file name %s\n", matches[i], direntry->d_name); } } else { /* TODO Handle driver overrides here */ @@ -421,6 +431,7 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip xfree(line); closedir(idsdir); } +#endif /* __linux__ */ char* chooseVideoDriver(void) @@ -448,24 +459,27 @@ chooseVideoDriver(void) ErrorF("Primary device is not PCI\n"); } +#ifdef __linux__ matchDriverFromFiles(matches, info->vendor_id, info->device_id); +#endif /* __linux__ */ /* TODO Handle multiple drivers claiming to support the same PCI ID */ if (matches[0]) { chosen_driver = matches[0]; } else { - chosen_driver = videoPtrToDriverName(info); - #if 0 /* Save for later */ - #if defined __i386__ || defined __amd64__ || defined __hurd__ - chosen_driver = "vesa"; - #elif defined __alpha__ - chosen_driver = "vga"; - #elif defined __sparc__ - chosen_driver = "sunffb"; - #else - chosen_driver = "fbdev"; - #endif - #endif + if (info != NULL) + chosen_driver = videoPtrToDriverName(info); + if (chosen_driver == NULL) { +#if defined __i386__ || defined __amd64__ || defined __hurd__ + chosen_driver = "vesa"; +#elif defined __alpha__ + chosen_driver = "vga"; +#elif defined __sparc__ + chosen_driver = "sunffb"; +#else + chosen_driver = "fbdev"; +#endif + } } xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n", chosen_driver); diff --git a/hw/xfree86/loader/misym.c b/hw/xfree86/loader/misym.c index 78ae10e02..025983b09 100644 --- a/hw/xfree86/loader/misym.c +++ b/hw/xfree86/loader/misym.c @@ -205,9 +205,6 @@ _X_HIDDEN void *miLookupTab[] = { SYMVAR(miPointerScreenIndex) SYMVAR(miInstalledMaps) SYMVAR(miInitVisualsProc) -#ifdef RENDER - SYMFUNC(miGlyphExtents) -#endif #ifdef DAMAGE SYMFUNC(DamageDamageRegion) #endif diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 0a48d5bd3..bb416fddc 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -1417,9 +1417,8 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) output->probed_modes = mode; } mode->type |= (M_T_PREFERRED|M_T_USERPREF); + break; } - else - mode->type &= ~M_T_PREFERRED; } } diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index 38435c924..7169f74c8 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -426,8 +426,18 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen) xf86OutputPtr output = config->output[config->compat_output]; xf86CrtcPtr crtc = output->crtc; - if (crtc && crtc->mode.HDisplay && - output->mm_width && output->mm_height) + if (output->conf_monitor && + (output->conf_monitor->mon_width > 0 && + output->conf_monitor->mon_height > 0)) + { + /* + * Prefer user configured DisplaySize + */ + mmWidth = output->conf_monitor->mon_width; + mmHeight = output->conf_monitor->mon_height; + } + else if (crtc && crtc->mode.HDisplay && + output->mm_width && output->mm_height) { /* * If the output has a mode and a declared size, use that diff --git a/include/os.h b/include/os.h index d91526786..597ecd742 100644 --- a/include/os.h +++ b/include/os.h @@ -517,7 +517,7 @@ __attribute((noreturn)) #ifdef DEBUG #define DebugF ErrorF #else -#define DebugF(x, ...) /* */ +#define DebugF(...) /* */ #endif extern void VErrorF(const char *f, va_list args); diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in index b9643a2a4..8e52ae106 100644 --- a/include/xorg-config.h.in +++ b/include/xorg-config.h.in @@ -115,4 +115,7 @@ /* Have execinfo.h */ #undef HAVE_EXECINFO_H +/* Path to text files containing PCI IDs */ +#undef PCI_TXT_IDS_PATH + #endif /* _XORG_CONFIG_H_ */ diff --git a/miext/cw/cw.h b/miext/cw/cw.h index 8e42ac256..a83949dc9 100644 --- a/miext/cw/cw.h +++ b/miext/cw/cw.h @@ -98,7 +98,6 @@ typedef struct { ValidatePictureProcPtr ValidatePicture; CompositeProcPtr Composite; - GlyphsProcPtr Glyphs; CompositeRectsProcPtr CompositeRects; TrapezoidsProcPtr Trapezoids; diff --git a/miext/cw/cw_render.c b/miext/cw/cw_render.c index 35416beb7..6e0c727c2 100644 --- a/miext/cw/cw_render.c +++ b/miext/cw/cw_render.c @@ -279,34 +279,6 @@ cwComposite (CARD8 op, cwPsWrap(Composite, cwComposite); } -static void -cwGlyphs (CARD8 op, - PicturePtr pSrcPicture, - PicturePtr pDstPicture, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlists, - GlyphListPtr lists, - GlyphPtr *glyphs) -{ - ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; - cwPsDecl(pScreen); - cwSrcPictureDecl; - cwDstPictureDecl; - - cwPsUnwrap(Glyphs); - if (nlists) - { - lists->xOff += dst_picture_x_off; - lists->yOff += dst_picture_y_off; - } - (*ps->Glyphs) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, - xSrc + src_picture_x_off, ySrc + src_picture_y_off, - nlists, lists, glyphs); - cwPsWrap(Glyphs, cwGlyphs); -} - static void cwCompositeRects (CARD8 op, PicturePtr pDstPicture, @@ -470,7 +442,6 @@ cwInitializeRender (ScreenPtr pScreen) cwPsWrap(ChangePicture, cwChangePicture); cwPsWrap(ValidatePicture, cwValidatePicture); cwPsWrap(Composite, cwComposite); - cwPsWrap(Glyphs, cwGlyphs); cwPsWrap(CompositeRects, cwCompositeRects); cwPsWrap(Trapezoids, cwTrapezoids); cwPsWrap(Triangles, cwTriangles); @@ -491,7 +462,6 @@ cwFiniRender (ScreenPtr pScreen) cwPsUnwrap(ChangePicture); cwPsUnwrap(ValidatePicture); cwPsUnwrap(Composite); - cwPsUnwrap(Glyphs); cwPsUnwrap(CompositeRects); cwPsUnwrap(Trapezoids); cwPsUnwrap(Triangles); diff --git a/render/Makefile.am b/render/Makefile.am index 830778a92..e53c7c746 100644 --- a/render/Makefile.am +++ b/render/Makefile.am @@ -6,7 +6,6 @@ librender_la_SOURCES = \ animcur.c \ filter.c \ glyph.c \ - miglyph.c \ miindex.c \ mipict.c \ mirect.c \ diff --git a/render/glyph.c b/render/glyph.c index 583a52ba3..5cd799226 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -26,6 +26,8 @@ #include #endif +#include + #include "misc.h" #include "scrnintstr.h" #include "os.h" @@ -41,6 +43,7 @@ #include "servermd.h" #include "picturestr.h" #include "glyphstr.h" +#include "mipict.h" /* * From Knuth -- a good choice for hash/rehash values is p, p-2 where @@ -412,7 +415,10 @@ _GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr) } GlyphRefPtr -FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) +FindGlyphRef (GlyphHashPtr hash, + CARD32 signature, + Bool match, + unsigned char sha1[20]) { CARD32 elt, step, s; GlyphPtr glyph; @@ -443,7 +449,7 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) } else if (s == signature && (!match || - memcmp (&compare->info, &glyph->info, compare->size) == 0)) + memcmp (glyph->sha1, sha1, 20) == 0)) { break; } @@ -460,17 +466,47 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) return gr; } -CARD32 -HashGlyph (GlyphPtr glyph) +int +HashGlyph (xGlyphInfo *gi, + CARD8 *bits, + unsigned long size, + unsigned char sha1[20]) { - CARD32 *bits = (CARD32 *) &(glyph->info); - CARD32 hash; - int n = glyph->size / sizeof (CARD32); + SHA_CTX ctx; + int success; - hash = 0; - while (n--) - hash ^= *bits++; - return hash; + success = SHA1_Init (&ctx); + if (! success) + return BadAlloc; + + success = SHA1_Update (&ctx, gi, sizeof (xGlyphInfo)); + if (! success) + return BadAlloc; + + success = SHA1_Update (&ctx, bits, size); + if (! success) + return BadAlloc; + + success = SHA1_Final (sha1, &ctx); + if (! success) + return BadAlloc; + + return Success; +} + +GlyphPtr +FindGlyphByHash (unsigned char sha1[20], int format) +{ + GlyphRefPtr gr; + CARD32 signature = *(CARD32 *) sha1; + + gr = FindGlyphRef (&globalGlyphs[format], + signature, TRUE, sha1); + + if (gr->glyph && gr->glyph != DeletedGlyph) + return gr->glyph; + else + return NULL; } #ifdef CHECK_DUPLICATES @@ -511,6 +547,7 @@ FreeGlyph (GlyphPtr glyph, int format) GlyphRefPtr gr; int i; int first; + CARD32 signature; first = -1; for (i = 0; i < globalGlyphs[format].hashSet->size; i++) @@ -521,8 +558,9 @@ FreeGlyph (GlyphPtr glyph, int format) first = i; } - gr = FindGlyphRef (&globalGlyphs[format], - HashGlyph (glyph), TRUE, glyph); + signature = *(CARD32 *) glyph->sha1; + gr = FindGlyphRef (&globalGlyphs[format], signature, + TRUE, glyph->sha1); if (gr - globalGlyphs[format].table != first) DuplicateRef (glyph, "Found wrong one"); if (gr->glyph && gr->glyph != DeletedGlyph) @@ -534,9 +572,13 @@ FreeGlyph (GlyphPtr glyph, int format) for (i = 0; i < screenInfo.numScreens; i++) { - ps = GetPictureScreenIfSet (screenInfo.screens[i]); + ScreenPtr pScreen = screenInfo.screens[i]; + + FreePicture ((pointer) GlyphPicture (glyph)[i], 0); + + ps = GetPictureScreenIfSet (pScreen); if (ps) - (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); + (*ps->UnrealizeGlyph) (pScreen, glyph); } if (glyph->devPrivates) @@ -549,13 +591,14 @@ void AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) { GlyphRefPtr gr; - CARD32 hash; + CARD32 signature; CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global"); /* Locate existing matching glyph */ - hash = HashGlyph (glyph); - gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph); - if (gr->glyph && gr->glyph != DeletedGlyph) + signature = *(CARD32 *) glyph->sha1; + gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], signature, + TRUE, glyph->sha1); + if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph) { PictureScreenPtr ps; int i; @@ -571,10 +614,10 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) xfree (glyph); glyph = gr->glyph; } - else + else if (gr->glyph != glyph) { gr->glyph = glyph; - gr->signature = hash; + gr->signature = signature; globalGlyphs[glyphSet->fdepth].tableEntries++; } @@ -627,7 +670,7 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth) GlyphPtr glyph; int i; - size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]); + size = screenInfo.numScreens * sizeof (PicturePtr); glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec)); if (!glyph) return 0; @@ -648,26 +691,28 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth) for (i = 0; i < screenInfo.numScreens; i++) { ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps) { if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph)) - { - while (i--) - { - ps = GetPictureScreenIfSet (screenInfo.screens[i]); - if (ps) - (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); - } - - if (glyph->devPrivates) - xfree (glyph->devPrivates); - xfree (glyph); - return 0; - } + goto bail; } } return glyph; + +bail: + while (i--) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps) + (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); + } + + if (glyph->devPrivates) + xfree (glyph->devPrivates); + xfree (glyph); + return 0; } Bool @@ -711,7 +756,7 @@ ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global) if (glyph && glyph != DeletedGlyph) { s = hash->table[i].signature; - gr = FindGlyphRef (&newHash, s, global, glyph); + gr = FindGlyphRef (&newHash, s, global, glyph->sha1); gr->signature = s; gr->glyph = glyph; ++newHash.tableEntries; @@ -801,3 +846,215 @@ FreeGlyphSet (pointer value, } return Success; } + +static void +GlyphExtents (int nlist, + GlyphListPtr list, + GlyphPtr *glyphs, + BoxPtr extents) +{ + int x1, x2, y1, y2; + int n; + GlyphPtr glyph; + int x, y; + + x = 0; + y = 0; + extents->x1 = MAXSHORT; + extents->x2 = MINSHORT; + extents->y1 = MAXSHORT; + extents->y2 = MINSHORT; + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + list++; + while (n--) + { + glyph = *glyphs++; + x1 = x - glyph->info.x; + if (x1 < MINSHORT) + x1 = MINSHORT; + y1 = y - glyph->info.y; + if (y1 < MINSHORT) + y1 = MINSHORT; + x2 = x1 + glyph->info.width; + if (x2 > MAXSHORT) + x2 = MAXSHORT; + y2 = y1 + glyph->info.height; + if (y2 > MAXSHORT) + y2 = MAXSHORT; + 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; + } + } +} + +#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) + +/* Stub ABI compatibility for mi*Glyph, should go away */ +_X_EXPORT void +miGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr list, + GlyphPtr *glyphs) +{ + CompositeGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, + glyphs); +} + +Bool +miRealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ + return TRUE; +} + +void +miUnrealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ +} + +_X_EXPORT void +CompositeGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr list, + GlyphPtr *glyphs) +{ + PicturePtr pPicture; + PixmapPtr pMaskPixmap = 0; + PicturePtr pMask; + ScreenPtr pScreen = pDst->pDrawable->pScreen; + int width = 0, height = 0; + int x, y; + int xDst = list->xOff, yDst = list->yOff; + int n; + GlyphPtr glyph; + int error; + BoxRec extents = {0, 0, 0, 0}; + CARD32 component_alpha; + + ValidatePicture (pSrc); + ValidatePicture (pDst); + + if (maskFormat) + { + GCPtr pGC; + xRectangle rect; + + GlyphExtents (nlist, list, glyphs, &extents); + + if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) + return; + width = extents.x2 - extents.x1; + height = extents.y2 - extents.y1; + pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, + maskFormat->depth); + if (!pMaskPixmap) + return; + component_alpha = NeedsComponent(maskFormat->format); + pMask = CreatePicture (0, &pMaskPixmap->drawable, + maskFormat, CPComponentAlpha, &component_alpha, + serverClient, &error); + if (!pMask) + { + (*pScreen->DestroyPixmap) (pMaskPixmap); + return; + } + pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); + ValidateGC (&pMaskPixmap->drawable, pGC); + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); + FreeScratchGC (pGC); + x = -extents.x1; + y = -extents.y1; + } + else + { + pMask = pDst; + x = 0; + y = 0; + } + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + while (n--) + { + glyph = *glyphs++; + pPicture = GlyphPicture (glyph)[pScreen->myNum]; + + if (maskFormat) + { + CompositePicture (PictOpAdd, + pPicture, + None, + pMask, + 0, 0, + 0, 0, + x - glyph->info.x, + y - glyph->info.y, + glyph->info.width, + glyph->info.height); + } + else + { + CompositePicture (op, + pSrc, + pPicture, + pDst, + xSrc + (x - glyph->info.x) - xDst, + ySrc + (y - glyph->info.y) - yDst, + 0, 0, + x - glyph->info.x, + y - glyph->info.y, + glyph->info.width, + glyph->info.height); + } + + x += glyph->info.xOff; + y += glyph->info.yOff; + } + list++; + } + if (maskFormat) + { + x = extents.x1; + y = extents.y1; + CompositePicture (op, + pSrc, + pMask, + pDst, + xSrc + x - xDst, + ySrc + y - yDst, + 0, 0, + x, y, + width, height); + FreePicture ((pointer) pMask, (XID) 0); + (*pScreen->DestroyPixmap) (pMaskPixmap); + } +} diff --git a/render/glyphstr.h b/render/glyphstr.h index 22150deee..c6ab5aa11 100644 --- a/render/glyphstr.h +++ b/render/glyphstr.h @@ -39,13 +39,16 @@ #define GlyphFormatNum 5 typedef struct _Glyph { - CARD32 refcnt; - DevUnion *devPrivates; - CARD32 size; /* info + bitmap */ - xGlyphInfo info; - /* bits follow */ + CARD32 refcnt; + DevUnion *devPrivates; + unsigned char sha1[20]; + CARD32 size; /* info + bitmap */ + xGlyphInfo info; + /* per-screen pixmaps follow */ } GlyphRec, *GlyphPtr; +#define GlyphPicture(glyph) ((PicturePtr *) ((glyph) + 1)) + typedef struct _GlyphRef { CARD32 signature; GlyphPtr glyph; @@ -127,10 +130,19 @@ GlyphHashSetPtr FindGlyphHashSet (CARD32 filled); GlyphRefPtr -FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare); +FindGlyphRef (GlyphHashPtr hash, + CARD32 signature, + Bool match, + unsigned char sha1[20]); -CARD32 -HashGlyph (GlyphPtr glyph); +GlyphPtr +FindGlyphByHash (unsigned char sha1[20], int format); + +int +HashGlyph (xGlyphInfo *gi, + CARD8 *bits, + unsigned long size, + unsigned char sha1[20]); void FreeGlyph (GlyphPtr glyph, int format); diff --git a/render/miglyph.c b/render/miglyph.c deleted file mode 100644 index 7968c90ea..000000000 --- a/render/miglyph.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * - * 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 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: Keith Packard, SuSE, Inc. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "scrnintstr.h" -#include "gcstruct.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "mi.h" -#include "picturestr.h" -#include "mipict.h" - -Bool -miRealizeGlyph (ScreenPtr pScreen, - GlyphPtr glyph) -{ - return TRUE; -} - -void -miUnrealizeGlyph (ScreenPtr pScreen, - GlyphPtr glyph) -{ -} - -_X_EXPORT void -miGlyphExtents (int nlist, - GlyphListPtr list, - GlyphPtr *glyphs, - BoxPtr extents) -{ - int x1, x2, y1, y2; - int n; - GlyphPtr glyph; - int x, y; - - x = 0; - y = 0; - extents->x1 = MAXSHORT; - extents->x2 = MINSHORT; - extents->y1 = MAXSHORT; - extents->y2 = MINSHORT; - while (nlist--) - { - x += list->xOff; - y += list->yOff; - n = list->len; - list++; - while (n--) - { - glyph = *glyphs++; - x1 = x - glyph->info.x; - if (x1 < MINSHORT) - x1 = MINSHORT; - y1 = y - glyph->info.y; - if (y1 < MINSHORT) - y1 = MINSHORT; - x2 = x1 + glyph->info.width; - if (x2 > MAXSHORT) - x2 = MAXSHORT; - y2 = y1 + glyph->info.height; - if (y2 > MAXSHORT) - y2 = MAXSHORT; - 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; - } - } -} - -#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) - -_X_EXPORT void -miGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs) -{ - PixmapPtr pPixmap = 0; - PicturePtr pPicture; - PixmapPtr pMaskPixmap = 0; - PicturePtr pMask; - ScreenPtr pScreen = pDst->pDrawable->pScreen; - int width = 0, height = 0; - int x, y; - int xDst = list->xOff, yDst = list->yOff; - int n; - GlyphPtr glyph; - int error; - BoxRec extents; - CARD32 component_alpha; - - if (maskFormat) - { - GCPtr pGC; - xRectangle rect; - - miGlyphExtents (nlist, list, glyphs, &extents); - - if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) - return; - width = extents.x2 - extents.x1; - height = extents.y2 - extents.y1; - pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth); - if (!pMaskPixmap) - return; - component_alpha = NeedsComponent(maskFormat->format); - pMask = CreatePicture (0, &pMaskPixmap->drawable, - maskFormat, CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pMask) - { - (*pScreen->DestroyPixmap) (pMaskPixmap); - return; - } - pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); - ValidateGC (&pMaskPixmap->drawable, pGC); - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); - FreeScratchGC (pGC); - x = -extents.x1; - y = -extents.y1; - } - else - { - pMask = pDst; - x = 0; - y = 0; - } - pPicture = 0; - while (nlist--) - { - x += list->xOff; - y += list->yOff; - n = list->len; - while (n--) - { - glyph = *glyphs++; - if (!pPicture) - { - pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height, - list->format->depth, - list->format->depth, - 0, (pointer) (glyph + 1)); - if (!pPixmap) - return; - component_alpha = NeedsComponent(list->format->format); - pPicture = CreatePicture (0, &pPixmap->drawable, list->format, - CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pPicture) - { - FreeScratchPixmapHeader (pPixmap); - return; - } - } - (*pScreen->ModifyPixmapHeader) (pPixmap, - glyph->info.width, glyph->info.height, - 0, 0, -1, (pointer) (glyph + 1)); - pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - if (maskFormat) - { - CompositePicture (PictOpAdd, - pPicture, - None, - pMask, - 0, 0, - 0, 0, - x - glyph->info.x, - y - glyph->info.y, - glyph->info.width, - glyph->info.height); - } - else - { - CompositePicture (op, - pSrc, - pPicture, - pDst, - xSrc + (x - glyph->info.x) - xDst, - ySrc + (y - glyph->info.y) - yDst, - 0, 0, - x - glyph->info.x, - y - glyph->info.y, - glyph->info.width, - glyph->info.height); - } - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - if (pPicture) - { - FreeScratchPixmapHeader (pPixmap); - FreePicture ((pointer) pPicture, 0); - pPicture = 0; - pPixmap = 0; - } - } - if (maskFormat) - { - x = extents.x1; - y = extents.y1; - CompositePicture (op, - pSrc, - pMask, - pDst, - xSrc + x - xDst, - ySrc + y - yDst, - 0, 0, - x, y, - width, height); - FreePicture ((pointer) pMask, (XID) 0); - (*pScreen->DestroyPixmap) (pMaskPixmap); - } -} diff --git a/render/mipict.c b/render/mipict.c index 87dccbbda..5aad676f5 100644 --- a/render/mipict.c +++ b/render/mipict.c @@ -636,7 +636,7 @@ miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats) /* MI rendering routines */ ps->Composite = 0; /* requires DDX support */ - ps->Glyphs = miGlyphs; + ps->Glyphs = NULL; ps->CompositeRects = miCompositeRects; ps->Trapezoids = miTrapezoids; ps->Triangles = miTriangles; diff --git a/render/mipict.h b/render/mipict.h index bd7c23f4b..60baf7f66 100644 --- a/render/mipict.h +++ b/render/mipict.h @@ -119,12 +119,6 @@ void miUnrealizeGlyph (ScreenPtr pScreen, GlyphPtr glyph); -void -miGlyphExtents (int nlist, - GlyphListPtr list, - GlyphPtr *glyphs, - BoxPtr extents); - void miGlyphs (CARD8 op, PicturePtr pSrc, diff --git a/render/picture.c b/render/picture.c index 129d0e7bf..8a4ac4714 100644 --- a/render/picture.c +++ b/render/picture.c @@ -1791,24 +1791,6 @@ CompositePicture (CARD8 op, height); } -void -CompositeGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr lists, - GlyphPtr *glyphs) -{ - PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); - - ValidatePicture (pSrc); - ValidatePicture (pDst); - (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs); -} - void CompositeRects (CARD8 op, PicturePtr pDst, diff --git a/render/picture.h b/render/picture.h index 14ac429ef..8de8dfeec 100644 --- a/render/picture.h +++ b/render/picture.h @@ -121,7 +121,7 @@ typedef enum _PictFormatShort { /* YUV formats */ PICT_yuy2 = PIXMAN_yuy2, - PICT_yv12 = PIXMAN_yv12, + PICT_yv12 = PIXMAN_yv12 } PictFormatShort; /* diff --git a/render/picturestr.h b/render/picturestr.h index 093321d8e..223ca3a01 100644 --- a/render/picturestr.h +++ b/render/picturestr.h @@ -368,7 +368,7 @@ typedef struct _PictureScreen { ValidatePictureProcPtr ValidatePicture; CompositeProcPtr Composite; - GlyphsProcPtr Glyphs; + GlyphsProcPtr Glyphs; /* unused */ CompositeRectsProcPtr CompositeRects; DestroyWindowProcPtr DestroyWindow; diff --git a/render/render.c b/render/render.c index 0b2b664c9..0e2275f05 100644 --- a/render/render.c +++ b/render/render.c @@ -1091,24 +1091,31 @@ ProcRenderFreeGlyphSet (ClientPtr client) } typedef struct _GlyphNew { - Glyph id; - GlyphPtr glyph; + Glyph id; + GlyphPtr glyph; + Bool found; + unsigned char sha1[20]; } GlyphNewRec, *GlyphNewPtr; +#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) + static int ProcRenderAddGlyphs (ClientPtr client) { GlyphSetPtr glyphSet; REQUEST(xRenderAddGlyphsReq); GlyphNewRec glyphsLocal[NLOCALGLYPH]; - GlyphNewPtr glyphsBase, glyphs; - GlyphPtr glyph; + GlyphNewPtr glyphsBase, glyphs, glyph_new; int remain, nglyphs; CARD32 *gids; xGlyphInfo *gi; CARD8 *bits; int size; int err = BadAlloc; + int i, screen; + PicturePtr pSrc = NULL, pDst = NULL; + PixmapPtr pSrcPix = NULL, pDstPix = NULL; + CARD32 component_alpha; REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client, @@ -1125,11 +1132,15 @@ ProcRenderAddGlyphs (ClientPtr client) if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec)) return BadAlloc; - if (nglyphs <= NLOCALGLYPH) + component_alpha = NeedsComponent (glyphSet->format->format); + + if (nglyphs <= NLOCALGLYPH) { + memset (glyphsLocal, 0, sizeof (glyphsLocal)); glyphsBase = glyphsLocal; + } else { - glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec)); + glyphsBase = (GlyphNewPtr) Xcalloc (nglyphs * sizeof (GlyphNewRec)); if (!glyphsBase) return BadAlloc; } @@ -1142,58 +1153,133 @@ ProcRenderAddGlyphs (ClientPtr client) gi = (xGlyphInfo *) (gids + nglyphs); bits = (CARD8 *) (gi + nglyphs); remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs; - while (remain >= 0 && nglyphs) + for (i = 0; i < nglyphs; i++) { - glyph = AllocateGlyph (gi, glyphSet->fdepth); - if (!glyph) - { - err = BadAlloc; - goto bail; - } - - glyphs->glyph = glyph; - glyphs->id = *gids; - - size = glyph->size - sizeof (xGlyphInfo); + glyph_new = &glyphs[i]; + size = gi[i].height * PixmapBytePad (gi[i].width, + glyphSet->format->depth); if (remain < size) break; - memcpy ((CARD8 *) (glyph + 1), bits, size); + + err = HashGlyph (&gi[i], bits, size, glyph_new->sha1); + if (err) + goto bail; + + glyph_new->glyph = FindGlyphByHash (glyph_new->sha1, + glyphSet->fdepth); + + if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) + { + glyph_new->found = TRUE; + } + else + { + GlyphPtr glyph; + + glyph_new->found = FALSE; + glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth); + if (! glyph) + { + err = BadAlloc; + goto bail; + } + + for (screen = 0; screen < screenInfo.numScreens; screen++) + { + int width = gi[i].width; + int height = gi[i].height; + int depth = glyphSet->format->depth; + ScreenPtr pScreen; + int error; + + pScreen = screenInfo.screens[screen]; + pSrcPix = GetScratchPixmapHeader (pScreen, + width, height, + depth, depth, + -1, bits); + if (! pSrcPix) + { + err = BadAlloc; + goto bail; + } + + pSrc = CreatePicture (0, &pSrcPix->drawable, + glyphSet->format, 0, NULL, + serverClient, &error); + if (! pSrc) + { + err = BadAlloc; + goto bail; + } + + pDstPix = (pScreen->CreatePixmap) (pScreen, + width, height, depth); + + GlyphPicture (glyph)[screen] = pDst = + CreatePicture (0, &pDstPix->drawable, + glyphSet->format, + CPComponentAlpha, &component_alpha, + serverClient, &error); + + /* The picture takes a reference to the pixmap, so we + drop ours. */ + (pScreen->DestroyPixmap) (pDstPix); + + if (! pDst) + { + err = BadAlloc; + goto bail; + } + + CompositePicture (PictOpSrc, + pSrc, + None, + pDst, + 0, 0, + 0, 0, + 0, 0, + width, height); + + FreePicture ((pointer) pSrc, 0); + pSrc = NULL; + FreeScratchPixmapHeader (pSrcPix); + pSrcPix = NULL; + } + + memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20); + } + + glyph_new->id = gids[i]; if (size & 3) size += 4 - (size & 3); bits += size; remain -= size; - gi++; - gids++; - glyphs++; - nglyphs--; } - if (nglyphs || remain) + if (remain || i < nglyphs) { err = BadLength; goto bail; } - nglyphs = stuff->nglyphs; if (!ResizeGlyphSet (glyphSet, nglyphs)) { err = BadAlloc; goto bail; } - glyphs = glyphsBase; - while (nglyphs--) { - AddGlyph (glyphSet, glyphs->glyph, glyphs->id); - glyphs++; - } + for (i = 0; i < nglyphs; i++) + AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id); if (glyphsBase != glyphsLocal) Xfree (glyphsBase); return client->noClientException; bail: - while (glyphs != glyphsBase) - { - --glyphs; - xfree (glyphs->glyph); - } + if (pSrc) + FreePicture ((pointer) pSrc, 0); + if (pSrcPix) + FreeScratchPixmapHeader (pSrcPix); + for (i = 0; i < nglyphs; i++) + if (glyphs[i].glyph && ! glyphs[i].found) + xfree (glyphs[i].glyph); if (glyphsBase != glyphsLocal) Xfree (glyphsBase); return err;