PageRenderTime 26ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/hw/directfb/rootlessScreen.c

https://bitbucket.org/hiyuh/xorg-server
C | 403 lines | 275 code | 76 blank | 52 comment | 40 complexity | d88b9b68da1398d629a0d575d8dfd07c MD5 | raw file
Possible License(s): MIT, AGPL-3.0
  1. /*
  2. (c) Copyright 2002-2003 Denis Oliver Kropp <dok@directfb.org>
  3. All rights reserved.
  4. XDirectFB is mainly based on XDarwin and
  5. also contains some KDrive, XFree and XWin code.
  6. */
  7. /*
  8. * Screen routines for Mac OS X rootless X server
  9. *
  10. * Greg Parker gparker@cs.stanford.edu
  11. *
  12. * February 2001 Created
  13. * March 3, 2001 Restructured as generic rootless mode
  14. */
  15. /* $XFree86: xc/programs/Xserver/hw/directfb/bundle/rootlessScreen.c,v 1.5 2001/12/22 05:28:35 torrey Exp $ */
  16. #include "mi.h"
  17. #include "fb.h"
  18. #include "scrnintstr.h"
  19. #include "gcstruct.h"
  20. #include "pixmapstr.h"
  21. #include "windowstr.h"
  22. #include "propertyst.h"
  23. #include "mivalidate.h"
  24. #include "picturestr.h"
  25. #include "mipict.h"
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <fcntl.h>
  29. #include "rootlessCommon.h"
  30. #include "rootlessWindow.h"
  31. extern int
  32. RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild, VTKind kind);
  33. extern Bool
  34. RootlessCreateGC(GCPtr pGC);
  35. // Initialize globals
  36. DevPrivateKey rootlessGCPrivateKey = &rootlessGCPrivateKey;
  37. DevPrivateKey rootlessScreenPrivateKey = &rootlessScreenPrivateKey;
  38. DevPrivateKey rootlessWindowPrivateKey = &rootlessWindowPrivateKey;
  39. static Bool
  40. RootlessCloseScreen(int i, ScreenPtr pScreen)
  41. {
  42. RootlessScreenRec *s;
  43. s = SCREENREC(pScreen);
  44. // fixme unwrap everything that was wrapped?
  45. pScreen->CloseScreen = s->CloseScreen;
  46. xfree(s);
  47. return pScreen->CloseScreen(i, pScreen);
  48. }
  49. static void
  50. RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
  51. unsigned int format, unsigned long planeMask, char *pdstLine)
  52. {
  53. ScreenPtr pScreen = pDrawable->pScreen;
  54. SCREEN_UNWRAP(pScreen, GetImage);
  55. if (pDrawable->type == DRAWABLE_WINDOW) {
  56. WindowPtr pWin = (WindowPtr)pDrawable;
  57. RootlessWindowRec *winRec = WINREC(pWin);
  58. /* Many apps use GetImage to sync with the visible frame buffer */
  59. /* fixme entire screen or just window or all screens? */
  60. RootlessRedisplayScreen(pScreen);
  61. if (IsRoot (pWin))
  62. CallFrameProc(pScreen, RootBeforeGetImage, (pScreen, &winRec->frame, sx, sy, w, h));
  63. pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
  64. if (IsRoot (pWin))
  65. CallFrameProc(pScreen, RootAfterGetImage, (pScreen, &winRec->frame));
  66. }
  67. else
  68. pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
  69. SCREEN_WRAP(pScreen, GetImage);
  70. }
  71. #ifdef RENDER
  72. static void
  73. RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
  74. INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
  75. INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
  76. {
  77. ScreenPtr pScreen = pDst->pDrawable->pScreen;
  78. PictureScreenPtr ps = GetPictureScreen(pScreen);
  79. WindowPtr dstWin;
  80. dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
  81. (WindowPtr)pDst->pDrawable : NULL;
  82. // SCREEN_UNWRAP(ps, Composite);
  83. ps->Composite = SCREENREC(pScreen)->Composite;
  84. ps->Composite(op, pSrc, pMask, pDst,
  85. xSrc, ySrc, xMask, yMask,
  86. xDst, yDst, width, height);
  87. if (dstWin && IsFramedWindow(dstWin)) {
  88. RootlessDamageRect(dstWin, xDst, yDst, width, height);
  89. }
  90. ps->Composite = RootlessComposite;
  91. // SCREEN_WRAP(ps, Composite);
  92. }
  93. void
  94. directfbGlyphExtents (int nlist,
  95. GlyphListPtr list,
  96. GlyphPtr *glyphs,
  97. BoxPtr extents);
  98. static void
  99. RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
  100. PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
  101. int nlist, GlyphListPtr list, GlyphPtr *glyphs)
  102. {
  103. ScreenPtr pScreen = pDst->pDrawable->pScreen;
  104. PictureScreenPtr ps = GetPictureScreen(pScreen);
  105. WindowPtr dstWin;
  106. BoxRec box;
  107. dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
  108. (WindowPtr)pDst->pDrawable : NULL;
  109. //SCREEN_UNWRAP(ps, Glyphs);
  110. ps->Glyphs = SCREENREC(pScreen)->Glyphs;
  111. ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
  112. ps->Glyphs = RootlessGlyphs;
  113. //SCREEN_WRAP(ps, Glyphs);
  114. if (dstWin && IsFramedWindow(dstWin)) {
  115. directfbGlyphExtents(nlist, list, glyphs, &box);
  116. RootlessDamageRect(dstWin, box.x1, box.y1, box.x2-box.x1, box.y2-box.y1);
  117. }
  118. }
  119. static void
  120. RootlessRects(CARD8 op, PicturePtr pDst, xRenderColor *color, int nrect, xRectangle *rects)
  121. {
  122. ScreenPtr pScreen = pDst->pDrawable->pScreen;
  123. PictureScreenPtr ps = GetPictureScreen(pScreen);
  124. WindowPtr dstWin;
  125. dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
  126. (WindowPtr)pDst->pDrawable : NULL;
  127. ps->Composite = SCREENREC(pScreen)->Composite;
  128. ps->CompositeRects = SCREENREC(pScreen)->CompositeRects;
  129. ps->CompositeRects(op, pDst, color, nrect, rects);
  130. ps->CompositeRects = RootlessRects;
  131. ps->Composite = RootlessComposite;
  132. if (dstWin && IsFramedWindow(dstWin)) {
  133. while (nrect--) {
  134. RootlessDamageRect(dstWin, rects->x, rects->y,
  135. rects->width, rects->height);
  136. rects++;
  137. }
  138. }
  139. }
  140. #endif // RENDER
  141. // RootlessValidateTree
  142. // ValidateTree is modified in two ways:
  143. // * top-level windows don't clip each other
  144. // * windows aren't clipped against root.
  145. // These only matter when validating from the root.
  146. static int
  147. RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
  148. {
  149. int result;
  150. RegionRec saveRoot;
  151. ScreenPtr pScreen = pParent->drawable.pScreen;
  152. SCREEN_UNWRAP(pScreen, ValidateTree);
  153. RL_DEBUG_MSG("VALIDATETREE start ");
  154. // Use our custom version to validate from root
  155. if (IsRoot(pParent)) {
  156. RL_DEBUG_MSG("custom ");
  157. result = RootlessMiValidateTree(pParent, pChild, kind);
  158. }
  159. else {
  160. HUGE_ROOT(pParent);
  161. result = pScreen->ValidateTree(pParent, pChild, kind);
  162. NORMAL_ROOT(pParent);
  163. }
  164. SCREEN_WRAP(pScreen, ValidateTree);
  165. RL_DEBUG_MSG("VALIDATETREE end\n");
  166. return result;
  167. }
  168. // RootlessMarkOverlappedWindows
  169. // MarkOverlappedWindows is modified to ignore overlapping
  170. // top-level windows.
  171. static Bool
  172. RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst,
  173. WindowPtr *ppLayerWin)
  174. {
  175. RegionRec saveRoot;
  176. Bool result;
  177. ScreenPtr pScreen = pWin->drawable.pScreen;
  178. SCREEN_UNWRAP(pScreen, MarkOverlappedWindows);
  179. RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start ");
  180. HUGE_ROOT(pWin);
  181. if (IsRoot(pWin)) {
  182. // root - mark nothing
  183. RL_DEBUG_MSG("is root not marking ");
  184. result = FALSE;
  185. }
  186. else if (! IsTopLevel(pWin)) {
  187. // not top-level window - mark normally
  188. result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin);
  189. }
  190. else {
  191. //top-level window - mark children ONLY - NO overlaps with sibs (?)
  192. // This code copied from miMarkOverlappedWindows()
  193. register WindowPtr pChild;
  194. Bool anyMarked = FALSE;
  195. void (* MarkWindow)(WindowPtr) = pScreen->MarkWindow;
  196. RL_DEBUG_MSG("is top level! ");
  197. /* single layered systems are easy */
  198. if (ppLayerWin) *ppLayerWin = pWin;
  199. if (pWin == pFirst) {
  200. /* Blindly mark pWin and all of its inferiors. This is a slight
  201. * overkill if there are mapped windows that outside pWin's border,
  202. * but it's better than wasting time on RectIn checks.
  203. */
  204. pChild = pWin;
  205. while (1) {
  206. if (pChild->viewable) {
  207. if (REGION_BROKEN (pScreen, &pChild->winSize))
  208. SetWinSize (pChild);
  209. if (REGION_BROKEN (pScreen, &pChild->borderSize))
  210. SetBorderSize (pChild);
  211. (* MarkWindow)(pChild);
  212. if (pChild->firstChild) {
  213. pChild = pChild->firstChild;
  214. continue;
  215. }
  216. }
  217. while (!pChild->nextSib && (pChild != pWin))
  218. pChild = pChild->parent;
  219. if (pChild == pWin)
  220. break;
  221. pChild = pChild->nextSib;
  222. }
  223. anyMarked = TRUE;
  224. pFirst = pFirst->nextSib;
  225. }
  226. if (anyMarked)
  227. (* MarkWindow)(pWin->parent);
  228. result = anyMarked;
  229. }
  230. NORMAL_ROOT(pWin);
  231. SCREEN_WRAP(pScreen, MarkOverlappedWindows);
  232. RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n");
  233. return result;
  234. }
  235. // Flush drawing before blocking on select().
  236. static void
  237. RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask)
  238. {
  239. RootlessRedisplayScreen((ScreenPtr) pbdata);
  240. }
  241. static void
  242. RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask)
  243. {
  244. // nothing here
  245. }
  246. static Bool
  247. RootlessAllocatePrivates(ScreenPtr pScreen)
  248. {
  249. RootlessScreenRec *s;
  250. // no allocation needed for screen privates
  251. if (!dixRequestPrivate(rootlessGCPrivateKey, sizeof(RootlessGCRec)))
  252. return FALSE;
  253. s = xalloc(sizeof(RootlessScreenRec));
  254. if (! s) return FALSE;
  255. dixSetPrivate(&pScreen->devPrivates, rootlessScreenPrivateKey, s);
  256. return TRUE;
  257. }
  258. static void
  259. RootlessWrap(ScreenPtr pScreen)
  260. {
  261. RootlessScreenRec *s = (RootlessScreenRec*)
  262. dixLookupPrivate(&pScreen->devPrivates, rootlessScreenPrivateKey);
  263. #define WRAP(a) \
  264. if (pScreen->a) { \
  265. s->a = pScreen->a; \
  266. } else { \
  267. RL_DEBUG_MSG("null screen fn " #a "\n"); \
  268. s->a = NULL; \
  269. } \
  270. pScreen->a = Rootless##a
  271. WRAP(CloseScreen);
  272. WRAP(CreateGC);
  273. WRAP(CopyWindow);
  274. WRAP(GetImage);
  275. WRAP(CreateWindow);
  276. WRAP(DestroyWindow);
  277. WRAP(RealizeWindow);
  278. WRAP(UnrealizeWindow);
  279. WRAP(MoveWindow);
  280. WRAP(PositionWindow);
  281. WRAP(ResizeWindow);
  282. WRAP(RestackWindow);
  283. WRAP(ChangeBorderWidth);
  284. WRAP(MarkOverlappedWindows);
  285. WRAP(ValidateTree);
  286. WRAP(ChangeWindowAttributes);
  287. #ifdef SHAPE
  288. WRAP(SetShape);
  289. #endif
  290. #ifdef RENDER
  291. {
  292. // Composite and Glyphs don't use normal screen wrapping
  293. PictureScreenPtr ps = GetPictureScreen(pScreen);
  294. s->Composite = ps->Composite;
  295. ps->Composite = RootlessComposite;
  296. s->Glyphs = ps->Glyphs;
  297. ps->Glyphs = RootlessGlyphs;
  298. s->CompositeRects = ps->CompositeRects;
  299. ps->CompositeRects = RootlessRects;
  300. }
  301. #endif
  302. // WRAP(ClearToBackground); fixme put this back? useful for shaped wins?
  303. // WRAP(RestoreAreas); fixme put this back?
  304. #undef WRAP
  305. }
  306. /*
  307. * RootlessInit
  308. * Rootless wraps lots of stuff and needs a bunch of devPrivates.
  309. */
  310. Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcs *procs)
  311. {
  312. RootlessScreenRec *s;
  313. if (! RootlessAllocatePrivates(pScreen))
  314. return FALSE;
  315. s = (RootlessScreenRec*)
  316. dixLookupPrivate(&pScreen->devPrivates, rootlessScreenPrivateKey);
  317. s->pScreen = pScreen;
  318. s->frameProcs = *procs;
  319. RootlessWrap(pScreen);
  320. if (!RegisterBlockAndWakeupHandlers (RootlessBlockHandler,
  321. RootlessWakeupHandler,
  322. (pointer) pScreen)) {
  323. return FALSE;
  324. }
  325. return TRUE;
  326. }