diff options
Diffstat (limited to 'xorg-server/hw/xquartz/xpr')
-rw-r--r-- | xorg-server/hw/xquartz/xpr/dri.c | 1768 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/xpr/xpr.h | 138 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/xpr/xprAppleWM.c | 324 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/xpr/xprEvent.c | 156 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/xpr/xprFrame.c | 1210 | ||||
-rw-r--r-- | xorg-server/hw/xquartz/xpr/xprScreen.c | 970 |
6 files changed, 2283 insertions, 2283 deletions
diff --git a/xorg-server/hw/xquartz/xpr/dri.c b/xorg-server/hw/xquartz/xpr/dri.c index 8bae6b009..63fcabe38 100644 --- a/xorg-server/hw/xquartz/xpr/dri.c +++ b/xorg-server/hw/xquartz/xpr/dri.c @@ -1,884 +1,884 @@ -/************************************************************************** - -Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. -Copyright 2000 VA Linux Systems, Inc. -Copyright (c) 2002, 2009 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 HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#ifdef XFree86LOADER -#include "xf86.h" -#include "xf86_ansic.h" -#else -#include <sys/time.h> -#include <unistd.h> -#endif - -#include <X11/X.h> -#include <X11/Xproto.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.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" -#include "driWrap.h" - -#include <AvailabilityMacros.h> - -static DevPrivateKeyRec DRIScreenPrivKeyRec; -#define DRIScreenPrivKey (&DRIScreenPrivKeyRec) -static DevPrivateKeyRec DRIWindowPrivKeyRec; -#define DRIWindowPrivKey (&DRIWindowPrivKeyRec) -static DevPrivateKeyRec DRIPixmapPrivKeyRec; -#define DRIPixmapPrivKey (&DRIPixmapPrivKeyRec) -static DevPrivateKeyRec DRIPixmapBufferPrivKeyRec; -#define DRIPixmapBufferPrivKey (&DRIPixmapBufferPrivKeyRec) - -static RESTYPE DRIDrawablePrivResType; - -static x_hash_table *surface_hash; /* maps surface ids -> drawablePrivs */ - -static Bool DRIFreePixmapImp(DrawablePtr pDrawable); - -typedef struct { - DrawablePtr pDrawable; - int refCount; - int bytesPerPixel; - int width; - int height; - char shmPath[PATH_MAX]; - int fd; /* From shm_open (for now) */ - size_t length; /* length of buffer */ - void *buffer; -} DRIPixmapBuffer, *DRIPixmapBufferPtr; - -Bool -DRIScreenInit(ScreenPtr pScreen) -{ - DRIScreenPrivPtr pDRIPriv; - int i; - - if (!dixRegisterPrivateKey(&DRIScreenPrivKeyRec, PRIVATE_SCREEN, 0)) - return FALSE; - if (!dixRegisterPrivateKey(&DRIWindowPrivKeyRec, PRIVATE_WINDOW, 0)) - return FALSE; - if (!dixRegisterPrivateKey(&DRIPixmapPrivKeyRec, PRIVATE_PIXMAP, 0)) - return FALSE; - if (!dixRegisterPrivateKey(&DRIPixmapBufferPrivKeyRec, PRIVATE_PIXMAP, 0)) - return FALSE; - - pDRIPriv = (DRIScreenPrivPtr) calloc(1, sizeof(DRIScreenPrivRec)); - if (!pDRIPriv) { - dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL); - return FALSE; - } - - dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, pDRIPriv); - pDRIPriv->directRenderingSupport = TRUE; - pDRIPriv->nrWindows = 0; - - /* 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); - - /* 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 DRIWrapInit(pScreen); -} - -void -DRICloseScreen(ScreenPtr pScreen) -{ - DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - - if (pDRIPriv && pDRIPriv->directRenderingSupport) { - free(pDRIPriv); - dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL); - } -} - -Bool -DRIExtensionInit(void) -{ - DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete, - "DRIDrawable"); - - return DRIDrawablePrivResType != 0; -} - -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 -DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv, DrawablePtr pDraw) -{ - xp_window_changes wc; - unsigned int flags = 0; - - if (pDRIDrawablePriv->sid == 0) - return; - -#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 - - 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 = RegionNumRects(&pWin->clipList); - wc.shape_rects = RegionRects(&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; - } - - xp_configure_surface(pDRIDrawablePriv->sid, flags, &wc); -} - -/* Return NULL if an error occurs. */ -static DRIDrawablePrivPtr -CreateSurfaceForWindow(ScreenPtr pScreen, WindowPtr pWin, xp_window_id *widPtr) { - DRIDrawablePrivPtr pDRIDrawablePriv; - xp_window_id wid = 0; - - *widPtr = 0; - - pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); - - if (pDRIDrawablePriv == NULL) { - xp_error err; - xp_window_changes wc; - - /* allocate a DRI Window Private record */ - if (!(pDRIDrawablePriv = malloc(sizeof(*pDRIDrawablePriv)))) { - return NULL; - } - - pDRIDrawablePriv->pDraw = (DrawablePtr)pWin; - pDRIDrawablePriv->pScreen = pScreen; - pDRIDrawablePriv->refCount = 0; - pDRIDrawablePriv->drawableIndex = -1; - pDRIDrawablePriv->notifiers = NULL; - - /* find the physical window */ - wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWin, TRUE)); - - if (wid == 0) { - free(pDRIDrawablePriv); - return NULL; - } - - /* allocate the physical surface */ - err = xp_create_surface(wid, &pDRIDrawablePriv->sid); - - if (err != Success) { - free(pDRIDrawablePriv); - return NULL; - } - - /* Make it visible */ - wc.stack_mode = XP_MAPPED_ABOVE; - wc.sibling = 0; - err = xp_configure_surface(pDRIDrawablePriv->sid, XP_STACKING, &wc); - - if (err != Success) { - xp_destroy_surface(pDRIDrawablePriv->sid); - free(pDRIDrawablePriv); - return NULL; - } - - /* save private off of preallocated index */ - dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, - pDRIDrawablePriv); - } - - *widPtr = wid; - - return pDRIDrawablePriv; -} - -/* Return NULL if an error occurs. */ -static DRIDrawablePrivPtr -CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) { - DRIDrawablePrivPtr pDRIDrawablePriv; - - pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix); - - if (pDRIDrawablePriv == NULL) { - xp_error err; - - /* allocate a DRI Window Private record */ - if (!(pDRIDrawablePriv = calloc(1, sizeof(*pDRIDrawablePriv)))) { - return NULL; - } - - pDRIDrawablePriv->pDraw = (DrawablePtr)pPix; - pDRIDrawablePriv->pScreen = pScreen; - pDRIDrawablePriv->refCount = 0; - pDRIDrawablePriv->drawableIndex = -1; - pDRIDrawablePriv->notifiers = NULL; - - /* Passing a null window id to Xplugin in 10.3+ asks for - an accelerated offscreen surface. */ - - err = xp_create_surface(0, &pDRIDrawablePriv->sid); - if (err != Success) { - free(pDRIDrawablePriv); - return NULL; - } - - /* - * The DRIUpdateSurface will be called to resize the surface - * after this function, if the export is successful. - */ - - /* save private off of preallocated index */ - dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, - pDRIDrawablePriv); - } - - return pDRIDrawablePriv; -} - - -Bool -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) -{ - DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - xp_window_id wid = 0; - DRIDrawablePrivPtr pDRIDrawablePriv; - - if (pDrawable->type == DRAWABLE_WINDOW) { - pDRIDrawablePriv = CreateSurfaceForWindow(pScreen, - (WindowPtr)pDrawable, &wid); - - if(NULL == pDRIDrawablePriv) - return FALSE; /*error*/ - } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 - else if (pDrawable->type == DRAWABLE_PIXMAP) { - pDRIDrawablePriv = CreateSurfaceForPixmap(pScreen, - (PixmapPtr)pDrawable); - - if(NULL == pDRIDrawablePriv) - return FALSE; /*error*/ - } -#endif - else { - /* We handle GLXPbuffers in a different way (via CGL). */ - return FALSE; - } - - - /* Finish initialization of new surfaces */ - if (pDRIDrawablePriv->refCount == 0) { - unsigned int key[2] = {0}; - xp_error err; - - /* try to give the client access to the surface */ - if (client_id != 0) { - /* - * Xplugin accepts a 0 wid if the surface id is offscreen, such - * as for a pixmap. - */ - err = xp_export_surface(wid, pDRIDrawablePriv->sid, - client_id, key); - if (err != Success) { - xp_destroy_surface(pDRIDrawablePriv->sid); - free(pDRIDrawablePriv); - - /* - * Now set the dix privates to NULL that were previously set. - * This prevents reusing an invalid pointer. - */ - if(pDrawable->type == DRAWABLE_WINDOW) { - WindowPtr pWin = (WindowPtr)pDrawable; - - dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL); - } else if(pDrawable->type == DRAWABLE_PIXMAP) { - PixmapPtr pPix = (PixmapPtr)pDrawable; - - dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL); - } - - return FALSE; - } - } - - 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, - x_cvt_uint_to_vptr(pDRIDrawablePriv->sid), pDRIDrawablePriv); - - /* track this in case this window is destroyed */ - AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable); - - /* Initialize shape */ - DRIUpdateSurface(pDRIDrawablePriv, pDrawable); - } - - 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); - } - - return TRUE; -} - -Bool -DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable, - void (*notify) (void *, void *), void *notify_data) -{ - DRIDrawablePrivPtr pDRIDrawablePriv; - - if (pDrawable->type == DRAWABLE_WINDOW) { - pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW((WindowPtr)pDrawable); - } else if (pDrawable->type == DRAWABLE_PIXMAP) { - pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP((PixmapPtr)pDrawable); - } else { - return FALSE; - } - - if (pDRIDrawablePriv != NULL) { - /* - * This doesn't seem to be used, because notify is NULL in all callers. - */ - - if (notify != NULL) { - pDRIDrawablePriv->notifiers = x_hook_remove(pDRIDrawablePriv->notifiers, - notify, notify_data); - } - - --pDRIDrawablePriv->refCount; - - /* - * Check if the drawable privates still have a reference to the - * surface. - */ - - if (pDRIDrawablePriv->refCount <= 0) { - /* - * This calls back to DRIDrawablePrivDelete which - * frees the private area and dispatches events, if needed. - */ - FreeResourceByType(id, DRIDrawablePrivResType, FALSE); - } - } - - return TRUE; -} - -/* - * The assumption is that this is called when the refCount of a surface - * drops to <= 0, or the window/pixmap is destroyed. - */ -Bool -DRIDrawablePrivDelete(pointer pResource, XID id) -{ - DrawablePtr pDrawable = (DrawablePtr)pResource; - DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen); - DRIDrawablePrivPtr pDRIDrawablePriv = NULL; - WindowPtr pWin = NULL; - PixmapPtr pPix = NULL; - - if (pDrawable->type == DRAWABLE_WINDOW) { - pWin = (WindowPtr)pDrawable; - pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); - } else if (pDrawable->type == DRAWABLE_PIXMAP) { - pPix = (PixmapPtr)pDrawable; - pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix); - } - - if (pDRIDrawablePriv == NULL) { - /* - * We reuse __func__ and the resource type for the GLXPixmap code. - * Attempt to free a pixmap buffer associated with the resource - * if possible. - */ - return DRIFreePixmapImp(pDrawable); - } - - if (pDRIDrawablePriv->drawableIndex != -1) { - /* release drawable table entry */ - pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL; - } - - if (pDRIDrawablePriv->sid != 0) { - DRISurfaceNotify(pDRIDrawablePriv->sid, AppleDRISurfaceNotifyDestroyed); - } - - - if (pDRIDrawablePriv->notifiers != NULL) - x_hook_free(pDRIDrawablePriv->notifiers); - - free(pDRIDrawablePriv); - - if (pDrawable->type == DRAWABLE_WINDOW) { - dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL); - } else if (pDrawable->type == DRAWABLE_PIXMAP) { - dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL); - } - - --pDRIPriv->nrWindows; - - 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); - - if (pDRIDrawablePriv) { - /* FIXME: something? */ - } - - pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures; - - (*pScreen->WindowExposures)(pWin, prgn, bsreg); - - 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) { - pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); - if (pDRIDrawablePriv != NULL) { - DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable); - } - } - - /* unwrap */ - pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow; - - /* call lower layers */ - (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc); - - /* rewrap */ - 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 */ - 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 */ - pScreen->PostValidateTree = DRIPostValidateTree; - } -} - -void -DRIClipNotify(WindowPtr pWin, int dx, int dy) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - DRIDrawablePrivPtr pDRIDrawablePriv; - - if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) { - DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable); - } - - if (pDRIPriv->wrap.ClipNotify) { - pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify; - - (*pScreen->ClipNotify)(pWin, dx, dy); - - 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; -} - -/* - * Note: this also cleans up the hash table in addition to notifying clients. - * The sid/surface-id should not be used after this, because it will be - * invalid. - */ -void -DRISurfaceNotify(xp_surface_id id, int kind) -{ - DRIDrawablePrivPtr pDRIDrawablePriv = NULL; - DRISurfaceNotifyArg arg; - - arg.id = id; - arg.kind = kind; - - if (surface_hash != NULL) - { - pDRIDrawablePriv = x_hash_table_lookup(surface_hash, - x_cvt_uint_to_vptr(id), NULL); - } - - if (pDRIDrawablePriv == NULL) - return; - - if (kind == AppleDRISurfaceNotifyDestroyed) - { - x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(id)); - } - - x_hook_run(pDRIDrawablePriv->notifiers, &arg); - - if (kind == AppleDRISurfaceNotifyDestroyed) - { - xp_error error; - - error = xp_destroy_surface(pDRIDrawablePriv->sid); - - if(error) - ErrorF("%s: xp_destroy_surface failed: %d\n", __func__, error); - - /* Guard against reuse, even though we are freeing after this. */ - pDRIDrawablePriv->sid = 0; - - FreeResourceByType(pDRIDrawablePriv->pDraw->id, - DRIDrawablePrivResType, FALSE); - } -} - -/* - * This creates a shared memory buffer for use with GLXPixmaps - * and AppleSGLX. - */ -Bool DRICreatePixmap(ScreenPtr pScreen, Drawable id, - DrawablePtr pDrawable, char *path, - size_t pathmax) -{ - DRIPixmapBufferPtr shared; - PixmapPtr pPix; - - if(pDrawable->type != DRAWABLE_PIXMAP) - return FALSE; - - pPix = (PixmapPtr)pDrawable; - - shared = malloc(sizeof(*shared)); - if(NULL == shared) { - FatalError("failed to allocate DRIPixmapBuffer in %s\n", __func__); - } - - shared->pDrawable = pDrawable; - shared->refCount = 1; - - if(pDrawable->bitsPerPixel >= 24) { - shared->bytesPerPixel = 4; - } else if(pDrawable->bitsPerPixel <= 16) { - shared->bytesPerPixel = 2; - } - - shared->width = pDrawable->width; - shared->height = pDrawable->height; - - if(-1 == snprintf(shared->shmPath, sizeof(shared->shmPath), - "%d_0x%lx", getpid(), - (unsigned long)id)) { - FatalError("buffer overflow in %s\n", __func__); - } - - shared->fd = shm_open(shared->shmPath, - O_RDWR | O_EXCL | O_CREAT, - S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH); - - if(-1 == shared->fd) { - free(shared); - return FALSE; - } - - shared->length = shared->width * shared->height * shared->bytesPerPixel; - - if(-1 == ftruncate(shared->fd, shared->length)) { - ErrorF("failed to ftruncate (extend) file."); - shm_unlink(shared->shmPath); - close(shared->fd); - free(shared); - return FALSE; - } - - shared->buffer = mmap(NULL, shared->length, - PROT_READ | PROT_WRITE, - MAP_FILE | MAP_SHARED, shared->fd, 0); - - if(MAP_FAILED == shared->buffer) { - ErrorF("failed to mmap shared memory."); - shm_unlink(shared->shmPath); - close(shared->fd); - free(shared); - return FALSE; - } - - strncpy(path, shared->shmPath, pathmax); - path[pathmax - 1] = '\0'; - - dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, shared); - - AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable); - - return TRUE; -} - - -Bool DRIGetPixmapData(DrawablePtr pDrawable, int *width, int *height, - int *pitch, int *bpp, void **ptr) { - PixmapPtr pPix; - DRIPixmapBufferPtr shared; - - if(pDrawable->type != DRAWABLE_PIXMAP) - return FALSE; - - pPix = (PixmapPtr)pDrawable; - - shared = dixLookupPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey); - - if(NULL == shared) - return FALSE; - - assert(pDrawable->width == shared->width); - assert(pDrawable->height == shared->height); - - *width = shared->width; - *height = shared->height; - *bpp = shared->bytesPerPixel; - *pitch = shared->width * shared->bytesPerPixel; - *ptr = shared->buffer; - - return TRUE; -} - -static Bool -DRIFreePixmapImp(DrawablePtr pDrawable) { - DRIPixmapBufferPtr shared; - PixmapPtr pPix; - - if(pDrawable->type != DRAWABLE_PIXMAP) - return FALSE; - - pPix = (PixmapPtr)pDrawable; - - shared = dixLookupPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey); - - if(NULL == shared) - return FALSE; - - close(shared->fd); - munmap(shared->buffer, shared->length); - shm_unlink(shared->shmPath); - free(shared); - - dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, (pointer)NULL); - - return TRUE; -} - -void -DRIDestroyPixmap(DrawablePtr pDrawable) { - if(DRIFreePixmapImp(pDrawable)) - FreeResourceByType(pDrawable->id, DRIDrawablePrivResType, FALSE); - -} +/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+Copyright (c) 2002, 2009 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 HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef XFree86LOADER
+#include "xf86.h"
+#include "xf86_ansic.h"
+#else
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.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"
+#include "driWrap.h"
+
+#include <AvailabilityMacros.h>
+
+static DevPrivateKeyRec DRIScreenPrivKeyRec;
+#define DRIScreenPrivKey (&DRIScreenPrivKeyRec)
+static DevPrivateKeyRec DRIWindowPrivKeyRec;
+#define DRIWindowPrivKey (&DRIWindowPrivKeyRec)
+static DevPrivateKeyRec DRIPixmapPrivKeyRec;
+#define DRIPixmapPrivKey (&DRIPixmapPrivKeyRec)
+static DevPrivateKeyRec DRIPixmapBufferPrivKeyRec;
+#define DRIPixmapBufferPrivKey (&DRIPixmapBufferPrivKeyRec)
+
+static RESTYPE DRIDrawablePrivResType;
+
+static x_hash_table *surface_hash; /* maps surface ids -> drawablePrivs */
+
+static Bool DRIFreePixmapImp(DrawablePtr pDrawable);
+
+typedef struct {
+ DrawablePtr pDrawable;
+ int refCount;
+ int bytesPerPixel;
+ int width;
+ int height;
+ char shmPath[PATH_MAX];
+ int fd; /* From shm_open (for now) */
+ size_t length; /* length of buffer */
+ void *buffer;
+} DRIPixmapBuffer, *DRIPixmapBufferPtr;
+
+Bool
+DRIScreenInit(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv;
+ int i;
+
+ if (!dixRegisterPrivateKey(&DRIScreenPrivKeyRec, PRIVATE_SCREEN, 0))
+ return FALSE;
+ if (!dixRegisterPrivateKey(&DRIWindowPrivKeyRec, PRIVATE_WINDOW, 0))
+ return FALSE;
+ if (!dixRegisterPrivateKey(&DRIPixmapPrivKeyRec, PRIVATE_PIXMAP, 0))
+ return FALSE;
+ if (!dixRegisterPrivateKey(&DRIPixmapBufferPrivKeyRec, PRIVATE_PIXMAP, 0))
+ return FALSE;
+
+ pDRIPriv = (DRIScreenPrivPtr) calloc(1, sizeof(DRIScreenPrivRec));
+ if (!pDRIPriv) {
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ return FALSE;
+ }
+
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, pDRIPriv);
+ pDRIPriv->directRenderingSupport = TRUE;
+ pDRIPriv->nrWindows = 0;
+
+ /* 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);
+
+ /* 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 DRIWrapInit(pScreen);
+}
+
+void
+DRICloseScreen(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv && pDRIPriv->directRenderingSupport) {
+ free(pDRIPriv);
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ }
+}
+
+Bool
+DRIExtensionInit(void)
+{
+ DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete,
+ "DRIDrawable");
+
+ return DRIDrawablePrivResType != 0;
+}
+
+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
+DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv, DrawablePtr pDraw)
+{
+ xp_window_changes wc;
+ unsigned int flags = 0;
+
+ if (pDRIDrawablePriv->sid == 0)
+ return;
+
+#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
+
+ 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 = RegionNumRects(&pWin->clipList);
+ wc.shape_rects = RegionRects(&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;
+ }
+
+ xp_configure_surface(pDRIDrawablePriv->sid, flags, &wc);
+}
+
+/* Return NULL if an error occurs. */
+static DRIDrawablePrivPtr
+CreateSurfaceForWindow(ScreenPtr pScreen, WindowPtr pWin, xp_window_id *widPtr) {
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+ xp_window_id wid = 0;
+
+ *widPtr = 0;
+
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+
+ if (pDRIDrawablePriv == NULL) {
+ xp_error err;
+ xp_window_changes wc;
+
+ /* allocate a DRI Window Private record */
+ if (!(pDRIDrawablePriv = malloc(sizeof(*pDRIDrawablePriv)))) {
+ return NULL;
+ }
+
+ pDRIDrawablePriv->pDraw = (DrawablePtr)pWin;
+ pDRIDrawablePriv->pScreen = pScreen;
+ pDRIDrawablePriv->refCount = 0;
+ pDRIDrawablePriv->drawableIndex = -1;
+ pDRIDrawablePriv->notifiers = NULL;
+
+ /* find the physical window */
+ wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWin, TRUE));
+
+ if (wid == 0) {
+ free(pDRIDrawablePriv);
+ return NULL;
+ }
+
+ /* allocate the physical surface */
+ err = xp_create_surface(wid, &pDRIDrawablePriv->sid);
+
+ if (err != Success) {
+ free(pDRIDrawablePriv);
+ return NULL;
+ }
+
+ /* Make it visible */
+ wc.stack_mode = XP_MAPPED_ABOVE;
+ wc.sibling = 0;
+ err = xp_configure_surface(pDRIDrawablePriv->sid, XP_STACKING, &wc);
+
+ if (err != Success) {
+ xp_destroy_surface(pDRIDrawablePriv->sid);
+ free(pDRIDrawablePriv);
+ return NULL;
+ }
+
+ /* save private off of preallocated index */
+ dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey,
+ pDRIDrawablePriv);
+ }
+
+ *widPtr = wid;
+
+ return pDRIDrawablePriv;
+}
+
+/* Return NULL if an error occurs. */
+static DRIDrawablePrivPtr
+CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
+
+ if (pDRIDrawablePriv == NULL) {
+ xp_error err;
+
+ /* allocate a DRI Window Private record */
+ if (!(pDRIDrawablePriv = calloc(1, sizeof(*pDRIDrawablePriv)))) {
+ return NULL;
+ }
+
+ pDRIDrawablePriv->pDraw = (DrawablePtr)pPix;
+ pDRIDrawablePriv->pScreen = pScreen;
+ pDRIDrawablePriv->refCount = 0;
+ pDRIDrawablePriv->drawableIndex = -1;
+ pDRIDrawablePriv->notifiers = NULL;
+
+ /* Passing a null window id to Xplugin in 10.3+ asks for
+ an accelerated offscreen surface. */
+
+ err = xp_create_surface(0, &pDRIDrawablePriv->sid);
+ if (err != Success) {
+ free(pDRIDrawablePriv);
+ return NULL;
+ }
+
+ /*
+ * The DRIUpdateSurface will be called to resize the surface
+ * after this function, if the export is successful.
+ */
+
+ /* save private off of preallocated index */
+ dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey,
+ pDRIDrawablePriv);
+ }
+
+ return pDRIDrawablePriv;
+}
+
+
+Bool
+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)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ xp_window_id wid = 0;
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ pDRIDrawablePriv = CreateSurfaceForWindow(pScreen,
+ (WindowPtr)pDrawable, &wid);
+
+ if(NULL == pDRIDrawablePriv)
+ return FALSE; /*error*/
+ }
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ else if (pDrawable->type == DRAWABLE_PIXMAP) {
+ pDRIDrawablePriv = CreateSurfaceForPixmap(pScreen,
+ (PixmapPtr)pDrawable);
+
+ if(NULL == pDRIDrawablePriv)
+ return FALSE; /*error*/
+ }
+#endif
+ else {
+ /* We handle GLXPbuffers in a different way (via CGL). */
+ return FALSE;
+ }
+
+
+ /* Finish initialization of new surfaces */
+ if (pDRIDrawablePriv->refCount == 0) {
+ unsigned int key[2] = {0};
+ xp_error err;
+
+ /* try to give the client access to the surface */
+ if (client_id != 0) {
+ /*
+ * Xplugin accepts a 0 wid if the surface id is offscreen, such
+ * as for a pixmap.
+ */
+ err = xp_export_surface(wid, pDRIDrawablePriv->sid,
+ client_id, key);
+ if (err != Success) {
+ xp_destroy_surface(pDRIDrawablePriv->sid);
+ free(pDRIDrawablePriv);
+
+ /*
+ * Now set the dix privates to NULL that were previously set.
+ * This prevents reusing an invalid pointer.
+ */
+ if(pDrawable->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr)pDrawable;
+
+ dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
+ } else if(pDrawable->type == DRAWABLE_PIXMAP) {
+ PixmapPtr pPix = (PixmapPtr)pDrawable;
+
+ dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL);
+ }
+
+ return FALSE;
+ }
+ }
+
+ 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,
+ x_cvt_uint_to_vptr(pDRIDrawablePriv->sid), pDRIDrawablePriv);
+
+ /* track this in case this window is destroyed */
+ AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable);
+
+ /* Initialize shape */
+ DRIUpdateSurface(pDRIDrawablePriv, pDrawable);
+ }
+
+ 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);
+ }
+
+ return TRUE;
+}
+
+Bool
+DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
+ void (*notify) (void *, void *), void *notify_data)
+{
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW((WindowPtr)pDrawable);
+ } else if (pDrawable->type == DRAWABLE_PIXMAP) {
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP((PixmapPtr)pDrawable);
+ } else {
+ return FALSE;
+ }
+
+ if (pDRIDrawablePriv != NULL) {
+ /*
+ * This doesn't seem to be used, because notify is NULL in all callers.
+ */
+
+ if (notify != NULL) {
+ pDRIDrawablePriv->notifiers = x_hook_remove(pDRIDrawablePriv->notifiers,
+ notify, notify_data);
+ }
+
+ --pDRIDrawablePriv->refCount;
+
+ /*
+ * Check if the drawable privates still have a reference to the
+ * surface.
+ */
+
+ if (pDRIDrawablePriv->refCount <= 0) {
+ /*
+ * This calls back to DRIDrawablePrivDelete which
+ * frees the private area and dispatches events, if needed.
+ */
+ FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
+ }
+ }
+
+ return TRUE;
+}
+
+/*
+ * The assumption is that this is called when the refCount of a surface
+ * drops to <= 0, or the window/pixmap is destroyed.
+ */
+Bool
+DRIDrawablePrivDelete(pointer pResource, XID id)
+{
+ DrawablePtr pDrawable = (DrawablePtr)pResource;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv = NULL;
+ WindowPtr pWin = NULL;
+ PixmapPtr pPix = NULL;
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ pWin = (WindowPtr)pDrawable;
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+ } else if (pDrawable->type == DRAWABLE_PIXMAP) {
+ pPix = (PixmapPtr)pDrawable;
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
+ }
+
+ if (pDRIDrawablePriv == NULL) {
+ /*
+ * We reuse __func__ and the resource type for the GLXPixmap code.
+ * Attempt to free a pixmap buffer associated with the resource
+ * if possible.
+ */
+ return DRIFreePixmapImp(pDrawable);
+ }
+
+ if (pDRIDrawablePriv->drawableIndex != -1) {
+ /* release drawable table entry */
+ pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
+ }
+
+ if (pDRIDrawablePriv->sid != 0) {
+ DRISurfaceNotify(pDRIDrawablePriv->sid, AppleDRISurfaceNotifyDestroyed);
+ }
+
+
+ if (pDRIDrawablePriv->notifiers != NULL)
+ x_hook_free(pDRIDrawablePriv->notifiers);
+
+ free(pDRIDrawablePriv);
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
+ } else if (pDrawable->type == DRAWABLE_PIXMAP) {
+ dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL);
+ }
+
+ --pDRIPriv->nrWindows;
+
+ 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);
+
+ if (pDRIDrawablePriv) {
+ /* FIXME: something? */
+ }
+
+ pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
+
+ (*pScreen->WindowExposures)(pWin, prgn, bsreg);
+
+ 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) {
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+ if (pDRIDrawablePriv != NULL) {
+ DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable);
+ }
+ }
+
+ /* unwrap */
+ pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
+
+ /* call lower layers */
+ (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
+
+ /* rewrap */
+ 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 */
+ 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 */
+ pScreen->PostValidateTree = DRIPostValidateTree;
+ }
+}
+
+void
+DRIClipNotify(WindowPtr pWin, int dx, int dy)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+
+ if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
+ DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable);
+ }
+
+ if (pDRIPriv->wrap.ClipNotify) {
+ pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
+
+ (*pScreen->ClipNotify)(pWin, dx, dy);
+
+ 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;
+}
+
+/*
+ * Note: this also cleans up the hash table in addition to notifying clients.
+ * The sid/surface-id should not be used after this, because it will be
+ * invalid.
+ */
+void
+DRISurfaceNotify(xp_surface_id id, int kind)
+{
+ DRIDrawablePrivPtr pDRIDrawablePriv = NULL;
+ DRISurfaceNotifyArg arg;
+
+ arg.id = id;
+ arg.kind = kind;
+
+ if (surface_hash != NULL)
+ {
+ pDRIDrawablePriv = x_hash_table_lookup(surface_hash,
+ x_cvt_uint_to_vptr(id), NULL);
+ }
+
+ if (pDRIDrawablePriv == NULL)
+ return;
+
+ if (kind == AppleDRISurfaceNotifyDestroyed)
+ {
+ x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(id));
+ }
+
+ x_hook_run(pDRIDrawablePriv->notifiers, &arg);
+
+ if (kind == AppleDRISurfaceNotifyDestroyed)
+ {
+ xp_error error;
+
+ error = xp_destroy_surface(pDRIDrawablePriv->sid);
+
+ if(error)
+ ErrorF("%s: xp_destroy_surface failed: %d\n", __func__, error);
+
+ /* Guard against reuse, even though we are freeing after this. */
+ pDRIDrawablePriv->sid = 0;
+
+ FreeResourceByType(pDRIDrawablePriv->pDraw->id,
+ DRIDrawablePrivResType, FALSE);
+ }
+}
+
+/*
+ * This creates a shared memory buffer for use with GLXPixmaps
+ * and AppleSGLX.
+ */
+Bool DRICreatePixmap(ScreenPtr pScreen, Drawable id,
+ DrawablePtr pDrawable, char *path,
+ size_t pathmax)
+{
+ DRIPixmapBufferPtr shared;
+ PixmapPtr pPix;
+
+ if(pDrawable->type != DRAWABLE_PIXMAP)
+ return FALSE;
+
+ pPix = (PixmapPtr)pDrawable;
+
+ shared = malloc(sizeof(*shared));
+ if(NULL == shared) {
+ FatalError("failed to allocate DRIPixmapBuffer in %s\n", __func__);
+ }
+
+ shared->pDrawable = pDrawable;
+ shared->refCount = 1;
+
+ if(pDrawable->bitsPerPixel >= 24) {
+ shared->bytesPerPixel = 4;
+ } else if(pDrawable->bitsPerPixel <= 16) {
+ shared->bytesPerPixel = 2;
+ }
+
+ shared->width = pDrawable->width;
+ shared->height = pDrawable->height;
+
+ if(-1 == snprintf(shared->shmPath, sizeof(shared->shmPath),
+ "%d_0x%lx", getpid(),
+ (unsigned long)id)) {
+ FatalError("buffer overflow in %s\n", __func__);
+ }
+
+ shared->fd = shm_open(shared->shmPath,
+ O_RDWR | O_EXCL | O_CREAT,
+ S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH);
+
+ if(-1 == shared->fd) {
+ free(shared);
+ return FALSE;
+ }
+
+ shared->length = shared->width * shared->height * shared->bytesPerPixel;
+
+ if(-1 == ftruncate(shared->fd, shared->length)) {
+ ErrorF("failed to ftruncate (extend) file.");
+ shm_unlink(shared->shmPath);
+ close(shared->fd);
+ free(shared);
+ return FALSE;
+ }
+
+ shared->buffer = mmap(NULL, shared->length,
+ PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED, shared->fd, 0);
+
+ if(MAP_FAILED == shared->buffer) {
+ ErrorF("failed to mmap shared memory.");
+ shm_unlink(shared->shmPath);
+ close(shared->fd);
+ free(shared);
+ return FALSE;
+ }
+
+ strncpy(path, shared->shmPath, pathmax);
+ path[pathmax - 1] = '\0';
+
+ dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, shared);
+
+ AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable);
+
+ return TRUE;
+}
+
+
+Bool DRIGetPixmapData(DrawablePtr pDrawable, int *width, int *height,
+ int *pitch, int *bpp, void **ptr) {
+ PixmapPtr pPix;
+ DRIPixmapBufferPtr shared;
+
+ if(pDrawable->type != DRAWABLE_PIXMAP)
+ return FALSE;
+
+ pPix = (PixmapPtr)pDrawable;
+
+ shared = dixLookupPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey);
+
+ if(NULL == shared)
+ return FALSE;
+
+ assert(pDrawable->width == shared->width);
+ assert(pDrawable->height == shared->height);
+
+ *width = shared->width;
+ *height = shared->height;
+ *bpp = shared->bytesPerPixel;
+ *pitch = shared->width * shared->bytesPerPixel;
+ *ptr = shared->buffer;
+
+ return TRUE;
+}
+
+static Bool
+DRIFreePixmapImp(DrawablePtr pDrawable) {
+ DRIPixmapBufferPtr shared;
+ PixmapPtr pPix;
+
+ if(pDrawable->type != DRAWABLE_PIXMAP)
+ return FALSE;
+
+ pPix = (PixmapPtr)pDrawable;
+
+ shared = dixLookupPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey);
+
+ if(NULL == shared)
+ return FALSE;
+
+ close(shared->fd);
+ munmap(shared->buffer, shared->length);
+ shm_unlink(shared->shmPath);
+ free(shared);
+
+ dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, (pointer)NULL);
+
+ return TRUE;
+}
+
+void
+DRIDestroyPixmap(DrawablePtr pDrawable) {
+ if(DRIFreePixmapImp(pDrawable))
+ FreeResourceByType(pDrawable->id, DRIDrawablePrivResType, FALSE);
+
+}
diff --git a/xorg-server/hw/xquartz/xpr/xpr.h b/xorg-server/hw/xquartz/xpr/xpr.h index 0b138ddd7..d25f2acc8 100644 --- a/xorg-server/hw/xquartz/xpr/xpr.h +++ b/xorg-server/hw/xquartz/xpr/xpr.h @@ -1,69 +1,69 @@ -/* - * Xplugin rootless implementation - * - * Copyright (c) 2003 Torrey T. Lyons. 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ - -#ifndef XPR_H -#define XPR_H - -#include "windowstr.h" -#include "screenint.h" -#include <Xplugin.h> - -#include "darwin.h" - -#undef DEBUG_LOG -#define DEBUG_LOG(msg, args...) ASL_LOG(ASL_LEVEL_DEBUG, "xpr", msg, ##args) - -Bool QuartzModeBundleInit(void); - -void AppleDRIExtensionInit(void); -void xprAppleWMInit(void); -Bool xprInit(ScreenPtr pScreen); -Bool xprIsX11Window(int windowNumber); -WindowPtr xprGetXWindow(xp_window_id wid); - -void xprHideWindows(Bool hide); - -Bool QuartzInitCursor(ScreenPtr pScreen); -void QuartzSuspendXCursor(ScreenPtr pScreen); -void QuartzResumeXCursor(ScreenPtr pScreen); - -/* If we are rooted, we need the root window and desktop levels to be below - * the menubar (24) but above native windows. Normal window level is 0. - * Floating window level is 3. The rest are filled in as appropriate. - * See CGWindowLevel.h - */ - -#include <X11/extensions/applewmconst.h> -static const int normal_window_levels[AppleWMNumWindowLevels+1] = { -0, 3, 4, 5, INT_MIN + 30, INT_MIN + 29, -}; -static const int rooted_window_levels[AppleWMNumWindowLevels+1] = { -20, 21, 22, 23, 19, 18, -}; - -#endif /* XPR_H */ +/*
+ * Xplugin rootless implementation
+ *
+ * Copyright (c) 2003 Torrey T. Lyons. 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, sublicense,
+ * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+
+#ifndef XPR_H
+#define XPR_H
+
+#include "windowstr.h"
+#include "screenint.h"
+#include <Xplugin.h>
+
+#include "darwin.h"
+
+#undef DEBUG_LOG
+#define DEBUG_LOG(msg, args...) ASL_LOG(ASL_LEVEL_DEBUG, "xpr", msg, ##args)
+
+Bool QuartzModeBundleInit(void);
+
+void AppleDRIExtensionInit(void);
+void xprAppleWMInit(void);
+Bool xprInit(ScreenPtr pScreen);
+Bool xprIsX11Window(int windowNumber);
+WindowPtr xprGetXWindow(xp_window_id wid);
+
+void xprHideWindows(Bool hide);
+
+Bool QuartzInitCursor(ScreenPtr pScreen);
+void QuartzSuspendXCursor(ScreenPtr pScreen);
+void QuartzResumeXCursor(ScreenPtr pScreen);
+
+/* If we are rooted, we need the root window and desktop levels to be below
+ * the menubar (24) but above native windows. Normal window level is 0.
+ * Floating window level is 3. The rest are filled in as appropriate.
+ * See CGWindowLevel.h
+ */
+
+#include <X11/extensions/applewmconst.h>
+static const int normal_window_levels[AppleWMNumWindowLevels+1] = {
+0, 3, 4, 5, INT_MIN + 30, INT_MIN + 29,
+};
+static const int rooted_window_levels[AppleWMNumWindowLevels+1] = {
+20, 21, 22, 23, 19, 18,
+};
+
+#endif /* XPR_H */
diff --git a/xorg-server/hw/xquartz/xpr/xprAppleWM.c b/xorg-server/hw/xquartz/xpr/xprAppleWM.c index b6b9a5fc8..6f501e201 100644 --- a/xorg-server/hw/xquartz/xpr/xprAppleWM.c +++ b/xorg-server/hw/xquartz/xpr/xprAppleWM.c @@ -1,162 +1,162 @@ -/* - * Xplugin rootless implementation functions for AppleWM extension - * - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. - * Copyright (c) 2003 Torrey T. Lyons. 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include "xpr.h" - -#include <X11/extensions/applewmproto.h> - -#include "applewmExt.h" -#include "rootless.h" -#include "rootlessCommon.h" -#include <Xplugin.h> -#include <X11/X.h> -#include "quartz.h" -#include "x-hash.h" - -static int xprSetWindowLevel( - WindowPtr pWin, - int level) -{ - xp_window_id wid; - xp_window_changes wc; - RootlessWindowRec *winRec; - - // AppleWMNumWindowLevels is allowed, but is only set by the server - // for the root window. - if (level < 0 || level >= AppleWMNumWindowLevels) { - return BadValue; - } - - wid = x_cvt_vptr_to_uint(RootlessFrameForWindow (pWin, TRUE)); - if (wid == 0) - return BadWindow; - - RootlessStopDrawing (pWin, FALSE); - winRec = WINREC(pWin); - - if(!winRec) - return BadWindow; - - if(XQuartzIsRootless) - wc.window_level = normal_window_levels[level]; - else if(XQuartzShieldingWindowLevel) - wc.window_level = XQuartzShieldingWindowLevel + 1; - else - wc.window_level = rooted_window_levels[level]; - - if (xp_configure_window (wid, XP_WINDOW_LEVEL, &wc) != Success) { - return BadValue; - } - - winRec->level = level; - - return Success; -} - -#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 3 -static int xprAttachTransient(WindowPtr pWinChild, WindowPtr pWinParent) { - xp_window_id child_wid, parent_wid; - xp_window_changes wc; - - child_wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWinChild, TRUE)); - if (child_wid == 0) - return BadWindow; - - if(pWinParent) { - parent_wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWinParent, TRUE)); - if (parent_wid == 0) - return BadWindow; - } else { - parent_wid = 0; - } - - wc.transient_for = parent_wid; - - RootlessStopDrawing (pWinChild, FALSE); - - if (xp_configure_window(child_wid, XP_ATTACH_TRANSIENT, &wc) != Success) { - return BadValue; - } - - return Success; -} -#endif - -static int xprFrameDraw( - WindowPtr pWin, - xp_frame_class class, - xp_frame_attr attr, - const BoxRec *outer, - const BoxRec *inner, - unsigned int title_len, - const unsigned char *title_bytes) -{ - xp_window_id wid; - - wid = x_cvt_vptr_to_uint(RootlessFrameForWindow (pWin, FALSE)); - if (wid == 0) - return BadWindow; - - if (xp_frame_draw (wid, class, attr, outer, inner, - title_len, title_bytes) != Success) - { - return BadValue; - } - - return Success; -} - -static AppleWMProcsRec xprAppleWMProcs = { - xp_disable_update, - xp_reenable_update, - xprSetWindowLevel, - xp_frame_get_rect, - xp_frame_hit_test, - xprFrameDraw, -#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 3 - xp_set_dock_proxy, - xprAttachTransient -#elif defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 2 - xp_set_dock_proxy, - NULL -#else - NULL, - NULL -#endif -}; - - -void xprAppleWMInit(void) -{ - AppleWMExtensionInit(&xprAppleWMProcs); -} +/*
+ * Xplugin rootless implementation functions for AppleWM extension
+ *
+ * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003 Torrey T. Lyons. 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, sublicense,
+ * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "xpr.h"
+
+#include <X11/extensions/applewmproto.h>
+
+#include "applewmExt.h"
+#include "rootless.h"
+#include "rootlessCommon.h"
+#include <Xplugin.h>
+#include <X11/X.h>
+#include "quartz.h"
+#include "x-hash.h"
+
+static int xprSetWindowLevel(
+ WindowPtr pWin,
+ int level)
+{
+ xp_window_id wid;
+ xp_window_changes wc;
+ RootlessWindowRec *winRec;
+
+ // AppleWMNumWindowLevels is allowed, but is only set by the server
+ // for the root window.
+ if (level < 0 || level >= AppleWMNumWindowLevels) {
+ return BadValue;
+ }
+
+ wid = x_cvt_vptr_to_uint(RootlessFrameForWindow (pWin, TRUE));
+ if (wid == 0)
+ return BadWindow;
+
+ RootlessStopDrawing (pWin, FALSE);
+ winRec = WINREC(pWin);
+
+ if(!winRec)
+ return BadWindow;
+
+ if(XQuartzIsRootless)
+ wc.window_level = normal_window_levels[level];
+ else if(XQuartzShieldingWindowLevel)
+ wc.window_level = XQuartzShieldingWindowLevel + 1;
+ else
+ wc.window_level = rooted_window_levels[level];
+
+ if (xp_configure_window (wid, XP_WINDOW_LEVEL, &wc) != Success) {
+ return BadValue;
+ }
+
+ winRec->level = level;
+
+ return Success;
+}
+
+#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 3
+static int xprAttachTransient(WindowPtr pWinChild, WindowPtr pWinParent) {
+ xp_window_id child_wid, parent_wid;
+ xp_window_changes wc;
+
+ child_wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWinChild, TRUE));
+ if (child_wid == 0)
+ return BadWindow;
+
+ if(pWinParent) {
+ parent_wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWinParent, TRUE));
+ if (parent_wid == 0)
+ return BadWindow;
+ } else {
+ parent_wid = 0;
+ }
+
+ wc.transient_for = parent_wid;
+
+ RootlessStopDrawing (pWinChild, FALSE);
+
+ if (xp_configure_window(child_wid, XP_ATTACH_TRANSIENT, &wc) != Success) {
+ return BadValue;
+ }
+
+ return Success;
+}
+#endif
+
+static int xprFrameDraw(
+ WindowPtr pWin,
+ xp_frame_class class,
+ xp_frame_attr attr,
+ const BoxRec *outer,
+ const BoxRec *inner,
+ unsigned int title_len,
+ const unsigned char *title_bytes)
+{
+ xp_window_id wid;
+
+ wid = x_cvt_vptr_to_uint(RootlessFrameForWindow (pWin, FALSE));
+ if (wid == 0)
+ return BadWindow;
+
+ if (xp_frame_draw (wid, class, attr, outer, inner,
+ title_len, title_bytes) != Success)
+ {
+ return BadValue;
+ }
+
+ return Success;
+}
+
+static AppleWMProcsRec xprAppleWMProcs = {
+ xp_disable_update,
+ xp_reenable_update,
+ xprSetWindowLevel,
+ xp_frame_get_rect,
+ xp_frame_hit_test,
+ xprFrameDraw,
+#if defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 3
+ xp_set_dock_proxy,
+ xprAttachTransient
+#elif defined(XPLUGIN_VERSION) && XPLUGIN_VERSION >= 2
+ xp_set_dock_proxy,
+ NULL
+#else
+ NULL,
+ NULL
+#endif
+};
+
+
+void xprAppleWMInit(void)
+{
+ AppleWMExtensionInit(&xprAppleWMProcs);
+}
diff --git a/xorg-server/hw/xquartz/xpr/xprEvent.c b/xorg-server/hw/xquartz/xpr/xprEvent.c index 4e7ece64f..9d476d1f4 100644 --- a/xorg-server/hw/xquartz/xpr/xprEvent.c +++ b/xorg-server/hw/xquartz/xpr/xprEvent.c @@ -1,78 +1,78 @@ -/* Copyright (c) 2008 Apple Inc. - * - * 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, sublicense, 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 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 - * NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT - * HOLDER(S) 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. - * - * Except as contained in this notice, the name(s) of the above - * copyright holders shall not be used in advertising or otherwise to - * promote the sale, use or other dealings in this Software without - * prior written authorization. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include "xpr.h" - -#include <X11/X.h> -#include <X11/Xmd.h> -#include <X11/Xproto.h> -#include "misc.h" -#include "windowstr.h" -#include "pixmapstr.h" -#include "inputstr.h" -#include "eventstr.h" -#include "mi.h" -#include "scrnintstr.h" -#include "mipointer.h" - -#include "quartz.h" -#include "quartzKeyboard.h" -#include "darwinEvents.h" - -#include <sys/types.h> -#include <sys/uio.h> -#include <unistd.h> - -#include "rootlessWindow.h" -#include "xprEvent.h" - -Bool QuartzModeEventHandler(int screenNum, XQuartzEvent *e, DeviceIntPtr dev) { - switch(e->subtype) { - case kXquartzWindowState: - DEBUG_LOG("kXquartzWindowState\n"); - RootlessNativeWindowStateChanged(xprGetXWindow(e->data[0]), - e->data[1]); - return TRUE; - - case kXquartzWindowMoved: - DEBUG_LOG("kXquartzWindowMoved\n"); - RootlessNativeWindowMoved(xprGetXWindow(e->data[0])); - return TRUE; - - case kXquartzBringAllToFront: - DEBUG_LOG("kXquartzBringAllToFront\n"); - RootlessOrderAllWindows(e->data[0]); - return TRUE; - default: - return FALSE; - } -} +/* Copyright (c) 2008 Apple Inc.
+ *
+ * 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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
+ * HOLDER(S) 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.
+ *
+ * Except as contained in this notice, the name(s) of the above
+ * copyright holders shall not be used in advertising or otherwise to
+ * promote the sale, use or other dealings in this Software without
+ * prior written authorization.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "xpr.h"
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "inputstr.h"
+#include "eventstr.h"
+#include "mi.h"
+#include "scrnintstr.h"
+#include "mipointer.h"
+
+#include "quartz.h"
+#include "quartzKeyboard.h"
+#include "darwinEvents.h"
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+#include "rootlessWindow.h"
+#include "xprEvent.h"
+
+Bool QuartzModeEventHandler(int screenNum, XQuartzEvent *e, DeviceIntPtr dev) {
+ switch(e->subtype) {
+ case kXquartzWindowState:
+ DEBUG_LOG("kXquartzWindowState\n");
+ RootlessNativeWindowStateChanged(xprGetXWindow(e->data[0]),
+ e->data[1]);
+ return TRUE;
+
+ case kXquartzWindowMoved:
+ DEBUG_LOG("kXquartzWindowMoved\n");
+ RootlessNativeWindowMoved(xprGetXWindow(e->data[0]));
+ return TRUE;
+
+ case kXquartzBringAllToFront:
+ DEBUG_LOG("kXquartzBringAllToFront\n");
+ RootlessOrderAllWindows(e->data[0]);
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
diff --git a/xorg-server/hw/xquartz/xpr/xprFrame.c b/xorg-server/hw/xquartz/xpr/xprFrame.c index 4818653f6..1d90d8a3d 100644 --- a/xorg-server/hw/xquartz/xpr/xprFrame.c +++ b/xorg-server/hw/xquartz/xpr/xprFrame.c @@ -1,605 +1,605 @@ -/* - * Xplugin rootless implementation frame functions - * - * Copyright (c) 2002-2011 Apple Computer, Inc. All rights reserved. - * Copyright (c) 2003 Torrey T. Lyons. 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include "xpr.h" -#include "rootlessCommon.h" -#include <Xplugin.h> -#include "x-hash.h" -#include "applewmExt.h" - -#include "propertyst.h" -#include "dix.h" -#include <X11/Xatom.h> -#include "windowstr.h" -#include "quartz.h" - -#ifdef HAVE_LIBDISPATCH -#include <dispatch/dispatch.h> -#else -#include <pthread.h> -#endif - -#define DEFINE_ATOM_HELPER(func,atom_name) \ -static Atom func (void) { \ - static int generation; \ - static Atom atom; \ - if (generation != serverGeneration) { \ - generation = serverGeneration; \ - atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \ - } \ - return atom; \ -} - -DEFINE_ATOM_HELPER(xa_native_window_id, "_NATIVE_WINDOW_ID") - -/* Maps xp_window_id -> RootlessWindowRec */ -static x_hash_table *window_hash; - -/* Need to guard window_hash since xprIsX11Window can be called from any thread. */ -#ifdef HAVE_LIBDISPATCH -static dispatch_queue_t window_hash_serial_q; -#else -static pthread_rwlock_t window_hash_rwlock; -#endif - -/* Prototypes for static functions */ -static Bool xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen, - int newX, int newY, RegionPtr pShape); -static void xprDestroyFrame(RootlessFrameID wid); -static void xprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY); -static void xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen, - int newX, int newY, unsigned int newW, unsigned int newH, - unsigned int gravity); -static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid); -static void xprReshapeFrame(RootlessFrameID wid, RegionPtr pShape); -static void xprUnmapFrame(RootlessFrameID wid); -static void xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow); -static void xprStopDrawing(RootlessFrameID wid, Bool flush); -static void xprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage); -static void xprDamageRects(RootlessFrameID wid, int nrects, const BoxRec *rects, - int shift_x, int shift_y); -static void xprSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin); -static Bool xprDoReorderWindow(RootlessWindowPtr pFrame); -static void xprHideWindow(RootlessFrameID wid); -static void xprUpdateColormap(RootlessFrameID wid, ScreenPtr pScreen); -static void xprCopyWindow(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, - int dx, int dy); - - -static inline xp_error -xprConfigureWindow(xp_window_id id, unsigned int mask, - const xp_window_changes *values) -{ - return xp_configure_window(id, mask, values); -} - - -static void -xprSetNativeProperty(RootlessWindowPtr pFrame) -{ - xp_error err; - unsigned int native_id; - long data; - - err = xp_get_native_window(x_cvt_vptr_to_uint(pFrame->wid), &native_id); - if (err == Success) - { - /* FIXME: move this to AppleWM extension */ - - data = native_id; - dixChangeWindowProperty(serverClient, pFrame->win, xa_native_window_id(), - XA_INTEGER, 32, PropModeReplace, 1, &data, TRUE); - } -} - -static xp_error -xprColormapCallback(void *data, int first_color, int n_colors, uint32_t *colors) -{ - return (RootlessResolveColormap (data, first_color, n_colors, colors) ? XP_Success : XP_BadMatch); -} - -/* - * Create and display a new frame. - */ -static Bool -xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen, - int newX, int newY, RegionPtr pShape) -{ - WindowPtr pWin = pFrame->win; - xp_window_changes wc; - unsigned int mask = 0; - xp_error err; - - wc.x = newX; - wc.y = newY; - wc.width = pFrame->width; - wc.height = pFrame->height; - wc.bit_gravity = XP_GRAVITY_NONE; - mask |= XP_BOUNDS; - - if (pWin->drawable.depth == 8) - { - wc.depth = XP_DEPTH_INDEX8; - wc.colormap = xprColormapCallback; - wc.colormap_data = pScreen; - mask |= XP_COLORMAP; - } - else if (pWin->drawable.depth == 15) - wc.depth = XP_DEPTH_RGB555; - else if (pWin->drawable.depth == 24) - wc.depth = XP_DEPTH_ARGB8888; - else - wc.depth = XP_DEPTH_NIL; - mask |= XP_DEPTH; - - if (pShape != NULL) - { - wc.shape_nrects = RegionNumRects(pShape); - wc.shape_rects = RegionRects(pShape); - wc.shape_tx = wc.shape_ty = 0; - mask |= XP_SHAPE; - } - - pFrame->level = !IsRoot (pWin) ? AppleWMWindowLevelNormal : AppleWMNumWindowLevels; - - if(XQuartzIsRootless) - wc.window_level = normal_window_levels[pFrame->level]; - else if(XQuartzShieldingWindowLevel) - wc.window_level = XQuartzShieldingWindowLevel + 1; - else - wc.window_level = rooted_window_levels[pFrame->level]; - mask |= XP_WINDOW_LEVEL; - - err = xp_create_window(mask, &wc, (xp_window_id *) &pFrame->wid); - - if (err != Success) - { - return FALSE; - } - -#ifdef HAVE_LIBDISPATCH - dispatch_async(window_hash_serial_q, ^{ - x_hash_table_insert(window_hash, pFrame->wid, pFrame); - }); -#else - pthread_rwlock_wrlock(&window_hash_rwlock); - x_hash_table_insert(window_hash, pFrame->wid, pFrame); - pthread_rwlock_wrlock(&window_hash_rwlock); -#endif - - xprSetNativeProperty(pFrame); - - return TRUE; -} - - -/* - * Destroy a frame. - */ -static void -xprDestroyFrame(RootlessFrameID wid) -{ - xp_error err; - -#ifdef HAVE_LIBDISPATCH - dispatch_async(window_hash_serial_q, ^{ - x_hash_table_remove(window_hash, wid); - }); -#else - pthread_rwlock_wrlock(&window_hash_rwlock); - x_hash_table_remove(window_hash, wid); - pthread_rwlock_unlock(&window_hash_rwlock); -#endif - - err = xp_destroy_window(x_cvt_vptr_to_uint(wid)); - if (err != Success) - FatalError("Could not destroy window %i.", (int)x_cvt_vptr_to_uint(wid)); -} - - -/* - * Move a frame on screen. - */ -static void -xprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY) -{ - xp_window_changes wc; - - wc.x = newX; - wc.y = newY; - // ErrorF("xprMoveFrame(%d, %p, %d, %d)\n", wid, pScreen, newX, newY); - xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_ORIGIN, &wc); -} - - -/* - * Resize and move a frame. - */ -static void -xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen, - int newX, int newY, unsigned int newW, unsigned int newH, - unsigned int gravity) -{ - xp_window_changes wc; - - wc.x = newX; - wc.y = newY; - wc.width = newW; - wc.height = newH; - wc.bit_gravity = gravity; - - /* It's unlikely that being async will save us anything here. - But it can't hurt. */ - - xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_BOUNDS, &wc); -} - - -/* - * Change frame stacking. - */ -static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) { - xp_window_changes wc; - unsigned int mask = XP_STACKING; -#ifdef HAVE_LIBDISPATCH - __block -#endif - RootlessWindowRec *winRec; - - /* Stack frame below nextWid it if it exists, or raise - frame above everything otherwise. */ - - if(nextWid == NULL) { - wc.stack_mode = XP_MAPPED_ABOVE; - wc.sibling = 0; - } else { - wc.stack_mode = XP_MAPPED_BELOW; - wc.sibling = x_cvt_vptr_to_uint(nextWid); - } - -#ifdef HAVE_LIBDISPATCH - dispatch_sync(window_hash_serial_q, ^{ - winRec = x_hash_table_lookup(window_hash, wid, NULL); - }); -#else - pthread_rwlock_rdlock(&window_hash_rwlock); - winRec = x_hash_table_lookup(window_hash, wid, NULL); - pthread_rwlock_unlock(&window_hash_rwlock); -#endif - - if(winRec) { - if(XQuartzIsRootless) - wc.window_level = normal_window_levels[winRec->level]; - else if(XQuartzShieldingWindowLevel) - wc.window_level = XQuartzShieldingWindowLevel + 1; - else - wc.window_level = rooted_window_levels[winRec->level]; - mask |= XP_WINDOW_LEVEL; - } - - xprConfigureWindow(x_cvt_vptr_to_uint(wid), mask, &wc); -} - - -/* - * Change the frame's shape. - */ -static void -xprReshapeFrame(RootlessFrameID wid, RegionPtr pShape) -{ - xp_window_changes wc; - - if (pShape != NULL) - { - wc.shape_nrects = RegionNumRects(pShape); - wc.shape_rects = RegionRects(pShape); - } - else - { - wc.shape_nrects = -1; - wc.shape_rects = NULL; - } - - wc.shape_tx = wc.shape_ty = 0; - - xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_SHAPE, &wc); -} - - -/* - * Unmap a frame. - */ -static void -xprUnmapFrame(RootlessFrameID wid) -{ - xp_window_changes wc; - - wc.stack_mode = XP_UNMAPPED; - wc.sibling = 0; - - xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_STACKING, &wc); -} - - -/* - * Start drawing to a frame. - * Prepare for direct access to its backing buffer. - */ -static void -xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow) -{ - void *data[2]; - unsigned int rowbytes[2]; - xp_error err; - - err = xp_lock_window(x_cvt_vptr_to_uint(wid), NULL, NULL, data, rowbytes, NULL); - if (err != Success) - FatalError("Could not lock window %i for drawing.", (int)x_cvt_vptr_to_uint(wid)); - - *pixelData = data[0]; - *bytesPerRow = rowbytes[0]; -} - - -/* - * Stop drawing to a frame. - */ -static void -xprStopDrawing(RootlessFrameID wid, Bool flush) -{ - xp_error err; - - err = xp_unlock_window(x_cvt_vptr_to_uint(wid), flush); - if(err != Success) - FatalError("Could not unlock window %i after drawing.", (int)x_cvt_vptr_to_uint(wid)); -} - - -/* - * Flush drawing updates to the screen. - */ -static void -xprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage) -{ - xp_flush_window(x_cvt_vptr_to_uint(wid)); -} - - -/* - * Mark damaged rectangles as requiring redisplay to screen. - */ -static void -xprDamageRects(RootlessFrameID wid, int nrects, const BoxRec *rects, - int shift_x, int shift_y) -{ - xp_mark_window(x_cvt_vptr_to_uint(wid), nrects, rects, shift_x, shift_y); -} - - -/* - * Called after the window associated with a frame has been switched - * to a new top-level parent. - */ -static void -xprSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin) -{ - DeleteProperty(serverClient, oldWin, xa_native_window_id()); - - xprSetNativeProperty(pFrame); -} - - -/* - * Called to check if the frame should be reordered when it is restacked. - */ -static Bool xprDoReorderWindow(RootlessWindowPtr pFrame) -{ - WindowPtr pWin = pFrame->win; - - return AppleWMDoReorderWindow(pWin); -} - - -/* - * Copy area in frame to another part of frame. - * Used to accelerate scrolling. - */ -static void -xprCopyWindow(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, - int dx, int dy) -{ - xp_copy_window(x_cvt_vptr_to_uint(wid), x_cvt_vptr_to_uint(wid), - dstNrects, dstRects, dx, dy); -} - - -static RootlessFrameProcsRec xprRootlessProcs = { - xprCreateFrame, - xprDestroyFrame, - xprMoveFrame, - xprResizeFrame, - xprRestackFrame, - xprReshapeFrame, - xprUnmapFrame, - xprStartDrawing, - xprStopDrawing, - xprUpdateRegion, - xprDamageRects, - xprSwitchWindow, - xprDoReorderWindow, - xprHideWindow, - xprUpdateColormap, - xp_copy_bytes, - xprCopyWindow -}; - - -/* - * Initialize XPR implementation - */ -Bool -xprInit(ScreenPtr pScreen) -{ - RootlessInit(pScreen, &xprRootlessProcs); - - rootless_CopyBytes_threshold = xp_copy_bytes_threshold; - rootless_CopyWindow_threshold = xp_scroll_area_threshold; - - assert((window_hash = x_hash_table_new(NULL, NULL, NULL, NULL))); -#ifdef HAVE_LIBDISPATCH - assert((window_hash_serial_q = dispatch_queue_create(BUNDLE_ID_PREFIX".X11.xpr_window_hash", NULL))); -#else - assert(0 == pthread_rwlock_init(&window_hash_rwlock, NULL)); -#endif - - return TRUE; -} - - -/* - * Given the id of a physical window, try to find the top-level (or root) - * X window that it represents. - */ -WindowPtr -xprGetXWindow(xp_window_id wid) -{ -#ifdef HAVE_LIBDISPATCH - RootlessWindowRec *winRec __block; - dispatch_sync(window_hash_serial_q, ^{ - winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL); - }); -#else - RootlessWindowRec *winRec; - pthread_rwlock_rdlock(&window_hash_rwlock); - winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL); - pthread_rwlock_unlock(&window_hash_rwlock); -#endif - - return winRec != NULL ? winRec->win : NULL; -} - -/* - * The windowNumber is an AppKit window number. Returns TRUE if xpr is - * displaying a window with that number. - */ -Bool -xprIsX11Window(int windowNumber) -{ - Bool ret; - xp_window_id wid; - - if (xp_lookup_native_window(windowNumber, &wid)) - ret = xprGetXWindow(wid) != NULL; - else - ret = FALSE; - - return ret; -} - - -/* - * xprHideWindows - * Hide or unhide all top level windows. This is called for application hide/ - * unhide events if the window manager is not Apple-WM aware. Xplugin windows - * do not hide or unhide themselves. - */ -void -xprHideWindows(Bool hide) -{ - int screen; - WindowPtr pRoot, pWin; - - for (screen = 0; screen < screenInfo.numScreens; screen++) { - RootlessFrameID prevWid = NULL; - pRoot = screenInfo.screens[screen]->root; - - for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) { - RootlessWindowRec *winRec = WINREC(pWin); - - if (winRec != NULL) { - if (hide) { - xprUnmapFrame(winRec->wid); - } else { - BoxRec box; - - xprRestackFrame(winRec->wid, prevWid); - prevWid = winRec->wid; - - box.x1 = 0; - box.y1 = 0; - box.x2 = winRec->width; - box.y2 = winRec->height; - - xprDamageRects(winRec->wid, 1, &box, 0, 0); - RootlessQueueRedisplay(screenInfo.screens[screen]); - } - } - } - } -} - -// XXX: identical to x_cvt_vptr_to_uint ? -#define MAKE_WINDOW_ID(x) ((xp_window_id)((size_t)(x))) - -Bool no_configure_window; - -static inline int -configure_window (xp_window_id id, unsigned int mask, - const xp_window_changes *values) -{ - if (!no_configure_window) - return xp_configure_window (id, mask, values); - else - return XP_Success; -} - - -static -void xprUpdateColormap(RootlessFrameID wid, ScreenPtr pScreen) -{ - /* This is how we tell xp that the colormap may have changed. */ - xp_window_changes wc; - wc.colormap = xprColormapCallback; - wc.colormap_data = pScreen; - - configure_window(MAKE_WINDOW_ID(wid), XP_COLORMAP, &wc); -} - -static -void xprHideWindow(RootlessFrameID wid) -{ - xp_window_changes wc; - wc.stack_mode = XP_UNMAPPED; - wc.sibling = 0; - configure_window(MAKE_WINDOW_ID(wid), XP_STACKING, &wc); -} +/*
+ * Xplugin rootless implementation frame functions
+ *
+ * Copyright (c) 2002-2011 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003 Torrey T. Lyons. 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, sublicense,
+ * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "xpr.h"
+#include "rootlessCommon.h"
+#include <Xplugin.h>
+#include "x-hash.h"
+#include "applewmExt.h"
+
+#include "propertyst.h"
+#include "dix.h"
+#include <X11/Xatom.h>
+#include "windowstr.h"
+#include "quartz.h"
+
+#ifdef HAVE_LIBDISPATCH
+#include <dispatch/dispatch.h>
+#else
+#include <pthread.h>
+#endif
+
+#define DEFINE_ATOM_HELPER(func,atom_name) \
+static Atom func (void) { \
+ static int generation; \
+ static Atom atom; \
+ if (generation != serverGeneration) { \
+ generation = serverGeneration; \
+ atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \
+ } \
+ return atom; \
+}
+
+DEFINE_ATOM_HELPER(xa_native_window_id, "_NATIVE_WINDOW_ID")
+
+/* Maps xp_window_id -> RootlessWindowRec */
+static x_hash_table *window_hash;
+
+/* Need to guard window_hash since xprIsX11Window can be called from any thread. */
+#ifdef HAVE_LIBDISPATCH
+static dispatch_queue_t window_hash_serial_q;
+#else
+static pthread_rwlock_t window_hash_rwlock;
+#endif
+
+/* Prototypes for static functions */
+static Bool xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
+ int newX, int newY, RegionPtr pShape);
+static void xprDestroyFrame(RootlessFrameID wid);
+static void xprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);
+static void xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen,
+ int newX, int newY, unsigned int newW, unsigned int newH,
+ unsigned int gravity);
+static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid);
+static void xprReshapeFrame(RootlessFrameID wid, RegionPtr pShape);
+static void xprUnmapFrame(RootlessFrameID wid);
+static void xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow);
+static void xprStopDrawing(RootlessFrameID wid, Bool flush);
+static void xprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage);
+static void xprDamageRects(RootlessFrameID wid, int nrects, const BoxRec *rects,
+ int shift_x, int shift_y);
+static void xprSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin);
+static Bool xprDoReorderWindow(RootlessWindowPtr pFrame);
+static void xprHideWindow(RootlessFrameID wid);
+static void xprUpdateColormap(RootlessFrameID wid, ScreenPtr pScreen);
+static void xprCopyWindow(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
+ int dx, int dy);
+
+
+static inline xp_error
+xprConfigureWindow(xp_window_id id, unsigned int mask,
+ const xp_window_changes *values)
+{
+ return xp_configure_window(id, mask, values);
+}
+
+
+static void
+xprSetNativeProperty(RootlessWindowPtr pFrame)
+{
+ xp_error err;
+ unsigned int native_id;
+ long data;
+
+ err = xp_get_native_window(x_cvt_vptr_to_uint(pFrame->wid), &native_id);
+ if (err == Success)
+ {
+ /* FIXME: move this to AppleWM extension */
+
+ data = native_id;
+ dixChangeWindowProperty(serverClient, pFrame->win, xa_native_window_id(),
+ XA_INTEGER, 32, PropModeReplace, 1, &data, TRUE);
+ }
+}
+
+static xp_error
+xprColormapCallback(void *data, int first_color, int n_colors, uint32_t *colors)
+{
+ return (RootlessResolveColormap (data, first_color, n_colors, colors) ? XP_Success : XP_BadMatch);
+}
+
+/*
+ * Create and display a new frame.
+ */
+static Bool
+xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
+ int newX, int newY, RegionPtr pShape)
+{
+ WindowPtr pWin = pFrame->win;
+ xp_window_changes wc;
+ unsigned int mask = 0;
+ xp_error err;
+
+ wc.x = newX;
+ wc.y = newY;
+ wc.width = pFrame->width;
+ wc.height = pFrame->height;
+ wc.bit_gravity = XP_GRAVITY_NONE;
+ mask |= XP_BOUNDS;
+
+ if (pWin->drawable.depth == 8)
+ {
+ wc.depth = XP_DEPTH_INDEX8;
+ wc.colormap = xprColormapCallback;
+ wc.colormap_data = pScreen;
+ mask |= XP_COLORMAP;
+ }
+ else if (pWin->drawable.depth == 15)
+ wc.depth = XP_DEPTH_RGB555;
+ else if (pWin->drawable.depth == 24)
+ wc.depth = XP_DEPTH_ARGB8888;
+ else
+ wc.depth = XP_DEPTH_NIL;
+ mask |= XP_DEPTH;
+
+ if (pShape != NULL)
+ {
+ wc.shape_nrects = RegionNumRects(pShape);
+ wc.shape_rects = RegionRects(pShape);
+ wc.shape_tx = wc.shape_ty = 0;
+ mask |= XP_SHAPE;
+ }
+
+ pFrame->level = !IsRoot (pWin) ? AppleWMWindowLevelNormal : AppleWMNumWindowLevels;
+
+ if(XQuartzIsRootless)
+ wc.window_level = normal_window_levels[pFrame->level];
+ else if(XQuartzShieldingWindowLevel)
+ wc.window_level = XQuartzShieldingWindowLevel + 1;
+ else
+ wc.window_level = rooted_window_levels[pFrame->level];
+ mask |= XP_WINDOW_LEVEL;
+
+ err = xp_create_window(mask, &wc, (xp_window_id *) &pFrame->wid);
+
+ if (err != Success)
+ {
+ return FALSE;
+ }
+
+#ifdef HAVE_LIBDISPATCH
+ dispatch_async(window_hash_serial_q, ^{
+ x_hash_table_insert(window_hash, pFrame->wid, pFrame);
+ });
+#else
+ pthread_rwlock_wrlock(&window_hash_rwlock);
+ x_hash_table_insert(window_hash, pFrame->wid, pFrame);
+ pthread_rwlock_wrlock(&window_hash_rwlock);
+#endif
+
+ xprSetNativeProperty(pFrame);
+
+ return TRUE;
+}
+
+
+/*
+ * Destroy a frame.
+ */
+static void
+xprDestroyFrame(RootlessFrameID wid)
+{
+ xp_error err;
+
+#ifdef HAVE_LIBDISPATCH
+ dispatch_async(window_hash_serial_q, ^{
+ x_hash_table_remove(window_hash, wid);
+ });
+#else
+ pthread_rwlock_wrlock(&window_hash_rwlock);
+ x_hash_table_remove(window_hash, wid);
+ pthread_rwlock_unlock(&window_hash_rwlock);
+#endif
+
+ err = xp_destroy_window(x_cvt_vptr_to_uint(wid));
+ if (err != Success)
+ FatalError("Could not destroy window %i.", (int)x_cvt_vptr_to_uint(wid));
+}
+
+
+/*
+ * Move a frame on screen.
+ */
+static void
+xprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY)
+{
+ xp_window_changes wc;
+
+ wc.x = newX;
+ wc.y = newY;
+ // ErrorF("xprMoveFrame(%d, %p, %d, %d)\n", wid, pScreen, newX, newY);
+ xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_ORIGIN, &wc);
+}
+
+
+/*
+ * Resize and move a frame.
+ */
+static void
+xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen,
+ int newX, int newY, unsigned int newW, unsigned int newH,
+ unsigned int gravity)
+{
+ xp_window_changes wc;
+
+ wc.x = newX;
+ wc.y = newY;
+ wc.width = newW;
+ wc.height = newH;
+ wc.bit_gravity = gravity;
+
+ /* It's unlikely that being async will save us anything here.
+ But it can't hurt. */
+
+ xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_BOUNDS, &wc);
+}
+
+
+/*
+ * Change frame stacking.
+ */
+static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) {
+ xp_window_changes wc;
+ unsigned int mask = XP_STACKING;
+#ifdef HAVE_LIBDISPATCH
+ __block
+#endif
+ RootlessWindowRec *winRec;
+
+ /* Stack frame below nextWid it if it exists, or raise
+ frame above everything otherwise. */
+
+ if(nextWid == NULL) {
+ wc.stack_mode = XP_MAPPED_ABOVE;
+ wc.sibling = 0;
+ } else {
+ wc.stack_mode = XP_MAPPED_BELOW;
+ wc.sibling = x_cvt_vptr_to_uint(nextWid);
+ }
+
+#ifdef HAVE_LIBDISPATCH
+ dispatch_sync(window_hash_serial_q, ^{
+ winRec = x_hash_table_lookup(window_hash, wid, NULL);
+ });
+#else
+ pthread_rwlock_rdlock(&window_hash_rwlock);
+ winRec = x_hash_table_lookup(window_hash, wid, NULL);
+ pthread_rwlock_unlock(&window_hash_rwlock);
+#endif
+
+ if(winRec) {
+ if(XQuartzIsRootless)
+ wc.window_level = normal_window_levels[winRec->level];
+ else if(XQuartzShieldingWindowLevel)
+ wc.window_level = XQuartzShieldingWindowLevel + 1;
+ else
+ wc.window_level = rooted_window_levels[winRec->level];
+ mask |= XP_WINDOW_LEVEL;
+ }
+
+ xprConfigureWindow(x_cvt_vptr_to_uint(wid), mask, &wc);
+}
+
+
+/*
+ * Change the frame's shape.
+ */
+static void
+xprReshapeFrame(RootlessFrameID wid, RegionPtr pShape)
+{
+ xp_window_changes wc;
+
+ if (pShape != NULL)
+ {
+ wc.shape_nrects = RegionNumRects(pShape);
+ wc.shape_rects = RegionRects(pShape);
+ }
+ else
+ {
+ wc.shape_nrects = -1;
+ wc.shape_rects = NULL;
+ }
+
+ wc.shape_tx = wc.shape_ty = 0;
+
+ xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_SHAPE, &wc);
+}
+
+
+/*
+ * Unmap a frame.
+ */
+static void
+xprUnmapFrame(RootlessFrameID wid)
+{
+ xp_window_changes wc;
+
+ wc.stack_mode = XP_UNMAPPED;
+ wc.sibling = 0;
+
+ xprConfigureWindow(x_cvt_vptr_to_uint(wid), XP_STACKING, &wc);
+}
+
+
+/*
+ * Start drawing to a frame.
+ * Prepare for direct access to its backing buffer.
+ */
+static void
+xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
+{
+ void *data[2];
+ unsigned int rowbytes[2];
+ xp_error err;
+
+ err = xp_lock_window(x_cvt_vptr_to_uint(wid), NULL, NULL, data, rowbytes, NULL);
+ if (err != Success)
+ FatalError("Could not lock window %i for drawing.", (int)x_cvt_vptr_to_uint(wid));
+
+ *pixelData = data[0];
+ *bytesPerRow = rowbytes[0];
+}
+
+
+/*
+ * Stop drawing to a frame.
+ */
+static void
+xprStopDrawing(RootlessFrameID wid, Bool flush)
+{
+ xp_error err;
+
+ err = xp_unlock_window(x_cvt_vptr_to_uint(wid), flush);
+ if(err != Success)
+ FatalError("Could not unlock window %i after drawing.", (int)x_cvt_vptr_to_uint(wid));
+}
+
+
+/*
+ * Flush drawing updates to the screen.
+ */
+static void
+xprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage)
+{
+ xp_flush_window(x_cvt_vptr_to_uint(wid));
+}
+
+
+/*
+ * Mark damaged rectangles as requiring redisplay to screen.
+ */
+static void
+xprDamageRects(RootlessFrameID wid, int nrects, const BoxRec *rects,
+ int shift_x, int shift_y)
+{
+ xp_mark_window(x_cvt_vptr_to_uint(wid), nrects, rects, shift_x, shift_y);
+}
+
+
+/*
+ * Called after the window associated with a frame has been switched
+ * to a new top-level parent.
+ */
+static void
+xprSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin)
+{
+ DeleteProperty(serverClient, oldWin, xa_native_window_id());
+
+ xprSetNativeProperty(pFrame);
+}
+
+
+/*
+ * Called to check if the frame should be reordered when it is restacked.
+ */
+static Bool xprDoReorderWindow(RootlessWindowPtr pFrame)
+{
+ WindowPtr pWin = pFrame->win;
+
+ return AppleWMDoReorderWindow(pWin);
+}
+
+
+/*
+ * Copy area in frame to another part of frame.
+ * Used to accelerate scrolling.
+ */
+static void
+xprCopyWindow(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
+ int dx, int dy)
+{
+ xp_copy_window(x_cvt_vptr_to_uint(wid), x_cvt_vptr_to_uint(wid),
+ dstNrects, dstRects, dx, dy);
+}
+
+
+static RootlessFrameProcsRec xprRootlessProcs = {
+ xprCreateFrame,
+ xprDestroyFrame,
+ xprMoveFrame,
+ xprResizeFrame,
+ xprRestackFrame,
+ xprReshapeFrame,
+ xprUnmapFrame,
+ xprStartDrawing,
+ xprStopDrawing,
+ xprUpdateRegion,
+ xprDamageRects,
+ xprSwitchWindow,
+ xprDoReorderWindow,
+ xprHideWindow,
+ xprUpdateColormap,
+ xp_copy_bytes,
+ xprCopyWindow
+};
+
+
+/*
+ * Initialize XPR implementation
+ */
+Bool
+xprInit(ScreenPtr pScreen)
+{
+ RootlessInit(pScreen, &xprRootlessProcs);
+
+ rootless_CopyBytes_threshold = xp_copy_bytes_threshold;
+ rootless_CopyWindow_threshold = xp_scroll_area_threshold;
+
+ assert((window_hash = x_hash_table_new(NULL, NULL, NULL, NULL)));
+#ifdef HAVE_LIBDISPATCH
+ assert((window_hash_serial_q = dispatch_queue_create(BUNDLE_ID_PREFIX".X11.xpr_window_hash", NULL)));
+#else
+ assert(0 == pthread_rwlock_init(&window_hash_rwlock, NULL));
+#endif
+
+ return TRUE;
+}
+
+
+/*
+ * Given the id of a physical window, try to find the top-level (or root)
+ * X window that it represents.
+ */
+WindowPtr
+xprGetXWindow(xp_window_id wid)
+{
+#ifdef HAVE_LIBDISPATCH
+ RootlessWindowRec *winRec __block;
+ dispatch_sync(window_hash_serial_q, ^{
+ winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL);
+ });
+#else
+ RootlessWindowRec *winRec;
+ pthread_rwlock_rdlock(&window_hash_rwlock);
+ winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL);
+ pthread_rwlock_unlock(&window_hash_rwlock);
+#endif
+
+ return winRec != NULL ? winRec->win : NULL;
+}
+
+/*
+ * The windowNumber is an AppKit window number. Returns TRUE if xpr is
+ * displaying a window with that number.
+ */
+Bool
+xprIsX11Window(int windowNumber)
+{
+ Bool ret;
+ xp_window_id wid;
+
+ if (xp_lookup_native_window(windowNumber, &wid))
+ ret = xprGetXWindow(wid) != NULL;
+ else
+ ret = FALSE;
+
+ return ret;
+}
+
+
+/*
+ * xprHideWindows
+ * Hide or unhide all top level windows. This is called for application hide/
+ * unhide events if the window manager is not Apple-WM aware. Xplugin windows
+ * do not hide or unhide themselves.
+ */
+void
+xprHideWindows(Bool hide)
+{
+ int screen;
+ WindowPtr pRoot, pWin;
+
+ for (screen = 0; screen < screenInfo.numScreens; screen++) {
+ RootlessFrameID prevWid = NULL;
+ pRoot = screenInfo.screens[screen]->root;
+
+ for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) {
+ RootlessWindowRec *winRec = WINREC(pWin);
+
+ if (winRec != NULL) {
+ if (hide) {
+ xprUnmapFrame(winRec->wid);
+ } else {
+ BoxRec box;
+
+ xprRestackFrame(winRec->wid, prevWid);
+ prevWid = winRec->wid;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = winRec->width;
+ box.y2 = winRec->height;
+
+ xprDamageRects(winRec->wid, 1, &box, 0, 0);
+ RootlessQueueRedisplay(screenInfo.screens[screen]);
+ }
+ }
+ }
+ }
+}
+
+// XXX: identical to x_cvt_vptr_to_uint ?
+#define MAKE_WINDOW_ID(x) ((xp_window_id)((size_t)(x)))
+
+Bool no_configure_window;
+
+static inline int
+configure_window (xp_window_id id, unsigned int mask,
+ const xp_window_changes *values)
+{
+ if (!no_configure_window)
+ return xp_configure_window (id, mask, values);
+ else
+ return XP_Success;
+}
+
+
+static
+void xprUpdateColormap(RootlessFrameID wid, ScreenPtr pScreen)
+{
+ /* This is how we tell xp that the colormap may have changed. */
+ xp_window_changes wc;
+ wc.colormap = xprColormapCallback;
+ wc.colormap_data = pScreen;
+
+ configure_window(MAKE_WINDOW_ID(wid), XP_COLORMAP, &wc);
+}
+
+static
+void xprHideWindow(RootlessFrameID wid)
+{
+ xp_window_changes wc;
+ wc.stack_mode = XP_UNMAPPED;
+ wc.sibling = 0;
+ configure_window(MAKE_WINDOW_ID(wid), XP_STACKING, &wc);
+}
diff --git a/xorg-server/hw/xquartz/xpr/xprScreen.c b/xorg-server/hw/xquartz/xpr/xprScreen.c index 002355eca..4df3b2b20 100644 --- a/xorg-server/hw/xquartz/xpr/xprScreen.c +++ b/xorg-server/hw/xquartz/xpr/xprScreen.c @@ -1,485 +1,485 @@ -/* - * Xplugin rootless implementation screen functions - * - * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved. - * Copyright (c) 2004 Torrey T. Lyons. 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, sublicense, - * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ - -#include "sanitizedCarbon.h" - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include "quartzCommon.h" -#include "inputstr.h" -#include "quartz.h" -#include "quartzRandR.h" -#include "xpr.h" -#include "xprEvent.h" -#include "pseudoramiX.h" -#include "darwinEvents.h" -#include "rootless.h" -#include "dri.h" -#include "globals.h" -#include <Xplugin.h> -#include "applewmExt.h" -#include "micmap.h" - -#include "rootlessCommon.h" - -#ifdef DAMAGE -# include "damage.h" -#endif - -/* 10.4's deferred update makes X slower.. have to live with the tearing - for now.. */ -#define XP_NO_DEFERRED_UPDATES 8 - -// Name of GLX bundle for native OpenGL -static const char *xprOpenGLBundle = "glxCGL.bundle"; - -/* - * eventHandler - * Callback handler for Xplugin events. - */ -static void eventHandler(unsigned int type, const void *arg, - unsigned int arg_size, void *data) { - - switch (type) { - case XP_EVENT_DISPLAY_CHANGED: - DEBUG_LOG("XP_EVENT_DISPLAY_CHANGED\n"); - DarwinSendDDXEvent(kXquartzDisplayChanged, 0); - break; - - case XP_EVENT_WINDOW_STATE_CHANGED: - if (arg_size >= sizeof(xp_window_state_event)) { - const xp_window_state_event *ws_arg = arg; - - DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: id=%d, state=%d\n", ws_arg->id, ws_arg->state); - DarwinSendDDXEvent(kXquartzWindowState, 2, - ws_arg->id, ws_arg->state); - } else { - DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: ignored\n"); - } - break; - - case XP_EVENT_WINDOW_MOVED: - DEBUG_LOG("XP_EVENT_WINDOW_MOVED\n"); - if (arg_size == sizeof(xp_window_id)) { - xp_window_id id = * (xp_window_id *) arg; - DarwinSendDDXEvent(kXquartzWindowMoved, 1, id); - } - break; - - case XP_EVENT_SURFACE_DESTROYED: - DEBUG_LOG("XP_EVENT_SURFACE_DESTROYED\n"); - case XP_EVENT_SURFACE_CHANGED: - DEBUG_LOG("XP_EVENT_SURFACE_CHANGED\n"); - if (arg_size == sizeof(xp_surface_id)) { - int kind; - - if (type == XP_EVENT_SURFACE_DESTROYED) - kind = AppleDRISurfaceNotifyDestroyed; - else - kind = AppleDRISurfaceNotifyChanged; - - DRISurfaceNotify(*(xp_surface_id *) arg, kind); - } - break; -#ifdef XP_EVENT_SPACE_CHANGED - case XP_EVENT_SPACE_CHANGED: - DEBUG_LOG("XP_EVENT_SPACE_CHANGED\n"); - if(arg_size == sizeof(uint32_t)) { - uint32_t space_id = *(uint32_t *)arg; - DarwinSendDDXEvent(kXquartzSpaceChanged, 1, space_id); - } - break; -#endif - default: - ErrorF("Unknown XP_EVENT type (%d) in xprScreen:eventHandler\n", type); - } -} - -/* - * displayAtIndex - * Return the display ID for a particular display index. - */ -static CGDirectDisplayID -displayAtIndex(int index) -{ - CGError err; - CGDisplayCount cnt; - CGDirectDisplayID dpy[index+1]; - - err = CGGetActiveDisplayList(index + 1, dpy, &cnt); - if (err == kCGErrorSuccess && cnt == index + 1) - return dpy[index]; - else - return kCGNullDirectDisplay; -} - -/* - * displayScreenBounds - * Return the bounds of a particular display. - */ -static CGRect -displayScreenBounds(CGDirectDisplayID id) -{ - CGRect frame; - - frame = CGDisplayBounds(id); - - DEBUG_LOG(" %dx%d @ (%d,%d).\n", - (int)frame.size.width, (int)frame.size.height, - (int)frame.origin.x, (int)frame.origin.y); - - /* Remove menubar to help standard X11 window managers. */ - if (XQuartzIsRootless && - frame.origin.x == 0 && frame.origin.y == 0) { - frame.origin.y += aquaMenuBarHeight; - frame.size.height -= aquaMenuBarHeight; - } - - DEBUG_LOG(" %dx%d @ (%d,%d).\n", - (int)frame.size.width, (int)frame.size.height, - (int)frame.origin.x, (int)frame.origin.y); - - return frame; -} - -/* - * xprAddPseudoramiXScreens - * Add a single virtual screen encompassing all the physical screens - * with PseudoramiX. - */ -static void -xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height, ScreenPtr pScreen) -{ - CGDisplayCount i, displayCount; - CGDirectDisplayID *displayList = NULL; - CGRect unionRect = CGRectNull, frame; - - // Find all the CoreGraphics displays - CGGetActiveDisplayList(0, NULL, &displayCount); - DEBUG_LOG("displayCount: %d\n", (int)displayCount); - - if(!displayCount) { - ErrorF("CoreGraphics has reported no connected displays. Creating a stub 800x600 display.\n"); - *x = *y = 0; - *width = 800; - *height = 600; - PseudoramiXAddScreen(*x, *y, *width, *height); - QuartzCopyDisplayIDs(pScreen, 0, NULL); - return; - } - - /* If the displays are captured, we are in a RandR game mode - * on the primary display, so we only want to include the first - * display. The others are covered by the shield window. - */ - if (CGDisplayIsCaptured(kCGDirectMainDisplay)) - displayCount = 1; - - displayList = malloc(displayCount * sizeof(CGDirectDisplayID)); - if(!displayList) - FatalError("Unable to allocate memory for list of displays.\n"); - CGGetActiveDisplayList(displayCount, displayList, &displayCount); - QuartzCopyDisplayIDs(pScreen, displayCount, displayList); - - /* Get the union of all screens */ - for (i = 0; i < displayCount; i++) { - CGDirectDisplayID dpy = displayList[i]; - frame = displayScreenBounds(dpy); - unionRect = CGRectUnion(unionRect, frame); - } - - /* Use unionRect as the screen size for the X server. */ - *x = unionRect.origin.x; - *y = unionRect.origin.y; - *width = unionRect.size.width; - *height = unionRect.size.height; - - DEBUG_LOG(" screen union origin: (%d,%d) size: (%d,%d).\n", - *x, *y, *width, *height); - - /* Tell PseudoramiX about the real screens. */ - for (i = 0; i < displayCount; i++) - { - CGDirectDisplayID dpy = displayList[i]; - - frame = displayScreenBounds(dpy); - frame.origin.x -= unionRect.origin.x; - frame.origin.y -= unionRect.origin.y; - - DEBUG_LOG(" placed at X11 coordinate (%d,%d).\n", - (int)frame.origin.x, (int)frame.origin.y); - - PseudoramiXAddScreen(frame.origin.x, frame.origin.y, - frame.size.width, frame.size.height); - } - - free(displayList); -} - -/* - * xprDisplayInit - * Find number of CoreGraphics displays and initialize Xplugin. - */ -static void -xprDisplayInit(void) -{ - CGDisplayCount displayCount; - - TRACE(); - - CGGetActiveDisplayList(0, NULL, &displayCount); - - /* With PseudoramiX, the X server only sees one screen; only PseudoramiX - itself knows about all of the screens. */ - - if (noPseudoramiXExtension) - darwinScreensFound = displayCount; - else - darwinScreensFound = 1; - - if (xp_init(XP_BACKGROUND_EVENTS | XP_NO_DEFERRED_UPDATES) != Success) - FatalError("Could not initialize the Xplugin library."); - - xp_select_events(XP_EVENT_DISPLAY_CHANGED - | XP_EVENT_WINDOW_STATE_CHANGED - | XP_EVENT_WINDOW_MOVED -#ifdef XP_EVENT_SPACE_CHANGED - | XP_EVENT_SPACE_CHANGED -#endif - | XP_EVENT_SURFACE_CHANGED - | XP_EVENT_SURFACE_DESTROYED, - eventHandler, NULL); - - AppleDRIExtensionInit(); - xprAppleWMInit(); - - XQuartzIsRootless = XQuartzRootlessDefault; - if (!XQuartzIsRootless) - RootlessHideAllWindows(); -} - -/* - * xprAddScreen - * Init the framebuffer and record pixmap parameters for the screen. - */ -static Bool -xprAddScreen(int index, ScreenPtr pScreen) -{ - DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen); - int depth = darwinDesiredDepth; - - DEBUG_LOG("index=%d depth=%d\n", index, depth); - - if(depth == -1) { -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - depth = CGDisplaySamplesPerPixel(kCGDirectMainDisplay) * CGDisplayBitsPerSample(kCGDirectMainDisplay); -#else - CGDisplayModeRef modeRef; - CFStringRef encStrRef; - - modeRef = CGDisplayCopyDisplayMode(kCGDirectMainDisplay); - if(!modeRef) - goto have_depth; - - encStrRef = CGDisplayModeCopyPixelEncoding(modeRef); - CFRelease(modeRef); - if(!encStrRef) - goto have_depth; - - if(CFStringCompare(encStrRef, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { - depth = 24; - } else if(CFStringCompare(encStrRef, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { - depth = 15; - } else if(CFStringCompare(encStrRef, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { - depth = 8; - } - - CFRelease(encStrRef); -#endif - } - -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 -have_depth: -#endif - switch(depth) { - case 8: // pseudo-working - dfb->visuals = PseudoColorMask; - dfb->preferredCVC = PseudoColor; - dfb->depth = 8; - dfb->bitsPerRGB = 8; - dfb->bitsPerPixel = 8; - dfb->redMask = 0; - dfb->greenMask = 0; - dfb->blueMask = 0; - break; - case 15: - dfb->visuals = TrueColorMask; //LARGE_VISUALS; - dfb->preferredCVC = TrueColor; - dfb->depth = 15; - dfb->bitsPerRGB = 5; - dfb->bitsPerPixel = 16; - dfb->redMask = RM_ARGB(0,5,5,5); - dfb->greenMask = GM_ARGB(0,5,5,5); - dfb->blueMask = BM_ARGB(0,5,5,5); - break; -// case 24: - default: - if(depth != 24) - ErrorF("Unsupported color depth requested. Defaulting to 24bit. (depth=%d darwinDesiredDepth=%d)\n", depth, darwinDesiredDepth); - dfb->visuals = TrueColorMask; //LARGE_VISUALS; - dfb->preferredCVC = TrueColor; - dfb->depth = 24; - dfb->bitsPerRGB = 8; - dfb->bitsPerPixel = 32; - dfb->redMask = RM_ARGB(0,8,8,8); - dfb->greenMask = GM_ARGB(0,8,8,8); - dfb->blueMask = BM_ARGB(0,8,8,8); - break; - } - - if (noPseudoramiXExtension) - { - CGDirectDisplayID dpy; - CGRect frame; - - ErrorF("Warning: noPseudoramiXExtension!\n"); - - dpy = displayAtIndex(index); - QuartzCopyDisplayIDs(pScreen, 1, &dpy); - - frame = displayScreenBounds(dpy); - - dfb->x = frame.origin.x; - dfb->y = frame.origin.y; - dfb->width = frame.size.width; - dfb->height = frame.size.height; - } - else - { - xprAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height, pScreen); - } - - /* Passing zero width (pitch) makes miCreateScreenResources set the - screen pixmap to the framebuffer pointer, i.e. NULL. The generic - rootless code takes care of making this work. */ - dfb->pitch = 0; - dfb->framebuffer = NULL; - - DRIScreenInit(pScreen); - - return TRUE; -} - -/* - * xprSetupScreen - * Setup the screen for rootless access. - */ -static Bool -xprSetupScreen(int index, ScreenPtr pScreen) -{ -#ifdef DAMAGE - // The Damage extension needs to wrap underneath the - // generic rootless layer, so do it now. - if (!DamageSetup(pScreen)) - return FALSE; -#endif - - // Initialize generic rootless code - if (!xprInit(pScreen)) - return FALSE; - - return DRIFinishScreenInit(pScreen); -} - -/* - * xprUpdateScreen - * Update screen after configuation change. - */ -static void -xprUpdateScreen(ScreenPtr pScreen) -{ - rootlessGlobalOffsetX = darwinMainScreenX; - rootlessGlobalOffsetY = darwinMainScreenY; - - AppleWMSetScreenOrigin(pScreen->root); - - RootlessRepositionWindows(pScreen); - RootlessUpdateScreenPixmap(pScreen); -} - -/* - * xprInitInput - * Finalize xpr specific setup. - */ -static void -xprInitInput(int argc, char **argv) -{ - int i; - - rootlessGlobalOffsetX = darwinMainScreenX; - rootlessGlobalOffsetY = darwinMainScreenY; - - for (i = 0; i < screenInfo.numScreens; i++) - AppleWMSetScreenOrigin(screenInfo.screens[i]->root); -} - -/* - * Quartz display mode function list. - */ -static QuartzModeProcsRec xprModeProcs = { - xprDisplayInit, - xprAddScreen, - xprSetupScreen, - xprInitInput, - QuartzInitCursor, - QuartzSuspendXCursor, - QuartzResumeXCursor, - xprAddPseudoramiXScreens, - xprUpdateScreen, - xprIsX11Window, - xprHideWindows, - RootlessFrameForWindow, - TopLevelParent, - DRICreateSurface, - DRIDestroySurface -}; - -/* - * QuartzModeBundleInit - * Initialize the display mode bundle after loading. - */ -Bool -QuartzModeBundleInit(void) -{ - quartzProcs = &xprModeProcs; - quartzOpenGLBundle = xprOpenGLBundle; - return TRUE; -} +/*
+ * Xplugin rootless implementation screen functions
+ *
+ * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2004 Torrey T. Lyons. 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, sublicense,
+ * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+
+#include "sanitizedCarbon.h"
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "quartzCommon.h"
+#include "inputstr.h"
+#include "quartz.h"
+#include "quartzRandR.h"
+#include "xpr.h"
+#include "xprEvent.h"
+#include "pseudoramiX.h"
+#include "darwinEvents.h"
+#include "rootless.h"
+#include "dri.h"
+#include "globals.h"
+#include <Xplugin.h>
+#include "applewmExt.h"
+#include "micmap.h"
+
+#include "rootlessCommon.h"
+
+#ifdef DAMAGE
+# include "damage.h"
+#endif
+
+/* 10.4's deferred update makes X slower.. have to live with the tearing
+ for now.. */
+#define XP_NO_DEFERRED_UPDATES 8
+
+// Name of GLX bundle for native OpenGL
+static const char *xprOpenGLBundle = "glxCGL.bundle";
+
+/*
+ * eventHandler
+ * Callback handler for Xplugin events.
+ */
+static void eventHandler(unsigned int type, const void *arg,
+ unsigned int arg_size, void *data) {
+
+ switch (type) {
+ case XP_EVENT_DISPLAY_CHANGED:
+ DEBUG_LOG("XP_EVENT_DISPLAY_CHANGED\n");
+ DarwinSendDDXEvent(kXquartzDisplayChanged, 0);
+ break;
+
+ case XP_EVENT_WINDOW_STATE_CHANGED:
+ if (arg_size >= sizeof(xp_window_state_event)) {
+ const xp_window_state_event *ws_arg = arg;
+
+ DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: id=%d, state=%d\n", ws_arg->id, ws_arg->state);
+ DarwinSendDDXEvent(kXquartzWindowState, 2,
+ ws_arg->id, ws_arg->state);
+ } else {
+ DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: ignored\n");
+ }
+ break;
+
+ case XP_EVENT_WINDOW_MOVED:
+ DEBUG_LOG("XP_EVENT_WINDOW_MOVED\n");
+ if (arg_size == sizeof(xp_window_id)) {
+ xp_window_id id = * (xp_window_id *) arg;
+ DarwinSendDDXEvent(kXquartzWindowMoved, 1, id);
+ }
+ break;
+
+ case XP_EVENT_SURFACE_DESTROYED:
+ DEBUG_LOG("XP_EVENT_SURFACE_DESTROYED\n");
+ case XP_EVENT_SURFACE_CHANGED:
+ DEBUG_LOG("XP_EVENT_SURFACE_CHANGED\n");
+ if (arg_size == sizeof(xp_surface_id)) {
+ int kind;
+
+ if (type == XP_EVENT_SURFACE_DESTROYED)
+ kind = AppleDRISurfaceNotifyDestroyed;
+ else
+ kind = AppleDRISurfaceNotifyChanged;
+
+ DRISurfaceNotify(*(xp_surface_id *) arg, kind);
+ }
+ break;
+#ifdef XP_EVENT_SPACE_CHANGED
+ case XP_EVENT_SPACE_CHANGED:
+ DEBUG_LOG("XP_EVENT_SPACE_CHANGED\n");
+ if(arg_size == sizeof(uint32_t)) {
+ uint32_t space_id = *(uint32_t *)arg;
+ DarwinSendDDXEvent(kXquartzSpaceChanged, 1, space_id);
+ }
+ break;
+#endif
+ default:
+ ErrorF("Unknown XP_EVENT type (%d) in xprScreen:eventHandler\n", type);
+ }
+}
+
+/*
+ * displayAtIndex
+ * Return the display ID for a particular display index.
+ */
+static CGDirectDisplayID
+displayAtIndex(int index)
+{
+ CGError err;
+ CGDisplayCount cnt;
+ CGDirectDisplayID dpy[index+1];
+
+ err = CGGetActiveDisplayList(index + 1, dpy, &cnt);
+ if (err == kCGErrorSuccess && cnt == index + 1)
+ return dpy[index];
+ else
+ return kCGNullDirectDisplay;
+}
+
+/*
+ * displayScreenBounds
+ * Return the bounds of a particular display.
+ */
+static CGRect
+displayScreenBounds(CGDirectDisplayID id)
+{
+ CGRect frame;
+
+ frame = CGDisplayBounds(id);
+
+ DEBUG_LOG(" %dx%d @ (%d,%d).\n",
+ (int)frame.size.width, (int)frame.size.height,
+ (int)frame.origin.x, (int)frame.origin.y);
+
+ /* Remove menubar to help standard X11 window managers. */
+ if (XQuartzIsRootless &&
+ frame.origin.x == 0 && frame.origin.y == 0) {
+ frame.origin.y += aquaMenuBarHeight;
+ frame.size.height -= aquaMenuBarHeight;
+ }
+
+ DEBUG_LOG(" %dx%d @ (%d,%d).\n",
+ (int)frame.size.width, (int)frame.size.height,
+ (int)frame.origin.x, (int)frame.origin.y);
+
+ return frame;
+}
+
+/*
+ * xprAddPseudoramiXScreens
+ * Add a single virtual screen encompassing all the physical screens
+ * with PseudoramiX.
+ */
+static void
+xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height, ScreenPtr pScreen)
+{
+ CGDisplayCount i, displayCount;
+ CGDirectDisplayID *displayList = NULL;
+ CGRect unionRect = CGRectNull, frame;
+
+ // Find all the CoreGraphics displays
+ CGGetActiveDisplayList(0, NULL, &displayCount);
+ DEBUG_LOG("displayCount: %d\n", (int)displayCount);
+
+ if(!displayCount) {
+ ErrorF("CoreGraphics has reported no connected displays. Creating a stub 800x600 display.\n");
+ *x = *y = 0;
+ *width = 800;
+ *height = 600;
+ PseudoramiXAddScreen(*x, *y, *width, *height);
+ QuartzCopyDisplayIDs(pScreen, 0, NULL);
+ return;
+ }
+
+ /* If the displays are captured, we are in a RandR game mode
+ * on the primary display, so we only want to include the first
+ * display. The others are covered by the shield window.
+ */
+ if (CGDisplayIsCaptured(kCGDirectMainDisplay))
+ displayCount = 1;
+
+ displayList = malloc(displayCount * sizeof(CGDirectDisplayID));
+ if(!displayList)
+ FatalError("Unable to allocate memory for list of displays.\n");
+ CGGetActiveDisplayList(displayCount, displayList, &displayCount);
+ QuartzCopyDisplayIDs(pScreen, displayCount, displayList);
+
+ /* Get the union of all screens */
+ for (i = 0; i < displayCount; i++) {
+ CGDirectDisplayID dpy = displayList[i];
+ frame = displayScreenBounds(dpy);
+ unionRect = CGRectUnion(unionRect, frame);
+ }
+
+ /* Use unionRect as the screen size for the X server. */
+ *x = unionRect.origin.x;
+ *y = unionRect.origin.y;
+ *width = unionRect.size.width;
+ *height = unionRect.size.height;
+
+ DEBUG_LOG(" screen union origin: (%d,%d) size: (%d,%d).\n",
+ *x, *y, *width, *height);
+
+ /* Tell PseudoramiX about the real screens. */
+ for (i = 0; i < displayCount; i++)
+ {
+ CGDirectDisplayID dpy = displayList[i];
+
+ frame = displayScreenBounds(dpy);
+ frame.origin.x -= unionRect.origin.x;
+ frame.origin.y -= unionRect.origin.y;
+
+ DEBUG_LOG(" placed at X11 coordinate (%d,%d).\n",
+ (int)frame.origin.x, (int)frame.origin.y);
+
+ PseudoramiXAddScreen(frame.origin.x, frame.origin.y,
+ frame.size.width, frame.size.height);
+ }
+
+ free(displayList);
+}
+
+/*
+ * xprDisplayInit
+ * Find number of CoreGraphics displays and initialize Xplugin.
+ */
+static void
+xprDisplayInit(void)
+{
+ CGDisplayCount displayCount;
+
+ TRACE();
+
+ CGGetActiveDisplayList(0, NULL, &displayCount);
+
+ /* With PseudoramiX, the X server only sees one screen; only PseudoramiX
+ itself knows about all of the screens. */
+
+ if (noPseudoramiXExtension)
+ darwinScreensFound = displayCount;
+ else
+ darwinScreensFound = 1;
+
+ if (xp_init(XP_BACKGROUND_EVENTS | XP_NO_DEFERRED_UPDATES) != Success)
+ FatalError("Could not initialize the Xplugin library.");
+
+ xp_select_events(XP_EVENT_DISPLAY_CHANGED
+ | XP_EVENT_WINDOW_STATE_CHANGED
+ | XP_EVENT_WINDOW_MOVED
+#ifdef XP_EVENT_SPACE_CHANGED
+ | XP_EVENT_SPACE_CHANGED
+#endif
+ | XP_EVENT_SURFACE_CHANGED
+ | XP_EVENT_SURFACE_DESTROYED,
+ eventHandler, NULL);
+
+ AppleDRIExtensionInit();
+ xprAppleWMInit();
+
+ XQuartzIsRootless = XQuartzRootlessDefault;
+ if (!XQuartzIsRootless)
+ RootlessHideAllWindows();
+}
+
+/*
+ * xprAddScreen
+ * Init the framebuffer and record pixmap parameters for the screen.
+ */
+static Bool
+xprAddScreen(int index, ScreenPtr pScreen)
+{
+ DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
+ int depth = darwinDesiredDepth;
+
+ DEBUG_LOG("index=%d depth=%d\n", index, depth);
+
+ if(depth == -1) {
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+ depth = CGDisplaySamplesPerPixel(kCGDirectMainDisplay) * CGDisplayBitsPerSample(kCGDirectMainDisplay);
+#else
+ CGDisplayModeRef modeRef;
+ CFStringRef encStrRef;
+
+ modeRef = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);
+ if(!modeRef)
+ goto have_depth;
+
+ encStrRef = CGDisplayModeCopyPixelEncoding(modeRef);
+ CFRelease(modeRef);
+ if(!encStrRef)
+ goto have_depth;
+
+ if(CFStringCompare(encStrRef, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+ depth = 24;
+ } else if(CFStringCompare(encStrRef, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+ depth = 15;
+ } else if(CFStringCompare(encStrRef, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+ depth = 8;
+ }
+
+ CFRelease(encStrRef);
+#endif
+ }
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
+have_depth:
+#endif
+ switch(depth) {
+ case 8: // pseudo-working
+ dfb->visuals = PseudoColorMask;
+ dfb->preferredCVC = PseudoColor;
+ dfb->depth = 8;
+ dfb->bitsPerRGB = 8;
+ dfb->bitsPerPixel = 8;
+ dfb->redMask = 0;
+ dfb->greenMask = 0;
+ dfb->blueMask = 0;
+ break;
+ case 15:
+ dfb->visuals = TrueColorMask; //LARGE_VISUALS;
+ dfb->preferredCVC = TrueColor;
+ dfb->depth = 15;
+ dfb->bitsPerRGB = 5;
+ dfb->bitsPerPixel = 16;
+ dfb->redMask = RM_ARGB(0,5,5,5);
+ dfb->greenMask = GM_ARGB(0,5,5,5);
+ dfb->blueMask = BM_ARGB(0,5,5,5);
+ break;
+// case 24:
+ default:
+ if(depth != 24)
+ ErrorF("Unsupported color depth requested. Defaulting to 24bit. (depth=%d darwinDesiredDepth=%d)\n", depth, darwinDesiredDepth);
+ dfb->visuals = TrueColorMask; //LARGE_VISUALS;
+ dfb->preferredCVC = TrueColor;
+ dfb->depth = 24;
+ dfb->bitsPerRGB = 8;
+ dfb->bitsPerPixel = 32;
+ dfb->redMask = RM_ARGB(0,8,8,8);
+ dfb->greenMask = GM_ARGB(0,8,8,8);
+ dfb->blueMask = BM_ARGB(0,8,8,8);
+ break;
+ }
+
+ if (noPseudoramiXExtension)
+ {
+ CGDirectDisplayID dpy;
+ CGRect frame;
+
+ ErrorF("Warning: noPseudoramiXExtension!\n");
+
+ dpy = displayAtIndex(index);
+ QuartzCopyDisplayIDs(pScreen, 1, &dpy);
+
+ frame = displayScreenBounds(dpy);
+
+ dfb->x = frame.origin.x;
+ dfb->y = frame.origin.y;
+ dfb->width = frame.size.width;
+ dfb->height = frame.size.height;
+ }
+ else
+ {
+ xprAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height, pScreen);
+ }
+
+ /* Passing zero width (pitch) makes miCreateScreenResources set the
+ screen pixmap to the framebuffer pointer, i.e. NULL. The generic
+ rootless code takes care of making this work. */
+ dfb->pitch = 0;
+ dfb->framebuffer = NULL;
+
+ DRIScreenInit(pScreen);
+
+ return TRUE;
+}
+
+/*
+ * xprSetupScreen
+ * Setup the screen for rootless access.
+ */
+static Bool
+xprSetupScreen(int index, ScreenPtr pScreen)
+{
+#ifdef DAMAGE
+ // The Damage extension needs to wrap underneath the
+ // generic rootless layer, so do it now.
+ if (!DamageSetup(pScreen))
+ return FALSE;
+#endif
+
+ // Initialize generic rootless code
+ if (!xprInit(pScreen))
+ return FALSE;
+
+ return DRIFinishScreenInit(pScreen);
+}
+
+/*
+ * xprUpdateScreen
+ * Update screen after configuation change.
+ */
+static void
+xprUpdateScreen(ScreenPtr pScreen)
+{
+ rootlessGlobalOffsetX = darwinMainScreenX;
+ rootlessGlobalOffsetY = darwinMainScreenY;
+
+ AppleWMSetScreenOrigin(pScreen->root);
+
+ RootlessRepositionWindows(pScreen);
+ RootlessUpdateScreenPixmap(pScreen);
+}
+
+/*
+ * xprInitInput
+ * Finalize xpr specific setup.
+ */
+static void
+xprInitInput(int argc, char **argv)
+{
+ int i;
+
+ rootlessGlobalOffsetX = darwinMainScreenX;
+ rootlessGlobalOffsetY = darwinMainScreenY;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ AppleWMSetScreenOrigin(screenInfo.screens[i]->root);
+}
+
+/*
+ * Quartz display mode function list.
+ */
+static QuartzModeProcsRec xprModeProcs = {
+ xprDisplayInit,
+ xprAddScreen,
+ xprSetupScreen,
+ xprInitInput,
+ QuartzInitCursor,
+ QuartzSuspendXCursor,
+ QuartzResumeXCursor,
+ xprAddPseudoramiXScreens,
+ xprUpdateScreen,
+ xprIsX11Window,
+ xprHideWindows,
+ RootlessFrameForWindow,
+ TopLevelParent,
+ DRICreateSurface,
+ DRIDestroySurface
+};
+
+/*
+ * QuartzModeBundleInit
+ * Initialize the display mode bundle after loading.
+ */
+Bool
+QuartzModeBundleInit(void)
+{
+ quartzProcs = &xprModeProcs;
+ quartzOpenGLBundle = xprOpenGLBundle;
+ return TRUE;
+}
|