1 /**************************************************************************
3 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4 Copyright 2000 VA Linux Systems, Inc.
5 Copyright (c) 2002 Apple Computer, Inc.
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sub license, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial portions
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
24 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Jens Owen <jens@valinux.com>
33 * Rickard E. (Rik) Faith <faith@valinux.com>
36 #ifdef HAVE_XORG_CONFIG_H
37 #include <xorg-config.h>
46 #include <X11/Xproto.h>
48 #include "dixstruct.h"
49 #include "extnsionst.h"
50 #include "colormapst.h"
51 #include "cursorstr.h"
52 #include "scrnintstr.h"
53 #include "windowstr.h"
55 #define _APPLEDRI_SERVER_
56 #include "appledristr.h"
59 #include "dristruct.h"
61 #include "mipointer.h"
66 #include <AvailabilityMacros.h>
68 static int DRIScreenPrivIndex
= -1;
69 static int DRIWindowPrivIndex
= -1;
70 static int DRIPixmapPrivIndex
= -1;
72 static RESTYPE DRIDrawablePrivResType
;
74 static x_hash_table
*surface_hash
; /* maps surface ids -> drawablePrivs */
76 /* FIXME: don't hardcode this? */
77 #define CG_INFO_FILE "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Resources/Info-macos.plist"
79 /* Corresponds to SU Jaguar Green */
80 #define CG_REQUIRED_MAJOR 1
81 #define CG_REQUIRED_MINOR 157
82 #define CG_REQUIRED_MICRO 11
84 /* Returns version as major.minor.micro in 10.10.10 fixed form */
88 static unsigned int version
;
96 /* I tried CFBundleGetVersion, but it returns zero, so.. */
98 fh
= fopen (CG_INFO_FILE
, "r");
103 while (fgets (buf
, sizeof (buf
), fh
) != NULL
)
107 if (!strstr (buf
, "<key>CFBundleShortVersionString</key>")
108 || fgets (buf
, sizeof (buf
), fh
) == NULL
)
113 ptr
= strstr (buf
, "<string>");
117 ptr
+= strlen ("<string>");
119 /* Now PTR points to "MAJOR.MINOR.MICRO". */
124 switch ((c
= *ptr
++))
127 version
= version
* 1024;
130 case '0': case '1': case '2': case '3': case '4':
131 case '5': case '6': case '7': case '8': case '9':
132 version
= ((version
& ~0x3ff)
133 + (version
& 0x3ff) * 10 + (c
- '0'));
146 test_cg_version (unsigned int major
, unsigned int minor
, unsigned int micro
)
148 unsigned int cg_ver
= get_cg_version ();
150 unsigned int cg_major
= (cg_ver
>> 20) & 0x3ff;
151 unsigned int cg_minor
= (cg_ver
>> 10) & 0x3ff;
152 unsigned int cg_micro
= cg_ver
& 0x3ff;
154 if (cg_major
> major
)
156 else if (cg_major
< major
)
159 /* cg_major == major */
161 if (cg_minor
> minor
)
163 else if (cg_minor
< minor
)
166 /* cg_minor == minor */
168 if (cg_micro
< micro
)
175 DRIScreenInit(ScreenPtr pScreen
)
177 DRIScreenPrivPtr pDRIPriv
;
180 pDRIPriv
= (DRIScreenPrivPtr
) xcalloc(1, sizeof(DRIScreenPrivRec
));
182 pScreen
->devPrivates
[DRIScreenPrivIndex
].ptr
= NULL
;
186 pScreen
->devPrivates
[DRIScreenPrivIndex
].ptr
= (pointer
) pDRIPriv
;
187 pDRIPriv
->directRenderingSupport
= TRUE
;
188 pDRIPriv
->nrWindows
= 0;
190 /* Need recent cg for window access update */
191 if (!test_cg_version (CG_REQUIRED_MAJOR
,
195 ErrorF ("[DRI] disabled direct rendering; requires CoreGraphics %d.%d.%d\n",
196 CG_REQUIRED_MAJOR
, CG_REQUIRED_MINOR
, CG_REQUIRED_MICRO
);
198 pDRIPriv
->directRenderingSupport
= FALSE
;
200 /* Note we don't nuke the dri private, since we need it for
201 managing indirect surfaces. */
204 /* Initialize drawable tables */
205 for (i
= 0; i
< DRI_MAX_DRAWABLES
; i
++) {
206 pDRIPriv
->DRIDrawables
[i
] = NULL
;
213 DRIFinishScreenInit(ScreenPtr pScreen
)
215 DRIScreenPrivPtr pDRIPriv
= DRI_SCREEN_PRIV(pScreen
);
217 /* Allocate zero sized private area for each window. Should a window
218 * become a DRI window, we'll hang a DRIWindowPrivateRec off of this
221 if (!AllocateWindowPrivate(pScreen
, DRIWindowPrivIndex
, 0))
224 /* Wrap DRI support */
225 pDRIPriv
->wrap
.ValidateTree
= pScreen
->ValidateTree
;
226 pScreen
->ValidateTree
= DRIValidateTree
;
228 pDRIPriv
->wrap
.PostValidateTree
= pScreen
->PostValidateTree
;
229 pScreen
->PostValidateTree
= DRIPostValidateTree
;
231 pDRIPriv
->wrap
.WindowExposures
= pScreen
->WindowExposures
;
232 pScreen
->WindowExposures
= DRIWindowExposures
;
234 pDRIPriv
->wrap
.CopyWindow
= pScreen
->CopyWindow
;
235 pScreen
->CopyWindow
= DRICopyWindow
;
237 pDRIPriv
->wrap
.ClipNotify
= pScreen
->ClipNotify
;
238 pScreen
->ClipNotify
= DRIClipNotify
;
240 ErrorF("[DRI] screen %d installation complete\n", pScreen
->myNum
);
246 DRICloseScreen(ScreenPtr pScreen
)
248 DRIScreenPrivPtr pDRIPriv
= DRI_SCREEN_PRIV(pScreen
);
250 if (pDRIPriv
&& pDRIPriv
->directRenderingSupport
) {
252 pScreen
->devPrivates
[DRIScreenPrivIndex
].ptr
= NULL
;
257 DRIExtensionInit(void)
259 static unsigned long DRIGeneration
= 0;
261 if (DRIGeneration
!= serverGeneration
) {
262 if ((DRIScreenPrivIndex
= AllocateScreenPrivateIndex()) < 0)
264 DRIGeneration
= serverGeneration
;
268 * Allocate a window private index with a zero sized private area for
269 * each window, then should a window become a DRI window, we'll hang
270 * a DRIWindowPrivateRec off of this private index. Do same for pixmaps.
272 if ((DRIWindowPrivIndex
= AllocateWindowPrivateIndex()) < 0)
274 if ((DRIPixmapPrivIndex
= AllocatePixmapPrivateIndex()) < 0)
277 DRIDrawablePrivResType
= CreateNewResourceType(DRIDrawablePrivDelete
);
286 * This stub routine is called when the X Server recycles, resources
287 * allocated by DRIExtensionInit need to be managed here.
289 * Currently this routine is a stub because all the interesting resources
290 * are managed via the screen init process.
295 DRIQueryDirectRenderingCapable(ScreenPtr pScreen
, Bool
* isCapable
)
297 DRIScreenPrivPtr pDRIPriv
= DRI_SCREEN_PRIV(pScreen
);
300 *isCapable
= pDRIPriv
->directRenderingSupport
;
308 DRIAuthConnection(ScreenPtr pScreen
, unsigned int magic
)
311 /* FIXME: something? */
313 DRIScreenPrivPtr pDRIPriv
= DRI_SCREEN_PRIV(pScreen
);
315 if (drmAuthMagic(pDRIPriv
->drmFD
, magic
)) return FALSE
;
321 DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv
, DrawablePtr pDraw
)
323 xp_window_changes wc
;
324 unsigned int flags
= 0;
326 if (pDRIDrawablePriv
->sid
== 0)
329 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
330 wc
.depth
= (pDraw
->bitsPerPixel
== 32 ? XP_DEPTH_ARGB8888
331 : pDraw
->bitsPerPixel
== 16 ? XP_DEPTH_RGB555
: XP_DEPTH_NIL
);
332 if (wc
.depth
!= XP_DEPTH_NIL
)
336 if (pDraw
->type
== DRAWABLE_WINDOW
) {
337 WindowPtr pWin
= (WindowPtr
) pDraw
;
338 WindowPtr pTopWin
= TopLevelParent(pWin
);
340 wc
.x
= pWin
->drawable
.x
- (pTopWin
->drawable
.x
- pTopWin
->borderWidth
);
341 wc
.y
= pWin
->drawable
.y
- (pTopWin
->drawable
.y
- pTopWin
->borderWidth
);
342 wc
.width
= pWin
->drawable
.width
+ 2 * pWin
->borderWidth
;
343 wc
.height
= pWin
->drawable
.height
+ 2 * pWin
->borderWidth
;
344 wc
.bit_gravity
= XP_GRAVITY_NONE
;
346 wc
.shape_nrects
= REGION_NUM_RECTS(&pWin
->clipList
);
347 wc
.shape_rects
= REGION_RECTS(&pWin
->clipList
);
348 wc
.shape_tx
= - (pTopWin
->drawable
.x
- pTopWin
->borderWidth
);
349 wc
.shape_ty
= - (pTopWin
->drawable
.y
- pTopWin
->borderWidth
);
351 flags
|= XP_BOUNDS
| XP_SHAPE
;
353 } else if (pDraw
->type
== DRAWABLE_PIXMAP
) {
356 wc
.width
= pDraw
->width
;
357 wc
.height
= pDraw
->height
;
358 wc
.bit_gravity
= XP_GRAVITY_NONE
;
362 xp_configure_surface(pDRIDrawablePriv
->sid
, flags
, &wc
);
366 DRICreateSurface(ScreenPtr pScreen
, Drawable id
,
367 DrawablePtr pDrawable
, xp_client_id client_id
,
368 xp_surface_id
*surface_id
, unsigned int ret_key
[2],
369 void (*notify
) (void *arg
, void *data
), void *notify_data
)
371 DRIScreenPrivPtr pDRIPriv
= DRI_SCREEN_PRIV(pScreen
);
372 DRIDrawablePrivPtr pDRIDrawablePriv
;
373 xp_window_id wid
= 0;
375 if (pDrawable
->type
== DRAWABLE_WINDOW
) {
376 WindowPtr pWin
= (WindowPtr
)pDrawable
;
378 pDRIDrawablePriv
= DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin
);
379 if (pDRIDrawablePriv
== NULL
) {
381 xp_window_changes wc
;
383 /* allocate a DRI Window Private record */
384 if (!(pDRIDrawablePriv
= xalloc(sizeof(DRIDrawablePrivRec
)))) {
388 pDRIDrawablePriv
->pDraw
= pDrawable
;
389 pDRIDrawablePriv
->pScreen
= pScreen
;
390 pDRIDrawablePriv
->refCount
= 0;
391 pDRIDrawablePriv
->drawableIndex
= -1;
392 pDRIDrawablePriv
->notifiers
= NULL
;
394 /* find the physical window */
395 wid
= (xp_window_id
) RootlessFrameForWindow(pWin
, TRUE
);
397 xfree(pDRIDrawablePriv
);
401 /* allocate the physical surface */
402 err
= xp_create_surface(wid
, &pDRIDrawablePriv
->sid
);
403 if (err
!= Success
) {
404 xfree(pDRIDrawablePriv
);
408 /* Make it visible */
409 wc
.stack_mode
= XP_MAPPED_ABOVE
;
411 err
= xp_configure_surface(pDRIDrawablePriv
->sid
, XP_STACKING
, &wc
);
414 xp_destroy_surface(pDRIDrawablePriv
->sid
);
415 xfree(pDRIDrawablePriv
);
419 /* save private off of preallocated index */
420 pWin
->devPrivates
[DRIWindowPrivIndex
].ptr
= (pointer
)pDRIDrawablePriv
;
424 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
425 else if (pDrawable
->type
== DRAWABLE_PIXMAP
) {
426 PixmapPtr pPix
= (PixmapPtr
)pDrawable
;
428 pDRIDrawablePriv
= DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix
);
429 if (pDRIDrawablePriv
== NULL
) {
432 /* allocate a DRI Window Private record */
433 if (!(pDRIDrawablePriv
= xcalloc(1, sizeof(DRIDrawablePrivRec
)))) {
437 pDRIDrawablePriv
->pDraw
= pDrawable
;
438 pDRIDrawablePriv
->pScreen
= pScreen
;
439 pDRIDrawablePriv
->refCount
= 0;
440 pDRIDrawablePriv
->drawableIndex
= -1;
441 pDRIDrawablePriv
->notifiers
= NULL
;
443 /* Passing a null window id to Xplugin in 10.3+ asks for
444 an accelerated offscreen surface. */
446 err
= xp_create_surface(0, &pDRIDrawablePriv
->sid
);
447 if (err
!= Success
) {
448 xfree(pDRIDrawablePriv
);
452 /* save private off of preallocated index */
453 pPix
->devPrivates
[DRIPixmapPrivIndex
].ptr
= (pointer
)pDRIDrawablePriv
;
458 else { /* for GLX 1.3, a PBuffer */
463 /* Finish initialization of new surfaces */
464 if (pDRIDrawablePriv
->refCount
== 0) {
465 unsigned int key
[2] = {0};
468 /* try to give the client access to the surface */
469 if (client_id
!= 0 && wid
!= 0)
471 err
= xp_export_surface(wid
, pDRIDrawablePriv
->sid
,
473 if (err
!= Success
) {
474 xp_destroy_surface(pDRIDrawablePriv
->sid
);
475 xfree(pDRIDrawablePriv
);
480 pDRIDrawablePriv
->key
[0] = key
[0];
481 pDRIDrawablePriv
->key
[1] = key
[1];
483 ++pDRIPriv
->nrWindows
;
485 /* and stash it by surface id */
486 if (surface_hash
== NULL
)
487 surface_hash
= x_hash_table_new(NULL
, NULL
, NULL
, NULL
);
488 x_hash_table_insert(surface_hash
,
489 (void *) pDRIDrawablePriv
->sid
, pDRIDrawablePriv
);
491 /* track this in case this window is destroyed */
492 AddResource(id
, DRIDrawablePrivResType
, (pointer
)pDrawable
);
494 /* Initialize shape */
495 DRIUpdateSurface(pDRIDrawablePriv
, pDrawable
);
498 pDRIDrawablePriv
->refCount
++;
500 *surface_id
= pDRIDrawablePriv
->sid
;
502 if (ret_key
!= NULL
) {
503 ret_key
[0] = pDRIDrawablePriv
->key
[0];
504 ret_key
[1] = pDRIDrawablePriv
->key
[1];
507 if (notify
!= NULL
) {
508 pDRIDrawablePriv
->notifiers
= x_hook_add(pDRIDrawablePriv
->notifiers
,
509 notify
, notify_data
);
516 DRIDestroySurface(ScreenPtr pScreen
, Drawable id
, DrawablePtr pDrawable
,
517 void (*notify
) (void *, void *), void *notify_data
)
519 DRIDrawablePrivPtr pDRIDrawablePriv
;
521 if (pDrawable
->type
== DRAWABLE_WINDOW
) {
522 pDRIDrawablePriv
= DRI_DRAWABLE_PRIV_FROM_WINDOW((WindowPtr
)pDrawable
);
523 } else if (pDrawable
->type
== DRAWABLE_PIXMAP
) {
524 pDRIDrawablePriv
= DRI_DRAWABLE_PRIV_FROM_PIXMAP((PixmapPtr
)pDrawable
);
529 if (pDRIDrawablePriv
!= NULL
) {
530 if (notify
!= NULL
) {
531 pDRIDrawablePriv
->notifiers
= x_hook_remove(pDRIDrawablePriv
->notifiers
,
532 notify
, notify_data
);
534 if (--pDRIDrawablePriv
->refCount
<= 0) {
535 /* This calls back to DRIDrawablePrivDelete
536 which frees the private area */
537 FreeResourceByType(id
, DRIDrawablePrivResType
, FALSE
);
545 DRIDrawablePrivDelete(pointer pResource
, XID id
)
547 DrawablePtr pDrawable
= (DrawablePtr
)pResource
;
548 DRIScreenPrivPtr pDRIPriv
= DRI_SCREEN_PRIV(pDrawable
->pScreen
);
549 DRIDrawablePrivPtr pDRIDrawablePriv
= NULL
;
550 WindowPtr pWin
= NULL
;
551 PixmapPtr pPix
= NULL
;
553 if (pDrawable
->type
== DRAWABLE_WINDOW
) {
554 pWin
= (WindowPtr
)pDrawable
;
555 pDRIDrawablePriv
= DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin
);
556 } else if (pDrawable
->type
== DRAWABLE_PIXMAP
) {
557 pPix
= (PixmapPtr
)pDrawable
;
558 pDRIDrawablePriv
= DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix
);
561 if (pDRIDrawablePriv
== NULL
)
564 if (pDRIDrawablePriv
->drawableIndex
!= -1) {
565 /* release drawable table entry */
566 pDRIPriv
->DRIDrawables
[pDRIDrawablePriv
->drawableIndex
] = NULL
;
569 if (pDRIDrawablePriv
->sid
!= 0) {
570 xp_destroy_surface(pDRIDrawablePriv
->sid
);
571 x_hash_table_remove(surface_hash
, (void *) pDRIDrawablePriv
->sid
);
574 if (pDRIDrawablePriv
->notifiers
!= NULL
)
575 x_hook_free(pDRIDrawablePriv
->notifiers
);
577 xfree(pDRIDrawablePriv
);
579 if (pDrawable
->type
== DRAWABLE_WINDOW
) {
580 pWin
->devPrivates
[DRIWindowPrivIndex
].ptr
= NULL
;
581 } else if (pDrawable
->type
== DRAWABLE_PIXMAP
) {
582 pPix
->devPrivates
[DRIPixmapPrivIndex
].ptr
= NULL
;
585 --pDRIPriv
->nrWindows
;
591 DRIWindowExposures(WindowPtr pWin
, RegionPtr prgn
, RegionPtr bsreg
)
593 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
594 DRIScreenPrivPtr pDRIPriv
= DRI_SCREEN_PRIV(pScreen
);
595 DRIDrawablePrivPtr pDRIDrawablePriv
= DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin
);
597 if (pDRIDrawablePriv
) {
598 /* FIXME: something? */
601 pScreen
->WindowExposures
= pDRIPriv
->wrap
.WindowExposures
;
603 (*pScreen
->WindowExposures
)(pWin
, prgn
, bsreg
);
605 pDRIPriv
->wrap
.WindowExposures
= pScreen
->WindowExposures
;
606 pScreen
->WindowExposures
= DRIWindowExposures
;
610 DRICopyWindow(WindowPtr pWin
, DDXPointRec ptOldOrg
, RegionPtr prgnSrc
)
612 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
613 DRIScreenPrivPtr pDRIPriv
= DRI_SCREEN_PRIV(pScreen
);
614 DRIDrawablePrivPtr pDRIDrawablePriv
;
616 if (pDRIPriv
->nrWindows
> 0) {
617 pDRIDrawablePriv
= DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin
);
618 if (pDRIDrawablePriv
!= NULL
) {
619 DRIUpdateSurface(pDRIDrawablePriv
, &pWin
->drawable
);
624 pScreen
->CopyWindow
= pDRIPriv
->wrap
.CopyWindow
;
626 /* call lower layers */
627 (*pScreen
->CopyWindow
)(pWin
, ptOldOrg
, prgnSrc
);
630 pDRIPriv
->wrap
.CopyWindow
= pScreen
->CopyWindow
;
631 pScreen
->CopyWindow
= DRICopyWindow
;
635 DRIValidateTree(WindowPtr pParent
, WindowPtr pChild
, VTKind kind
)
637 ScreenPtr pScreen
= pParent
->drawable
.pScreen
;
638 DRIScreenPrivPtr pDRIPriv
= DRI_SCREEN_PRIV(pScreen
);
642 pScreen
->ValidateTree
= pDRIPriv
->wrap
.ValidateTree
;
644 /* call lower layers */
645 returnValue
= (*pScreen
->ValidateTree
)(pParent
, pChild
, kind
);
648 pDRIPriv
->wrap
.ValidateTree
= pScreen
->ValidateTree
;
649 pScreen
->ValidateTree
= DRIValidateTree
;
655 DRIPostValidateTree(WindowPtr pParent
, WindowPtr pChild
, VTKind kind
)
658 DRIScreenPrivPtr pDRIPriv
;
661 pScreen
= pParent
->drawable
.pScreen
;
663 pScreen
= pChild
->drawable
.pScreen
;
665 pDRIPriv
= DRI_SCREEN_PRIV(pScreen
);
667 if (pDRIPriv
->wrap
.PostValidateTree
) {
669 pScreen
->PostValidateTree
= pDRIPriv
->wrap
.PostValidateTree
;
671 /* call lower layers */
672 (*pScreen
->PostValidateTree
)(pParent
, pChild
, kind
);
675 pDRIPriv
->wrap
.PostValidateTree
= pScreen
->PostValidateTree
;
676 pScreen
->PostValidateTree
= DRIPostValidateTree
;
681 DRIClipNotify(WindowPtr pWin
, int dx
, int dy
)
683 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
684 DRIScreenPrivPtr pDRIPriv
= DRI_SCREEN_PRIV(pScreen
);
685 DRIDrawablePrivPtr pDRIDrawablePriv
;
687 if ((pDRIDrawablePriv
= DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin
))) {
688 DRIUpdateSurface(pDRIDrawablePriv
, &pWin
->drawable
);
691 if (pDRIPriv
->wrap
.ClipNotify
) {
692 pScreen
->ClipNotify
= pDRIPriv
->wrap
.ClipNotify
;
694 (*pScreen
->ClipNotify
)(pWin
, dx
, dy
);
696 pDRIPriv
->wrap
.ClipNotify
= pScreen
->ClipNotify
;
697 pScreen
->ClipNotify
= DRIClipNotify
;
701 /* This lets us get at the unwrapped functions so that they can correctly
702 * call the lower level functions, and choose whether they will be
703 * called at every level of recursion (eg in validatetree).
706 DRIGetWrappedFuncs(ScreenPtr pScreen
)
708 return &(DRI_SCREEN_PRIV(pScreen
)->wrap
);
712 DRIQueryVersion(int *majorVersion
,
716 *majorVersion
= APPLE_DRI_MAJOR_VERSION
;
717 *minorVersion
= APPLE_DRI_MINOR_VERSION
;
718 *patchVersion
= APPLE_DRI_PATCH_VERSION
;
722 DRISurfaceNotify(xp_surface_id id
, int kind
)
724 DRIDrawablePrivPtr pDRIDrawablePriv
= NULL
;
725 DRISurfaceNotifyArg arg
;
730 if (surface_hash
!= NULL
)
732 pDRIDrawablePriv
= x_hash_table_lookup(surface_hash
,
736 if (pDRIDrawablePriv
== NULL
)
739 if (kind
== AppleDRISurfaceNotifyDestroyed
)
741 pDRIDrawablePriv
->sid
= 0;
742 x_hash_table_remove(surface_hash
, (void *) id
);
745 x_hook_run(pDRIDrawablePriv
->notifiers
, &arg
);
747 if (kind
== AppleDRISurfaceNotifyDestroyed
)
749 /* Kill off the handle. */
751 FreeResourceByType(pDRIDrawablePriv
->pDraw
->id
,
752 DRIDrawablePrivResType
, FALSE
);