2004-04-23 21:54:30 +02:00
|
|
|
/* $XFree86: xc/programs/Xserver/GL/dri/dri.c,v 1.34 2001/12/10 19:07:19 dawes Exp $ */
|
2003-11-25 20:29:01 +01:00
|
|
|
/**************************************************************************
|
|
|
|
|
|
|
|
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
|
|
|
|
Copyright 2000 VA Linux Systems, Inc.
|
|
|
|
Copyright (c) 2002 Apple Computer, Inc.
|
|
|
|
All Rights Reserved.
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
copy of this software and associated documentation files (the
|
|
|
|
"Software"), to deal in the Software without restriction, including
|
|
|
|
without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
distribute, sub license, and/or sell copies of the Software, and to
|
|
|
|
permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice (including the
|
|
|
|
next paragraph) shall be included in all copies or substantial portions
|
|
|
|
of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
|
|
IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
|
|
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
|
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
|
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Authors:
|
|
|
|
* Jens Owen <jens@valinux.com>
|
|
|
|
* Rickard E. (Rik) Faith <faith@valinux.com>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef XFree86LOADER
|
|
|
|
#include "xf86.h"
|
|
|
|
#include "xf86_ansic.h"
|
|
|
|
#else
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define NEED_REPLIES
|
|
|
|
#define NEED_EVENTS
|
|
|
|
#include "X.h"
|
|
|
|
#include "Xproto.h"
|
|
|
|
#include "misc.h"
|
|
|
|
#include "dixstruct.h"
|
|
|
|
#include "extnsionst.h"
|
|
|
|
#include "colormapst.h"
|
|
|
|
#include "cursorstr.h"
|
|
|
|
#include "scrnintstr.h"
|
|
|
|
#include "windowstr.h"
|
|
|
|
#include "servermd.h"
|
|
|
|
#define _APPLEDRI_SERVER_
|
|
|
|
#include "appledristr.h"
|
|
|
|
#include "swaprep.h"
|
|
|
|
#include "dri.h"
|
|
|
|
#include "dristruct.h"
|
|
|
|
#include "mi.h"
|
|
|
|
#include "mipointer.h"
|
|
|
|
#include "rootless.h"
|
|
|
|
#include "x-hash.h"
|
|
|
|
#include "x-hook.h"
|
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
#include <AvailabilityMacros.h>
|
|
|
|
|
2003-11-25 20:29:01 +01:00
|
|
|
static int DRIScreenPrivIndex = -1;
|
|
|
|
static int DRIWindowPrivIndex = -1;
|
2004-09-22 00:01:14 +02:00
|
|
|
static int DRIPixmapPrivIndex = -1;
|
2003-11-25 20:29:01 +01:00
|
|
|
|
|
|
|
static RESTYPE DRIDrawablePrivResType;
|
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
static x_hash_table *surface_hash; /* maps surface ids -> drawablePrivs */
|
2003-11-25 20:29:01 +01:00
|
|
|
|
|
|
|
/* FIXME: don't hardcode this? */
|
|
|
|
#define CG_INFO_FILE "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Resources/Info-macos.plist"
|
|
|
|
|
|
|
|
/* Corresponds to SU Jaguar Green */
|
|
|
|
#define CG_REQUIRED_MAJOR 1
|
|
|
|
#define CG_REQUIRED_MINOR 157
|
|
|
|
#define CG_REQUIRED_MICRO 11
|
|
|
|
|
|
|
|
/* Returns version as major.minor.micro in 10.10.10 fixed form */
|
|
|
|
static unsigned int
|
|
|
|
get_cg_version (void)
|
|
|
|
{
|
|
|
|
static unsigned int version;
|
|
|
|
|
|
|
|
FILE *fh;
|
|
|
|
char *ptr;
|
|
|
|
|
|
|
|
if (version != 0)
|
|
|
|
return version;
|
|
|
|
|
|
|
|
/* I tried CFBundleGetVersion, but it returns zero, so.. */
|
|
|
|
|
|
|
|
fh = fopen (CG_INFO_FILE, "r");
|
|
|
|
if (fh != NULL)
|
|
|
|
{
|
|
|
|
char buf[256];
|
|
|
|
|
|
|
|
while (fgets (buf, sizeof (buf), fh) != NULL)
|
|
|
|
{
|
|
|
|
unsigned char c;
|
|
|
|
|
|
|
|
if (!strstr (buf, "<key>CFBundleShortVersionString</key>")
|
|
|
|
|| fgets (buf, sizeof (buf), fh) == NULL)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
ptr = strstr (buf, "<string>");
|
|
|
|
if (ptr == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ptr += strlen ("<string>");
|
|
|
|
|
|
|
|
/* Now PTR points to "MAJOR.MINOR.MICRO". */
|
|
|
|
|
|
|
|
version = 0;
|
|
|
|
|
|
|
|
again:
|
|
|
|
switch ((c = *ptr++))
|
|
|
|
{
|
|
|
|
case '.':
|
|
|
|
version = version * 1024;
|
|
|
|
goto again;
|
|
|
|
|
|
|
|
case '0': case '1': case '2': case '3': case '4':
|
|
|
|
case '5': case '6': case '7': case '8': case '9':
|
|
|
|
version = ((version & ~0x3ff)
|
|
|
|
+ (version & 0x3ff) * 10 + (c - '0'));
|
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose (fh);
|
|
|
|
}
|
|
|
|
|
|
|
|
return version;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Bool
|
|
|
|
test_cg_version (unsigned int major, unsigned int minor, unsigned int micro)
|
|
|
|
{
|
|
|
|
unsigned int cg_ver = get_cg_version ();
|
|
|
|
|
|
|
|
unsigned int cg_major = (cg_ver >> 20) & 0x3ff;
|
|
|
|
unsigned int cg_minor = (cg_ver >> 10) & 0x3ff;
|
|
|
|
unsigned int cg_micro = cg_ver & 0x3ff;
|
|
|
|
|
|
|
|
if (cg_major > major)
|
|
|
|
return TRUE;
|
|
|
|
else if (cg_major < major)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* cg_major == major */
|
|
|
|
|
|
|
|
if (cg_minor > minor)
|
|
|
|
return TRUE;
|
|
|
|
else if (cg_minor < minor)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* cg_minor == minor */
|
|
|
|
|
|
|
|
if (cg_micro < micro)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Bool
|
|
|
|
DRIScreenInit(ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
DRIScreenPrivPtr pDRIPriv;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
pDRIPriv = (DRIScreenPrivPtr) xcalloc(1, sizeof(DRIScreenPrivRec));
|
|
|
|
if (!pDRIPriv) {
|
|
|
|
pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pScreen->devPrivates[DRIScreenPrivIndex].ptr = (pointer) pDRIPriv;
|
|
|
|
pDRIPriv->directRenderingSupport = TRUE;
|
|
|
|
pDRIPriv->nrWindows = 0;
|
|
|
|
|
|
|
|
/* Need recent cg for window access update */
|
|
|
|
if (!test_cg_version (CG_REQUIRED_MAJOR,
|
|
|
|
CG_REQUIRED_MINOR,
|
|
|
|
CG_REQUIRED_MICRO))
|
|
|
|
{
|
|
|
|
ErrorF ("[DRI] disabled direct rendering; requires CoreGraphics %d.%d.%d\n",
|
|
|
|
CG_REQUIRED_MAJOR, CG_REQUIRED_MINOR, CG_REQUIRED_MICRO);
|
|
|
|
|
|
|
|
pDRIPriv->directRenderingSupport = FALSE;
|
|
|
|
|
|
|
|
/* Note we don't nuke the dri private, since we need it for
|
|
|
|
managing indirect surfaces. */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize drawable tables */
|
|
|
|
for (i = 0; i < DRI_MAX_DRAWABLES; i++) {
|
|
|
|
pDRIPriv->DRIDrawables[i] = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Bool
|
|
|
|
DRIFinishScreenInit(ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
|
|
|
|
|
|
|
|
/* Allocate zero sized private area for each window. Should a window
|
|
|
|
* become a DRI window, we'll hang a DRIWindowPrivateRec off of this
|
|
|
|
* private index.
|
|
|
|
*/
|
|
|
|
if (!AllocateWindowPrivate(pScreen, DRIWindowPrivIndex, 0))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* Wrap DRI support */
|
|
|
|
pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
|
|
|
|
pScreen->ValidateTree = DRIValidateTree;
|
|
|
|
|
|
|
|
pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
|
|
|
|
pScreen->PostValidateTree = DRIPostValidateTree;
|
|
|
|
|
|
|
|
pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
|
|
|
|
pScreen->WindowExposures = DRIWindowExposures;
|
|
|
|
|
|
|
|
pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
|
|
|
|
pScreen->CopyWindow = DRICopyWindow;
|
|
|
|
|
|
|
|
pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
|
|
|
|
pScreen->ClipNotify = DRIClipNotify;
|
|
|
|
|
|
|
|
ErrorF("[DRI] screen %d installation complete\n", pScreen->myNum);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DRICloseScreen(ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
|
|
|
|
|
|
|
|
if (pDRIPriv && pDRIPriv->directRenderingSupport) {
|
|
|
|
xfree(pDRIPriv);
|
|
|
|
pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Bool
|
|
|
|
DRIExtensionInit(void)
|
|
|
|
{
|
|
|
|
static unsigned long DRIGeneration = 0;
|
|
|
|
|
|
|
|
if (DRIGeneration != serverGeneration) {
|
|
|
|
if ((DRIScreenPrivIndex = AllocateScreenPrivateIndex()) < 0)
|
|
|
|
return FALSE;
|
|
|
|
DRIGeneration = serverGeneration;
|
|
|
|
}
|
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
/*
|
|
|
|
* Allocate a window private index with a zero sized private area for
|
2003-11-25 20:29:01 +01:00
|
|
|
* each window, then should a window become a DRI window, we'll hang
|
2004-09-22 00:01:14 +02:00
|
|
|
* a DRIWindowPrivateRec off of this private index. Do same for pixmaps.
|
2003-11-25 20:29:01 +01:00
|
|
|
*/
|
|
|
|
if ((DRIWindowPrivIndex = AllocateWindowPrivateIndex()) < 0)
|
|
|
|
return FALSE;
|
2004-09-22 00:01:14 +02:00
|
|
|
if ((DRIPixmapPrivIndex = AllocatePixmapPrivateIndex()) < 0)
|
|
|
|
return FALSE;
|
2003-11-25 20:29:01 +01:00
|
|
|
|
|
|
|
DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DRIReset(void)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* This stub routine is called when the X Server recycles, resources
|
|
|
|
* allocated by DRIExtensionInit need to be managed here.
|
|
|
|
*
|
|
|
|
* Currently this routine is a stub because all the interesting resources
|
|
|
|
* are managed via the screen init process.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
Bool
|
|
|
|
DRIQueryDirectRenderingCapable(ScreenPtr pScreen, Bool* isCapable)
|
|
|
|
{
|
|
|
|
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
|
|
|
|
|
|
|
|
if (pDRIPriv)
|
|
|
|
*isCapable = pDRIPriv->directRenderingSupport;
|
|
|
|
else
|
|
|
|
*isCapable = FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Bool
|
|
|
|
DRIAuthConnection(ScreenPtr pScreen, unsigned int magic)
|
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
/* FIXME: something? */
|
|
|
|
|
|
|
|
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
|
|
|
|
|
|
|
|
if (drmAuthMagic(pDRIPriv->drmFD, magic)) return FALSE;
|
|
|
|
#endif
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-09-22 00:01:14 +02:00
|
|
|
DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv, DrawablePtr pDraw)
|
2003-11-25 20:29:01 +01:00
|
|
|
{
|
|
|
|
xp_window_changes wc;
|
2004-09-22 00:01:14 +02:00
|
|
|
unsigned int flags = 0;
|
2003-11-25 20:29:01 +01:00
|
|
|
|
|
|
|
if (pDRIDrawablePriv->sid == 0)
|
|
|
|
return;
|
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
|
|
|
|
wc.depth = (pDraw->bitsPerPixel == 32 ? XP_DEPTH_ARGB8888
|
|
|
|
: pDraw->bitsPerPixel == 16 ? XP_DEPTH_RGB555 : XP_DEPTH_NIL);
|
|
|
|
if (wc.depth != XP_DEPTH_NIL)
|
|
|
|
flags |= XP_DEPTH;
|
|
|
|
#endif
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
if (pDraw->type == DRAWABLE_WINDOW) {
|
|
|
|
WindowPtr pWin = (WindowPtr) pDraw;
|
|
|
|
WindowPtr pTopWin = TopLevelParent(pWin);
|
|
|
|
|
|
|
|
wc.x = pWin->drawable.x - (pTopWin->drawable.x - pTopWin->borderWidth);
|
|
|
|
wc.y = pWin->drawable.y - (pTopWin->drawable.y - pTopWin->borderWidth);
|
|
|
|
wc.width = pWin->drawable.width + 2 * pWin->borderWidth;
|
|
|
|
wc.height = pWin->drawable.height + 2 * pWin->borderWidth;
|
|
|
|
wc.bit_gravity = XP_GRAVITY_NONE;
|
|
|
|
|
|
|
|
wc.shape_nrects = REGION_NUM_RECTS(&pWin->clipList);
|
|
|
|
wc.shape_rects = REGION_RECTS(&pWin->clipList);
|
|
|
|
wc.shape_tx = - (pTopWin->drawable.x - pTopWin->borderWidth);
|
|
|
|
wc.shape_ty = - (pTopWin->drawable.y - pTopWin->borderWidth);
|
|
|
|
|
|
|
|
flags |= XP_BOUNDS | XP_SHAPE;
|
|
|
|
|
|
|
|
} else if (pDraw->type == DRAWABLE_PIXMAP) {
|
|
|
|
wc.x = 0;
|
|
|
|
wc.y = 0;
|
|
|
|
wc.width = pDraw->width;
|
|
|
|
wc.height = pDraw->height;
|
|
|
|
wc.bit_gravity = XP_GRAVITY_NONE;
|
|
|
|
flags |= XP_BOUNDS;
|
|
|
|
}
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
xp_configure_surface(pDRIDrawablePriv->sid, flags, &wc);
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Bool
|
2004-09-22 00:01:14 +02:00
|
|
|
DRICreateSurface(ScreenPtr pScreen, Drawable id,
|
|
|
|
DrawablePtr pDrawable, xp_client_id client_id,
|
|
|
|
xp_surface_id *surface_id, unsigned int ret_key[2],
|
|
|
|
void (*notify) (void *arg, void *data), void *notify_data)
|
2003-11-25 20:29:01 +01:00
|
|
|
{
|
2004-09-22 00:01:14 +02:00
|
|
|
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
|
|
|
|
DRIDrawablePrivPtr pDRIDrawablePriv;
|
|
|
|
xp_window_id wid = 0;
|
2003-11-25 20:29:01 +01:00
|
|
|
|
|
|
|
if (pDrawable->type == DRAWABLE_WINDOW) {
|
2004-09-22 00:01:14 +02:00
|
|
|
WindowPtr pWin = (WindowPtr)pDrawable;
|
|
|
|
|
|
|
|
pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
|
|
|
|
if (pDRIDrawablePriv == NULL) {
|
2003-11-25 20:29:01 +01:00
|
|
|
xp_error err;
|
|
|
|
xp_window_changes wc;
|
|
|
|
|
|
|
|
/* allocate a DRI Window Private record */
|
|
|
|
if (!(pDRIDrawablePriv = xalloc(sizeof(DRIDrawablePrivRec)))) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
pDRIDrawablePriv->pDraw = pDrawable;
|
|
|
|
pDRIDrawablePriv->pScreen = pScreen;
|
|
|
|
pDRIDrawablePriv->refCount = 0;
|
|
|
|
pDRIDrawablePriv->drawableIndex = -1;
|
|
|
|
pDRIDrawablePriv->notifiers = NULL;
|
|
|
|
|
2003-11-25 20:29:01 +01:00
|
|
|
/* find the physical window */
|
2004-09-22 00:01:14 +02:00
|
|
|
wid = (xp_window_id) RootlessFrameForWindow(pWin, TRUE);
|
2003-11-25 20:29:01 +01:00
|
|
|
if (wid == 0) {
|
2004-09-22 00:01:14 +02:00
|
|
|
xfree(pDRIDrawablePriv);
|
2003-11-25 20:29:01 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* allocate the physical surface */
|
2004-09-22 00:01:14 +02:00
|
|
|
err = xp_create_surface(wid, &pDRIDrawablePriv->sid);
|
2003-11-25 20:29:01 +01:00
|
|
|
if (err != Success) {
|
2004-09-22 00:01:14 +02:00
|
|
|
xfree(pDRIDrawablePriv);
|
2003-11-25 20:29:01 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make it visible */
|
|
|
|
wc.stack_mode = XP_MAPPED_ABOVE;
|
|
|
|
wc.sibling = 0;
|
2004-09-22 00:01:14 +02:00
|
|
|
err = xp_configure_surface(pDRIDrawablePriv->sid, XP_STACKING, &wc);
|
2003-11-25 20:29:01 +01:00
|
|
|
if (err != Success)
|
|
|
|
{
|
2004-09-22 00:01:14 +02:00
|
|
|
xp_destroy_surface(pDRIDrawablePriv->sid);
|
|
|
|
xfree(pDRIDrawablePriv);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* save private off of preallocated index */
|
|
|
|
pWin->devPrivates[DRIWindowPrivIndex].ptr = (pointer)pDRIDrawablePriv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
|
|
|
|
else if (pDrawable->type == DRAWABLE_PIXMAP) {
|
|
|
|
PixmapPtr pPix = (PixmapPtr)pDrawable;
|
|
|
|
|
|
|
|
pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
|
|
|
|
if (pDRIDrawablePriv == NULL) {
|
|
|
|
xp_error err;
|
|
|
|
|
|
|
|
/* allocate a DRI Window Private record */
|
|
|
|
if (!(pDRIDrawablePriv = xcalloc(1, sizeof(DRIDrawablePrivRec)))) {
|
2003-11-25 20:29:01 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pDRIDrawablePriv->pDraw = pDrawable;
|
|
|
|
pDRIDrawablePriv->pScreen = pScreen;
|
2004-09-22 00:01:14 +02:00
|
|
|
pDRIDrawablePriv->refCount = 0;
|
2003-11-25 20:29:01 +01:00
|
|
|
pDRIDrawablePriv->drawableIndex = -1;
|
|
|
|
pDRIDrawablePriv->notifiers = NULL;
|
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
/* Passing a null window id to Xplugin in 10.3+ asks for
|
|
|
|
an accelerated offscreen surface. */
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
err = xp_create_surface(0, &pDRIDrawablePriv->sid);
|
|
|
|
if (err != Success) {
|
|
|
|
xfree(pDRIDrawablePriv);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
/* save private off of preallocated index */
|
|
|
|
pPix->devPrivates[DRIPixmapPrivIndex].ptr = (pointer)pDRIDrawablePriv;
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
2004-09-22 00:01:14 +02:00
|
|
|
}
|
|
|
|
#endif
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
else { /* for GLX 1.3, a PBuffer */
|
|
|
|
/* NOT_DONE */
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
/* Finish initialization of new surfaces */
|
|
|
|
if (pDRIDrawablePriv->refCount == 0) {
|
|
|
|
unsigned int key[2] = {0};
|
|
|
|
xp_error err;
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
/* try to give the client access to the surface */
|
|
|
|
if (client_id != 0 && wid != 0)
|
2003-11-25 20:29:01 +01:00
|
|
|
{
|
2004-09-22 00:01:14 +02:00
|
|
|
err = xp_export_surface(wid, pDRIDrawablePriv->sid,
|
|
|
|
client_id, key);
|
|
|
|
if (err != Success) {
|
|
|
|
xp_destroy_surface(pDRIDrawablePriv->sid);
|
|
|
|
xfree(pDRIDrawablePriv);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
2004-09-22 00:01:14 +02:00
|
|
|
|
|
|
|
pDRIDrawablePriv->key[0] = key[0];
|
|
|
|
pDRIDrawablePriv->key[1] = key[1];
|
|
|
|
|
|
|
|
++pDRIPriv->nrWindows;
|
|
|
|
|
|
|
|
/* and stash it by surface id */
|
|
|
|
if (surface_hash == NULL)
|
|
|
|
surface_hash = x_hash_table_new(NULL, NULL, NULL, NULL);
|
|
|
|
x_hash_table_insert(surface_hash,
|
|
|
|
(void *) pDRIDrawablePriv->sid, pDRIDrawablePriv);
|
|
|
|
|
|
|
|
/* track this in case this window is destroyed */
|
|
|
|
AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable);
|
|
|
|
|
|
|
|
/* Initialize shape */
|
|
|
|
DRIUpdateSurface(pDRIDrawablePriv, pDrawable);
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
2004-09-22 00:01:14 +02:00
|
|
|
|
|
|
|
pDRIDrawablePriv->refCount++;
|
|
|
|
|
|
|
|
*surface_id = pDRIDrawablePriv->sid;
|
|
|
|
|
|
|
|
if (ret_key != NULL) {
|
|
|
|
ret_key[0] = pDRIDrawablePriv->key[0];
|
|
|
|
ret_key[1] = pDRIDrawablePriv->key[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (notify != NULL) {
|
|
|
|
pDRIDrawablePriv->notifiers = x_hook_add(pDRIDrawablePriv->notifiers,
|
|
|
|
notify, notify_data);
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Bool
|
|
|
|
DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
|
|
|
|
void (*notify) (void *, void *), void *notify_data)
|
|
|
|
{
|
2004-09-22 00:01:14 +02:00
|
|
|
DRIDrawablePrivPtr pDRIDrawablePriv;
|
2003-11-25 20:29:01 +01:00
|
|
|
|
|
|
|
if (pDrawable->type == DRAWABLE_WINDOW) {
|
2004-09-22 00:01:14 +02:00
|
|
|
pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW((WindowPtr)pDrawable);
|
|
|
|
} else if (pDrawable->type == DRAWABLE_PIXMAP) {
|
|
|
|
pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP((PixmapPtr)pDrawable);
|
|
|
|
} else {
|
2003-11-25 20:29:01 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
if (pDRIDrawablePriv != NULL) {
|
|
|
|
if (notify != NULL) {
|
|
|
|
pDRIDrawablePriv->notifiers = x_hook_remove(pDRIDrawablePriv->notifiers,
|
|
|
|
notify, notify_data);
|
|
|
|
}
|
|
|
|
if (--pDRIDrawablePriv->refCount <= 0) {
|
|
|
|
/* This calls back to DRIDrawablePrivDelete
|
|
|
|
which frees the private area */
|
|
|
|
FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-11-25 20:29:01 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Bool
|
|
|
|
DRIDrawablePrivDelete(pointer pResource, XID id)
|
|
|
|
{
|
2004-09-22 00:01:14 +02:00
|
|
|
DrawablePtr pDrawable = (DrawablePtr)pResource;
|
|
|
|
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen);
|
|
|
|
DRIDrawablePrivPtr pDRIDrawablePriv = NULL;
|
|
|
|
WindowPtr pWin = NULL;
|
|
|
|
PixmapPtr pPix = NULL;
|
2003-11-25 20:29:01 +01:00
|
|
|
|
|
|
|
if (pDrawable->type == DRAWABLE_WINDOW) {
|
|
|
|
pWin = (WindowPtr)pDrawable;
|
|
|
|
pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
|
2004-09-22 00:01:14 +02:00
|
|
|
} else if (pDrawable->type == DRAWABLE_PIXMAP) {
|
|
|
|
pPix = (PixmapPtr)pDrawable;
|
|
|
|
pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
|
|
|
|
}
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
if (pDRIDrawablePriv == NULL)
|
|
|
|
return FALSE;
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
if (pDRIDrawablePriv->drawableIndex != -1) {
|
|
|
|
/* release drawable table entry */
|
|
|
|
pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
|
|
|
|
}
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
if (pDRIDrawablePriv->sid != 0) {
|
|
|
|
xp_destroy_surface(pDRIDrawablePriv->sid);
|
|
|
|
x_hash_table_remove(surface_hash, (void *) pDRIDrawablePriv->sid);
|
|
|
|
}
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
if (pDRIDrawablePriv->notifiers != NULL)
|
|
|
|
x_hook_free(pDRIDrawablePriv->notifiers);
|
2003-11-25 20:29:01 +01:00
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
xfree(pDRIDrawablePriv);
|
|
|
|
|
|
|
|
if (pDrawable->type == DRAWABLE_WINDOW) {
|
|
|
|
pWin->devPrivates[DRIWindowPrivIndex].ptr = NULL;
|
|
|
|
} else if (pDrawable->type == DRAWABLE_PIXMAP) {
|
|
|
|
pPix->devPrivates[DRIPixmapPrivIndex].ptr = NULL;
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
--pDRIPriv->nrWindows;
|
|
|
|
|
2003-11-25 20:29:01 +01:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DRIWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr bsreg)
|
|
|
|
{
|
|
|
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
|
|
|
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
|
|
|
|
DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
|
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
if (pDRIDrawablePriv) {
|
2003-11-25 20:29:01 +01:00
|
|
|
/* FIXME: something? */
|
|
|
|
}
|
|
|
|
|
|
|
|
pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
|
|
|
|
|
|
|
|
(*pScreen->WindowExposures)(pWin, prgn, bsreg);
|
|
|
|
|
|
|
|
pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
|
|
|
|
pScreen->WindowExposures = DRIWindowExposures;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
|
|
|
{
|
|
|
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
|
|
|
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
|
|
|
|
DRIDrawablePrivPtr pDRIDrawablePriv;
|
|
|
|
|
|
|
|
if (pDRIPriv->nrWindows > 0) {
|
2004-09-22 00:01:14 +02:00
|
|
|
pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
|
2003-11-25 20:29:01 +01:00
|
|
|
if (pDRIDrawablePriv != NULL) {
|
2004-09-22 00:01:14 +02:00
|
|
|
DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable);
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* unwrap */
|
|
|
|
pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
|
|
|
|
|
|
|
|
/* call lower layers */
|
|
|
|
(*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
|
|
|
|
|
|
|
|
/* rewrap */
|
|
|
|
pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
|
|
|
|
pScreen->CopyWindow = DRICopyWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
DRIValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
|
|
|
|
{
|
|
|
|
ScreenPtr pScreen = pParent->drawable.pScreen;
|
|
|
|
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
|
|
|
|
int returnValue;
|
|
|
|
|
|
|
|
/* unwrap */
|
|
|
|
pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
|
|
|
|
|
|
|
|
/* call lower layers */
|
|
|
|
returnValue = (*pScreen->ValidateTree)(pParent, pChild, kind);
|
|
|
|
|
|
|
|
/* rewrap */
|
|
|
|
pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
|
|
|
|
pScreen->ValidateTree = DRIValidateTree;
|
|
|
|
|
|
|
|
return returnValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DRIPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
|
|
|
|
{
|
|
|
|
ScreenPtr pScreen;
|
|
|
|
DRIScreenPrivPtr pDRIPriv;
|
|
|
|
|
|
|
|
if (pParent) {
|
|
|
|
pScreen = pParent->drawable.pScreen;
|
|
|
|
} else {
|
|
|
|
pScreen = pChild->drawable.pScreen;
|
|
|
|
}
|
|
|
|
pDRIPriv = DRI_SCREEN_PRIV(pScreen);
|
|
|
|
|
|
|
|
if (pDRIPriv->wrap.PostValidateTree) {
|
|
|
|
/* unwrap */
|
|
|
|
pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
|
|
|
|
|
|
|
|
/* call lower layers */
|
|
|
|
(*pScreen->PostValidateTree)(pParent, pChild, kind);
|
|
|
|
|
|
|
|
/* rewrap */
|
|
|
|
pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
|
|
|
|
pScreen->PostValidateTree = DRIPostValidateTree;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DRIClipNotify(WindowPtr pWin, int dx, int dy)
|
|
|
|
{
|
|
|
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
|
|
|
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
|
2004-09-22 00:01:14 +02:00
|
|
|
DRIDrawablePrivPtr pDRIDrawablePriv;
|
2003-11-25 20:29:01 +01:00
|
|
|
|
|
|
|
if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
|
2004-09-22 00:01:14 +02:00
|
|
|
DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable);
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
if (pDRIPriv->wrap.ClipNotify) {
|
2003-11-25 20:29:01 +01:00
|
|
|
pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
|
|
|
|
|
|
|
|
(*pScreen->ClipNotify)(pWin, dx, dy);
|
|
|
|
|
|
|
|
pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
|
|
|
|
pScreen->ClipNotify = DRIClipNotify;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This lets us get at the unwrapped functions so that they can correctly
|
|
|
|
* call the lower level functions, and choose whether they will be
|
|
|
|
* called at every level of recursion (eg in validatetree).
|
|
|
|
*/
|
|
|
|
DRIWrappedFuncsRec *
|
|
|
|
DRIGetWrappedFuncs(ScreenPtr pScreen)
|
|
|
|
{
|
|
|
|
return &(DRI_SCREEN_PRIV(pScreen)->wrap);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
DRIQueryVersion(int *majorVersion,
|
|
|
|
int *minorVersion,
|
|
|
|
int *patchVersion)
|
|
|
|
{
|
|
|
|
*majorVersion = APPLE_DRI_MAJOR_VERSION;
|
|
|
|
*minorVersion = APPLE_DRI_MINOR_VERSION;
|
|
|
|
*patchVersion = APPLE_DRI_PATCH_VERSION;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2004-09-22 00:01:14 +02:00
|
|
|
DRISurfaceNotify(xp_surface_id id, int kind)
|
2003-11-25 20:29:01 +01:00
|
|
|
{
|
|
|
|
DRIDrawablePrivPtr pDRIDrawablePriv = NULL;
|
|
|
|
DRISurfaceNotifyArg arg;
|
|
|
|
|
|
|
|
arg.id = id;
|
|
|
|
arg.kind = kind;
|
|
|
|
|
|
|
|
if (surface_hash != NULL)
|
|
|
|
{
|
2004-09-22 00:01:14 +02:00
|
|
|
pDRIDrawablePriv = x_hash_table_lookup(surface_hash,
|
|
|
|
(void *) id, NULL);
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pDRIDrawablePriv == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (kind == AppleDRISurfaceNotifyDestroyed)
|
|
|
|
{
|
|
|
|
pDRIDrawablePriv->sid = 0;
|
2004-09-22 00:01:14 +02:00
|
|
|
x_hash_table_remove(surface_hash, (void *) id);
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
x_hook_run(pDRIDrawablePriv->notifiers, &arg);
|
2003-11-25 20:29:01 +01:00
|
|
|
|
|
|
|
if (kind == AppleDRISurfaceNotifyDestroyed)
|
|
|
|
{
|
|
|
|
/* Kill off the handle. */
|
|
|
|
|
2004-09-22 00:01:14 +02:00
|
|
|
FreeResourceByType(pDRIDrawablePriv->pDraw->id,
|
|
|
|
DRIDrawablePrivResType, FALSE);
|
2003-11-25 20:29:01 +01:00
|
|
|
}
|
|
|
|
}
|