123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- /*
- Copyright (C) 1999. The XFree86 Project Inc.
- Copyright 2014 Red Hat, Inc.
- Written by Mark Vojkovich (mvojkovi@ucsd.edu)
- Pre-fb-write callbacks and RENDER support - Nolan Leake (nolan@vmware.com)
- */
- #ifdef HAVE_XORG_CONFIG_H
- #include <xorg-config.h>
- #endif
- #include <X11/X.h>
- #include <X11/Xproto.h>
- #include "misc.h"
- #include "pixmapstr.h"
- #include "input.h"
- #include <X11/fonts/font.h>
- #include "mi.h"
- #include "scrnintstr.h"
- #include "windowstr.h"
- #include "gcstruct.h"
- #include "dixfontstr.h"
- #include <X11/fonts/fontstruct.h>
- #include "xf86.h"
- #include "xf86str.h"
- #include "shadowfb.h"
- #include "picturestr.h"
- static Bool ShadowCloseScreen(ScreenPtr pScreen);
- static Bool ShadowCreateRootWindow(WindowPtr pWin);
- typedef struct {
- ScrnInfoPtr pScrn;
- RefreshAreaFuncPtr preRefresh;
- RefreshAreaFuncPtr postRefresh;
- CloseScreenProcPtr CloseScreen;
- CreateWindowProcPtr CreateWindow;
- } ShadowScreenRec, *ShadowScreenPtr;
- static DevPrivateKeyRec ShadowScreenKeyRec;
- static ShadowScreenPtr
- shadowfbGetScreenPrivate(ScreenPtr pScreen)
- {
- return dixLookupPrivate(&(pScreen)->devPrivates, &ShadowScreenKeyRec);
- }
- Bool
- ShadowFBInit2(ScreenPtr pScreen,
- RefreshAreaFuncPtr preRefreshArea,
- RefreshAreaFuncPtr postRefreshArea)
- {
- ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
- ShadowScreenPtr pPriv;
- if (!preRefreshArea && !postRefreshArea)
- return FALSE;
- if (!dixRegisterPrivateKey(&ShadowScreenKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
- if (!(pPriv = (ShadowScreenPtr) malloc(sizeof(ShadowScreenRec))))
- return FALSE;
- dixSetPrivate(&pScreen->devPrivates, &ShadowScreenKeyRec, pPriv);
- pPriv->pScrn = pScrn;
- pPriv->preRefresh = preRefreshArea;
- pPriv->postRefresh = postRefreshArea;
- pPriv->CloseScreen = pScreen->CloseScreen;
- pPriv->CreateWindow = pScreen->CreateWindow;
- pScreen->CloseScreen = ShadowCloseScreen;
- pScreen->CreateWindow = ShadowCreateRootWindow;
- return TRUE;
- }
- Bool
- ShadowFBInit(ScreenPtr pScreen, RefreshAreaFuncPtr refreshArea)
- {
- return ShadowFBInit2(pScreen, NULL, refreshArea);
- }
- /*
- * Note that we don't do DamageEmpty, or indeed look at the region inside the
- * DamagePtr at all. This is an optimization, believe it or not. The
- * incoming RegionPtr is the new damage, and if we were to empty the region
- * miext/damage would just have to waste time reallocating and re-unioning
- * it every time, whereas if we leave it around the union gets fast-pathed
- * away.
- */
- static void
- shadowfbReportPre(DamagePtr damage, RegionPtr reg, void *closure)
- {
- ShadowScreenPtr pPriv = closure;
- if (!pPriv->pScrn->vtSema)
- return;
- pPriv->preRefresh(pPriv->pScrn, RegionNumRects(reg), RegionRects(reg));
- }
- static void
- shadowfbReportPost(DamagePtr damage, RegionPtr reg, void *closure)
- {
- ShadowScreenPtr pPriv = closure;
- if (!pPriv->pScrn->vtSema)
- return;
- pPriv->postRefresh(pPriv->pScrn, RegionNumRects(reg), RegionRects(reg));
- }
- static Bool
- ShadowCreateRootWindow(WindowPtr pWin)
- {
- Bool ret;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- ShadowScreenPtr pPriv = shadowfbGetScreenPrivate(pScreen);
- /* paranoia */
- if (pWin != pScreen->root)
- ErrorF("ShadowCreateRootWindow called unexpectedly\n");
- /* call down, but don't hook ourselves back in; we know the first time
- * we're called it's for the root window.
- */
- pScreen->CreateWindow = pPriv->CreateWindow;
- ret = pScreen->CreateWindow(pWin);
- /* this might look like it leaks, but the damage code reaps listeners
- * when their drawable disappears.
- */
- if (ret) {
- DamagePtr damage;
- if (pPriv->preRefresh) {
- damage = DamageCreate(shadowfbReportPre, NULL,
- DamageReportRawRegion,
- TRUE, pScreen, pPriv);
- DamageRegister(&pWin->drawable, damage);
- }
- if (pPriv->postRefresh) {
- damage = DamageCreate(shadowfbReportPost, NULL,
- DamageReportRawRegion,
- TRUE, pScreen, pPriv);
- DamageSetReportAfterOp(damage, TRUE);
- DamageRegister(&pWin->drawable, damage);
- }
- }
- return ret;
- }
- static Bool
- ShadowCloseScreen(ScreenPtr pScreen)
- {
- ShadowScreenPtr pPriv = shadowfbGetScreenPrivate(pScreen);
- pScreen->CloseScreen = pPriv->CloseScreen;
- free(pPriv);
- return (*pScreen->CloseScreen) (pScreen);
- }
|