📄 hpsprite.c
字号:
/* * hpsprite.c * * hp screen independent software sprite routines *//* $XConsortium: misprite.c,v 5.28 90/01/13 17:33:32 rws Exp $ *//*Copyright 1989 by the Massachusetts Institute of TechnologyPermission to use, copy, modify, and distribute this software and itsdocumentation for any purpose and without fee is hereby granted,provided that the above copyright notice appear in all copies and thatboth that copyright notice and this permission notice appear insupporting documentation, and that the name of M.I.T. not be used inadvertising or publicity pertaining to distribution of the softwarewithout specific, written prior permission. M.I.T. makes norepresentations about the suitability of this software for anypurpose. It is provided "as is" without express or implied warranty.*/# include "X.h"# include "Xproto.h"# include "misc.h"# include "pixmapstr.h"# include "input.h"# include "mi.h"# include "cursorstr.h"# include "font.h"# include "scrnintstr.h"# include "colormapst.h"# include "windowstr.h"# include "gcstruct.h"# include "hpspritest.h"# include "dixfontstr.h"# include "fontstruct.h"# include "hppriv.h"/* * screen wrappers */static Bool hpSpriteCloseScreen();static void hpSpriteGetImage();static void hpSpriteGetSpans();static void hpSpriteSourceValidate();static Bool hpSpriteCreateGC();static void hpSpriteInstallColormap();static void hpSpriteStoreColors();static void hpSpritePaintWindowBackground();static void hpSpritePaintWindowBorder();static void hpSpriteCopyWindow();static void hpSpriteClearToBackground();static void hpSpriteSaveDoomedAreas();static RegionPtr hpSpriteRestoreAreas();extern Bool hpCursorLoc();#define SCREEN_PROLOGUE(pScreen, field)\ ((pScreen)->field = getPrivScreenPtr(pScreen)->field)#define SCREEN_EPILOGUE(pScreen, field, wrapper)\ ((pScreen)->field = wrapper)/* * GC func wrappers */static unsigned long hpSpriteGeneration = 0;static int hpSpriteGCIndex;static void hpSpriteValidateGC (), hpSpriteCopyGC ();static void hpSpriteDestroyGC(), hpSpriteChangeGC();static void hpSpriteChangeClip(), hpSpriteDestroyClip();static void hpSpriteCopyClip();static GCFuncs hpSpriteGCFuncs = { hpSpriteValidateGC, hpSpriteChangeGC, hpSpriteCopyGC, hpSpriteDestroyGC, hpSpriteChangeClip, hpSpriteDestroyClip, hpSpriteCopyClip,};#define GC_FUNC_PROLOGUE(pGC) \ hpSpriteGCPtr pGCPriv = \ (hpSpriteGCPtr) (pGC)->devPrivates[hpSpriteGCIndex].ptr;\ (pGC)->funcs = pGCPriv->wrapFuncs; \ if (pGCPriv->wrapOps) \ (pGC)->ops = pGCPriv->wrapOps;#define GC_FUNC_EPILOGUE(pGC) \ pGCPriv->wrapFuncs = (pGC)->funcs; \ (pGC)->funcs = &hpSpriteGCFuncs; \ if (pGCPriv->wrapOps) \ { \ pGCPriv->wrapOps = (pGC)->ops; \ (pGC)->ops = &hpSpriteGCOps; \ }/* * GC op wrappers */static void hpSpriteFillSpans(), hpSpriteSetSpans();static void hpSpritePutImage();static RegionPtr hpSpriteCopyArea(), hpSpriteCopyPlane();static void hpSpritePolyPoint(), hpSpritePolylines();static void hpSpritePolySegment(), hpSpritePolyRectangle();static void hpSpritePolyArc(), hpSpriteFillPolygon();static void hpSpritePolyFillRect(), hpSpritePolyFillArc();static int hpSpritePolyText8(), hpSpritePolyText16();static void hpSpriteImageText8(), hpSpriteImageText16();static void hpSpriteImageGlyphBlt(), hpSpritePolyGlyphBlt();static void hpSpritePushPixels(), hpSpriteLineHelper();static void hpSpriteChangeClip(), hpSpriteDestroyClip();static void hpSpriteCopyClip();static GCOps hpSpriteGCOps = { hpSpriteFillSpans, hpSpriteSetSpans, hpSpritePutImage, hpSpriteCopyArea, hpSpriteCopyPlane, hpSpritePolyPoint, hpSpritePolylines, hpSpritePolySegment, hpSpritePolyRectangle, hpSpritePolyArc, hpSpriteFillPolygon, hpSpritePolyFillRect, hpSpritePolyFillArc, hpSpritePolyText8, hpSpritePolyText16, hpSpriteImageText8, hpSpriteImageText16, hpSpriteImageGlyphBlt, hpSpritePolyGlyphBlt, hpSpritePushPixels, hpSpriteLineHelper,};/* * testing only -- remove cursor for every draw. Eventually, * each draw operation will perform a bounding box check against * the saved cursor area */#define GC_SETUP_CHEAP(pDrawable) \ hpPrivScreenPtr pScreenPriv = getPrivScreenPtr((pDrawable)->pScreen);#define GC_SETUP(pDrawable, pGC) \ GC_SETUP_CHEAP(pDrawable) \ hpSpriteGCPtr pGCPrivate = (hpSpriteGCPtr) \ (pGC)->devPrivates[hpSpriteGCIndex].ptr; \ GCFuncs *oldFuncs = pGC->funcs;#define GC_SETUP_AND_CHECK(pDrawable, pGC) \ GC_SETUP(pDrawable, pGC); \ if (GC_CHECK((WindowPtr)pDrawable)) \ (*pScreenPriv->CursorOff) (pDrawable->pScreen); #define GC_CHECK(pWin) \ (pScreenPriv->cstate == CURSOR_ON && \ (pWin)->drawable.x < pScreenPriv->saved.x2 && \ pScreenPriv->saved.x1 < (pWin)->drawable.x + (int) (pWin)->drawable.width && \ (pWin)->drawable.y < pScreenPriv->saved.y2 && \ pScreenPriv->saved.y1 < (pWin)->drawable.y + (int) (pWin)->drawable.height)#define GC_OP_PROLOGUE(pGC) { \ (pGC)->funcs = pGCPrivate->wrapFuncs; \ (pGC)->ops = pGCPrivate->wrapOps; \ }#define GC_OP_EPILOGUE(pGC) { \ pGCPrivate->wrapOps = (pGC)->ops; \ (pGC)->funcs = oldFuncs; \ (pGC)->ops = &hpSpriteGCOps; \ }/* * hpSpriteInitialize -- called from device-dependent screen * initialization proc after all of the function pointers have * been stored in the screen structure. */BoolhpSpriteInitialize (pScreen) ScreenPtr pScreen;{ hpPrivScreenPtr pPriv; if (hpSpriteGeneration != serverGeneration) { hpSpriteGeneration = serverGeneration; hpSpriteGCIndex = AllocateGCPrivateIndex (); } if (!AllocateGCPrivate(pScreen, hpSpriteGCIndex, sizeof(hpSpriteGCRec))) return FALSE; pPriv = getPrivScreenPtr(pScreen); pPriv->pInstalledMap = NULL; pPriv->CloseScreen = pScreen->CloseScreen; pPriv->GetImage = pScreen->GetImage; pPriv->GetSpans = pScreen->GetSpans; pPriv->SourceValidate = pScreen->SourceValidate; pPriv->CreateGC = pScreen->CreateGC; pPriv->InstallColormap = pScreen->InstallColormap; pPriv->StoreColors = pScreen->StoreColors; pPriv->PaintWindowBackground = pScreen->PaintWindowBackground; pPriv->PaintWindowBorder = pScreen->PaintWindowBorder; pPriv->CopyWindow = pScreen->CopyWindow; pPriv->ClearToBackground = pScreen->ClearToBackground; pPriv->SaveDoomedAreas = pScreen->SaveDoomedAreas; pPriv->RestoreAreas = pScreen->RestoreAreas; pScreen->CloseScreen = hpSpriteCloseScreen; pScreen->GetImage = hpSpriteGetImage; pScreen->GetSpans = hpSpriteGetSpans; pScreen->SourceValidate = hpSpriteSourceValidate; pScreen->CreateGC = hpSpriteCreateGC; pScreen->InstallColormap = hpSpriteInstallColormap; pScreen->StoreColors = hpSpriteStoreColors; pScreen->PaintWindowBackground = hpSpritePaintWindowBackground; pScreen->PaintWindowBorder = hpSpritePaintWindowBorder; pScreen->CopyWindow = hpSpriteCopyWindow; pScreen->ClearToBackground = hpSpriteClearToBackground; pScreen->SaveDoomedAreas = hpSpriteSaveDoomedAreas; pScreen->RestoreAreas = hpSpriteRestoreAreas; return TRUE;}/* * Screen wrappers *//* * CloseScreen wrapper -- unwrap everything, free the private data * and call the wrapped function */static BoolhpSpriteCloseScreen (i, pScreen) int i; ScreenPtr pScreen;{ hpPrivScreenPtr pScreenPriv = getPrivScreenPtr(pScreen); pScreen->CloseScreen = pScreenPriv->CloseScreen; pScreen->GetImage = pScreenPriv->GetImage; pScreen->GetSpans = pScreenPriv->GetSpans; pScreen->SourceValidate = pScreenPriv->SourceValidate; pScreen->CreateGC = pScreenPriv->CreateGC; pScreen->InstallColormap = pScreenPriv->InstallColormap; pScreen->StoreColors = pScreenPriv->StoreColors; pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground; pScreen->PaintWindowBorder = pScreenPriv->PaintWindowBorder; pScreen->CopyWindow = pScreenPriv->CopyWindow; pScreen->ClearToBackground = pScreenPriv->ClearToBackground; pScreen->SaveDoomedAreas = pScreenPriv->SaveDoomedAreas; pScreen->RestoreAreas = pScreenPriv->RestoreAreas; return (*pScreen->CloseScreen) (i, pScreen);}static voidhpSpriteGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine) DrawablePtr pDrawable; int sx, sy, w, h; unsigned int format; unsigned long planemask; pointer pdstLine;{ ScreenPtr pScreen = pDrawable->pScreen; hpPrivScreenPtr pScreenPriv; SCREEN_PROLOGUE (pScreen, GetImage); pScreenPriv = getPrivScreenPtr(pScreen); if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->cstate == CURSOR_ON && ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y, sx, sy, w, h)) (*pScreenPriv->CursorOff) (pScreen); (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine); SCREEN_EPILOGUE (pScreen, GetImage, hpSpriteGetImage);}static voidhpSpriteGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart) DrawablePtr pDrawable; int wMax; DDXPointPtr ppt; int *pwidth; int nspans; unsigned int *pdstStart;{ ScreenPtr pScreen = pDrawable->pScreen; hpPrivScreenPtr pScreenPriv; SCREEN_PROLOGUE (pScreen, GetSpans); pScreenPriv = getPrivScreenPtr(pScreen); if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->cstate == CURSOR_ON) { register DDXPointPtr pts; register int *widths; register int nPts; register int xorg, yorg; xorg = pDrawable->x; yorg = pDrawable->y; for (pts = ppt, widths = pwidth, nPts = nspans; nPts--; pts++, widths++) { if (SPN_OVERLAP(&pScreenPriv->saved, pts->y+yorg, pts->x+xorg,*widths)) { (*pScreenPriv->CursorOff) (pScreen); break; } } } (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); SCREEN_EPILOGUE (pScreen, GetSpans, hpSpriteGetSpans);}static voidhpSpriteSourceValidate (pDrawable, x, y, width, height) DrawablePtr pDrawable; int x, y, width, height;{ ScreenPtr pScreen = pDrawable->pScreen; hpPrivScreenPtr pScreenPriv; SCREEN_PROLOGUE (pScreen, SourceValidate); pScreenPriv = getPrivScreenPtr(pScreen); if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->cstate == CURSOR_ON && ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y, x, y, width, height)) { (*pScreenPriv->CursorOff) (pScreen); } if (pScreen->SourceValidate) (*pScreen->SourceValidate) (pDrawable, x, y, width, height); SCREEN_EPILOGUE (pScreen, SourceValidate, hpSpriteSourceValidate);}static BoolhpSpriteCreateGC (pGC) GCPtr pGC;{ ScreenPtr pScreen = pGC->pScreen; Bool ret; hpSpriteGCPtr pPriv; SCREEN_PROLOGUE (pScreen, CreateGC); pPriv = (hpSpriteGCPtr)pGC->devPrivates[hpSpriteGCIndex].ptr; ret = (*pScreen->CreateGC) (pGC); pPriv->wrapOps = NULL; pPriv->wrapFuncs = pGC->funcs; pGC->funcs = &hpSpriteGCFuncs; SCREEN_EPILOGUE (pScreen, CreateGC, hpSpriteCreateGC); return ret;}static voidhpSpriteInstallColormap (pMap) ColormapPtr pMap;{ ScreenPtr pScreen = pMap->pScreen; hpPrivScreenPtr pPriv; pPriv = getPrivScreenPtr(pScreen); SCREEN_PROLOGUE(pScreen, InstallColormap); (*pScreen->InstallColormap) (pMap); SCREEN_EPILOGUE(pScreen, InstallColormap, hpSpriteInstallColormap); if (pPriv->pInstalledMap != pMap) { pPriv->pInstalledMap = pMap; (*pPriv->CursorOff) (pScreen); }}static voidhpSpriteStoreColors (pMap, ndef, pdef) ColormapPtr pMap; int ndef; xColorItem *pdef;{ ScreenPtr pScreen = pMap->pScreen; hpPrivScreenPtr pPriv;#if 0 int i;#endif pPriv = getPrivScreenPtr(pScreen); SCREEN_PROLOGUE(pScreen, StoreColors); (*pScreen->StoreColors) (pMap, ndef, pdef); SCREEN_EPILOGUE(pScreen, StoreColors, hpSpriteStoreColors); if (pPriv->pInstalledMap == pMap) {#if 0 for (i = 0; i < ndef; i++) /* * XXX direct color will affect pixels other than * pdef[i].pixel -- this will be more difficult... */ if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel || pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel) { pPriv->checkPixels = TRUE; if (pPriv->isUp && pPriv->shouldBeUp)#endif (*pPriv->CursorOff) (pScreen);#if 0 break; }#endif }}voidhpSpriteFindColors(pScreen, pCursor, fgpix, bgpix) ScreenPtr pScreen; CursorPtr pCursor; Pixel *fgpix, *bgpix;{ ColormapPtr cmap = getPrivScreenPtr(pScreen)->pInstalledMap; xColorItem fgitem, bgitem; fgitem.red = pCursor->foreRed; fgitem.green = pCursor->foreGreen; fgitem.blue = pCursor->foreBlue; FakeAllocColor(cmap, &fgitem); bgitem.red = pCursor->backRed; bgitem.green = pCursor->backGreen; bgitem.blue = pCursor->backBlue; FakeAllocColor(cmap, &bgitem); *fgpix = fgitem.pixel; *bgpix = bgitem.pixel; /* "free" the pixels right away, don't let this confuse you */ FakeFreeColor(cmap, fgitem.pixel); FakeFreeColor(cmap, bgitem.pixel);}/* * BackingStore wrappers */static voidhpSpriteSaveDoomedAreas (pWin, pObscured, dx, dy) WindowPtr pWin; RegionPtr pObscured; int dx, dy;{ ScreenPtr pScreen; hpPrivScreenPtr pScreenPriv; BoxRec cursorBox; pScreen = pWin->drawable.pScreen; SCREEN_PROLOGUE (pScreen, SaveDoomedAreas); pScreenPriv = getPrivScreenPtr(pScreen); if (pScreenPriv->cstate == CURSOR_ON) { cursorBox = pScreenPriv->saved; if (dx || dy) { cursorBox.x1 += dx; cursorBox.y1 += dy; cursorBox.x2 += dx; cursorBox.y2 += dy; } if ((* pScreen->RectIn) (pObscured, &cursorBox) != rgnOUT) (*pScreenPriv->CursorOff) (pScreen); } (*pScreen->SaveDoomedAreas) (pWin, pObscured, dx, dy); SCREEN_EPILOGUE (pScreen, SaveDoomedAreas, hpSpriteSaveDoomedAreas);}static RegionPtrhpSpriteRestoreAreas (pWin, prgnExposed) WindowPtr pWin; RegionPtr prgnExposed;{ ScreenPtr pScreen; hpPrivScreenPtr pScreenPriv; RegionPtr result; pScreen = pWin->drawable.pScreen; SCREEN_PROLOGUE (pScreen, RestoreAreas); pScreenPriv = getPrivScreenPtr(pScreen); if (pScreenPriv->cstate == CURSOR_ON) { if ((* pScreen->RectIn) (prgnExposed, &pScreenPriv->saved) != rgnOUT) (*pScreenPriv->CursorOff) (pScreen); } result = (*pScreen->RestoreAreas) (pWin, prgnExposed); SCREEN_EPILOGUE (pScreen, RestoreAreas, hpSpriteRestoreAreas); return result;}/* * Window wrappers */static voidhpSpritePaintWindowBackground (pWin, pRegion, what) WindowPtr pWin; RegionPtr pRegion; int what;{ ScreenPtr pScreen; hpPrivScreenPtr pScreenPriv; pScreen = pWin->drawable.pScreen; SCREEN_PROLOGUE (pScreen, PaintWindowBackground); pScreenPriv = getPrivScreenPtr(pScreen); if (pScreenPriv->cstate == CURSOR_ON) { /* * If the cursor is on the same screen as the window, check the * region to paint for the cursor and remove it as necessary */ if ((* pScreen->RectIn) (pRegion, &pScreenPriv->saved) != rgnOUT) (*pScreenPriv->CursorOff) (pScreen); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -