📄 sprite.c
字号:
if (imageblt) { if (extents.overallWidth > extents.overallRight) extents.overallRight = extents.overallWidth; if (extents.overallWidth < extents.overallLeft) extents.overallLeft = extents.overallWidth; if (extents.overallLeft > 0) extents.overallLeft = 0; if (extents.fontAscent > extents.overallAscent) extents.overallAscent = extents.fontAscent; if (extents.fontDescent > extents.overallDescent) extents.overallDescent = extents.fontDescent; } return (BOX_OVERLAP(cursorBox, x + extents.overallLeft, y - extents.overallAscent, x + extents.overallRight, y + extents.overallDescent));}/* * values for textType: */#define TT_POLY8 0#define TT_IMAGE8 1#define TT_POLY16 2#define TT_IMAGE16 3static int rfbSpriteText (pDraw, pGC, x, y, count, chars, fontEncoding, textType, cursorBox) DrawablePtr pDraw; GCPtr pGC; int x, y; unsigned long count; char *chars; FontEncoding fontEncoding; Bool textType; BoxPtr cursorBox;{ CharInfoPtr *charinfo; register CharInfoPtr *info; unsigned long i; unsigned int n; int w; void (*drawFunc)(); Bool imageblt; imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16); charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr)); if (!charinfo) return x; GetGlyphs(pGC->font, count, (unsigned char *)chars, fontEncoding, &i, charinfo); n = (unsigned int)i; w = 0; if (!imageblt) for (info = charinfo; i--; info++) w += (*info)->metrics.characterWidth; if (n != 0) { if (rfbSpriteTextOverlap(pDraw, pGC->font, x, y, n, charinfo, imageblt, w, cursorBox)) rfbSpriteRemoveCursor(pDraw->pScreen);#ifdef AVOID_GLYPHBLT /* * On displays like Apollos, which do not optimize the GlyphBlt functions because they * convert fonts to their internal form in RealizeFont and optimize text directly, we * want to invoke the text functions here, not the GlyphBlt functions. */ switch (textType) { case TT_POLY8: drawFunc = (void (*)())pGC->ops->PolyText8; break; case TT_IMAGE8: drawFunc = pGC->ops->ImageText8; break; case TT_POLY16: drawFunc = (void (*)())pGC->ops->PolyText16; break; case TT_IMAGE16: drawFunc = pGC->ops->ImageText16; break; } (*drawFunc) (pDraw, pGC, x, y, (int) count, chars);#else /* don't AVOID_GLYPHBLT */ /* * On the other hand, if the device does use GlyphBlt ultimately to do text, we * don't want to slow it down by invoking the text functions and having them call * GetGlyphs all over again, so we go directly to the GlyphBlt functions here. */ drawFunc = imageblt ? pGC->ops->ImageGlyphBlt : pGC->ops->PolyGlyphBlt; (*drawFunc) (pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));#endif /* AVOID_GLYPHBLT */ } DEALLOCATE_LOCAL(charinfo); return x + w;}static intrfbSpritePolyText8(pDrawable, pGC, x, y, count, chars) DrawablePtr pDrawable; GCPtr pGC; int x, y; int count; char *chars;{ int ret; GC_SETUP (pDrawable, pGC); GC_OP_PROLOGUE (pGC); if (GC_CHECK((WindowPtr) pDrawable)) ret = rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count, chars, Linear8Bit, TT_POLY8, &pScreenPriv->saved); else ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars); GC_OP_EPILOGUE (pGC); return ret;}static intrfbSpritePolyText16(pDrawable, pGC, x, y, count, chars) DrawablePtr pDrawable; GCPtr pGC; int x, y; int count; unsigned short *chars;{ int ret; GC_SETUP(pDrawable, pGC); GC_OP_PROLOGUE (pGC); if (GC_CHECK((WindowPtr) pDrawable)) ret = rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count, (char *)chars, FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit, TT_POLY16, &pScreenPriv->saved); else ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars); GC_OP_EPILOGUE (pGC); return ret;}static voidrfbSpriteImageText8(pDrawable, pGC, x, y, count, chars) DrawablePtr pDrawable; GCPtr pGC; int x, y; int count; char *chars;{ GC_SETUP(pDrawable, pGC); GC_OP_PROLOGUE (pGC); if (GC_CHECK((WindowPtr) pDrawable)) (void) rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count, chars, Linear8Bit, TT_IMAGE8, &pScreenPriv->saved); else (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars); GC_OP_EPILOGUE (pGC);}static voidrfbSpriteImageText16(pDrawable, pGC, x, y, count, chars) DrawablePtr pDrawable; GCPtr pGC; int x, y; int count; unsigned short *chars;{ GC_SETUP(pDrawable, pGC); GC_OP_PROLOGUE (pGC); if (GC_CHECK((WindowPtr) pDrawable)) (void) rfbSpriteText (pDrawable, pGC, x, y, (unsigned long)count, (char *)chars, FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit, TT_IMAGE16, &pScreenPriv->saved); else (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars); GC_OP_EPILOGUE (pGC);}static voidrfbSpriteImageGlyphBlt(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 */{ GC_SETUP(pDrawable, pGC); GC_OP_PROLOGUE (pGC); if (GC_CHECK((WindowPtr) pDrawable) && rfbSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, TRUE, 0, &pScreenPriv->saved)) { rfbSpriteRemoveCursor(pDrawable->pScreen); } (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); GC_OP_EPILOGUE (pGC);}static voidrfbSpritePolyGlyphBlt(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 */{ GC_SETUP (pDrawable, pGC); GC_OP_PROLOGUE (pGC); if (GC_CHECK((WindowPtr) pDrawable) && rfbSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, FALSE, 0, &pScreenPriv->saved)) { rfbSpriteRemoveCursor(pDrawable->pScreen); } (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); GC_OP_EPILOGUE (pGC);}static voidrfbSpritePushPixels(pGC, pBitMap, pDrawable, w, h, x, y) GCPtr pGC; PixmapPtr pBitMap; DrawablePtr pDrawable; int w, h, x, y;{ GC_SETUP(pDrawable, pGC); if (GC_CHECK((WindowPtr) pDrawable) && ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y,x,y,w,h)) { rfbSpriteRemoveCursor (pDrawable->pScreen); } GC_OP_PROLOGUE (pGC); (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y); GC_OP_EPILOGUE (pGC);}#ifdef NEED_LINEHELPER/* * I don't expect this routine will ever be called, as the GC * will have been unwrapped for the line drawing */static voidrfbSpriteLineHelper(){ FatalError("rfbSpriteLineHelper called\n");}#endif/* * miPointer interface routines */static BoolrfbSpriteRealizeCursor (pScreen, pCursor) ScreenPtr pScreen; CursorPtr pCursor;{ rfbSpriteScreenPtr pScreenPriv; pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr; if (pCursor == pScreenPriv->pCursor) pScreenPriv->checkPixels = TRUE; return (*pScreenPriv->funcs->RealizeCursor) (pScreen, pCursor);}static BoolrfbSpriteUnrealizeCursor (pScreen, pCursor) ScreenPtr pScreen; CursorPtr pCursor;{ rfbSpriteScreenPtr pScreenPriv; pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr; return (*pScreenPriv->funcs->UnrealizeCursor) (pScreen, pCursor);}static voidrfbSpriteSetCursor (pScreen, pCursor, x, y) ScreenPtr pScreen; CursorPtr pCursor;{ rfbSpriteScreenPtr pScreenPriv; rfbClientPtr cl, nextCl; pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr; if (pScreenPriv->x == x && pScreenPriv->y == y && pScreenPriv->pCursor == pCursor && !pScreenPriv->checkPixels) { return; } if (rfbScreen.cursorIsDrawn) rfbSpriteRemoveCursor (pScreen); pScreenPriv->x = x; pScreenPriv->y = y; pScreenPriv->pCursor = pCursor; for (cl = rfbClientHead; cl; cl = nextCl) { nextCl = cl->next; if (cl->enableCursorPosUpdates) { if (x == cl->cursorX && y == cl->cursorY) { cl->cursorWasMoved = FALSE; continue; } cl->cursorWasMoved = TRUE; } if ( !cl->deferredUpdateScheduled && REGION_NOTEMPTY(pScreen,&cl->requestedRegion) ) { /* cursorIsDrawn is guaranteed to be FALSE here, so we definitely want to send a screen update to the client, even if that's only putting up the cursor */ rfbSendFramebufferUpdate(cl); } }}static voidrfbSpriteMoveCursor (pScreen, x, y) ScreenPtr pScreen; int x, y;{ rfbSpriteScreenPtr pScreenPriv; pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr; rfbSpriteSetCursor (pScreen, pScreenPriv->pCursor, x, y);}/* * undraw/draw cursor */voidrfbSpriteRemoveCursor (pScreen) ScreenPtr pScreen;{ rfbSpriteScreenPtr pScreenPriv; if (!rfbScreen.cursorIsDrawn) return; pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr; rfbScreen.dontSendFramebufferUpdate = TRUE; rfbScreen.cursorIsDrawn = FALSE; pScreenPriv->pCacheWin = NullWindow; if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pScreen, pScreenPriv->saved.x1, pScreenPriv->saved.y1, pScreenPriv->saved.x2 - pScreenPriv->saved.x1, pScreenPriv->saved.y2 - pScreenPriv->saved.y1)) { rfbScreen.cursorIsDrawn = TRUE; } rfbScreen.dontSendFramebufferUpdate = FALSE;}voidrfbSpriteRestoreCursor (pScreen) ScreenPtr pScreen;{ rfbSpriteScreenPtr pScreenPriv; int x, y; CursorPtr pCursor; pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr; pCursor = pScreenPriv->pCursor; if (rfbScreen.cursorIsDrawn || !pCursor) return; rfbScreen.dontSendFramebufferUpdate = TRUE; rfbSpriteComputeSaved (pScreen); x = pScreenPriv->x - (int)pCursor->bits->xhot; y = pScreenPriv->y - (int)pCursor->bits->yhot; if ((*pScreenPriv->funcs->SaveUnderCursor) (pScreen, pScreenPriv->saved.x1, pScreenPriv->saved.y1, pScreenPriv->saved.x2 - pScreenPriv->saved.x1, pScreenPriv->saved.y2 - pScreenPriv->saved.y1)) { if (pScreenPriv->checkPixels) rfbSpriteFindColors (pScreen); if ((*pScreenPriv->funcs->PutUpCursor) (pScreen, pCursor, x, y, pScreenPriv->colors[SOURCE_COLOR].pixel, pScreenPriv->colors[MASK_COLOR].pixel)) rfbScreen.cursorIsDrawn = TRUE; } rfbScreen.dontSendFramebufferUpdate = FALSE;}/* * compute the desired area of the screen to save */static voidrfbSpriteComputeSaved (pScreen) ScreenPtr pScreen;{ rfbSpriteScreenPtr pScreenPriv; int x, y, w, h; CursorPtr pCursor; pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr; pCursor = pScreenPriv->pCursor; x = pScreenPriv->x - (int)pCursor->bits->xhot; y = pScreenPriv->y - (int)pCursor->bits->yhot; w = pCursor->bits->width; h = pCursor->bits->height; pScreenPriv->saved.x1 = x; pScreenPriv->saved.y1 = y; pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w; pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h;}/* * this function is called when the cursor shape is being changed */static BoolrfbDisplayCursor(pScreen, pCursor) ScreenPtr pScreen; CursorPtr pCursor;{ rfbClientPtr cl; rfbSpriteScreenPtr pPriv; Bool result; pPriv = (rfbSpriteScreenPtr)pScreen->devPrivates[rfbSpriteScreenIndex].ptr; result = (*pPriv->DisplayCursor)(pScreen, pCursor); for (cl = rfbClientHead; cl; cl = cl->next) { if (cl->enableCursorShapeUpdates) { cl->cursorWasChanged = TRUE; if ( !cl->deferredUpdateScheduled && REGION_NOTEMPTY(pScreen,&cl->requestedRegion) ) { rfbSendFramebufferUpdate(cl); } } } return result;}/* * obtain current cursor pointer */CursorPtrrfbSpriteGetCursorPtr (pScreen) ScreenPtr pScreen;{ rfbSpriteScreenPtr pScreenPriv; pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr; return pScreenPriv->pCursor;}/* * obtain current cursor position */voidrfbSpriteGetCursorPos (pScreen, px, py) ScreenPtr pScreen; int *px, *py;{ rfbSpriteScreenPtr pScreenPriv; pScreenPriv = (rfbSpriteScreenPtr) pScreen->devPrivates[rfbSpriteScreenIndex].ptr; *px = pScreenPriv->x; *py = pScreenPriv->y;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -