1 /* $XFree86: xc/programs/Xserver/GL/dri/dri.c,v 1.34 2001/12/10 19:07:19 dawes Exp $ */
2 /**************************************************************************
4 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5 Copyright 2000 VA Linux Systems, Inc.
6 Copyright (c) 2002 Apple Computer, Inc.
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
33 * Jens Owen <jens@valinux.com>
34 * Rickard E. (Rik) Faith <faith@valinux.com>
40 #include "xf86_ansic.h"
51 #include "dixstruct.h"
52 #include "extnsionst.h"
53 #include "colormapst.h"
54 #include "cursorstr.h"
55 #include "scrnintstr.h"
56 #include "windowstr.h"
58 #define _APPLEDRI_SERVER_
59 #include "appledristr.h"
61 #include "dri-surface.h"
62 #include "dristruct.h"
64 #include "mipointer.h"
65 #include "rootless-common.h"
69 #include <AvailabilityMacros.h>
71 static int DRIScreenPrivIndex = -1;
72 static int DRIWindowPrivIndex = -1;
73 static int DRIPixmapPrivIndex = -1;
74 static unsigned long DRIGeneration = 0;
76 static RESTYPE DRIDrawablePrivResType;
78 static x_hash_table *surface_hash; /* maps surface ids -> drawablePrivs */
81 DRIScreenInit(ScreenPtr pScreen)
83 DRIScreenPrivPtr pDRIPriv;
86 if (DRIGeneration != serverGeneration) {
87 if ((DRIScreenPrivIndex = AllocateScreenPrivateIndex()) < 0)
89 DRIGeneration = serverGeneration;
92 pDRIPriv = (DRIScreenPrivPtr) xcalloc(1, sizeof(DRIScreenPrivRec));
94 pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
98 pScreen->devPrivates[DRIScreenPrivIndex].ptr = (pointer) pDRIPriv;
99 pDRIPriv->directRenderingSupport = TRUE;
100 pDRIPriv->nrWindows = 0;
102 /* Initialize drawable tables */
103 for( i=0; i < DRI_MAX_DRAWABLES; i++) {
104 pDRIPriv->DRIDrawables[i] = NULL;
111 DRIFinishScreenInit(ScreenPtr pScreen)
113 DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
115 /* Wrap DRI support */
116 pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
117 pScreen->ValidateTree = DRIValidateTree;
119 pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
120 pScreen->PostValidateTree = DRIPostValidateTree;
122 pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
123 pScreen->WindowExposures = DRIWindowExposures;
125 pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
126 pScreen->CopyWindow = DRICopyWindow;
128 pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
129 pScreen->ClipNotify = DRIClipNotify;
131 ErrorF("[DRI] screen %d installation complete\n", pScreen->myNum);
137 DRICloseScreen(ScreenPtr pScreen)
139 DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
141 if (pDRIPriv && pDRIPriv->directRenderingSupport) {
143 pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
148 DRIExtensionInit(void)
153 if (DRIScreenPrivIndex < 0) {
157 /* Allocate a window private index with a zero sized private area for
158 * each window, then should a window become a DRI window, we'll hang
159 * a DRIWindowPrivateRec off of this private index.
161 if ((DRIWindowPrivIndex = AllocateWindowPrivateIndex()) < 0)
163 if ((DRIPixmapPrivIndex = AllocatePixmapPrivateIndex()) < 0)
166 DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete);
168 for (i = 0; i < screenInfo.numScreens; i++)
170 pScreen = screenInfo.screens[i];
171 if (!AllocateWindowPrivate(pScreen, DRIWindowPrivIndex, 0))
173 if (!AllocatePixmapPrivate(pScreen, DRIPixmapPrivIndex, 0))
184 * This stub routine is called when the X Server recycles, resources
185 * allocated by DRIExtensionInit need to be managed here.
187 * Currently this routine is a stub because all the interesting resources
188 * are managed via the screen init process.
193 DRIQueryDirectRenderingCapable(ScreenPtr pScreen, Bool* isCapable)
195 DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
198 *isCapable = pDRIPriv->directRenderingSupport;
206 DRIAuthConnection(ScreenPtr pScreen, unsigned int magic)
209 /* FIXME: something? */
211 DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
213 if (drmAuthMagic(pDRIPriv->drmFD, magic)) return FALSE;
219 DRIUpdateSurface (DRIDrawablePrivPtr pDRIDrawablePriv, DrawablePtr pDraw)
222 xp_window_changes wc;
223 unsigned int flags = 0;
225 if (pDRIDrawablePriv->sid == 0)
228 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
229 wc.depth = (pDraw->bitsPerPixel == 32 ? XP_DEPTH_ARGB8888
230 : pDraw->bitsPerPixel == 16 ? XP_DEPTH_RGB555 : XP_DEPTH_NIL);
231 if (wc.depth != XP_DEPTH_NIL)
235 if (pDraw->type == DRAWABLE_WINDOW) {
236 WindowPtr pWin = (WindowPtr) pDraw;
238 DRIStopDrawing (&pWin->drawable, FALSE);
240 pTopWin = TopLevelParent (pWin);
242 wc.x = pWin->drawable.x - (pTopWin->drawable.x - pTopWin->borderWidth);
243 wc.y = pWin->drawable.y - (pTopWin->drawable.y - pTopWin->borderWidth);
244 wc.width = pWin->drawable.width;
245 wc.height = pWin->drawable.height;
246 wc.bit_gravity = XP_GRAVITY_NONE;
248 wc.shape_nrects = REGION_NUM_RECTS (&pWin->clipList);
249 wc.shape_rects = REGION_RECTS (&pWin->clipList);
250 wc.shape_tx = - (pTopWin->drawable.x - pTopWin->borderWidth);
251 wc.shape_ty = - (pTopWin->drawable.y - pTopWin->borderWidth);
253 flags |= XP_BOUNDS | XP_SHAPE;
255 pDRIDrawablePriv->x = pWin->drawable.x - pTopWin->borderWidth;
256 pDRIDrawablePriv->y = pWin->drawable.y - pTopWin->borderWidth;
258 } else if (pDraw->type == DRAWABLE_PIXMAP) {
261 wc.width = pDraw->width;
262 wc.height = pDraw->height;
263 wc.bit_gravity = XP_GRAVITY_NONE;
267 xp_configure_surface (pDRIDrawablePriv->sid, flags, &wc);
271 DRICreateSurface (ScreenPtr pScreen, Drawable id,
272 DrawablePtr pDrawable, xp_client_id client_id,
273 xp_surface_id *surface_id, unsigned int ret_key[2],
274 void (*notify) (void *arg, void *data), void *notify_data)
276 DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
277 DRIDrawablePrivPtr pDRIDrawablePriv;
280 xp_window_id wid = 0;
282 if (pDrawable->type == DRAWABLE_WINDOW) {
283 pWin = (WindowPtr)pDrawable;
284 pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
285 if (pDRIDrawablePriv == NULL) {
288 xp_window_changes wc;
290 pTopWin = TopLevelParent (pWin);
292 /* allocate a DRI Window Private record */
293 if (!(pDRIDrawablePriv = xcalloc(1, sizeof(DRIDrawablePrivRec)))) {
297 pDRIDrawablePriv->pDraw = pDrawable;
298 pDRIDrawablePriv->pScreen = pScreen;
299 pDRIDrawablePriv->refCount = 0;
300 pDRIDrawablePriv->drawableIndex = -1;
301 pDRIDrawablePriv->notifiers = NULL;
303 /* find the physical window */
304 wid = RootlessGetPhysicalWindow (pTopWin, TRUE);
306 xfree (pDRIDrawablePriv);
310 /* allocate the physical surface */
311 err = xp_create_surface (wid, &pDRIDrawablePriv->sid);
312 if (err != Success) {
313 xfree (pDRIDrawablePriv);
317 /* Make it visible */
318 wc.stack_mode = XP_MAPPED_ABOVE;
320 err = xp_configure_surface (pDRIDrawablePriv->sid,
324 xp_destroy_surface (pDRIDrawablePriv->sid);
325 xfree (pDRIDrawablePriv);
329 /* save private off of preallocated index */
330 pWin->devPrivates[DRIWindowPrivIndex].ptr = (pointer)pDRIDrawablePriv;
333 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
334 else if (pDrawable->type == DRAWABLE_PIXMAP) {
335 pPix = (PixmapPtr)pDrawable;
336 pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
337 if (pDRIDrawablePriv == NULL) {
340 /* allocate a DRI Window Private record */
341 if (!(pDRIDrawablePriv = xcalloc(1, sizeof(DRIDrawablePrivRec)))) {
345 pDRIDrawablePriv->pDraw = pDrawable;
346 pDRIDrawablePriv->pScreen = pScreen;
347 pDRIDrawablePriv->refCount = 0;
348 pDRIDrawablePriv->drawableIndex = -1;
349 pDRIDrawablePriv->notifiers = NULL;
351 /* Passing a null window id to Xplugin in 10.3+ asks for
352 an accelerated offscreen surface. */
354 err = xp_create_surface (0, &pDRIDrawablePriv->sid);
355 if (err != Success) {
356 xfree (pDRIDrawablePriv);
360 /* save private off of preallocated index */
361 pPix->devPrivates[DRIPixmapPrivIndex].ptr = (pointer)pDRIDrawablePriv;
365 else { /* for GLX 1.3, a PBuffer */
370 /* Finish initialization of new surfaces */
371 if (pDRIDrawablePriv->refCount == 0) {
372 unsigned int key[2] = {0};
375 /* try to give the client access to the surface
376 FIXME: how to export pixmaps? */
377 if (client_id != 0 && wid != 0)
379 err = xp_export_surface (wid, pDRIDrawablePriv->sid,
381 if (err != Success) {
382 xp_destroy_surface (pDRIDrawablePriv->sid);
383 xfree (pDRIDrawablePriv);
388 pDRIDrawablePriv->key[0] = key[0];
389 pDRIDrawablePriv->key[1] = key[1];
391 ++pDRIPriv->nrWindows;
393 /* and stash it by surface id */
394 if (surface_hash == NULL)
395 surface_hash = x_hash_table_new (NULL, NULL, NULL, NULL);
396 x_hash_table_insert (surface_hash,
397 (void *) pDRIDrawablePriv->sid, pDRIDrawablePriv);
399 /* track this in case this window is destroyed */
400 AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable);
402 /* Initialize shape */
403 DRIUpdateSurface (pDRIDrawablePriv, pDrawable);
406 pDRIDrawablePriv->refCount++;
408 *surface_id = pDRIDrawablePriv->sid;
410 if (ret_key != NULL) {
411 ret_key[0] = pDRIDrawablePriv->key[0];
412 ret_key[1] = pDRIDrawablePriv->key[1];
415 if (notify != NULL) {
416 pDRIDrawablePriv->notifiers = x_hook_add (pDRIDrawablePriv->notifiers,
417 notify, notify_data);
424 DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
425 void (*notify) (void *, void *), void *notify_data)
427 DRIDrawablePrivPtr pDRIDrawablePriv;
429 if (pDrawable->type == DRAWABLE_WINDOW) {
430 pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW((WindowPtr)pDrawable);
431 } else if (pDrawable->type == DRAWABLE_PIXMAP) {
432 pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP((PixmapPtr)pDrawable);
437 if (pDRIDrawablePriv != NULL) {
438 if (notify != NULL) {
439 pDRIDrawablePriv->notifiers = x_hook_remove (pDRIDrawablePriv->notifiers,
440 notify, notify_data);
442 if (--pDRIDrawablePriv->refCount <= 0) {
443 /* This calls back to DRIDrawablePrivDelete
444 which frees the private area */
445 FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
453 DRIDrawablePrivDelete(pointer pResource, XID id)
455 DrawablePtr pDrawable = (DrawablePtr)pResource;
456 DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen);
457 DRIDrawablePrivPtr pDRIDrawablePriv = NULL;
458 WindowPtr pWin = NULL;
459 PixmapPtr pPix = NULL;
461 if (pDrawable->type == DRAWABLE_WINDOW) {
462 pWin = (WindowPtr)pDrawable;
463 pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
464 DRIStopDrawing (pDrawable, FALSE);
465 pDRIPriv->drawing = x_list_remove (pDRIPriv->drawing,
467 } else if (pDrawable->type == DRAWABLE_PIXMAP) {
468 pPix = (PixmapPtr)pDrawable;
469 pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
472 if (pDRIDrawablePriv == NULL)
475 if (pDRIDrawablePriv->drawableIndex != -1) {
476 /* release drawable table entry */
477 pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
480 if (pDRIDrawablePriv->sid != 0) {
481 xp_destroy_surface (pDRIDrawablePriv->sid);
482 x_hash_table_remove (surface_hash, (void *) pDRIDrawablePriv->sid);
485 if (pDRIDrawablePriv->notifiers != NULL)
486 x_hook_free (pDRIDrawablePriv->notifiers);
488 xfree(pDRIDrawablePriv);
490 if (pDrawable->type == DRAWABLE_WINDOW) {
491 pWin->devPrivates[DRIWindowPrivIndex].ptr = NULL;
492 } else if (pDrawable->type == DRAWABLE_PIXMAP) {
493 pPix->devPrivates[DRIPixmapPrivIndex].ptr = NULL;
496 --pDRIPriv->nrWindows;
502 DRIWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr bsreg)
504 ScreenPtr pScreen = pWin->drawable.pScreen;
505 DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
506 DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
508 if(pDRIDrawablePriv) {
509 /* FIXME: something? */
512 pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
514 (*pScreen->WindowExposures)(pWin, prgn, bsreg);
516 pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
517 pScreen->WindowExposures = DRIWindowExposures;
522 DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
524 ScreenPtr pScreen = pWin->drawable.pScreen;
525 DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
526 DRIDrawablePrivPtr pDRIDrawablePriv;
528 if(pDRIPriv->nrWindows > 0) {
529 pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW (pWin);
530 if (pDRIDrawablePriv != NULL) {
531 DRIUpdateSurface (pDRIDrawablePriv, &pWin->drawable);
536 pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
538 /* call lower layers */
539 (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
542 pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
543 pScreen->CopyWindow = DRICopyWindow;
547 DRIValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
549 ScreenPtr pScreen = pParent->drawable.pScreen;
550 DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
554 pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
556 /* call lower layers */
557 returnValue = (*pScreen->ValidateTree)(pParent, pChild, kind);
560 pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
561 pScreen->ValidateTree = DRIValidateTree;
567 DRIPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
570 DRIScreenPrivPtr pDRIPriv;
573 pScreen = pParent->drawable.pScreen;
575 pScreen = pChild->drawable.pScreen;
577 pDRIPriv = DRI_SCREEN_PRIV(pScreen);
579 if (pDRIPriv->wrap.PostValidateTree) {
581 pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
583 /* call lower layers */
584 (*pScreen->PostValidateTree)(pParent, pChild, kind);
587 pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
588 pScreen->PostValidateTree = DRIPostValidateTree;
593 DRIClipNotify(WindowPtr pWin, int dx, int dy)
595 ScreenPtr pScreen = pWin->drawable.pScreen;
596 DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
597 DRIDrawablePrivPtr pDRIDrawablePriv;
599 if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
600 DRIUpdateSurface (pDRIDrawablePriv, &pWin->drawable);
603 if(pDRIPriv->wrap.ClipNotify) {
604 pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
606 (*pScreen->ClipNotify)(pWin, dx, dy);
608 pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
609 pScreen->ClipNotify = DRIClipNotify;
613 /* This lets get at the unwrapped functions so that they can correctly
614 * call the lowerlevel functions, and choose whether they will be
615 * called at every level of recursion (eg in validatetree).
618 DRIGetWrappedFuncs(ScreenPtr pScreen)
620 return &(DRI_SCREEN_PRIV(pScreen)->wrap);
624 DRIQueryVersion(int *majorVersion,
628 *majorVersion = APPLE_DRI_MAJOR_VERSION;
629 *minorVersion = APPLE_DRI_MINOR_VERSION;
630 *patchVersion = APPLE_DRI_PATCH_VERSION;
634 DRISurfaceNotify (xp_surface_id id, int kind)
636 DRIDrawablePrivPtr pDRIDrawablePriv = NULL;
637 DRISurfaceNotifyArg arg;
642 if (surface_hash != NULL)
644 pDRIDrawablePriv = x_hash_table_lookup (surface_hash,
648 if (pDRIDrawablePriv == NULL)
651 if (kind == AppleDRISurfaceNotifyDestroyed)
653 pDRIDrawablePriv->sid = 0;
654 x_hash_table_remove (surface_hash, (void *) id);
657 x_hook_run (pDRIDrawablePriv->notifiers, &arg);
659 if (kind == AppleDRISurfaceNotifyDestroyed)
661 /* Kill off the handle. */
663 FreeResourceByType (pDRIDrawablePriv->pDraw->id,
664 DRIDrawablePrivResType, FALSE);
669 /* Experimental support for X drawing directly into VRAM surfaces. */
672 DRIStartDrawing (DrawablePtr pDraw)
674 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
677 DRIDrawablePrivPtr priv = NULL;
678 DRIScreenPrivPtr pDRIPriv;
680 if (pDraw->type == DRAWABLE_WINDOW)
681 priv = DRI_DRAWABLE_PRIV_FROM_WINDOW ((WindowPtr)pDraw);
683 /* FIXME: support pixmaps */
684 else if (pDraw->type == DRAWABLE_PIXMAP)
685 priv = DRI_DRAWABLE_PRIV_FROM_PIXMAP ((PixmapPtr)pDraw);
691 pDRIPriv = DRI_SCREEN_PRIV(priv->pScreen);
693 if (!priv->is_drawing)
698 err = xp_lock_window (priv->sid, NULL, NULL,
699 &priv->data, &priv->rowbytes, &r);
703 if (pDraw->type == DRAWABLE_WINDOW)
705 WindowPtr pWin = (WindowPtr) pDraw;
706 int bw = wBorderWidth (pWin);
709 GetScratchPixmapHeader(pWin->drawable.pScreen, r.x2 - r.x1,
710 r.y2 - r.y1, pWin->drawable.depth,
711 pWin->drawable.bitsPerPixel,
712 priv->rowbytes, priv->data);
713 TranslatePixmapBase (priv->pixmap,
714 - (pWin->drawable.x - bw),
715 - (pWin->drawable.y - bw));
718 priv->is_drawing = TRUE;
719 pDRIPriv->drawing = x_list_prepend (pDRIPriv->drawing, priv);
722 if (pDraw->type == DRAWABLE_WINDOW)
724 WindowPtr pWin = (WindowPtr) pDraw;
726 priv->oldPixmap = pWin->drawable.pScreen->GetWindowPixmap (pWin);
727 pWin->drawable.pScreen->SetWindowPixmap (pWin, priv->pixmap);
735 DRIStopDrawing (DrawablePtr pDraw, Bool flush)
737 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
740 DRIDrawablePrivPtr priv = NULL;
742 DRIScreenPrivPtr pDRIPriv;
744 if (pDraw->type == DRAWABLE_WINDOW)
745 priv = DRI_DRAWABLE_PRIV_FROM_WINDOW ((WindowPtr)pDraw);
746 else if (pDraw->type == DRAWABLE_PIXMAP)
747 priv = DRI_DRAWABLE_PRIV_FROM_PIXMAP ((PixmapPtr)pDraw);
752 pScreen = priv->pScreen;
753 pDRIPriv = DRI_SCREEN_PRIV(pScreen);
755 if (priv->is_drawing)
757 xp_unlock_window (priv->sid, flush);
759 if (pDraw->type == DRAWABLE_WINDOW)
761 FreeScratchPixmapHeader (priv->pixmap);
762 pScreen->SetWindowPixmap ((WindowPtr)pDraw, priv->oldPixmap);
767 /* If we didn't flush don't forget that we still need to.. */
769 pDRIPriv->drawing = x_list_remove (pDRIPriv->drawing, priv);
771 priv->is_drawing = FALSE;
775 xp_flush_window (priv->sid);
782 /* true iff two Boxes overlap */
783 #define EXTENTCHECK(r1,r2) \
784 (!( ((r1)->x2 <= (r2)->x1) || \
785 ((r1)->x1 >= (r2)->x2) || \
786 ((r1)->y2 <= (r2)->y1) || \
787 ((r1)->y1 >= (r2)->y2) ) )
790 DRIDamageRegion (DrawablePtr pDraw, RegionPtr pRegion)
792 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
795 DRIDrawablePrivPtr priv = NULL;
799 if (pDraw->type == DRAWABLE_WINDOW)
800 priv = DRI_DRAWABLE_PRIV_FROM_WINDOW ((WindowPtr)pDraw);
805 /* adapted from RootlessDamageRegion () */
807 if (pDraw->type == DRAWABLE_WINDOW)
809 WindowPtr pWin = (WindowPtr) pDraw;
811 b1 = REGION_EXTENTS (pWin->drawable.pScreen, &pWin->borderClip);
812 b2 = REGION_EXTENTS (pWin->drawable.pScreen, pRegion);
814 if (EXTENTCHECK (b1, b2))
816 /* Regions may overlap. */
818 if (REGION_NUM_RECTS (pRegion) == 1)
822 /* Damaged region only has a single rect, so we can
823 just compare that against the region */
825 in = RECT_IN_REGION (pWin->drawable.pScreen, &pWin->borderClip,
826 REGION_RECTS (pRegion));
829 /* clip totally contains pRegion */
831 xp_mark_window (priv->sid, REGION_NUM_RECTS (pRegion),
832 REGION_RECTS (pRegion),
835 RootlessQueueRedisplay (pWin->drawable.pScreen);
838 else if (in == rgnOUT)
840 /* clip doesn't contain pRegion */
846 /* clip overlaps pRegion, need to intersect */
848 REGION_INIT (pWin->drawable.pScreen, &clipped, NullBox, 0);
849 REGION_INTERSECT (pWin->drawable.pScreen, &clipped,
850 &pWin->borderClip, pRegion);
852 xp_mark_window (priv->sid, REGION_NUM_RECTS (&clipped),
853 REGION_RECTS (&clipped), -priv->x, -priv->y);
855 REGION_UNINIT (pWin->drawable.pScreen, &clipped);
857 RootlessQueueRedisplay (pWin->drawable.pScreen);
867 DRISynchronizeDrawable (DrawablePtr pDraw, Bool flush)
869 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
871 DRIScreenPrivPtr pDRIPriv;
872 DRIDrawablePrivPtr priv;
875 pScreen = pDraw->pScreen;
876 pDRIPriv = DRI_SCREEN_PRIV(pScreen);
878 if (pDRIPriv == NULL || pDRIPriv->drawing == NULL)
881 if (pDraw->type == DRAWABLE_WINDOW)
883 WindowPtr pWin = TopLevelParent ((WindowPtr) pDraw);
885 /* need to find _any_ window under pWin that is drawing. Scan the
886 list looking for candidates. */
888 copy = x_list_copy (pDRIPriv->drawing);
890 for (node = copy; node != NULL; node = node->next)
894 if (priv->pDraw->type == DRAWABLE_WINDOW
895 && TopLevelParent ((WindowPtr) priv->pDraw) == pWin)
897 DRIStopDrawing (priv->pDraw, flush);
905 DRIStopDrawing (pDraw, flush);
911 DRISynchronize (Bool flush)
913 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
916 DRIScreenPrivPtr pDRIPriv;
917 DRIDrawablePrivPtr priv;
920 for (i = 0; i < screenInfo.numScreens; i++)
922 pScreen = screenInfo.screens[i];
923 pDRIPriv = DRI_SCREEN_PRIV(pScreen);
925 if (pDRIPriv == NULL || pDRIPriv->drawing == NULL)
928 copy = x_list_copy (pDRIPriv->drawing);
930 for (node = copy; node != NULL; node = node->next)
934 DRIStopDrawing (priv->pDraw, flush);