📄 draw.c
字号:
GC_FUNC_EPILOGUE(pGC);}/* * All other GC funcs simply unwrap the GC funcs and ops, call the wrapped * function and then rewrap the funcs and ops. */static voidrfbChangeGC (pGC, mask) GCPtr pGC; unsigned long mask;{ GC_FUNC_PROLOGUE(pGC); (*pGC->funcs->ChangeGC) (pGC, mask); GC_FUNC_EPILOGUE(pGC);}static voidrfbCopyGC (pGCSrc, mask, pGCDst) GCPtr pGCSrc, pGCDst; unsigned long mask;{ GC_FUNC_PROLOGUE(pGCDst); (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); GC_FUNC_EPILOGUE(pGCDst);}static voidrfbDestroyGC (pGC) GCPtr pGC;{ GC_FUNC_PROLOGUE(pGC); (*pGC->funcs->DestroyGC) (pGC); GC_FUNC_EPILOGUE(pGC);}static voidrfbChangeClip (pGC, type, pvalue, nrects) GCPtr pGC; int type; pointer pvalue; int nrects;{ GC_FUNC_PROLOGUE(pGC); (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); GC_FUNC_EPILOGUE(pGC);}static voidrfbDestroyClip(pGC) GCPtr pGC;{ GC_FUNC_PROLOGUE(pGC); (* pGC->funcs->DestroyClip)(pGC); GC_FUNC_EPILOGUE(pGC);}static voidrfbCopyClip(pgcDst, pgcSrc) GCPtr pgcDst, pgcSrc;{ GC_FUNC_PROLOGUE(pgcDst); (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); GC_FUNC_EPILOGUE(pgcDst);}/****************************************************************************//* * GC ops wrapper stuff * * Note that these routines will only have been wrapped for drawing to * viewable windows so we don't need to check each time that the drawable * is a viewable window. *//****************************************************************************/#define GC_OP_PROLOGUE(pDrawable,pGC) \ rfbScreenInfoPtr prfb = &rfbScreen; \ rfbGCPtr pGCPrivate = (rfbGCPtr) (pGC)->devPrivates[rfbGCIndex].ptr; \ GCFuncs *oldFuncs = pGC->funcs; \ (pGC)->funcs = pGCPrivate->wrapFuncs; \ (pGC)->ops = pGCPrivate->wrapOps;#define GC_OP_EPILOGUE(pGC) \ pGCPrivate->wrapOps = (pGC)->ops; \ (pGC)->funcs = oldFuncs; \ (pGC)->ops = &rfbGCOps;/* * FillSpans - being very safe - the region being modified is the border clip * region of the window. */static voidrfbFillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted) DrawablePtr pDrawable; GCPtr pGC; int nInit; /* number of spans to fill */ DDXPointPtr pptInit; /* pointer to list of start points */ int *pwidthInit; /* pointer to list of n widths */ int fSorted;{ GC_OP_PROLOGUE(pDrawable,pGC); TRC((stderr,"rfbFillSpans called\n")); ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &((WindowPtr)pDrawable)->borderClip); (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit,pwidthInit,fSorted); SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb); GC_OP_EPILOGUE(pGC);}/* * SetSpans - being very safe - the region being modified is the border clip * region of the window. */static voidrfbSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted) DrawablePtr pDrawable; GCPtr pGC; char *psrc; register DDXPointPtr ppt; int *pwidth; int nspans; int fSorted;{ GC_OP_PROLOGUE(pDrawable,pGC); TRC((stderr,"rfbSetSpans called\n")); ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &((WindowPtr)pDrawable)->borderClip); (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb); GC_OP_EPILOGUE(pGC);}/* * PutImage - the region being modified is the rectangle of the * PutImage (clipped to the window clip region). */static voidrfbPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits) DrawablePtr pDrawable; GCPtr pGC; int depth; int x; int y; int w; int h; int leftPad; int format; char *pBits;{ RegionRec tmpRegion; BoxRec box; GC_OP_PROLOGUE(pDrawable, pGC); TRC((stderr,"rfbPutImage called\n")); box.x1 = x + pDrawable->x; box.y1 = y + pDrawable->y; box.x2 = box.x1 + w; box.y2 = box.y1 + h; SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0); REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion, WINDOW_CLIP_REGION((WindowPtr)pDrawable,pGC)); ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion); REGION_UNINIT(pDrawable->pScreen, &tmpRegion); (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits); SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb); GC_OP_EPILOGUE(pGC);}/* * CopyArea - the region being modified is the destination rectangle (clipped * to the window clip region). * If the client will accept CopyRect messages then use rfbCopyRegion * to optimise the pending screen changes into a single "copy region" plus * the ordinary modified region. */static RegionPtrrfbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty) DrawablePtr pSrc; DrawablePtr pDst; GCPtr pGC; int srcx; int srcy; int w; int h; int dstx; int dsty;{ rfbClientPtr cl; RegionPtr rgn; RegionRec srcRegion, dstRegion; BoxRec box; GC_OP_PROLOGUE(pDst, pGC); TRC((stderr,"rfbCopyArea called\n")); box.x1 = dstx + pDst->x; box.y1 = dsty + pDst->y; box.x2 = box.x1 + w; box.y2 = box.y1 + h; SAFE_REGION_INIT(pDst->pScreen, &dstRegion, &box, 0); REGION_INTERSECT(pDst->pScreen, &dstRegion, &dstRegion, WINDOW_CLIP_REGION((WindowPtr)pDst,pGC)); if ((pSrc->type == DRAWABLE_WINDOW) && (pSrc->pScreen == pDst->pScreen)) { box.x1 = srcx + pSrc->x; box.y1 = srcy + pSrc->y; box.x2 = box.x1 + w; box.y2 = box.y1 + h; for (cl = rfbClientHead; cl; cl = cl->next) { if (cl->useCopyRect) { SAFE_REGION_INIT(pSrc->pScreen, &srcRegion, &box, 0); REGION_INTERSECT(pSrc->pScreen, &srcRegion, &srcRegion, &((WindowPtr)pSrc)->clipList); rfbCopyRegion(pSrc->pScreen, cl, &srcRegion, &dstRegion, dstx + pDst->x - srcx - pSrc->x, dsty + pDst->y - srcy - pSrc->y); REGION_UNINIT(pSrc->pScreen, &srcRegion); } else { REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, &dstRegion); } } } else { ADD_TO_MODIFIED_REGION(pDst->pScreen, &dstRegion); } REGION_UNINIT(pDst->pScreen, &dstRegion); rgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); SCHEDULE_FB_UPDATE(pDst->pScreen, prfb); GC_OP_EPILOGUE(pGC); return rgn;}/* * CopyPlane - the region being modified is the destination rectangle (clipped * to the window clip region). */static RegionPtrrfbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane) DrawablePtr pSrc; DrawablePtr pDst; register GCPtr pGC; int srcx, srcy; int w, h; int dstx, dsty; unsigned long plane;{ RegionPtr rgn; RegionRec tmpRegion; BoxRec box; GC_OP_PROLOGUE(pDst, pGC); TRC((stderr,"rfbCopyPlane called\n")); box.x1 = dstx + pDst->x; box.y1 = dsty + pDst->y; box.x2 = box.x1 + w; box.y2 = box.y1 + h; SAFE_REGION_INIT(pDst->pScreen, &tmpRegion, &box, 0); REGION_INTERSECT(pDst->pScreen, &tmpRegion, &tmpRegion, WINDOW_CLIP_REGION((WindowPtr)pDst,pGC)); ADD_TO_MODIFIED_REGION(pDst->pScreen, &tmpRegion); REGION_UNINIT(pDst->pScreen, &tmpRegion); rgn = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane); SCHEDULE_FB_UPDATE(pDst->pScreen, prfb); GC_OP_EPILOGUE(pGC); return rgn;}/* * PolyPoint - find the smallest rectangle which encloses the points drawn * (and clip). */static voidrfbPolyPoint (pDrawable, pGC, mode, npt, pts) DrawablePtr pDrawable; GCPtr pGC; int mode; /* Origin or Previous */ int npt; xPoint *pts;{ int i; RegionRec tmpRegion; BoxRec box; GC_OP_PROLOGUE(pDrawable, pGC); TRC((stderr,"rfbPolyPoint called\n")); if (npt) { int minX = pts[0].x, maxX = pts[0].x; int minY = pts[0].y, maxY = pts[0].y; if (mode == CoordModePrevious) { int x = pts[0].x, y = pts[0].y; for (i = 1; i < npt; i++) { x += pts[i].x; y += pts[i].y; if (x < minX) minX = x; if (x > maxX) maxX = x; if (y < minY) minY = y; if (y > maxY) maxY = y; } } else { for (i = 1; i < npt; i++) { if (pts[i].x < minX) minX = pts[i].x; if (pts[i].x > maxX) maxX = pts[i].x; if (pts[i].y < minY) minY = pts[i].y; if (pts[i].y > maxY) maxY = pts[i].y; } } box.x1 = minX + pDrawable->x; box.y1 = minY + pDrawable->y; box.x2 = maxX + 1 + pDrawable->x; box.y2 = maxY + 1 + pDrawable->y; SAFE_REGION_INIT(pDrawable->pScreen, &tmpRegion, &box, 0); REGION_INTERSECT(pDrawable->pScreen, &tmpRegion, &tmpRegion, WINDOW_CLIP_REGION(((WindowPtr)pDrawable),pGC)); ADD_TO_MODIFIED_REGION(pDrawable->pScreen, &tmpRegion); REGION_UNINIT(pDrawable->pScreen, &tmpRegion); } (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pts); if (npt) { SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb); } GC_OP_EPILOGUE(pGC);}/* * PolyLines - take the union of bounding boxes around each line (and clip). */static voidrfbPolylines (pDrawable, pGC, mode, npt, ppts) DrawablePtr pDrawable; GCPtr pGC; int mode; int npt; DDXPointPtr ppts;{ RegionPtr tmpRegion; xRectangle *rects; int i, extra, nlines, lw; int x1, x2, y1, y2; GC_OP_PROLOGUE(pDrawable, pGC); TRC((stderr,"rfbPolylines called\n")); if (npt) { lw = pGC->lineWidth; if (lw == 0) lw = 1; if (npt == 1) { nlines = 1; rects = (xRectangle *)xalloc(sizeof(xRectangle)); if (!rects) { FatalError("rfbPolylines: xalloc failed\n"); } rects[0].x = ppts[0].x - lw + pDrawable->x; /* being safe here */ rects[0].y = ppts[0].y - lw + pDrawable->y; rects[0].width = 2*lw; rects[0].height = 2*lw; } else { nlines = npt - 1; rects = (xRectangle *)xalloc(nlines*sizeof(xRectangle)); if (!rects) { FatalError("rfbPolylines: xalloc failed\n"); } /* * mitered joins can project quite a way from * the line end; the 11 degree miter limit limits * this extension to lw / (2 * tan(11/2)), rounded up * and converted to int yields 6 * lw */ if (pGC->joinStyle == JoinMiter) { extra = 6 * lw; } else { extra = lw / 2; } x1 = ppts[0].x + pDrawable->x; y1 = ppts[0].y + pDrawable->y; for (i = 0; i < nlines; i++) { if (mode == CoordModeOrigin) { x2 = pDrawable->x + ppts[i+1].x; y2 = pDrawable->y + ppts[i+1].y; } else { x2 = x1 + ppts[i+1].x; y2 = y1 + ppts[i+1].y; } if (x1 > x2) { rects[i].x = x2 - extra; rects[i].width = x1 - x2 + 1 + 2 * extra; } else { rects[i].x = x1 - extra;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -