📄 draw.c
字号:
GC_OP_PROLOGUE(pDrawable, pGC); TRC((stderr,"rfbPolyText8 called '%.*s'\n",count,chars)); if (count) { GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); 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); } ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars); if (count) { SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb); } GC_OP_EPILOGUE(pGC); return ret;}/* * PolyText16 - use rough bounding box. */static intrfbPolyText16(pDrawable, pGC, x, y, count, chars) DrawablePtr pDrawable; GCPtr pGC; int x, y; int count; unsigned short *chars;{ int ret; RegionRec tmpRegion; BoxRec box; GC_OP_PROLOGUE(pDrawable, pGC); TRC((stderr,"rfbPolyText16 called\n")); if (count) { GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); 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); } ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars); if (count) { SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb); } GC_OP_EPILOGUE(pGC); return ret;}/* * ImageText8 - use rough bounding box. */static voidrfbImageText8(pDrawable, pGC, x, y, count, chars) DrawablePtr pDrawable; GCPtr pGC; int x, y; int count; char *chars;{ RegionRec tmpRegion; BoxRec box; GC_OP_PROLOGUE(pDrawable, pGC); TRC((stderr,"rfbImageText8 called '%.*s'\n",count,chars)); if (count) { GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); 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->ImageText8) (pDrawable, pGC, x, y, count, chars); if (count) { SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb); } GC_OP_EPILOGUE(pGC);}/* * ImageText16 - use rough bounding box. */static voidrfbImageText16(pDrawable, pGC, x, y, count, chars) DrawablePtr pDrawable; GCPtr pGC; int x, y; int count; unsigned short *chars;{ RegionRec tmpRegion; BoxRec box; GC_OP_PROLOGUE(pDrawable, pGC); TRC((stderr,"rfbImageText16 called\n")); if (count) { GetTextBoundingBox(pDrawable, pGC->font, x, y, count, &box); 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->ImageText16) (pDrawable, pGC, x, y, count, chars); if (count) { SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb); } GC_OP_EPILOGUE(pGC);}/* * ImageGlyphBlt - use rough bounding box. */static voidrfbImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) DrawablePtr pDrawable; GCPtr pGC; int x, y; unsigned int nglyph; CharInfoPtr *ppci; /* array of character info */ pointer pglyphBase; /* start of array of glyphs */{ RegionRec tmpRegion; BoxRec box; GC_OP_PROLOGUE(pDrawable, pGC); TRC((stderr,"rfbImageGlyphBlt called\n")); if (nglyph) { GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box); 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->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci,pglyphBase); if (nglyph) { SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb); } GC_OP_EPILOGUE(pGC);}/* * PolyGlyphBlt - use rough bounding box. */static voidrfbPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) DrawablePtr pDrawable; GCPtr pGC; int x, y; unsigned int nglyph; CharInfoPtr *ppci; /* array of character info */ pointer pglyphBase; /* start of array of glyphs */{ RegionRec tmpRegion; BoxRec box; GC_OP_PROLOGUE(pDrawable, pGC); TRC((stderr,"rfbPolyGlyphBlt called\n")); if (nglyph) { GetTextBoundingBox(pDrawable, pGC->font, x, y, nglyph, &box); 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->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); if (nglyph) { SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb); } GC_OP_EPILOGUE(pGC);}/* * PushPixels - be fairly safe - region modified is intersection of the given * rectangle with the window clip region. */static voidrfbPushPixels(pGC, pBitMap, pDrawable, w, h, x, y) GCPtr pGC; PixmapPtr pBitMap; DrawablePtr pDrawable; int w, h, x, y;{ RegionRec tmpRegion; BoxRec box; GC_OP_PROLOGUE(pDrawable, pGC); TRC((stderr,"rfbPushPixels 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->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y); SCHEDULE_FB_UPDATE(pDrawable->pScreen, prfb); GC_OP_EPILOGUE(pGC);}/****************************************************************************//* * Other functions *//****************************************************************************//* * rfbCopyRegion. Args are src and dst regions plus a translation (dx,dy). * Takes these args together with the existing modified region and possibly an * existing copy region and translation. Produces a combined modified region * plus copy region and translation. Note that the copy region is the * destination of the copy. * * First we trim parts of src which are invalid (ie in the modified region). * Then we see if there is any overlap between the src and the existing copy * region. If not then the two copies cannot be combined, so we choose * whichever is bigger to form the basis of a new copy, while the other copy is * just done the hard way by being added to the modified region. So if the * existing copy is bigger then we simply add the destination of the new copy * to the modified region and we're done. If the new copy is bigger, we add * the old copy region to the modified region and behave as though there is no * existing copy region. * * At this stage we now know that either the two copies can be combined, or * that there is no existing copy. We temporarily add both the existing copy * region and dst to the modified region (this is the entire area of the screen * affected in any way). Finally we calculate the new copy region, and remove * it from the modified region. * * Note: * 1. The src region is modified by this routine. * 2. When the copy region is empty, copyDX and copyDY MUST be set to zero. */static voidrfbCopyRegion(pScreen, cl, src, dst, dx, dy) ScreenPtr pScreen; rfbClientPtr cl; RegionPtr src; RegionPtr dst; int dx, dy;{ RegionRec tmp; /* src = src - modifiedRegion */ REGION_SUBTRACT(pScreen, src, src, &cl->modifiedRegion); if (REGION_NOTEMPTY(pScreen, &cl->copyRegion)) { REGION_INIT(pScreen, &tmp, NullBox, 0); REGION_INTERSECT(pScreen, &tmp, src, &cl->copyRegion); if (REGION_NOTEMPTY(pScreen, &tmp)) { /* if src and copyRegion overlap: src = src intersect copyRegion */ REGION_COPY(pScreen, src, &tmp); } else { /* if no overlap, find bigger region */ int newArea = (((REGION_EXTENTS(pScreen,src))->x2 - (REGION_EXTENTS(pScreen,src))->x1) * ((REGION_EXTENTS(pScreen,src))->y2 - (REGION_EXTENTS(pScreen,src))->y1)); int oldArea = (((REGION_EXTENTS(pScreen,&cl->copyRegion))->x2 - (REGION_EXTENTS(pScreen,&cl->copyRegion))->x1) * ((REGION_EXTENTS(pScreen,&cl->copyRegion))->y2 - (REGION_EXTENTS(pScreen,&cl->copyRegion))->y1)); if (oldArea > newArea) { /* existing copy is bigger: modifiedRegion = modifiedRegion union dst copyRegion = copyRegion - dst return */ REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, dst); REGION_SUBTRACT(pScreen, &cl->copyRegion, &cl->copyRegion, dst); if (!REGION_NOTEMPTY(pScreen, &cl->copyRegion)) { cl->copyDX = 0; cl->copyDY = 0; } return; } /* new copy is bigger: modifiedRegion = modifiedRegion union copyRegion copyRegion = empty */ REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, &cl->copyRegion); REGION_EMPTY(pScreen, &cl->copyRegion); cl->copyDX = cl->copyDY = 0; } } /* modifiedRegion = modifiedRegion union dst union copyRegion */ REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, dst); REGION_UNION(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, &cl->copyRegion); /* copyRegion = T(src) intersect dst */ REGION_TRANSLATE(pScreen, src, dx, dy); REGION_INTERSECT(pScreen, &cl->copyRegion, src, dst); /* modifiedRegion = modifiedRegion - copyRegion */ REGION_SUBTRACT(pScreen, &cl->modifiedRegion, &cl->modifiedRegion, &cl->copyRegion); /* combine new translation T with existing translation */ if (REGION_NOTEMPTY(pScreen, &cl->copyRegion)) { cl->copyDX += dx; cl->copyDY += dy; } else { cl->copyDX = 0; cl->copyDY = 0; }}/* * rfbDeferredUpdateCallback() is called when a client's deferredUpdateTimer * goes off. */static CARD32rfbDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg){ rfbClientPtr cl = (rfbClientPtr)arg; rfbSendFramebufferUpdate(cl); cl->deferredUpdateScheduled = FALSE; return 0;}/* * rfbScheduleDeferredUpdate() is called from the SCHEDULE_FB_UPDATE macro * to schedule an update. */static voidrfbScheduleDeferredUpdate(rfbClientPtr cl){ if (rfbDeferUpdateTime != 0) { cl->deferredUpdateTimer = TimerSet(cl->deferredUpdateTimer, 0, rfbDeferUpdateTime, rfbDeferredUpdateCallback, cl); cl->deferredUpdateScheduled = TRUE; } else { rfbSendFramebufferUpdate(cl); }}/* * PrintRegion is useful for debugging. */static voidPrintRegion(pScreen,reg) ScreenPtr pScreen; RegionPtr reg;{ int nrects = REGION_NUM_RECTS(reg); int i; rfbLog("Region num rects %d extents %d,%d %d,%d\n",nrects, (REGION_EXTENTS(pScreen,reg))->x1, (REGION_EXTENTS(pScreen,reg))->y1, (REGION_EXTENTS(pScreen,reg))->x2, (REGION_EXTENTS(pScreen,reg))->y2); for (i = 0; i < nrects; i++) { rfbLog(" rect %d,%d %dx%d\n", REGION_RECTS(reg)[i].x1, REGION_RECTS(reg)[i].y1, REGION_RECTS(reg)[i].x2-REGION_RECTS(reg)[i].x1, REGION_RECTS(reg)[i].y2-REGION_RECTS(reg)[i].y1); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -