From c38dead3ea7e177728d90cd815cf4eead0c9f534 Mon Sep 17 00:00:00 2001 From: marha Date: Sat, 15 May 2010 16:28:11 +0000 Subject: xserver git update 15/5/2010 --- xorg-server/hw/xquartz/GL/glcontextmodes.c | 1100 ++++++++-------- xorg-server/hw/xquartz/GL/indirect.c | 18 +- xorg-server/hw/xquartz/GL/visualConfigs.c | 570 ++++----- xorg-server/hw/xquartz/applewm.c | 1492 +++++++++++----------- xorg-server/hw/xquartz/darwin.c | 1816 +++++++++++++------------- xorg-server/hw/xquartz/pseudoramiX.c | 942 +++++++------- xorg-server/hw/xquartz/quartz.c | 897 +++++++------ xorg-server/hw/xquartz/xpr/appledri.c | 858 ++++++------- xorg-server/hw/xquartz/xpr/dri.c | 1906 ++++++++++++++-------------- xorg-server/hw/xquartz/xpr/driWrap.c | 1094 ++++++++-------- xorg-server/hw/xquartz/xpr/x-hook.c | 240 ++-- xorg-server/hw/xquartz/xpr/xprCursor.c | 836 ++++++------ xorg-server/hw/xquartz/xpr/xprScreen.c | 4 +- 13 files changed, 5886 insertions(+), 5887 deletions(-) (limited to 'xorg-server/hw/xquartz') diff --git a/xorg-server/hw/xquartz/GL/glcontextmodes.c b/xorg-server/hw/xquartz/GL/glcontextmodes.c index 326c8b235..52a9ca440 100644 --- a/xorg-server/hw/xquartz/GL/glcontextmodes.c +++ b/xorg-server/hw/xquartz/GL/glcontextmodes.c @@ -1,550 +1,550 @@ -/* - * (C) Copyright IBM Corporation 2003 - * 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 - * on 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 - * VA LINUX SYSTEM, IBM AND/OR THEIR 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. - */ - -/** - * \file glcontextmodes.c - * Utility routines for working with \c __GLcontextModes structures. At - * some point most or all of these functions will be moved to the Mesa - * code base. - * - * \author Ian Romanick - */ - -#if defined(IN_MINI_GLX) -#include -#else -#if defined(HAVE_DIX_CONFIG_H) -# include -#endif -#include -#include -#include "GL/glxint.h" -#endif - -/* Memory macros */ -#if defined(IN_MINI_GLX) -# include -# include -# define _mesa_malloc(b) malloc(b) -# define _mesa_free(m) free(m) -# define _mesa_memset memset -#else -# ifdef XFree86Server -# include -# include -# define _mesa_malloc(b) xalloc(b) -# define _mesa_free(m) xfree(m) -# define _mesa_memset memset -# else -# include -# define _mesa_memset memset -# define _mesa_malloc(b) Xmalloc(b) -# define _mesa_free(m) Xfree(m) -# endif /* XFree86Server */ -#endif /* !defined(IN_MINI_GLX) */ - -#include "glcontextmodes.h" - -#if !defined(IN_MINI_GLX) -#define NUM_VISUAL_TYPES 6 - -/** - * Convert an X visual type to a GLX visual type. - * - * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) - * to be converted. - * \return If \c visualType is a valid X visual type, a GLX visual type will - * be returned. Otherwise \c GLX_NONE will be returned. - */ -GLint -_gl_convert_from_x_visual_type( int visualType ) -{ - static const int glx_visual_types[ NUM_VISUAL_TYPES ] = { - GLX_STATIC_GRAY, GLX_GRAY_SCALE, - GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, - GLX_TRUE_COLOR, GLX_DIRECT_COLOR - }; - - return ( (unsigned) visualType < NUM_VISUAL_TYPES ) - ? glx_visual_types[ visualType ] : GLX_NONE; -} - - -/** - * Convert a GLX visual type to an X visual type. - * - * \param visualType GLX visual type (i.e., \c GLX_TRUE_COLOR, - * \c GLX_STATIC_GRAY, etc.) to be converted. - * \return If \c visualType is a valid GLX visual type, an X visual type will - * be returned. Otherwise -1 will be returned. - */ -GLint -_gl_convert_to_x_visual_type( int visualType ) -{ - static const int x_visual_types[ NUM_VISUAL_TYPES ] = { - TrueColor, DirectColor, - PseudoColor, StaticColor, - GrayScale, StaticGray - }; - - return ( (unsigned) (visualType - GLX_TRUE_COLOR) < NUM_VISUAL_TYPES ) - ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1; -} - - -/** - * Copy a GLX visual config structure to a GL context mode structure. All - * of the fields in \c config are copied to \c mode. Additional fields in - * \c mode that can be derrived from the fields of \c config (i.e., - * \c haveDepthBuffer) are also filled in. The remaining fields in \c mode - * that cannot be derived are set to default values. - * - * \param mode Destination GL context mode. - * \param config Source GLX visual config. - * - * \note - * The \c fbconfigID and \c visualID fields of the \c __GLcontextModes - * structure will be set to the \c vid of the \c __GLXvisualConfig structure. - */ -void -_gl_copy_visual_to_context_mode( __GLcontextModes * mode, - const __GLXvisualConfig * config ) -{ - __GLcontextModes * const next = mode->next; - - (void) _mesa_memset( mode, 0, sizeof( __GLcontextModes ) ); - mode->next = next; - - mode->visualID = config->vid; - mode->visualType = _gl_convert_from_x_visual_type( config->class ); - mode->xRenderable = GL_TRUE; - mode->fbconfigID = config->vid; - mode->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; - - mode->rgbMode = (config->rgba != 0); - mode->renderType = (mode->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; - - mode->colorIndexMode = !(mode->rgbMode); - mode->doubleBufferMode = (config->doubleBuffer != 0); - mode->stereoMode = (config->stereo != 0); - - mode->haveAccumBuffer = ((config->accumRedSize + - config->accumGreenSize + - config->accumBlueSize + - config->accumAlphaSize) > 0); - mode->haveDepthBuffer = (config->depthSize > 0); - mode->haveStencilBuffer = (config->stencilSize > 0); - - mode->redBits = config->redSize; - mode->greenBits = config->greenSize; - mode->blueBits = config->blueSize; - mode->alphaBits = config->alphaSize; - mode->redMask = config->redMask; - mode->greenMask = config->greenMask; - mode->blueMask = config->blueMask; - mode->alphaMask = config->alphaMask; - mode->rgbBits = mode->rgbMode ? config->bufferSize : 0; - mode->indexBits = mode->colorIndexMode ? config->bufferSize : 0; - - mode->accumRedBits = config->accumRedSize; - mode->accumGreenBits = config->accumGreenSize; - mode->accumBlueBits = config->accumBlueSize; - mode->accumAlphaBits = config->accumAlphaSize; - mode->depthBits = config->depthSize; - mode->stencilBits = config->stencilSize; - - mode->numAuxBuffers = config->auxBuffers; - mode->level = config->level; - - mode->visualRating = config->visualRating; - mode->transparentPixel = config->transparentPixel; - mode->transparentRed = config->transparentRed; - mode->transparentGreen = config->transparentGreen; - mode->transparentBlue = config->transparentBlue; - mode->transparentAlpha = config->transparentAlpha; - mode->transparentIndex = config->transparentIndex; - mode->samples = config->multiSampleSize; - mode->sampleBuffers = config->nMultiSampleBuffers; - /* mode->visualSelectGroup = config->visualSelectGroup; ? */ - - mode->swapMethod = GLX_SWAP_UNDEFINED_OML; - - mode->bindToTextureRgb = (mode->rgbMode) ? GL_TRUE : GL_FALSE; - mode->bindToTextureRgba = (mode->rgbMode && mode->alphaBits) ? - GL_TRUE : GL_FALSE; - mode->bindToMipmapTexture = mode->rgbMode ? GL_TRUE : GL_FALSE; - mode->bindToTextureTargets = mode->rgbMode ? - GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT | - GLX_TEXTURE_RECTANGLE_BIT_EXT : 0; - mode->yInverted = GL_FALSE; -} - - -/** - * Get data from a GL context mode. - * - * \param mode GL context mode whose data is to be returned. - * \param attribute Attribute of \c mode that is to be returned. - * \param value_return Location to store the data member of \c mode. - * \return If \c attribute is a valid attribute of \c mode, zero is - * returned. Otherwise \c GLX_BAD_ATTRIBUTE is returned. - */ -int -_gl_get_context_mode_data(const __GLcontextModes *mode, int attribute, - int *value_return) -{ - switch (attribute) { - case GLX_USE_GL: - *value_return = GL_TRUE; - return 0; - case GLX_BUFFER_SIZE: - *value_return = mode->rgbBits; - return 0; - case GLX_RGBA: - *value_return = mode->rgbMode; - return 0; - case GLX_RED_SIZE: - *value_return = mode->redBits; - return 0; - case GLX_GREEN_SIZE: - *value_return = mode->greenBits; - return 0; - case GLX_BLUE_SIZE: - *value_return = mode->blueBits; - return 0; - case GLX_ALPHA_SIZE: - *value_return = mode->alphaBits; - return 0; - case GLX_DOUBLEBUFFER: - *value_return = mode->doubleBufferMode; - return 0; - case GLX_STEREO: - *value_return = mode->stereoMode; - return 0; - case GLX_AUX_BUFFERS: - *value_return = mode->numAuxBuffers; - return 0; - case GLX_DEPTH_SIZE: - *value_return = mode->depthBits; - return 0; - case GLX_STENCIL_SIZE: - *value_return = mode->stencilBits; - return 0; - case GLX_ACCUM_RED_SIZE: - *value_return = mode->accumRedBits; - return 0; - case GLX_ACCUM_GREEN_SIZE: - *value_return = mode->accumGreenBits; - return 0; - case GLX_ACCUM_BLUE_SIZE: - *value_return = mode->accumBlueBits; - return 0; - case GLX_ACCUM_ALPHA_SIZE: - *value_return = mode->accumAlphaBits; - return 0; - case GLX_LEVEL: - *value_return = mode->level; - return 0; - case GLX_TRANSPARENT_TYPE_EXT: - *value_return = mode->transparentPixel; - return 0; - case GLX_TRANSPARENT_RED_VALUE: - *value_return = mode->transparentRed; - return 0; - case GLX_TRANSPARENT_GREEN_VALUE: - *value_return = mode->transparentGreen; - return 0; - case GLX_TRANSPARENT_BLUE_VALUE: - *value_return = mode->transparentBlue; - return 0; - case GLX_TRANSPARENT_ALPHA_VALUE: - *value_return = mode->transparentAlpha; - return 0; - case GLX_TRANSPARENT_INDEX_VALUE: - *value_return = mode->transparentIndex; - return 0; - case GLX_X_VISUAL_TYPE: - *value_return = mode->visualType; - return 0; - case GLX_CONFIG_CAVEAT: - *value_return = mode->visualRating; - return 0; - case GLX_VISUAL_ID: - *value_return = mode->visualID; - return 0; - case GLX_DRAWABLE_TYPE: - *value_return = mode->drawableType; - return 0; - case GLX_RENDER_TYPE: - *value_return = mode->renderType; - return 0; - case GLX_X_RENDERABLE: - *value_return = mode->xRenderable; - return 0; - case GLX_FBCONFIG_ID: - *value_return = mode->fbconfigID; - return 0; - case GLX_MAX_PBUFFER_WIDTH: - *value_return = mode->maxPbufferWidth; - return 0; - case GLX_MAX_PBUFFER_HEIGHT: - *value_return = mode->maxPbufferHeight; - return 0; - case GLX_MAX_PBUFFER_PIXELS: - *value_return = mode->maxPbufferPixels; - return 0; - case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX: - *value_return = mode->optimalPbufferWidth; - return 0; - case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX: - *value_return = mode->optimalPbufferHeight; - return 0; - case GLX_SWAP_METHOD_OML: - *value_return = mode->swapMethod; - return 0; - case GLX_SAMPLE_BUFFERS_SGIS: - *value_return = mode->sampleBuffers; - return 0; - case GLX_SAMPLES_SGIS: - *value_return = mode->samples; - return 0; - case GLX_BIND_TO_TEXTURE_RGB_EXT: - *value_return = mode->bindToTextureRgb; - return 0; - case GLX_BIND_TO_TEXTURE_RGBA_EXT: - *value_return = mode->bindToTextureRgba; - return 0; - case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: - *value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE : - GL_FALSE; - return 0; - case GLX_BIND_TO_TEXTURE_TARGETS_EXT: - *value_return = mode->bindToTextureTargets; - return 0; - case GLX_Y_INVERTED_EXT: - *value_return = mode->yInverted; - return 0; - - /* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX. - * It is ONLY for communication between the GLX client and the GLX - * server. - */ - case GLX_VISUAL_SELECT_GROUP_SGIX: - default: - return GLX_BAD_ATTRIBUTE; - } -} -#endif /* !defined(IN_MINI_GLX) */ - - -/** - * Allocate a linked list of \c __GLcontextModes structures. The fields of - * each structure will be initialized to "reasonable" default values. In - * most cases this is the default value defined by table 3.4 of the GLX - * 1.3 specification. This means that most values are either initialized to - * zero or \c GLX_DONT_CARE (which is -1). As support for additional - * extensions is added, the new values will be initialized to appropriate - * values from the extension specification. - * - * \param count Number of structures to allocate. - * \param minimum_size Minimum size of a structure to allocate. This allows - * for differences in the version of the - * \c __GLcontextModes stucture used in libGL and in a - * DRI-based driver. - * \returns A pointer to the first element in a linked list of \c count - * stuctures on success, or \c NULL on failure. - * - * \warning Use of \c minimum_size does \b not guarantee binary compatibility. - * The fundamental assumption is that if the \c minimum_size - * specified by the driver and the size of the \c __GLcontextModes - * structure in libGL is the same, then the meaning of each byte in - * the structure is the same in both places. \b Be \b careful! - * Basically this means that fields have to be added in libGL and - * then propagated to drivers. Drivers should \b never arbitrarilly - * extend the \c __GLcontextModes data-structure. - */ -__GLcontextModes * -_gl_context_modes_create( unsigned count, size_t minimum_size ) -{ - const size_t size = (minimum_size > sizeof( __GLcontextModes )) - ? minimum_size : sizeof( __GLcontextModes ); - __GLcontextModes * base = NULL; - __GLcontextModes ** next; - unsigned i; - - next = & base; - for ( i = 0 ; i < count ; i++ ) { - *next = (__GLcontextModes *) _mesa_malloc( size ); - if ( *next == NULL ) { - _gl_context_modes_destroy( base ); - base = NULL; - break; - } - - (void) _mesa_memset( *next, 0, size ); - (*next)->visualID = GLX_DONT_CARE; - (*next)->visualType = GLX_DONT_CARE; - (*next)->visualRating = GLX_NONE; - (*next)->transparentPixel = GLX_NONE; - (*next)->transparentRed = GLX_DONT_CARE; - (*next)->transparentGreen = GLX_DONT_CARE; - (*next)->transparentBlue = GLX_DONT_CARE; - (*next)->transparentAlpha = GLX_DONT_CARE; - (*next)->transparentIndex = GLX_DONT_CARE; - (*next)->xRenderable = GLX_DONT_CARE; - (*next)->fbconfigID = GLX_DONT_CARE; - (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; - (*next)->bindToTextureRgb = GLX_DONT_CARE; - (*next)->bindToTextureRgba = GLX_DONT_CARE; - (*next)->bindToMipmapTexture = GLX_DONT_CARE; - (*next)->bindToTextureTargets = GLX_DONT_CARE; - (*next)->yInverted = GLX_DONT_CARE; - - next = & ((*next)->next); - } - - return base; -} - - -/** - * Destroy a linked list of \c __GLcontextModes structures created by - * \c _gl_context_modes_create. - * - * \param modes Linked list of structures to be destroyed. All structres - * in the list will be freed. - */ -void -_gl_context_modes_destroy( __GLcontextModes * modes ) -{ - while ( modes != NULL ) { - __GLcontextModes * const next = modes->next; - - _mesa_free( modes ); - modes = next; - } -} - - -/** - * Find a context mode matching a Visual ID. - * - * \param modes List list of context-mode structures to be searched. - * \param vid Visual ID to be found. - * \returns A pointer to a context-mode in \c modes if \c vid was found in - * the list, or \c NULL if it was not. - */ - -__GLcontextModes * -_gl_context_modes_find_visual(__GLcontextModes *modes, int vid) -{ - __GLcontextModes *m; - - for (m = modes; m != NULL; m = m->next) - if (m->visualID == vid) - return m; - - return NULL; -} - -__GLcontextModes * -_gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid) -{ - __GLcontextModes *m; - - for (m = modes; m != NULL; m = m->next) - if (m->fbconfigID == fbid) - return m; - - return NULL; -} - -/** - * Determine if two context-modes are the same. This is intended to be used - * by libGL implementations to compare to sets of driver generated FBconfigs. - * - * \param a Context-mode to be compared. - * \param b Context-mode to be compared. - * \returns \c GL_TRUE if the two context-modes are the same. \c GL_FALSE is - * returned otherwise. - */ -GLboolean -_gl_context_modes_are_same( const __GLcontextModes * a, - const __GLcontextModes * b ) -{ - return( (a->rgbMode == b->rgbMode) && - (a->floatMode == b->floatMode) && - (a->colorIndexMode == b->colorIndexMode) && - (a->doubleBufferMode == b->doubleBufferMode) && - (a->stereoMode == b->stereoMode) && - (a->redBits == b->redBits) && - (a->greenBits == b->greenBits) && - (a->blueBits == b->blueBits) && - (a->alphaBits == b->alphaBits) && -#if 0 /* For some reason these don't get set on the client-side in libGL. */ - (a->redMask == b->redMask) && - (a->greenMask == b->greenMask) && - (a->blueMask == b->blueMask) && - (a->alphaMask == b->alphaMask) && -#endif - (a->rgbBits == b->rgbBits) && - (a->indexBits == b->indexBits) && - (a->accumRedBits == b->accumRedBits) && - (a->accumGreenBits == b->accumGreenBits) && - (a->accumBlueBits == b->accumBlueBits) && - (a->accumAlphaBits == b->accumAlphaBits) && - (a->depthBits == b->depthBits) && - (a->stencilBits == b->stencilBits) && - (a->numAuxBuffers == b->numAuxBuffers) && - (a->level == b->level) && - (a->pixmapMode == b->pixmapMode) && - (a->visualRating == b->visualRating) && - - (a->transparentPixel == b->transparentPixel) && - - ((a->transparentPixel != GLX_TRANSPARENT_RGB) || - ((a->transparentRed == b->transparentRed) && - (a->transparentGreen == b->transparentGreen) && - (a->transparentBlue == b->transparentBlue) && - (a->transparentAlpha == b->transparentAlpha))) && - - ((a->transparentPixel != GLX_TRANSPARENT_INDEX) || - (a->transparentIndex == b->transparentIndex)) && - - (a->sampleBuffers == b->sampleBuffers) && - (a->samples == b->samples) && - ((a->drawableType & b->drawableType) != 0) && - (a->renderType == b->renderType) && - (a->maxPbufferWidth == b->maxPbufferWidth) && - (a->maxPbufferHeight == b->maxPbufferHeight) && - (a->maxPbufferPixels == b->maxPbufferPixels) && - (a->optimalPbufferWidth == b->optimalPbufferWidth) && - (a->optimalPbufferHeight == b->optimalPbufferHeight) && - (a->swapMethod == b->swapMethod) && - (a->bindToTextureRgb == b->bindToTextureRgb) && - (a->bindToTextureRgba == b->bindToTextureRgba) && - (a->bindToMipmapTexture == b->bindToMipmapTexture) && - (a->bindToTextureTargets == b->bindToTextureTargets) && - (a->yInverted == b->yInverted) ); -} +/* + * (C) Copyright IBM Corporation 2003 + * 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 + * on 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 + * VA LINUX SYSTEM, IBM AND/OR THEIR 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. + */ + +/** + * \file glcontextmodes.c + * Utility routines for working with \c __GLcontextModes structures. At + * some point most or all of these functions will be moved to the Mesa + * code base. + * + * \author Ian Romanick + */ + +#if defined(IN_MINI_GLX) +#include +#else +#if defined(HAVE_DIX_CONFIG_H) +# include +#endif +#include +#include +#include "GL/glxint.h" +#endif + +/* Memory macros */ +#if defined(IN_MINI_GLX) +# include +# include +# define _mesa_malloc(b) malloc(b) +# define _mesa_free(m) free(m) +# define _mesa_memset memset +#else +# ifdef XFree86Server +# include +# include +# define _mesa_malloc(b) malloc(b) +# define _mesa_free(m) free(m) +# define _mesa_memset memset +# else +# include +# define _mesa_memset memset +# define _mesa_malloc(b) Xmalloc(b) +# define _mesa_free(m) free(m) +# endif /* XFree86Server */ +#endif /* !defined(IN_MINI_GLX) */ + +#include "glcontextmodes.h" + +#if !defined(IN_MINI_GLX) +#define NUM_VISUAL_TYPES 6 + +/** + * Convert an X visual type to a GLX visual type. + * + * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) + * to be converted. + * \return If \c visualType is a valid X visual type, a GLX visual type will + * be returned. Otherwise \c GLX_NONE will be returned. + */ +GLint +_gl_convert_from_x_visual_type( int visualType ) +{ + static const int glx_visual_types[ NUM_VISUAL_TYPES ] = { + GLX_STATIC_GRAY, GLX_GRAY_SCALE, + GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, + GLX_TRUE_COLOR, GLX_DIRECT_COLOR + }; + + return ( (unsigned) visualType < NUM_VISUAL_TYPES ) + ? glx_visual_types[ visualType ] : GLX_NONE; +} + + +/** + * Convert a GLX visual type to an X visual type. + * + * \param visualType GLX visual type (i.e., \c GLX_TRUE_COLOR, + * \c GLX_STATIC_GRAY, etc.) to be converted. + * \return If \c visualType is a valid GLX visual type, an X visual type will + * be returned. Otherwise -1 will be returned. + */ +GLint +_gl_convert_to_x_visual_type( int visualType ) +{ + static const int x_visual_types[ NUM_VISUAL_TYPES ] = { + TrueColor, DirectColor, + PseudoColor, StaticColor, + GrayScale, StaticGray + }; + + return ( (unsigned) (visualType - GLX_TRUE_COLOR) < NUM_VISUAL_TYPES ) + ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1; +} + + +/** + * Copy a GLX visual config structure to a GL context mode structure. All + * of the fields in \c config are copied to \c mode. Additional fields in + * \c mode that can be derrived from the fields of \c config (i.e., + * \c haveDepthBuffer) are also filled in. The remaining fields in \c mode + * that cannot be derived are set to default values. + * + * \param mode Destination GL context mode. + * \param config Source GLX visual config. + * + * \note + * The \c fbconfigID and \c visualID fields of the \c __GLcontextModes + * structure will be set to the \c vid of the \c __GLXvisualConfig structure. + */ +void +_gl_copy_visual_to_context_mode( __GLcontextModes * mode, + const __GLXvisualConfig * config ) +{ + __GLcontextModes * const next = mode->next; + + (void) _mesa_memset( mode, 0, sizeof( __GLcontextModes ) ); + mode->next = next; + + mode->visualID = config->vid; + mode->visualType = _gl_convert_from_x_visual_type( config->class ); + mode->xRenderable = GL_TRUE; + mode->fbconfigID = config->vid; + mode->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; + + mode->rgbMode = (config->rgba != 0); + mode->renderType = (mode->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + + mode->colorIndexMode = !(mode->rgbMode); + mode->doubleBufferMode = (config->doubleBuffer != 0); + mode->stereoMode = (config->stereo != 0); + + mode->haveAccumBuffer = ((config->accumRedSize + + config->accumGreenSize + + config->accumBlueSize + + config->accumAlphaSize) > 0); + mode->haveDepthBuffer = (config->depthSize > 0); + mode->haveStencilBuffer = (config->stencilSize > 0); + + mode->redBits = config->redSize; + mode->greenBits = config->greenSize; + mode->blueBits = config->blueSize; + mode->alphaBits = config->alphaSize; + mode->redMask = config->redMask; + mode->greenMask = config->greenMask; + mode->blueMask = config->blueMask; + mode->alphaMask = config->alphaMask; + mode->rgbBits = mode->rgbMode ? config->bufferSize : 0; + mode->indexBits = mode->colorIndexMode ? config->bufferSize : 0; + + mode->accumRedBits = config->accumRedSize; + mode->accumGreenBits = config->accumGreenSize; + mode->accumBlueBits = config->accumBlueSize; + mode->accumAlphaBits = config->accumAlphaSize; + mode->depthBits = config->depthSize; + mode->stencilBits = config->stencilSize; + + mode->numAuxBuffers = config->auxBuffers; + mode->level = config->level; + + mode->visualRating = config->visualRating; + mode->transparentPixel = config->transparentPixel; + mode->transparentRed = config->transparentRed; + mode->transparentGreen = config->transparentGreen; + mode->transparentBlue = config->transparentBlue; + mode->transparentAlpha = config->transparentAlpha; + mode->transparentIndex = config->transparentIndex; + mode->samples = config->multiSampleSize; + mode->sampleBuffers = config->nMultiSampleBuffers; + /* mode->visualSelectGroup = config->visualSelectGroup; ? */ + + mode->swapMethod = GLX_SWAP_UNDEFINED_OML; + + mode->bindToTextureRgb = (mode->rgbMode) ? GL_TRUE : GL_FALSE; + mode->bindToTextureRgba = (mode->rgbMode && mode->alphaBits) ? + GL_TRUE : GL_FALSE; + mode->bindToMipmapTexture = mode->rgbMode ? GL_TRUE : GL_FALSE; + mode->bindToTextureTargets = mode->rgbMode ? + GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT | + GLX_TEXTURE_RECTANGLE_BIT_EXT : 0; + mode->yInverted = GL_FALSE; +} + + +/** + * Get data from a GL context mode. + * + * \param mode GL context mode whose data is to be returned. + * \param attribute Attribute of \c mode that is to be returned. + * \param value_return Location to store the data member of \c mode. + * \return If \c attribute is a valid attribute of \c mode, zero is + * returned. Otherwise \c GLX_BAD_ATTRIBUTE is returned. + */ +int +_gl_get_context_mode_data(const __GLcontextModes *mode, int attribute, + int *value_return) +{ + switch (attribute) { + case GLX_USE_GL: + *value_return = GL_TRUE; + return 0; + case GLX_BUFFER_SIZE: + *value_return = mode->rgbBits; + return 0; + case GLX_RGBA: + *value_return = mode->rgbMode; + return 0; + case GLX_RED_SIZE: + *value_return = mode->redBits; + return 0; + case GLX_GREEN_SIZE: + *value_return = mode->greenBits; + return 0; + case GLX_BLUE_SIZE: + *value_return = mode->blueBits; + return 0; + case GLX_ALPHA_SIZE: + *value_return = mode->alphaBits; + return 0; + case GLX_DOUBLEBUFFER: + *value_return = mode->doubleBufferMode; + return 0; + case GLX_STEREO: + *value_return = mode->stereoMode; + return 0; + case GLX_AUX_BUFFERS: + *value_return = mode->numAuxBuffers; + return 0; + case GLX_DEPTH_SIZE: + *value_return = mode->depthBits; + return 0; + case GLX_STENCIL_SIZE: + *value_return = mode->stencilBits; + return 0; + case GLX_ACCUM_RED_SIZE: + *value_return = mode->accumRedBits; + return 0; + case GLX_ACCUM_GREEN_SIZE: + *value_return = mode->accumGreenBits; + return 0; + case GLX_ACCUM_BLUE_SIZE: + *value_return = mode->accumBlueBits; + return 0; + case GLX_ACCUM_ALPHA_SIZE: + *value_return = mode->accumAlphaBits; + return 0; + case GLX_LEVEL: + *value_return = mode->level; + return 0; + case GLX_TRANSPARENT_TYPE_EXT: + *value_return = mode->transparentPixel; + return 0; + case GLX_TRANSPARENT_RED_VALUE: + *value_return = mode->transparentRed; + return 0; + case GLX_TRANSPARENT_GREEN_VALUE: + *value_return = mode->transparentGreen; + return 0; + case GLX_TRANSPARENT_BLUE_VALUE: + *value_return = mode->transparentBlue; + return 0; + case GLX_TRANSPARENT_ALPHA_VALUE: + *value_return = mode->transparentAlpha; + return 0; + case GLX_TRANSPARENT_INDEX_VALUE: + *value_return = mode->transparentIndex; + return 0; + case GLX_X_VISUAL_TYPE: + *value_return = mode->visualType; + return 0; + case GLX_CONFIG_CAVEAT: + *value_return = mode->visualRating; + return 0; + case GLX_VISUAL_ID: + *value_return = mode->visualID; + return 0; + case GLX_DRAWABLE_TYPE: + *value_return = mode->drawableType; + return 0; + case GLX_RENDER_TYPE: + *value_return = mode->renderType; + return 0; + case GLX_X_RENDERABLE: + *value_return = mode->xRenderable; + return 0; + case GLX_FBCONFIG_ID: + *value_return = mode->fbconfigID; + return 0; + case GLX_MAX_PBUFFER_WIDTH: + *value_return = mode->maxPbufferWidth; + return 0; + case GLX_MAX_PBUFFER_HEIGHT: + *value_return = mode->maxPbufferHeight; + return 0; + case GLX_MAX_PBUFFER_PIXELS: + *value_return = mode->maxPbufferPixels; + return 0; + case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX: + *value_return = mode->optimalPbufferWidth; + return 0; + case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX: + *value_return = mode->optimalPbufferHeight; + return 0; + case GLX_SWAP_METHOD_OML: + *value_return = mode->swapMethod; + return 0; + case GLX_SAMPLE_BUFFERS_SGIS: + *value_return = mode->sampleBuffers; + return 0; + case GLX_SAMPLES_SGIS: + *value_return = mode->samples; + return 0; + case GLX_BIND_TO_TEXTURE_RGB_EXT: + *value_return = mode->bindToTextureRgb; + return 0; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + *value_return = mode->bindToTextureRgba; + return 0; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + *value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE : + GL_FALSE; + return 0; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + *value_return = mode->bindToTextureTargets; + return 0; + case GLX_Y_INVERTED_EXT: + *value_return = mode->yInverted; + return 0; + + /* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX. + * It is ONLY for communication between the GLX client and the GLX + * server. + */ + case GLX_VISUAL_SELECT_GROUP_SGIX: + default: + return GLX_BAD_ATTRIBUTE; + } +} +#endif /* !defined(IN_MINI_GLX) */ + + +/** + * Allocate a linked list of \c __GLcontextModes structures. The fields of + * each structure will be initialized to "reasonable" default values. In + * most cases this is the default value defined by table 3.4 of the GLX + * 1.3 specification. This means that most values are either initialized to + * zero or \c GLX_DONT_CARE (which is -1). As support for additional + * extensions is added, the new values will be initialized to appropriate + * values from the extension specification. + * + * \param count Number of structures to allocate. + * \param minimum_size Minimum size of a structure to allocate. This allows + * for differences in the version of the + * \c __GLcontextModes stucture used in libGL and in a + * DRI-based driver. + * \returns A pointer to the first element in a linked list of \c count + * stuctures on success, or \c NULL on failure. + * + * \warning Use of \c minimum_size does \b not guarantee binary compatibility. + * The fundamental assumption is that if the \c minimum_size + * specified by the driver and the size of the \c __GLcontextModes + * structure in libGL is the same, then the meaning of each byte in + * the structure is the same in both places. \b Be \b careful! + * Basically this means that fields have to be added in libGL and + * then propagated to drivers. Drivers should \b never arbitrarilly + * extend the \c __GLcontextModes data-structure. + */ +__GLcontextModes * +_gl_context_modes_create( unsigned count, size_t minimum_size ) +{ + const size_t size = (minimum_size > sizeof( __GLcontextModes )) + ? minimum_size : sizeof( __GLcontextModes ); + __GLcontextModes * base = NULL; + __GLcontextModes ** next; + unsigned i; + + next = & base; + for ( i = 0 ; i < count ; i++ ) { + *next = (__GLcontextModes *) _mesa_malloc( size ); + if ( *next == NULL ) { + _gl_context_modes_destroy( base ); + base = NULL; + break; + } + + (void) _mesa_memset( *next, 0, size ); + (*next)->visualID = GLX_DONT_CARE; + (*next)->visualType = GLX_DONT_CARE; + (*next)->visualRating = GLX_NONE; + (*next)->transparentPixel = GLX_NONE; + (*next)->transparentRed = GLX_DONT_CARE; + (*next)->transparentGreen = GLX_DONT_CARE; + (*next)->transparentBlue = GLX_DONT_CARE; + (*next)->transparentAlpha = GLX_DONT_CARE; + (*next)->transparentIndex = GLX_DONT_CARE; + (*next)->xRenderable = GLX_DONT_CARE; + (*next)->fbconfigID = GLX_DONT_CARE; + (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; + (*next)->bindToTextureRgb = GLX_DONT_CARE; + (*next)->bindToTextureRgba = GLX_DONT_CARE; + (*next)->bindToMipmapTexture = GLX_DONT_CARE; + (*next)->bindToTextureTargets = GLX_DONT_CARE; + (*next)->yInverted = GLX_DONT_CARE; + + next = & ((*next)->next); + } + + return base; +} + + +/** + * Destroy a linked list of \c __GLcontextModes structures created by + * \c _gl_context_modes_create. + * + * \param modes Linked list of structures to be destroyed. All structres + * in the list will be freed. + */ +void +_gl_context_modes_destroy( __GLcontextModes * modes ) +{ + while ( modes != NULL ) { + __GLcontextModes * const next = modes->next; + + _mesa_free( modes ); + modes = next; + } +} + + +/** + * Find a context mode matching a Visual ID. + * + * \param modes List list of context-mode structures to be searched. + * \param vid Visual ID to be found. + * \returns A pointer to a context-mode in \c modes if \c vid was found in + * the list, or \c NULL if it was not. + */ + +__GLcontextModes * +_gl_context_modes_find_visual(__GLcontextModes *modes, int vid) +{ + __GLcontextModes *m; + + for (m = modes; m != NULL; m = m->next) + if (m->visualID == vid) + return m; + + return NULL; +} + +__GLcontextModes * +_gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid) +{ + __GLcontextModes *m; + + for (m = modes; m != NULL; m = m->next) + if (m->fbconfigID == fbid) + return m; + + return NULL; +} + +/** + * Determine if two context-modes are the same. This is intended to be used + * by libGL implementations to compare to sets of driver generated FBconfigs. + * + * \param a Context-mode to be compared. + * \param b Context-mode to be compared. + * \returns \c GL_TRUE if the two context-modes are the same. \c GL_FALSE is + * returned otherwise. + */ +GLboolean +_gl_context_modes_are_same( const __GLcontextModes * a, + const __GLcontextModes * b ) +{ + return( (a->rgbMode == b->rgbMode) && + (a->floatMode == b->floatMode) && + (a->colorIndexMode == b->colorIndexMode) && + (a->doubleBufferMode == b->doubleBufferMode) && + (a->stereoMode == b->stereoMode) && + (a->redBits == b->redBits) && + (a->greenBits == b->greenBits) && + (a->blueBits == b->blueBits) && + (a->alphaBits == b->alphaBits) && +#if 0 /* For some reason these don't get set on the client-side in libGL. */ + (a->redMask == b->redMask) && + (a->greenMask == b->greenMask) && + (a->blueMask == b->blueMask) && + (a->alphaMask == b->alphaMask) && +#endif + (a->rgbBits == b->rgbBits) && + (a->indexBits == b->indexBits) && + (a->accumRedBits == b->accumRedBits) && + (a->accumGreenBits == b->accumGreenBits) && + (a->accumBlueBits == b->accumBlueBits) && + (a->accumAlphaBits == b->accumAlphaBits) && + (a->depthBits == b->depthBits) && + (a->stencilBits == b->stencilBits) && + (a->numAuxBuffers == b->numAuxBuffers) && + (a->level == b->level) && + (a->pixmapMode == b->pixmapMode) && + (a->visualRating == b->visualRating) && + + (a->transparentPixel == b->transparentPixel) && + + ((a->transparentPixel != GLX_TRANSPARENT_RGB) || + ((a->transparentRed == b->transparentRed) && + (a->transparentGreen == b->transparentGreen) && + (a->transparentBlue == b->transparentBlue) && + (a->transparentAlpha == b->transparentAlpha))) && + + ((a->transparentPixel != GLX_TRANSPARENT_INDEX) || + (a->transparentIndex == b->transparentIndex)) && + + (a->sampleBuffers == b->sampleBuffers) && + (a->samples == b->samples) && + ((a->drawableType & b->drawableType) != 0) && + (a->renderType == b->renderType) && + (a->maxPbufferWidth == b->maxPbufferWidth) && + (a->maxPbufferHeight == b->maxPbufferHeight) && + (a->maxPbufferPixels == b->maxPbufferPixels) && + (a->optimalPbufferWidth == b->optimalPbufferWidth) && + (a->optimalPbufferHeight == b->optimalPbufferHeight) && + (a->swapMethod == b->swapMethod) && + (a->bindToTextureRgb == b->bindToTextureRgb) && + (a->bindToTextureRgba == b->bindToTextureRgba) && + (a->bindToMipmapTexture == b->bindToMipmapTexture) && + (a->bindToTextureTargets == b->bindToTextureTargets) && + (a->yInverted == b->yInverted) ); +} diff --git a/xorg-server/hw/xquartz/GL/indirect.c b/xorg-server/hw/xquartz/GL/indirect.c index e56dac1a1..b40f38d31 100644 --- a/xorg-server/hw/xquartz/GL/indirect.c +++ b/xorg-server/hw/xquartz/GL/indirect.c @@ -222,7 +222,7 @@ __glXAquaScreenCreateContext(__GLXscreen *screen, GLAQUA_DEBUG_MSG("glXAquaScreenCreateContext\n"); - context = xcalloc(1, sizeof (__GLXAquaContext)); + context = calloc(1, sizeof (__GLXAquaContext)); if (context == NULL) return NULL; @@ -241,7 +241,7 @@ __glXAquaScreenCreateContext(__GLXscreen *screen, context->pixelFormat = makeFormat(conf); if (!context->pixelFormat) { - xfree(context); + free(context); return NULL; } @@ -253,7 +253,7 @@ __glXAquaScreenCreateContext(__GLXscreen *screen, if (gl_err != 0) { ErrorF("CGLCreateContext error: %s\n", CGLErrorString(gl_err)); CGLDestroyPixelFormat(context->pixelFormat); - xfree(context); + free(context); return NULL; } @@ -286,7 +286,7 @@ static void __glXAquaContextDestroy(__GLXcontext *baseContext) { if (context->pixelFormat != NULL) CGLDestroyPixelFormat(context->pixelFormat); - xfree(context); + free(context); } } @@ -566,7 +566,7 @@ static void __glXAquaScreenDestroy(__GLXscreen *screen) { GLAQUA_DEBUG_MSG("glXAquaScreenDestroy(%p)\n", screen); __glXScreenDestroy(screen); - xfree(screen); + free(screen); } /* This is called by __glXInitScreens(). */ @@ -578,7 +578,7 @@ static __GLXscreen * __glXAquaScreenProbe(ScreenPtr pScreen) { if (pScreen == NULL) return NULL; - screen = xcalloc(1, sizeof *screen); + screen = calloc(1, sizeof *screen); if(NULL == screen) return NULL; @@ -635,7 +635,7 @@ static void __glXAquaDrawableDestroy(__GLXdrawable *base) { *to validate the test, beyond using gdb with print. */ - xfree(glxPriv); + free(glxPriv); } static __GLXdrawable * @@ -648,7 +648,7 @@ __glXAquaScreenCreateDrawable(ClientPtr client, __GLXconfig *conf) { __GLXAquaDrawable *glxPriv; - glxPriv = xalloc(sizeof *glxPriv); + glxPriv = malloc(sizeof *glxPriv); if(glxPriv == NULL) return NULL; @@ -656,7 +656,7 @@ __glXAquaScreenCreateDrawable(ClientPtr client, memset(glxPriv, 0, sizeof *glxPriv); if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, glxDrawId, conf)) { - xfree(glxPriv); + free(glxPriv); return NULL; } diff --git a/xorg-server/hw/xquartz/GL/visualConfigs.c b/xorg-server/hw/xquartz/GL/visualConfigs.c index cecc90265..0d5793262 100644 --- a/xorg-server/hw/xquartz/GL/visualConfigs.c +++ b/xorg-server/hw/xquartz/GL/visualConfigs.c @@ -1,285 +1,285 @@ -/* - * Copyright (c) 2007, 2008 Apple Inc. - * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved. - * Copyright (c) 2002 Greg Parker. All Rights Reserved. - * - * Portions of this file are copied from Mesa's xf86glx.c, - * which contains the following copyright: - * - * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. - * 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. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "dri.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "capabilities.h" -#include "visualConfigs.h" -#include "darwinfb.h" - -/* Based originally on code from indirect.c which was based on code from i830_dri.c. */ -__GLXconfig *__glXAquaCreateVisualConfigs(int *numConfigsPtr, int screenNumber) { - int numConfigs = 0; - __GLXconfig *visualConfigs, *c; - struct glCapabilities caps; - struct glCapabilitiesConfig *conf; - int stereo, depth, aux, buffers, stencil, accum, color, msample; - - if(getGlCapabilities(&caps)) { - ErrorF("error from getGlCapabilities()!\n"); - return NULL; - } - - /* - conf->stereo is 0 or 1, but we need at least 1 iteration of the loop, - so we treat a true conf->stereo as 2. - - The depth size is 0 or 24. Thus we do 2 iterations for that. - - conf->aux_buffers (when available/non-zero) result in 2 iterations instead of 1. - - conf->buffers indicates whether we have single or double buffering. - - conf->total_stencil_bit_depths - - conf->total_color_buffers indicates the RGB/RGBA color depths. - - conf->total_accum_buffers iterations for accum (with at least 1 if equal to 0) - - conf->total_depth_buffer_depths - - conf->multisample_buffers iterations (with at least 1 if equal to 0). We add 1 - for the 0 multisampling config. - - */ - - assert(NULL != caps.configurations); - - numConfigs = 0; - - for(conf = caps.configurations; conf; conf = conf->next) { - if(conf->total_color_buffers <= 0) - continue; - - numConfigs += (conf->stereo ? 2 : 1) - * (conf->aux_buffers ? 2 : 1) - * conf->buffers - * ((conf->total_stencil_bit_depths > 0) ? conf->total_stencil_bit_depths : 1) - * conf->total_color_buffers - * ((conf->total_accum_buffers > 0) ? conf->total_accum_buffers : 1) - * conf->total_depth_buffer_depths - * (conf->multisample_buffers + 1); - } - - if(numConfigsPtr) - *numConfigsPtr = numConfigs; - - visualConfigs = xcalloc(sizeof(*visualConfigs), numConfigs); - - if(NULL == visualConfigs) { - ErrorF("xcalloc failure when allocating visualConfigs\n"); - freeGlCapabilities(&caps); - return NULL; - } - - c = visualConfigs; /* current buffer */ - for(conf = caps.configurations; conf; conf = conf->next) { - for(stereo = 0; stereo < (conf->stereo ? 2 : 1); ++stereo) { - for(aux = 0; aux < (conf->aux_buffers ? 2 : 1); ++aux) { - for(buffers = 0; buffers < conf->buffers; ++buffers) { - for(stencil = 0; stencil < ((conf->total_stencil_bit_depths > 0) ? - conf->total_stencil_bit_depths : 1); ++stencil) { - for(color = 0; color < conf->total_color_buffers; ++color) { - for(accum = 0; accum < ((conf->total_accum_buffers > 0) ? - conf->total_accum_buffers : 1); ++accum) { - for(depth = 0; depth < conf->total_depth_buffer_depths; ++depth) { - for(msample = 0; msample < (conf->multisample_buffers + 1); ++msample) { - - // Global - c->visualID = -1; - c->visualType = GLX_TRUE_COLOR; - c->next = c + 1; - - c->screen = screenNumber; - - c->level = 0; - c->indexBits = 0; - c->pixmapMode = 0; // TODO: What should this be? - - if(conf->accelerated) { - c->visualRating = GLX_NONE; - } else { - c->visualRating = GLX_SLOW_VISUAL_EXT; - } - - c->transparentPixel = GLX_NONE; - c->transparentRed = GLX_NONE; - c->transparentGreen = GLX_NONE; - c->transparentBlue = GLX_NONE; - c->transparentAlpha = GLX_NONE; - c->transparentIndex = GLX_NONE; - - c->visualSelectGroup = 0; - - c->swapMethod = GLX_SWAP_UNDEFINED_OML; - - // Stereo - c->stereoMode = stereo ? TRUE : FALSE; - - // Aux buffers - c->numAuxBuffers = aux ? conf->aux_buffers : 0; - - // Double Buffered - c->doubleBufferMode = buffers ? TRUE : FALSE; - - // Stencil Buffer - if(conf->total_stencil_bit_depths > 0) { - c->stencilBits = conf->stencil_bit_depths[stencil]; - } else { - c->stencilBits = 0; - } - - // Color - if(GLCAPS_COLOR_BUF_INVALID_VALUE != conf->color_buffers[color].a) { - c->alphaBits = conf->color_buffers[color].a; - } else { - c->alphaBits = 0; - } - c->redBits = conf->color_buffers[color].r; - c->greenBits = conf->color_buffers[color].g; - c->blueBits = conf->color_buffers[color].b; - - c->rgbBits = c->alphaBits + c->redBits + c->greenBits + c->blueBits; - - c->alphaMask = AM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits); - c->redMask = RM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits); - c->greenMask = GM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits); - c->blueMask = BM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits); - - // Accumulation Buffers - if(conf->total_accum_buffers > 0) { - c->accumRedBits = conf->accum_buffers[accum].r; - c->accumGreenBits = conf->accum_buffers[accum].g; - c->accumBlueBits = conf->accum_buffers[accum].b; - if(GLCAPS_COLOR_BUF_INVALID_VALUE != conf->accum_buffers[accum].a) { - c->accumAlphaBits = conf->accum_buffers[accum].a; - } else { - c->accumAlphaBits = 0; - } - } else { - c->accumRedBits = 0; - c->accumGreenBits = 0; - c->accumBlueBits = 0; - c->accumAlphaBits = 0; - } - - // Depth - c->depthBits = conf->depth_buffers[depth]; - - // MultiSample - if(msample > 0) { - c->samples = conf->multisample_samples; - c->sampleBuffers = conf->multisample_buffers; - } else { - c->samples = 0; - c->sampleBuffers = 0; - } - - /* - * The Apple libGL supports GLXPixmaps and - * GLXPbuffers in direct mode. - */ - /* SGIX_fbconfig / GLX 1.3 */ - c->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; - c->renderType = GLX_RGBA_BIT; - c->xRenderable = GL_TRUE; - c->fbconfigID = -1; - - /* SGIX_pbuffer / GLX 1.3 */ - - /* - * The CGL layer provides a way of retrieving - * the maximum pbuffer width/height, but only - * if we create a context and call glGetIntegerv. - * - * The following values are from a test program - * that does so. - */ - c->maxPbufferWidth = 8192; - c->maxPbufferHeight = 8192; - c->maxPbufferPixels = /*Do we need this?*/ 0; - /* - * There is no introspection for this sort of thing - * with CGL. What should we do realistically? - */ - c->optimalPbufferWidth = 0; - c->optimalPbufferHeight = 0; - - /* EXT_texture_from_pixmap */ - c->bindToTextureRgb = 0; - c->bindToTextureRgba = 0; - c->bindToMipmapTexture = 0; - c->bindToTextureTargets = 0; - c->yInverted = 0; - - c = c->next; - } - } - } - } - } - } - } - } - } - - (c-1)->next = NULL; - - if (c - visualConfigs != numConfigs) { - FatalError("numConfigs calculation error in setVisualConfigs! numConfigs is %d i is %d\n", numConfigs, (int)(c - visualConfigs)); - } - - freeGlCapabilities(&caps); - return visualConfigs; -} +/* + * Copyright (c) 2007, 2008 Apple Inc. + * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved. + * Copyright (c) 2002 Greg Parker. All Rights Reserved. + * + * Portions of this file are copied from Mesa's xf86glx.c, + * which contains the following copyright: + * + * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + * 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "dri.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "capabilities.h" +#include "visualConfigs.h" +#include "darwinfb.h" + +/* Based originally on code from indirect.c which was based on code from i830_dri.c. */ +__GLXconfig *__glXAquaCreateVisualConfigs(int *numConfigsPtr, int screenNumber) { + int numConfigs = 0; + __GLXconfig *visualConfigs, *c; + struct glCapabilities caps; + struct glCapabilitiesConfig *conf; + int stereo, depth, aux, buffers, stencil, accum, color, msample; + + if(getGlCapabilities(&caps)) { + ErrorF("error from getGlCapabilities()!\n"); + return NULL; + } + + /* + conf->stereo is 0 or 1, but we need at least 1 iteration of the loop, + so we treat a true conf->stereo as 2. + + The depth size is 0 or 24. Thus we do 2 iterations for that. + + conf->aux_buffers (when available/non-zero) result in 2 iterations instead of 1. + + conf->buffers indicates whether we have single or double buffering. + + conf->total_stencil_bit_depths + + conf->total_color_buffers indicates the RGB/RGBA color depths. + + conf->total_accum_buffers iterations for accum (with at least 1 if equal to 0) + + conf->total_depth_buffer_depths + + conf->multisample_buffers iterations (with at least 1 if equal to 0). We add 1 + for the 0 multisampling config. + + */ + + assert(NULL != caps.configurations); + + numConfigs = 0; + + for(conf = caps.configurations; conf; conf = conf->next) { + if(conf->total_color_buffers <= 0) + continue; + + numConfigs += (conf->stereo ? 2 : 1) + * (conf->aux_buffers ? 2 : 1) + * conf->buffers + * ((conf->total_stencil_bit_depths > 0) ? conf->total_stencil_bit_depths : 1) + * conf->total_color_buffers + * ((conf->total_accum_buffers > 0) ? conf->total_accum_buffers : 1) + * conf->total_depth_buffer_depths + * (conf->multisample_buffers + 1); + } + + if(numConfigsPtr) + *numConfigsPtr = numConfigs; + + visualConfigs = calloc(sizeof(*visualConfigs), numConfigs); + + if(NULL == visualConfigs) { + ErrorF("xcalloc failure when allocating visualConfigs\n"); + freeGlCapabilities(&caps); + return NULL; + } + + c = visualConfigs; /* current buffer */ + for(conf = caps.configurations; conf; conf = conf->next) { + for(stereo = 0; stereo < (conf->stereo ? 2 : 1); ++stereo) { + for(aux = 0; aux < (conf->aux_buffers ? 2 : 1); ++aux) { + for(buffers = 0; buffers < conf->buffers; ++buffers) { + for(stencil = 0; stencil < ((conf->total_stencil_bit_depths > 0) ? + conf->total_stencil_bit_depths : 1); ++stencil) { + for(color = 0; color < conf->total_color_buffers; ++color) { + for(accum = 0; accum < ((conf->total_accum_buffers > 0) ? + conf->total_accum_buffers : 1); ++accum) { + for(depth = 0; depth < conf->total_depth_buffer_depths; ++depth) { + for(msample = 0; msample < (conf->multisample_buffers + 1); ++msample) { + + // Global + c->visualID = -1; + c->visualType = GLX_TRUE_COLOR; + c->next = c + 1; + + c->screen = screenNumber; + + c->level = 0; + c->indexBits = 0; + c->pixmapMode = 0; // TODO: What should this be? + + if(conf->accelerated) { + c->visualRating = GLX_NONE; + } else { + c->visualRating = GLX_SLOW_VISUAL_EXT; + } + + c->transparentPixel = GLX_NONE; + c->transparentRed = GLX_NONE; + c->transparentGreen = GLX_NONE; + c->transparentBlue = GLX_NONE; + c->transparentAlpha = GLX_NONE; + c->transparentIndex = GLX_NONE; + + c->visualSelectGroup = 0; + + c->swapMethod = GLX_SWAP_UNDEFINED_OML; + + // Stereo + c->stereoMode = stereo ? TRUE : FALSE; + + // Aux buffers + c->numAuxBuffers = aux ? conf->aux_buffers : 0; + + // Double Buffered + c->doubleBufferMode = buffers ? TRUE : FALSE; + + // Stencil Buffer + if(conf->total_stencil_bit_depths > 0) { + c->stencilBits = conf->stencil_bit_depths[stencil]; + } else { + c->stencilBits = 0; + } + + // Color + if(GLCAPS_COLOR_BUF_INVALID_VALUE != conf->color_buffers[color].a) { + c->alphaBits = conf->color_buffers[color].a; + } else { + c->alphaBits = 0; + } + c->redBits = conf->color_buffers[color].r; + c->greenBits = conf->color_buffers[color].g; + c->blueBits = conf->color_buffers[color].b; + + c->rgbBits = c->alphaBits + c->redBits + c->greenBits + c->blueBits; + + c->alphaMask = AM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits); + c->redMask = RM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits); + c->greenMask = GM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits); + c->blueMask = BM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits); + + // Accumulation Buffers + if(conf->total_accum_buffers > 0) { + c->accumRedBits = conf->accum_buffers[accum].r; + c->accumGreenBits = conf->accum_buffers[accum].g; + c->accumBlueBits = conf->accum_buffers[accum].b; + if(GLCAPS_COLOR_BUF_INVALID_VALUE != conf->accum_buffers[accum].a) { + c->accumAlphaBits = conf->accum_buffers[accum].a; + } else { + c->accumAlphaBits = 0; + } + } else { + c->accumRedBits = 0; + c->accumGreenBits = 0; + c->accumBlueBits = 0; + c->accumAlphaBits = 0; + } + + // Depth + c->depthBits = conf->depth_buffers[depth]; + + // MultiSample + if(msample > 0) { + c->samples = conf->multisample_samples; + c->sampleBuffers = conf->multisample_buffers; + } else { + c->samples = 0; + c->sampleBuffers = 0; + } + + /* + * The Apple libGL supports GLXPixmaps and + * GLXPbuffers in direct mode. + */ + /* SGIX_fbconfig / GLX 1.3 */ + c->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT; + c->renderType = GLX_RGBA_BIT; + c->xRenderable = GL_TRUE; + c->fbconfigID = -1; + + /* SGIX_pbuffer / GLX 1.3 */ + + /* + * The CGL layer provides a way of retrieving + * the maximum pbuffer width/height, but only + * if we create a context and call glGetIntegerv. + * + * The following values are from a test program + * that does so. + */ + c->maxPbufferWidth = 8192; + c->maxPbufferHeight = 8192; + c->maxPbufferPixels = /*Do we need this?*/ 0; + /* + * There is no introspection for this sort of thing + * with CGL. What should we do realistically? + */ + c->optimalPbufferWidth = 0; + c->optimalPbufferHeight = 0; + + /* EXT_texture_from_pixmap */ + c->bindToTextureRgb = 0; + c->bindToTextureRgba = 0; + c->bindToMipmapTexture = 0; + c->bindToTextureTargets = 0; + c->yInverted = 0; + + c = c->next; + } + } + } + } + } + } + } + } + } + + (c-1)->next = NULL; + + if (c - visualConfigs != numConfigs) { + FatalError("numConfigs calculation error in setVisualConfigs! numConfigs is %d i is %d\n", numConfigs, (int)(c - visualConfigs)); + } + + freeGlCapabilities(&caps); + return visualConfigs; +} diff --git a/xorg-server/hw/xquartz/applewm.c b/xorg-server/hw/xquartz/applewm.c index 15c86de00..b0f811750 100644 --- a/xorg-server/hw/xquartz/applewm.c +++ b/xorg-server/hw/xquartz/applewm.c @@ -1,746 +1,746 @@ -/************************************************************************** - -Copyright (c) 2002-2007 Apple 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, 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. - -**************************************************************************/ - -#include "sanitizedCarbon.h" - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "quartzCommon.h" - -#include "misc.h" -#include "dixstruct.h" -#include "globals.h" -#include "extnsionst.h" -#include "colormapst.h" -#include "cursorstr.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "servermd.h" -#include "swaprep.h" -#include "propertyst.h" -#include -#include "darwin.h" -#define _APPLEWM_SERVER_ -#include -#include "applewmExt.h" -#include "X11Application.h" -#include "protocol-versions.h" - -#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_screen_origin, "_NATIVE_SCREEN_ORIGIN") -DEFINE_ATOM_HELPER (xa_apple_no_order_in, "_APPLE_NO_ORDER_IN") - -static AppleWMProcsPtr appleWMProcs; - -static int WMErrorBase; - -static DISPATCH_PROC(ProcAppleWMDispatch); -static DISPATCH_PROC(SProcAppleWMDispatch); - -static unsigned char WMReqCode = 0; -static int WMEventBase = 0; - -static RESTYPE ClientType, EventType; /* resource types for event masks */ -static XID eventResource; - -/* Currently selected events */ -static unsigned int eventMask = 0; - -static int WMFreeClient (pointer data, XID id); -static int WMFreeEvents (pointer data, XID id); -static void SNotifyEvent(xAppleWMNotifyEvent *from, xAppleWMNotifyEvent *to); - -typedef struct _WMEvent *WMEventPtr; -typedef struct _WMEvent { - WMEventPtr next; - ClientPtr client; - XID clientResource; - unsigned int mask; -} WMEventRec; - -static inline BoxRec -make_box (int x, int y, int w, int h) -{ - BoxRec r; - r.x1 = x; - r.y1 = y; - r.x2 = x + w; - r.y2 = y + h; - return r; -} - -void -AppleWMExtensionInit( - AppleWMProcsPtr procsPtr) -{ - ExtensionEntry* extEntry; - - ClientType = CreateNewResourceType(WMFreeClient, "WMClient"); - EventType = CreateNewResourceType(WMFreeEvents, "WMEvent"); - eventResource = FakeClientID(0); - - if (ClientType && EventType && - (extEntry = AddExtension(APPLEWMNAME, - AppleWMNumberEvents, - AppleWMNumberErrors, - ProcAppleWMDispatch, - SProcAppleWMDispatch, - NULL, - StandardMinorOpcode))) - { - WMReqCode = (unsigned char)extEntry->base; - WMErrorBase = extEntry->errorBase; - WMEventBase = extEntry->eventBase; - EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent; - appleWMProcs = procsPtr; - } -} - -/* Updates the _NATIVE_SCREEN_ORIGIN property on the given root window. */ -void -AppleWMSetScreenOrigin( - WindowPtr pWin -) -{ - int32_t data[2]; - - data[0] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].x - + darwinMainScreenX); - data[1] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].y - + darwinMainScreenY); - - dixChangeWindowProperty(serverClient, pWin, xa_native_screen_origin(), - XA_INTEGER, 32, PropModeReplace, 2, data, TRUE); -} - -/* Window managers can set the _APPLE_NO_ORDER_IN property on windows - that are being genie-restored from the Dock. We want them to - be mapped but remain ordered-out until the animation - completes (when the Dock will order them in). */ -Bool -AppleWMDoReorderWindow( - WindowPtr pWin -) -{ - Atom atom; - PropertyPtr prop; - int rc; - - atom = xa_apple_no_order_in(); - rc = dixLookupProperty(&prop, pWin, atom, serverClient, DixReadAccess); - - if(Success == rc && prop->type == atom) - return 0; - - return 1; -} - - -static int -ProcAppleWMQueryVersion( - register ClientPtr client -) -{ - xAppleWMQueryVersionReply rep; - register int n; - - REQUEST_SIZE_MATCH(xAppleWMQueryVersionReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.majorVersion = SERVER_APPLEWM_MAJOR_VERSION; - rep.minorVersion = SERVER_APPLEWM_MINOR_VERSION; - rep.patchVersion = SERVER_APPLEWM_PATCH_VERSION; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - } - WriteToClient(client, sizeof(xAppleWMQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - - -/* events */ - -static inline void -updateEventMask (WMEventPtr *pHead) -{ - WMEventPtr pCur; - - eventMask = 0; - for (pCur = *pHead; pCur != NULL; pCur = pCur->next) - eventMask |= pCur->mask; -} - -/*ARGSUSED*/ -static int -WMFreeClient (pointer data, XID id) { - WMEventPtr pEvent; - WMEventPtr *pHead, pCur, pPrev; - int i; - - pEvent = (WMEventPtr) data; - i = dixLookupResourceByType((pointer *)&pHead, eventResource, EventType, serverClient, DixReadAccess | DixWriteAccess | DixDestroyAccess); - if (i == Success && pHead) { - pPrev = 0; - for (pCur = *pHead; pCur && pCur != pEvent; pCur=pCur->next) - pPrev = pCur; - if (pCur) { - if (pPrev) - pPrev->next = pEvent->next; - else - *pHead = pEvent->next; - } - updateEventMask (pHead); - } - xfree ((pointer) pEvent); - return 1; -} - -/*ARGSUSED*/ -static int -WMFreeEvents (pointer data, XID id) { - WMEventPtr *pHead, pCur, pNext; - - pHead = (WMEventPtr *) data; - for (pCur = *pHead; pCur; pCur = pNext) { - pNext = pCur->next; - FreeResource (pCur->clientResource, ClientType); - xfree ((pointer) pCur); - } - xfree ((pointer) pHead); - eventMask = 0; - return 1; -} - -static int -ProcAppleWMSelectInput (register ClientPtr client) -{ - REQUEST(xAppleWMSelectInputReq); - WMEventPtr pEvent, pNewEvent, *pHead; - XID clientResource; - int i; - - REQUEST_SIZE_MATCH (xAppleWMSelectInputReq); - i = dixLookupResourceByType((pointer *)&pHead, eventResource, EventType, client, DixWriteAccess); - if (stuff->mask != 0) { - if (i == Success && pHead) { - /* check for existing entry. */ - for (pEvent = *pHead; pEvent; pEvent = pEvent->next) - { - if (pEvent->client == client) - { - pEvent->mask = stuff->mask; - updateEventMask (pHead); - return Success; - } - } - } - - /* build the entry */ - pNewEvent = (WMEventPtr) xalloc (sizeof (WMEventRec)); - if (!pNewEvent) - return BadAlloc; - pNewEvent->next = 0; - pNewEvent->client = client; - pNewEvent->mask = stuff->mask; - /* - * add a resource that will be deleted when - * the client goes away - */ - clientResource = FakeClientID (client->index); - pNewEvent->clientResource = clientResource; - if (!AddResource (clientResource, ClientType, (pointer)pNewEvent)) - return BadAlloc; - /* - * create a resource to contain a pointer to the list - * of clients selecting input. This must be indirect as - * the list may be arbitrarily rearranged which cannot be - * done through the resource database. - */ - if (i != Success || !pHead) - { - pHead = (WMEventPtr *) xalloc (sizeof (WMEventPtr)); - if (!pHead || - !AddResource (eventResource, EventType, (pointer)pHead)) - { - FreeResource (clientResource, RT_NONE); - return BadAlloc; - } - *pHead = 0; - } - pNewEvent->next = *pHead; - *pHead = pNewEvent; - updateEventMask (pHead); - } else if (stuff->mask == 0) { - /* delete the interest */ - if (i == Success && pHead) { - pNewEvent = 0; - for (pEvent = *pHead; pEvent; pEvent = pEvent->next) { - if (pEvent->client == client) - break; - pNewEvent = pEvent; - } - if (pEvent) { - FreeResource (pEvent->clientResource, ClientType); - if (pNewEvent) - pNewEvent->next = pEvent->next; - else - *pHead = pEvent->next; - xfree (pEvent); - updateEventMask (pHead); - } - } - } else { - client->errorValue = stuff->mask; - return BadValue; - } - return Success; -} - -/* - * deliver the event - */ - -void -AppleWMSendEvent (int type, unsigned int mask, int which, int arg) { - WMEventPtr *pHead, pEvent; - ClientPtr client; - xAppleWMNotifyEvent se; - int i; - - i = dixLookupResourceByType((pointer *)&pHead, eventResource, EventType, serverClient, DixReadAccess); - if (i != Success || !pHead) - return; - for (pEvent = *pHead; pEvent; pEvent = pEvent->next) { - client = pEvent->client; - if ((pEvent->mask & mask) == 0 - || client == serverClient || client->clientGone) - { - continue; - } - se.type = type + WMEventBase; - se.kind = which; - se.arg = arg; - se.sequenceNumber = client->sequence; - se.time = currentTime.milliseconds; - WriteEventsToClient (client, 1, (xEvent *) &se); - } -} - -/* Safe to call from any thread. */ -unsigned int -AppleWMSelectedEvents (void) -{ - return eventMask; -} - - -/* general utility functions */ - -static int -ProcAppleWMDisableUpdate( - register ClientPtr client -) -{ - REQUEST_SIZE_MATCH(xAppleWMDisableUpdateReq); - - appleWMProcs->DisableUpdate(); - - return (client->noClientException); -} - -static int -ProcAppleWMReenableUpdate( - register ClientPtr client -) -{ - REQUEST_SIZE_MATCH(xAppleWMReenableUpdateReq); - - appleWMProcs->EnableUpdate(); - - return (client->noClientException); -} - - -/* window functions */ - -static int -ProcAppleWMSetWindowMenu( - register ClientPtr client -) -{ - const char *bytes, **items; - char *shortcuts; - int max_len, nitems, i, j; - REQUEST(xAppleWMSetWindowMenuReq); - - REQUEST_AT_LEAST_SIZE(xAppleWMSetWindowMenuReq); - - nitems = stuff->nitems; - items = xalloc (sizeof (char *) * nitems); - shortcuts = xalloc (sizeof (char) * nitems); - - max_len = (stuff->length << 2) - sizeof(xAppleWMSetWindowMenuReq); - bytes = (char *) &stuff[1]; - - for (i = j = 0; i < max_len && j < nitems;) - { - shortcuts[j] = bytes[i++]; - items[j++] = bytes + i; - - while (i < max_len) - { - if (bytes[i++] == 0) - break; - } - } - X11ApplicationSetWindowMenu (nitems, items, shortcuts); - free(items); - free(shortcuts); - - return (client->noClientException); -} - -static int -ProcAppleWMSetWindowMenuCheck( - register ClientPtr client -) -{ - REQUEST(xAppleWMSetWindowMenuCheckReq); - - REQUEST_SIZE_MATCH(xAppleWMSetWindowMenuCheckReq); - X11ApplicationSetWindowMenuCheck(stuff->index); - return (client->noClientException); -} - -static int -ProcAppleWMSetFrontProcess( - register ClientPtr client -) -{ - REQUEST_SIZE_MATCH(xAppleWMSetFrontProcessReq); - - X11ApplicationSetFrontProcess(); - return (client->noClientException); -} - -static int -ProcAppleWMSetWindowLevel(register ClientPtr client) -{ - REQUEST(xAppleWMSetWindowLevelReq); - WindowPtr pWin; - int err; - - REQUEST_SIZE_MATCH(xAppleWMSetWindowLevelReq); - - if (Success != dixLookupWindow(&pWin, stuff->window, client, - DixReadAccess)) - return BadValue; - - if (stuff->level < 0 || stuff->level >= AppleWMNumWindowLevels) { - return BadValue; - } - - err = appleWMProcs->SetWindowLevel(pWin, stuff->level); - if (err != Success) { - return err; - } - - return (client->noClientException); -} - -static int -ProcAppleWMSendPSN(register ClientPtr client) -{ - REQUEST(xAppleWMSendPSNReq); - int err; - - REQUEST_SIZE_MATCH(xAppleWMSendPSNReq); - - if(!appleWMProcs->SendPSN) - return BadRequest; - - err = appleWMProcs->SendPSN(stuff->psn_hi, stuff->psn_lo); - if (err != Success) { - return err; - } - - return (client->noClientException); -} - -static int -ProcAppleWMAttachTransient(register ClientPtr client) -{ - WindowPtr pWinChild, pWinParent; - REQUEST(xAppleWMAttachTransientReq); - int err; - - REQUEST_SIZE_MATCH(xAppleWMAttachTransientReq); - - if(!appleWMProcs->AttachTransient) - return BadRequest; - - if (Success != dixLookupWindow(&pWinChild, stuff->child, client, DixReadAccess)) - return BadValue; - - if(stuff->parent) { - if(Success != dixLookupWindow(&pWinParent, stuff->parent, client, DixReadAccess)) - return BadValue; - } else { - pWinParent = NULL; - } - - err = appleWMProcs->AttachTransient(pWinChild, pWinParent); - if (err != Success) { - return err; - } - - return (client->noClientException); -} - -static int -ProcAppleWMSetCanQuit( - register ClientPtr client -) -{ - REQUEST(xAppleWMSetCanQuitReq); - - REQUEST_SIZE_MATCH(xAppleWMSetCanQuitReq); - - X11ApplicationSetCanQuit(stuff->state); - return (client->noClientException); -} - - -/* frame functions */ - -static int -ProcAppleWMFrameGetRect( - register ClientPtr client -) -{ - xAppleWMFrameGetRectReply rep; - BoxRec ir, or, rr; - REQUEST(xAppleWMFrameGetRectReq); - - REQUEST_SIZE_MATCH(xAppleWMFrameGetRectReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih); - or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh); - - if (appleWMProcs->FrameGetRect(stuff->frame_rect, - stuff->frame_class, - &or, &ir, &rr) != Success) - { - return BadValue; - } - - rep.x = rr.x1; - rep.y = rr.y1; - rep.w = rr.x2 - rr.x1; - rep.h = rr.y2 - rr.y1; - - WriteToClient(client, sizeof(xAppleWMFrameGetRectReply), (char *)&rep); - return (client->noClientException); -} - -static int -ProcAppleWMFrameHitTest( - register ClientPtr client -) -{ - xAppleWMFrameHitTestReply rep; - BoxRec ir, or; - int ret; - REQUEST(xAppleWMFrameHitTestReq); - - REQUEST_SIZE_MATCH(xAppleWMFrameHitTestReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih); - or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh); - - if (appleWMProcs->FrameHitTest(stuff->frame_class, stuff->px, - stuff->py, &or, &ir, &ret) != Success) - { - return BadValue; - } - - rep.ret = ret; - - WriteToClient(client, sizeof(xAppleWMFrameHitTestReply), (char *)&rep); - return (client->noClientException); -} - -static int -ProcAppleWMFrameDraw( - register ClientPtr client -) -{ - BoxRec ir, or; - unsigned int title_length, title_max; - unsigned char *title_bytes; - REQUEST(xAppleWMFrameDrawReq); - WindowPtr pWin; - - REQUEST_AT_LEAST_SIZE(xAppleWMFrameDrawReq); - - if (Success != dixLookupWindow(&pWin, stuff->window, client, - DixReadAccess)) - return BadValue; - - ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih); - or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh); - - title_length = stuff->title_length; - title_max = (stuff->length << 2) - sizeof(xAppleWMFrameDrawReq); - - if (title_max < title_length) - return BadValue; - - title_bytes = (unsigned char *) &stuff[1]; - - errno = appleWMProcs->FrameDraw(pWin, stuff->frame_class, - stuff->frame_attr, &or, &ir, - title_length, title_bytes); - if (errno != Success) { - return errno; - } - - return (client->noClientException); -} - - -/* dispatch */ - -static int -ProcAppleWMDispatch ( - register ClientPtr client -) -{ - REQUEST(xReq); - - switch (stuff->data) - { - case X_AppleWMQueryVersion: - return ProcAppleWMQueryVersion(client); - } - - if (!LocalClient(client)) - return WMErrorBase + AppleWMClientNotLocal; - - switch (stuff->data) - { - case X_AppleWMSelectInput: - return ProcAppleWMSelectInput(client); - case X_AppleWMDisableUpdate: - return ProcAppleWMDisableUpdate(client); - case X_AppleWMReenableUpdate: - return ProcAppleWMReenableUpdate(client); - case X_AppleWMSetWindowMenu: - return ProcAppleWMSetWindowMenu(client); - case X_AppleWMSetWindowMenuCheck: - return ProcAppleWMSetWindowMenuCheck(client); - case X_AppleWMSetFrontProcess: - return ProcAppleWMSetFrontProcess(client); - case X_AppleWMSetWindowLevel: - return ProcAppleWMSetWindowLevel(client); - case X_AppleWMSetCanQuit: - return ProcAppleWMSetCanQuit(client); - case X_AppleWMFrameGetRect: - return ProcAppleWMFrameGetRect(client); - case X_AppleWMFrameHitTest: - return ProcAppleWMFrameHitTest(client); - case X_AppleWMFrameDraw: - return ProcAppleWMFrameDraw(client); - case X_AppleWMSendPSN: - return ProcAppleWMSendPSN(client); - case X_AppleWMAttachTransient: - return ProcAppleWMAttachTransient(client); - default: - return BadRequest; - } -} - -static void -SNotifyEvent(xAppleWMNotifyEvent *from, xAppleWMNotifyEvent *to) { - to->type = from->type; - to->kind = from->kind; - cpswaps (from->sequenceNumber, to->sequenceNumber); - cpswapl (from->time, to->time); - cpswapl (from->arg, to->arg); -} - -static int -SProcAppleWMQueryVersion( - register ClientPtr client -) -{ - register int n; - REQUEST(xAppleWMQueryVersionReq); - swaps(&stuff->length, n); - return ProcAppleWMQueryVersion(client); -} - -static int -SProcAppleWMDispatch ( - register ClientPtr client -) -{ - REQUEST(xReq); - - /* It is bound to be non-local when there is byte swapping */ - if (!LocalClient(client)) - return WMErrorBase + AppleWMClientNotLocal; - - /* only local clients are allowed WM access */ - switch (stuff->data) - { - case X_AppleWMQueryVersion: - return SProcAppleWMQueryVersion(client); - default: - return BadRequest; - } -} +/************************************************************************** + +Copyright (c) 2002-2007 Apple 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, 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. + +**************************************************************************/ + +#include "sanitizedCarbon.h" + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "quartzCommon.h" + +#include "misc.h" +#include "dixstruct.h" +#include "globals.h" +#include "extnsionst.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "servermd.h" +#include "swaprep.h" +#include "propertyst.h" +#include +#include "darwin.h" +#define _APPLEWM_SERVER_ +#include +#include "applewmExt.h" +#include "X11Application.h" +#include "protocol-versions.h" + +#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_screen_origin, "_NATIVE_SCREEN_ORIGIN") +DEFINE_ATOM_HELPER (xa_apple_no_order_in, "_APPLE_NO_ORDER_IN") + +static AppleWMProcsPtr appleWMProcs; + +static int WMErrorBase; + +static DISPATCH_PROC(ProcAppleWMDispatch); +static DISPATCH_PROC(SProcAppleWMDispatch); + +static unsigned char WMReqCode = 0; +static int WMEventBase = 0; + +static RESTYPE ClientType, EventType; /* resource types for event masks */ +static XID eventResource; + +/* Currently selected events */ +static unsigned int eventMask = 0; + +static int WMFreeClient (pointer data, XID id); +static int WMFreeEvents (pointer data, XID id); +static void SNotifyEvent(xAppleWMNotifyEvent *from, xAppleWMNotifyEvent *to); + +typedef struct _WMEvent *WMEventPtr; +typedef struct _WMEvent { + WMEventPtr next; + ClientPtr client; + XID clientResource; + unsigned int mask; +} WMEventRec; + +static inline BoxRec +make_box (int x, int y, int w, int h) +{ + BoxRec r; + r.x1 = x; + r.y1 = y; + r.x2 = x + w; + r.y2 = y + h; + return r; +} + +void +AppleWMExtensionInit( + AppleWMProcsPtr procsPtr) +{ + ExtensionEntry* extEntry; + + ClientType = CreateNewResourceType(WMFreeClient, "WMClient"); + EventType = CreateNewResourceType(WMFreeEvents, "WMEvent"); + eventResource = FakeClientID(0); + + if (ClientType && EventType && + (extEntry = AddExtension(APPLEWMNAME, + AppleWMNumberEvents, + AppleWMNumberErrors, + ProcAppleWMDispatch, + SProcAppleWMDispatch, + NULL, + StandardMinorOpcode))) + { + WMReqCode = (unsigned char)extEntry->base; + WMErrorBase = extEntry->errorBase; + WMEventBase = extEntry->eventBase; + EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent; + appleWMProcs = procsPtr; + } +} + +/* Updates the _NATIVE_SCREEN_ORIGIN property on the given root window. */ +void +AppleWMSetScreenOrigin( + WindowPtr pWin +) +{ + int32_t data[2]; + + data[0] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].x + + darwinMainScreenX); + data[1] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].y + + darwinMainScreenY); + + dixChangeWindowProperty(serverClient, pWin, xa_native_screen_origin(), + XA_INTEGER, 32, PropModeReplace, 2, data, TRUE); +} + +/* Window managers can set the _APPLE_NO_ORDER_IN property on windows + that are being genie-restored from the Dock. We want them to + be mapped but remain ordered-out until the animation + completes (when the Dock will order them in). */ +Bool +AppleWMDoReorderWindow( + WindowPtr pWin +) +{ + Atom atom; + PropertyPtr prop; + int rc; + + atom = xa_apple_no_order_in(); + rc = dixLookupProperty(&prop, pWin, atom, serverClient, DixReadAccess); + + if(Success == rc && prop->type == atom) + return 0; + + return 1; +} + + +static int +ProcAppleWMQueryVersion( + register ClientPtr client +) +{ + xAppleWMQueryVersionReply rep; + register int n; + + REQUEST_SIZE_MATCH(xAppleWMQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = SERVER_APPLEWM_MAJOR_VERSION; + rep.minorVersion = SERVER_APPLEWM_MINOR_VERSION; + rep.patchVersion = SERVER_APPLEWM_PATCH_VERSION; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + } + WriteToClient(client, sizeof(xAppleWMQueryVersionReply), (char *)&rep); + return Success; +} + + +/* events */ + +static inline void +updateEventMask (WMEventPtr *pHead) +{ + WMEventPtr pCur; + + eventMask = 0; + for (pCur = *pHead; pCur != NULL; pCur = pCur->next) + eventMask |= pCur->mask; +} + +/*ARGSUSED*/ +static int +WMFreeClient (pointer data, XID id) { + WMEventPtr pEvent; + WMEventPtr *pHead, pCur, pPrev; + int i; + + pEvent = (WMEventPtr) data; + i = dixLookupResourceByType((pointer *)&pHead, eventResource, EventType, serverClient, DixReadAccess | DixWriteAccess | DixDestroyAccess); + if (i == Success && pHead) { + pPrev = 0; + for (pCur = *pHead; pCur && pCur != pEvent; pCur=pCur->next) + pPrev = pCur; + if (pCur) { + if (pPrev) + pPrev->next = pEvent->next; + else + *pHead = pEvent->next; + } + updateEventMask (pHead); + } + free((pointer) pEvent); + return 1; +} + +/*ARGSUSED*/ +static int +WMFreeEvents (pointer data, XID id) { + WMEventPtr *pHead, pCur, pNext; + + pHead = (WMEventPtr *) data; + for (pCur = *pHead; pCur; pCur = pNext) { + pNext = pCur->next; + FreeResource (pCur->clientResource, ClientType); + free((pointer) pCur); + } + free((pointer) pHead); + eventMask = 0; + return 1; +} + +static int +ProcAppleWMSelectInput (register ClientPtr client) +{ + REQUEST(xAppleWMSelectInputReq); + WMEventPtr pEvent, pNewEvent, *pHead; + XID clientResource; + int i; + + REQUEST_SIZE_MATCH (xAppleWMSelectInputReq); + i = dixLookupResourceByType((pointer *)&pHead, eventResource, EventType, client, DixWriteAccess); + if (stuff->mask != 0) { + if (i == Success && pHead) { + /* check for existing entry. */ + for (pEvent = *pHead; pEvent; pEvent = pEvent->next) + { + if (pEvent->client == client) + { + pEvent->mask = stuff->mask; + updateEventMask (pHead); + return Success; + } + } + } + + /* build the entry */ + pNewEvent = (WMEventPtr) malloc(sizeof (WMEventRec)); + if (!pNewEvent) + return BadAlloc; + pNewEvent->next = 0; + pNewEvent->client = client; + pNewEvent->mask = stuff->mask; + /* + * add a resource that will be deleted when + * the client goes away + */ + clientResource = FakeClientID (client->index); + pNewEvent->clientResource = clientResource; + if (!AddResource (clientResource, ClientType, (pointer)pNewEvent)) + return BadAlloc; + /* + * create a resource to contain a pointer to the list + * of clients selecting input. This must be indirect as + * the list may be arbitrarily rearranged which cannot be + * done through the resource database. + */ + if (i != Success || !pHead) + { + pHead = (WMEventPtr *) malloc(sizeof (WMEventPtr)); + if (!pHead || + !AddResource (eventResource, EventType, (pointer)pHead)) + { + FreeResource (clientResource, RT_NONE); + return BadAlloc; + } + *pHead = 0; + } + pNewEvent->next = *pHead; + *pHead = pNewEvent; + updateEventMask (pHead); + } else if (stuff->mask == 0) { + /* delete the interest */ + if (i == Success && pHead) { + pNewEvent = 0; + for (pEvent = *pHead; pEvent; pEvent = pEvent->next) { + if (pEvent->client == client) + break; + pNewEvent = pEvent; + } + if (pEvent) { + FreeResource (pEvent->clientResource, ClientType); + if (pNewEvent) + pNewEvent->next = pEvent->next; + else + *pHead = pEvent->next; + free(pEvent); + updateEventMask (pHead); + } + } + } else { + client->errorValue = stuff->mask; + return BadValue; + } + return Success; +} + +/* + * deliver the event + */ + +void +AppleWMSendEvent (int type, unsigned int mask, int which, int arg) { + WMEventPtr *pHead, pEvent; + ClientPtr client; + xAppleWMNotifyEvent se; + int i; + + i = dixLookupResourceByType((pointer *)&pHead, eventResource, EventType, serverClient, DixReadAccess); + if (i != Success || !pHead) + return; + for (pEvent = *pHead; pEvent; pEvent = pEvent->next) { + client = pEvent->client; + if ((pEvent->mask & mask) == 0 + || client == serverClient || client->clientGone) + { + continue; + } + se.type = type + WMEventBase; + se.kind = which; + se.arg = arg; + se.sequenceNumber = client->sequence; + se.time = currentTime.milliseconds; + WriteEventsToClient (client, 1, (xEvent *) &se); + } +} + +/* Safe to call from any thread. */ +unsigned int +AppleWMSelectedEvents (void) +{ + return eventMask; +} + + +/* general utility functions */ + +static int +ProcAppleWMDisableUpdate( + register ClientPtr client +) +{ + REQUEST_SIZE_MATCH(xAppleWMDisableUpdateReq); + + appleWMProcs->DisableUpdate(); + + return Success; +} + +static int +ProcAppleWMReenableUpdate( + register ClientPtr client +) +{ + REQUEST_SIZE_MATCH(xAppleWMReenableUpdateReq); + + appleWMProcs->EnableUpdate(); + + return Success; +} + + +/* window functions */ + +static int +ProcAppleWMSetWindowMenu( + register ClientPtr client +) +{ + const char *bytes, **items; + char *shortcuts; + int max_len, nitems, i, j; + REQUEST(xAppleWMSetWindowMenuReq); + + REQUEST_AT_LEAST_SIZE(xAppleWMSetWindowMenuReq); + + nitems = stuff->nitems; + items = malloc(sizeof (char *) * nitems); + shortcuts = malloc(sizeof (char) * nitems); + + max_len = (stuff->length << 2) - sizeof(xAppleWMSetWindowMenuReq); + bytes = (char *) &stuff[1]; + + for (i = j = 0; i < max_len && j < nitems;) + { + shortcuts[j] = bytes[i++]; + items[j++] = bytes + i; + + while (i < max_len) + { + if (bytes[i++] == 0) + break; + } + } + X11ApplicationSetWindowMenu (nitems, items, shortcuts); + free(items); + free(shortcuts); + + return Success; +} + +static int +ProcAppleWMSetWindowMenuCheck( + register ClientPtr client +) +{ + REQUEST(xAppleWMSetWindowMenuCheckReq); + + REQUEST_SIZE_MATCH(xAppleWMSetWindowMenuCheckReq); + X11ApplicationSetWindowMenuCheck(stuff->index); + return Success; +} + +static int +ProcAppleWMSetFrontProcess( + register ClientPtr client +) +{ + REQUEST_SIZE_MATCH(xAppleWMSetFrontProcessReq); + + X11ApplicationSetFrontProcess(); + return Success; +} + +static int +ProcAppleWMSetWindowLevel(register ClientPtr client) +{ + REQUEST(xAppleWMSetWindowLevelReq); + WindowPtr pWin; + int err; + + REQUEST_SIZE_MATCH(xAppleWMSetWindowLevelReq); + + if (Success != dixLookupWindow(&pWin, stuff->window, client, + DixReadAccess)) + return BadValue; + + if (stuff->level < 0 || stuff->level >= AppleWMNumWindowLevels) { + return BadValue; + } + + err = appleWMProcs->SetWindowLevel(pWin, stuff->level); + if (err != Success) { + return err; + } + + return Success; +} + +static int +ProcAppleWMSendPSN(register ClientPtr client) +{ + REQUEST(xAppleWMSendPSNReq); + int err; + + REQUEST_SIZE_MATCH(xAppleWMSendPSNReq); + + if(!appleWMProcs->SendPSN) + return BadRequest; + + err = appleWMProcs->SendPSN(stuff->psn_hi, stuff->psn_lo); + if (err != Success) { + return err; + } + + return Success; +} + +static int +ProcAppleWMAttachTransient(register ClientPtr client) +{ + WindowPtr pWinChild, pWinParent; + REQUEST(xAppleWMAttachTransientReq); + int err; + + REQUEST_SIZE_MATCH(xAppleWMAttachTransientReq); + + if(!appleWMProcs->AttachTransient) + return BadRequest; + + if (Success != dixLookupWindow(&pWinChild, stuff->child, client, DixReadAccess)) + return BadValue; + + if(stuff->parent) { + if(Success != dixLookupWindow(&pWinParent, stuff->parent, client, DixReadAccess)) + return BadValue; + } else { + pWinParent = NULL; + } + + err = appleWMProcs->AttachTransient(pWinChild, pWinParent); + if (err != Success) { + return err; + } + + return Success; +} + +static int +ProcAppleWMSetCanQuit( + register ClientPtr client +) +{ + REQUEST(xAppleWMSetCanQuitReq); + + REQUEST_SIZE_MATCH(xAppleWMSetCanQuitReq); + + X11ApplicationSetCanQuit(stuff->state); + return Success; +} + + +/* frame functions */ + +static int +ProcAppleWMFrameGetRect( + register ClientPtr client +) +{ + xAppleWMFrameGetRectReply rep; + BoxRec ir, or, rr; + REQUEST(xAppleWMFrameGetRectReq); + + REQUEST_SIZE_MATCH(xAppleWMFrameGetRectReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih); + or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh); + + if (appleWMProcs->FrameGetRect(stuff->frame_rect, + stuff->frame_class, + &or, &ir, &rr) != Success) + { + return BadValue; + } + + rep.x = rr.x1; + rep.y = rr.y1; + rep.w = rr.x2 - rr.x1; + rep.h = rr.y2 - rr.y1; + + WriteToClient(client, sizeof(xAppleWMFrameGetRectReply), (char *)&rep); + return Success; +} + +static int +ProcAppleWMFrameHitTest( + register ClientPtr client +) +{ + xAppleWMFrameHitTestReply rep; + BoxRec ir, or; + int ret; + REQUEST(xAppleWMFrameHitTestReq); + + REQUEST_SIZE_MATCH(xAppleWMFrameHitTestReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih); + or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh); + + if (appleWMProcs->FrameHitTest(stuff->frame_class, stuff->px, + stuff->py, &or, &ir, &ret) != Success) + { + return BadValue; + } + + rep.ret = ret; + + WriteToClient(client, sizeof(xAppleWMFrameHitTestReply), (char *)&rep); + return Success; +} + +static int +ProcAppleWMFrameDraw( + register ClientPtr client +) +{ + BoxRec ir, or; + unsigned int title_length, title_max; + unsigned char *title_bytes; + REQUEST(xAppleWMFrameDrawReq); + WindowPtr pWin; + + REQUEST_AT_LEAST_SIZE(xAppleWMFrameDrawReq); + + if (Success != dixLookupWindow(&pWin, stuff->window, client, + DixReadAccess)) + return BadValue; + + ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih); + or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh); + + title_length = stuff->title_length; + title_max = (stuff->length << 2) - sizeof(xAppleWMFrameDrawReq); + + if (title_max < title_length) + return BadValue; + + title_bytes = (unsigned char *) &stuff[1]; + + errno = appleWMProcs->FrameDraw(pWin, stuff->frame_class, + stuff->frame_attr, &or, &ir, + title_length, title_bytes); + if (errno != Success) { + return errno; + } + + return Success; +} + + +/* dispatch */ + +static int +ProcAppleWMDispatch ( + register ClientPtr client +) +{ + REQUEST(xReq); + + switch (stuff->data) + { + case X_AppleWMQueryVersion: + return ProcAppleWMQueryVersion(client); + } + + if (!LocalClient(client)) + return WMErrorBase + AppleWMClientNotLocal; + + switch (stuff->data) + { + case X_AppleWMSelectInput: + return ProcAppleWMSelectInput(client); + case X_AppleWMDisableUpdate: + return ProcAppleWMDisableUpdate(client); + case X_AppleWMReenableUpdate: + return ProcAppleWMReenableUpdate(client); + case X_AppleWMSetWindowMenu: + return ProcAppleWMSetWindowMenu(client); + case X_AppleWMSetWindowMenuCheck: + return ProcAppleWMSetWindowMenuCheck(client); + case X_AppleWMSetFrontProcess: + return ProcAppleWMSetFrontProcess(client); + case X_AppleWMSetWindowLevel: + return ProcAppleWMSetWindowLevel(client); + case X_AppleWMSetCanQuit: + return ProcAppleWMSetCanQuit(client); + case X_AppleWMFrameGetRect: + return ProcAppleWMFrameGetRect(client); + case X_AppleWMFrameHitTest: + return ProcAppleWMFrameHitTest(client); + case X_AppleWMFrameDraw: + return ProcAppleWMFrameDraw(client); + case X_AppleWMSendPSN: + return ProcAppleWMSendPSN(client); + case X_AppleWMAttachTransient: + return ProcAppleWMAttachTransient(client); + default: + return BadRequest; + } +} + +static void +SNotifyEvent(xAppleWMNotifyEvent *from, xAppleWMNotifyEvent *to) { + to->type = from->type; + to->kind = from->kind; + cpswaps (from->sequenceNumber, to->sequenceNumber); + cpswapl (from->time, to->time); + cpswapl (from->arg, to->arg); +} + +static int +SProcAppleWMQueryVersion( + register ClientPtr client +) +{ + register int n; + REQUEST(xAppleWMQueryVersionReq); + swaps(&stuff->length, n); + return ProcAppleWMQueryVersion(client); +} + +static int +SProcAppleWMDispatch ( + register ClientPtr client +) +{ + REQUEST(xReq); + + /* It is bound to be non-local when there is byte swapping */ + if (!LocalClient(client)) + return WMErrorBase + AppleWMClientNotLocal; + + /* only local clients are allowed WM access */ + switch (stuff->data) + { + case X_AppleWMQueryVersion: + return SProcAppleWMQueryVersion(client); + default: + return BadRequest; + } +} diff --git a/xorg-server/hw/xquartz/darwin.c b/xorg-server/hw/xquartz/darwin.c index 1fb158b26..ed9543eb2 100644 --- a/xorg-server/hw/xquartz/darwin.c +++ b/xorg-server/hw/xquartz/darwin.c @@ -1,908 +1,908 @@ -/************************************************************** - * - * Xquartz initialization code - * - * Copyright (c) 2007-2008 Apple Inc. - * Copyright (c) 2001-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. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include -#include -#include "os.h" -#include "servermd.h" -#include "inputstr.h" -#include "scrnintstr.h" -#include "mibstore.h" // mi backing store implementation -#include "mipointer.h" // mi software cursor -#include "micmap.h" // mi colormap code -#include "fb.h" // fb framebuffer code -#include "site.h" -#include "globals.h" -#include "dix.h" -#include "xkbsrv.h" - -#include -#include -#include "exevents.h" -#include "extinit.h" - -#include "xserver-properties.h" - -#include -#include -#include -#include -#include -#include - -#define HAS_UTSNAME 1 -#include - -#define NO_CFPLUGIN -#include - -#ifdef MITSHM -#include "shmint.h" -#endif - -#include "darwin.h" -#include "darwinEvents.h" -#include "quartzKeyboard.h" -#include "quartz.h" - -#ifdef ENABLE_DEBUG_LOG -FILE *debug_log_fp = NULL; -#endif - -/* - * X server shared global variables - */ -int darwinScreensFound = 0; -static int darwinScreenKeyIndex; -DevPrivateKey darwinScreenKey = &darwinScreenKeyIndex; -io_connect_t darwinParamConnect = 0; -int darwinEventReadFD = -1; -int darwinEventWriteFD = -1; -// int darwinMouseAccelChange = 1; -int darwinFakeButtons = 0; - -// location of X11's (0,0) point in global screen coordinates -int darwinMainScreenX = 0; -int darwinMainScreenY = 0; - -// parameters read from the command line or user preferences -int darwinDesiredDepth = -1; -int darwinSyncKeymap = FALSE; - -// modifier masks for faking mouse buttons - ANY of these bits trigger it (not all) -#ifdef NX_DEVICELCMDKEYMASK -int darwinFakeMouse2Mask = NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK; -int darwinFakeMouse3Mask = NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK; -#else -int darwinFakeMouse2Mask = NX_ALTERNATEMASK; -int darwinFakeMouse3Mask = NX_COMMANDMASK; -#endif - -// Modifier mask for overriding event delivery to appkit (might be useful to set this to rcommand for input menu -unsigned int darwinAppKitModMask = 0; // Any of these bits - -// Modifier mask for items in the Window menu (0 and -1 cause shortcuts to be disabled) -unsigned int windowItemModMask = NX_COMMANDMASK; - -// devices -DeviceIntPtr darwinKeyboard = NULL; -DeviceIntPtr darwinPointer = NULL; -DeviceIntPtr darwinTabletCurrent = NULL; -DeviceIntPtr darwinTabletStylus = NULL; -DeviceIntPtr darwinTabletCursor = NULL; -DeviceIntPtr darwinTabletEraser = NULL; - -// Common pixmap formats -static PixmapFormatRec formats[] = { - { 1, 1, BITMAP_SCANLINE_PAD }, - { 4, 8, BITMAP_SCANLINE_PAD }, - { 8, 8, BITMAP_SCANLINE_PAD }, - { 15, 16, BITMAP_SCANLINE_PAD }, - { 16, 16, BITMAP_SCANLINE_PAD }, - { 24, 32, BITMAP_SCANLINE_PAD }, - { 32, 32, BITMAP_SCANLINE_PAD } -}; -const int NUMFORMATS = sizeof(formats)/sizeof(formats[0]); - -#ifndef OSNAME -#define OSNAME " Darwin" -#endif -#ifndef OSVENDOR -#define OSVENDOR "" -#endif -#ifndef PRE_RELEASE -#define PRE_RELEASE XORG_VERSION_SNAP -#endif -#ifndef BUILD_DATE -#define BUILD_DATE "" -#endif -#ifndef XORG_RELEASE -#define XORG_RELEASE "?" -#endif - -void -DarwinPrintBanner(void) -{ - // this should change depending on which specific server we are building - ErrorF("Xquartz starting:\n"); - ErrorF("X.Org X Server %s\nBuild Date: %s\n", XSERVER_VERSION, BUILD_DATE ); -} - - -/* - * DarwinSaveScreen - * X screensaver support. Not implemented. - */ -static Bool DarwinSaveScreen(ScreenPtr pScreen, int on) -{ - // FIXME - if (on == SCREEN_SAVER_FORCER) { - } else if (on == SCREEN_SAVER_ON) { - } else { - } - return TRUE; -} - -/* - * DarwinScreenInit - * This is a callback from dix during AddScreen() from InitOutput(). - * Initialize the screen and communicate information about it back to dix. - */ -static Bool DarwinScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) { - int dpi; - static int foundIndex = 0; - Bool ret; - DarwinFramebufferPtr dfb; - - // reset index of found screens for each server generation - if (index == 0) { - foundIndex = 0; - - // reset the visual list - miClearVisualTypes(); - } - - // allocate space for private per screen storage - dfb = xalloc(sizeof(DarwinFramebufferRec)); - - // SCREEN_PRIV(pScreen) = dfb; - dixSetPrivate(&pScreen->devPrivates, darwinScreenKey, dfb); - - // setup hardware/mode specific details - ret = QuartzAddScreen(foundIndex, pScreen); - foundIndex++; - if (! ret) - return FALSE; - - // setup a single visual appropriate for our pixel type - if(!miSetVisualTypesAndMasks(dfb->depth, dfb->visuals, dfb->bitsPerRGB, - dfb->preferredCVC, dfb->redMask, - dfb->greenMask, dfb->blueMask)) { - return FALSE; - } - -// TODO: Make PseudoColor visuals not suck in TrueColor mode -// if(dfb->depth > 8) -// miSetVisualTypesAndMasks(8, PseudoColorMask, 8, PseudoColor, 0, 0, 0); - if(dfb->depth > 15) - miSetVisualTypesAndMasks(15, TrueColorMask, 5, TrueColor, RM_ARGB(0,5,5,5), GM_ARGB(0,5,5,5), BM_ARGB(0,5,5,5)); - if(dfb->depth > 24) - miSetVisualTypesAndMasks(24, TrueColorMask, 8, TrueColor, RM_ARGB(0,8,8,8), GM_ARGB(0,8,8,8), BM_ARGB(0,8,8,8)); - - miSetPixmapDepths(); - - // machine independent screen init - // setup _Screen structure in pScreen - if (monitorResolution) - dpi = monitorResolution; - else - dpi = 96; - - // initialize fb - if (! fbScreenInit(pScreen, - dfb->framebuffer, // pointer to screen bitmap - dfb->width, dfb->height, // screen size in pixels - dpi, dpi, // dots per inch - dfb->pitch/(dfb->bitsPerPixel/8), // pixel width of framebuffer - dfb->bitsPerPixel)) // bits per pixel for screen - { - return FALSE; - } - - if (! fbPictureInit(pScreen, 0, 0)) { - return FALSE; - } - -#ifdef MITSHM - ShmRegisterFbFuncs(pScreen); -#endif - - // this must be initialized (why doesn't X have a default?) - pScreen->SaveScreen = DarwinSaveScreen; - - // finish mode dependent screen setup including cursor support - if (!QuartzSetupScreen(index, pScreen)) { - return FALSE; - } - - // create and install the default colormap and - // set pScreen->blackPixel / pScreen->white - if (!miCreateDefColormap( pScreen )) { - return FALSE; - } - - dixScreenOrigins[index].x = dfb->x; - dixScreenOrigins[index].y = dfb->y; - - /* ErrorF("Screen %d added: %dx%d @ (%d,%d)\n", - index, dfb->width, dfb->height, dfb->x, dfb->y); */ - - return TRUE; -} - -/* - ============================================================================= - - mouse and keyboard callbacks - - ============================================================================= -*/ - -/* - * DarwinMouseProc: Handle the initialization, etc. of a mouse - */ -static int DarwinMouseProc(DeviceIntPtr pPointer, int what) { -#define NBUTTONS 7 -#define NAXES 2 - // 7 buttons: left, right, middle, then four scroll wheel "buttons" - CARD8 map[NBUTTONS + 1] = {0, 1, 2, 3, 4, 5, 6, 7}; - Atom btn_labels[NBUTTONS] = {0}; - Atom axes_labels[NAXES] = {0}; - - switch (what) { - case DEVICE_INIT: - pPointer->public.on = FALSE; - - btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); - btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); - btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); - btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); - btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); - btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); - btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); - - axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); - axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); - - - // Set button map. - InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS, - btn_labels, - (PtrCtrlProcPtr)NoopDDA, - GetMotionHistorySize(), NAXES, - axes_labels); - pPointer->valuator->mode = Absolute; // Relative - InitAbsoluteClassDeviceStruct(pPointer); -// InitValuatorAxisStruct(pPointer, 0, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); -// InitValuatorAxisStruct(pPointer, 1, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); - break; - case DEVICE_ON: - pPointer->public.on = TRUE; - AddEnabledDevice( darwinEventReadFD ); - return Success; - case DEVICE_CLOSE: - case DEVICE_OFF: - pPointer->public.on = FALSE; - RemoveEnabledDevice(darwinEventReadFD); - return Success; - } - - return Success; -#undef NBUTTONS -#undef NAXES -} - -static int DarwinTabletProc(DeviceIntPtr pPointer, int what) { -#define NBUTTONS 3 -#define NAXES 5 - CARD8 map[NBUTTONS + 1] = {0, 1, 2, 3}; - Atom btn_labels[NBUTTONS] = {0}; - Atom axes_labels[NAXES] = {0}; - - switch (what) { - case DEVICE_INIT: - pPointer->public.on = FALSE; - - btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); - btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); - btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); - - axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X); - axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y); - axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE); - axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X); - axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y); - - // Set button map. - InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS, - btn_labels, - (PtrCtrlProcPtr)NoopDDA, - GetMotionHistorySize(), NAXES, - axes_labels); - pPointer->valuator->mode = Absolute; // Relative - InitProximityClassDeviceStruct(pPointer); - InitAbsoluteClassDeviceStruct(pPointer); - - InitValuatorAxisStruct(pPointer, 0, axes_labels[0], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); - InitValuatorAxisStruct(pPointer, 1, axes_labels[1], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); - InitValuatorAxisStruct(pPointer, 2, axes_labels[2], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); - InitValuatorAxisStruct(pPointer, 3, axes_labels[3], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); - InitValuatorAxisStruct(pPointer, 4, axes_labels[4], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); -// pPointer->use = IsXExtensionDevice; - break; - case DEVICE_ON: - pPointer->public.on = TRUE; - AddEnabledDevice( darwinEventReadFD ); - return Success; - case DEVICE_CLOSE: - case DEVICE_OFF: - pPointer->public.on = FALSE; - RemoveEnabledDevice(darwinEventReadFD); - return Success; - } - return Success; -#undef NBUTTONS -#undef NAXES -} - -/* - * DarwinKeybdProc - * Callback from X - */ -static int DarwinKeybdProc( DeviceIntPtr pDev, int onoff ) -{ - switch ( onoff ) { - case DEVICE_INIT: - DarwinKeyboardInit( pDev ); - break; - case DEVICE_ON: - pDev->public.on = TRUE; - AddEnabledDevice( darwinEventReadFD ); - break; - case DEVICE_OFF: - pDev->public.on = FALSE; - RemoveEnabledDevice( darwinEventReadFD ); - break; - case DEVICE_CLOSE: - break; - } - - return Success; -} - -/* -=========================================================================== - - Utility routines - -=========================================================================== -*/ - -/* - * DarwinParseModifierList - * Parse a list of modifier names and return a corresponding modifier mask - */ -int DarwinParseModifierList(const char *constmodifiers, int separatelr) -{ - int result = 0; - - if (constmodifiers) { - char *modifiers = strdup(constmodifiers); - char *modifier; - int nxkey; - char *p = modifiers; - - while (p) { - modifier = strsep(&p, " ,+&|/"); // allow lots of separators - nxkey = DarwinModifierStringToNXMask(modifier, separatelr); - if(nxkey) - result |= nxkey; - else - ErrorF("fakebuttons: Unknown modifier \"%s\"\n", modifier); - } - free(modifiers); - } - return result; -} - -/* -=========================================================================== - - Functions needed to link against device independent X - -=========================================================================== -*/ - -/* - * InitInput - * Register the keyboard and mouse devices - */ -void InitInput( int argc, char **argv ) -{ - XkbRMLVOSet rmlvo = { .rules = "base", .model = "empty", .layout = "empty", - .variant = NULL, .options = NULL }; - /* We need to really have rules... or something... */ - XkbSetRulesDflts(&rmlvo); - - darwinKeyboard = AddInputDevice(serverClient, DarwinKeybdProc, TRUE); - RegisterKeyboardDevice( darwinKeyboard ); - darwinKeyboard->name = strdup("keyboard"); - - /* here's the snippet from the current gdk sources: - if (!strcmp (tmp_name, "pointer")) - gdkdev->info.source = GDK_SOURCE_MOUSE; - else if (!strcmp (tmp_name, "wacom") || - !strcmp (tmp_name, "pen")) - gdkdev->info.source = GDK_SOURCE_PEN; - else if (!strcmp (tmp_name, "eraser")) - gdkdev->info.source = GDK_SOURCE_ERASER; - else if (!strcmp (tmp_name, "cursor")) - gdkdev->info.source = GDK_SOURCE_CURSOR; - else - gdkdev->info.source = GDK_SOURCE_PEN; - */ - - darwinPointer = AddInputDevice(serverClient, DarwinMouseProc, TRUE); - RegisterPointerDevice( darwinPointer ); - darwinPointer->name = strdup("pointer"); - - darwinTabletStylus = AddInputDevice(serverClient, DarwinTabletProc, TRUE); - RegisterPointerDevice( darwinTabletStylus ); - darwinTabletStylus->name = strdup("pen"); - - darwinTabletCursor = AddInputDevice(serverClient, DarwinTabletProc, TRUE); - RegisterPointerDevice( darwinTabletCursor ); - darwinTabletCursor->name = strdup("cursor"); - - darwinTabletEraser = AddInputDevice(serverClient, DarwinTabletProc, TRUE); - RegisterPointerDevice( darwinTabletEraser ); - darwinTabletEraser->name = strdup("eraser"); - - darwinTabletCurrent = darwinTabletStylus; - - DarwinEQInit(); - - QuartzInitInput(argc, argv); -} - - -/* - * DarwinAdjustScreenOrigins - * Shift all screens so the X11 (0, 0) coordinate is at the top - * left of the global screen coordinates. - * - * Screens can be arranged so the top left isn't on any screen, so - * instead use the top left of the leftmost screen as (0,0). This - * may mean some screen space is in -y, but it's better that (0,0) - * be onscreen, or else default xterms disappear. It's better that - * -y be used than -x, because when popup menus are forced - * "onscreen" by dumb window managers like twm, they'll shift the - * menus down instead of left, which still looks funny but is an - * easier target to hit. - */ -void -DarwinAdjustScreenOrigins(ScreenInfo *pScreenInfo) -{ - int i, left, top; - - left = dixScreenOrigins[0].x; - top = dixScreenOrigins[0].y; - - /* Find leftmost screen. If there's a tie, take the topmost of the two. */ - for (i = 1; i < pScreenInfo->numScreens; i++) { - if (dixScreenOrigins[i].x < left || - (dixScreenOrigins[i].x == left && dixScreenOrigins[i].y < top)) - { - left = dixScreenOrigins[i].x; - top = dixScreenOrigins[i].y; - } - } - - darwinMainScreenX = left; - darwinMainScreenY = top; - - DEBUG_LOG("top = %d, left=%d\n", top, left); - - /* Shift all screens so that there is a screen whose top left - * is at X11 (0,0) and at global screen coordinate - * (darwinMainScreenX, darwinMainScreenY). - */ - - if (darwinMainScreenX != 0 || darwinMainScreenY != 0) { - for (i = 0; i < pScreenInfo->numScreens; i++) { - dixScreenOrigins[i].x -= darwinMainScreenX; - dixScreenOrigins[i].y -= darwinMainScreenY; - DEBUG_LOG("Screen %d placed at X11 coordinate (%d,%d).\n", - i, dixScreenOrigins[i].x, dixScreenOrigins[i].y); - } - } -} - - -/* - * InitOutput - * Initialize screenInfo for all actually accessible framebuffers. - * - * The display mode dependent code gets called three times. The mode - * specific InitOutput routines are expected to discover the number - * of potentially useful screens and cache routes to them internally. - * Inside DarwinScreenInit are two other mode specific calls. - * A mode specific AddScreen routine is called for each screen to - * actually initialize the screen with the ScreenPtr structure. - * After other screen setup has been done, a mode specific - * SetupScreen function can be called to finalize screen setup. - */ -void InitOutput( ScreenInfo *pScreenInfo, int argc, char **argv ) -{ - int i; - - pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER; - pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; - pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; - pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; - - // List how we want common pixmap formats to be padded - pScreenInfo->numPixmapFormats = NUMFORMATS; - for (i = 0; i < NUMFORMATS; i++) - pScreenInfo->formats[i] = formats[i]; - - // Discover screens and do mode specific initialization - QuartzInitOutput(argc, argv); - - // Add screens - for (i = 0; i < darwinScreensFound; i++) { - AddScreen(DarwinScreenInit, argc, argv); - } - - DarwinAdjustScreenOrigins(pScreenInfo); -} - - -/* - * OsVendorFatalError - */ -void OsVendorFatalError( void ) -{ - ErrorF( " OsVendorFatalError\n" ); -} - - -/* - * OsVendorInit - * Initialization of Darwin OS support. - */ -void OsVendorInit(void) -{ - if (serverGeneration == 1) { - DarwinPrintBanner(); -#ifdef ENABLE_DEBUG_LOG - { - char *home_dir=NULL, *log_file_path=NULL; - home_dir = getenv("HOME"); - if (home_dir) asprintf(&log_file_path, "%s/%s", home_dir, DEBUG_LOG_NAME); - if (log_file_path) { - if (!access(log_file_path, F_OK)) { - debug_log_fp = fopen(log_file_path, "a"); - if (debug_log_fp) ErrorF("Debug logging enabled to %s\n", log_file_path); - } - free(log_file_path); - } - } -#endif - } -} - - -/* - * ddxProcessArgument - * Process device-dependent command line args. Returns 0 if argument is - * not device dependent, otherwise Count of number of elements of argv - * that are part of a device dependent commandline option. - */ -int ddxProcessArgument( int argc, char *argv[], int i ) -{ -// if ( !strcmp( argv[i], "-fullscreen" ) ) { -// ErrorF( "Running full screen in parallel with Mac OS X Quartz window server.\n" ); -// return 1; -// } - -// if ( !strcmp( argv[i], "-rootless" ) ) { -// ErrorF( "Running rootless inside Mac OS X window server.\n" ); -// return 1; -// } - - // This command line arg is passed when launched from the Aqua GUI. - if ( !strncmp( argv[i], "-psn_", 5 ) ) { - return 1; - } - - if ( !strcmp( argv[i], "-fakebuttons" ) ) { - darwinFakeButtons = TRUE; - ErrorF( "Faking a three button mouse\n" ); - return 1; - } - - if ( !strcmp( argv[i], "-nofakebuttons" ) ) { - darwinFakeButtons = FALSE; - ErrorF( "Not faking a three button mouse\n" ); - return 1; - } - - if (!strcmp( argv[i], "-fakemouse2" ) ) { - if ( i == argc-1 ) { - FatalError( "-fakemouse2 must be followed by a modifer list\n" ); - } - if (!strcasecmp(argv[i+1], "none") || !strcmp(argv[i+1], "")) - darwinFakeMouse2Mask = 0; - else - darwinFakeMouse2Mask = DarwinParseModifierList(argv[i+1], 1); - ErrorF("Modifier mask to fake mouse button 2 = 0x%x\n", - darwinFakeMouse2Mask); - return 2; - } - - if (!strcmp( argv[i], "-fakemouse3" ) ) { - if ( i == argc-1 ) { - FatalError( "-fakemouse3 must be followed by a modifer list\n" ); - } - if (!strcasecmp(argv[i+1], "none") || !strcmp(argv[i+1], "")) - darwinFakeMouse3Mask = 0; - else - darwinFakeMouse3Mask = DarwinParseModifierList(argv[i+1], 1); - ErrorF("Modifier mask to fake mouse button 3 = 0x%x\n", - darwinFakeMouse3Mask); - return 2; - } - - if ( !strcmp( argv[i], "+synckeymap" ) ) { - darwinSyncKeymap = TRUE; - return 1; - } - - if ( !strcmp( argv[i], "-synckeymap" ) ) { - darwinSyncKeymap = FALSE; - return 1; - } - - if ( !strcmp( argv[i], "-depth" ) ) { - if ( i == argc-1 ) { - FatalError( "-depth must be followed by a number\n" ); - } - darwinDesiredDepth = atoi( argv[i+1] ); - if(darwinDesiredDepth != -1 && - darwinDesiredDepth != 8 && - darwinDesiredDepth != 15 && - darwinDesiredDepth != 24) { - FatalError( "Unsupported pixel depth. Use 8, 15, or 24 bits\n" ); - } - - ErrorF( "Attempting to use pixel depth of %i\n", darwinDesiredDepth ); - return 2; - } - - if (!strcmp( argv[i], "-showconfig" ) || !strcmp( argv[i], "-version" )) { - DarwinPrintBanner(); - exit(0); - } - - return 0; -} - - -/* - * ddxUseMsg -- - * Print out correct use of device dependent commandline options. - * Maybe the user now knows what really to do ... - */ -void ddxUseMsg( void ) -{ - ErrorF("\n"); - ErrorF("\n"); - ErrorF("Device Dependent Usage:\n"); - ErrorF("\n"); - ErrorF("-depth <8,15,24> : use this bit depth.\n"); - ErrorF("-fakebuttons : fake a three button mouse with Command and Option keys.\n"); - ErrorF("-nofakebuttons : don't fake a three button mouse.\n"); - ErrorF("-fakemouse2 : fake middle mouse button with modifier keys.\n"); - ErrorF("-fakemouse3 : fake right mouse button with modifier keys.\n"); - ErrorF(" ex: -fakemouse2 \"option,shift\" = option-shift-click is middle button.\n"); - ErrorF("-version : show the server version.\n"); - ErrorF("\n"); -} - - -/* - * ddxGiveUp -- - * Device dependent cleanup. Called by dix before normal server death. - */ -void ddxGiveUp( void ) -{ - ErrorF( "Quitting Xquartz\n" ); -} - - -/* - * AbortDDX -- - * DDX - specific abort routine. Called by AbortServer(). The attempt is - * made to restore all original setting of the displays. Also all devices - * are closed. - */ -void AbortDDX( void ) -{ - ErrorF( " AbortDDX\n" ); - OsAbort(); -} - -#include "mivalidate.h" // for union _Validate used by windowstr.h -#include "windowstr.h" // for struct _Window -#include "scrnintstr.h" // for struct _Screen - -// This is copied from Xserver/hw/xfree86/common/xf86Helper.c. -// Quartz mode uses this when switching in and out of Quartz. -// Quartz or IOKit can use this when waking from sleep. -// Copyright (c) 1997-1998 by The XFree86 Project, Inc. - -/* - * xf86SetRootClip -- - * Enable or disable rendering to the screen by - * setting the root clip list and revalidating - * all of the windows - */ - -void -xf86SetRootClip (ScreenPtr pScreen, int enable) -{ - WindowPtr pWin = WindowTable[pScreen->myNum]; - WindowPtr pChild; - Bool WasViewable = (Bool)(pWin->viewable); - Bool anyMarked = TRUE; - RegionPtr pOldClip = NULL, bsExposed; - WindowPtr pLayerWin; - BoxRec box; - - if (WasViewable) - { - for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) - { - (void) (*pScreen->MarkOverlappedWindows)(pChild, - pChild, - &pLayerWin); - } - (*pScreen->MarkWindow) (pWin); - anyMarked = TRUE; - if (pWin->valdata) - { - if (HasBorder (pWin)) - { - RegionPtr borderVisible; - - borderVisible = REGION_CREATE(pScreen, NullBox, 1); - REGION_SUBTRACT(pScreen, borderVisible, - &pWin->borderClip, &pWin->winSize); - pWin->valdata->before.borderVisible = borderVisible; - } - pWin->valdata->before.resized = TRUE; - } - } - - /* - * Use REGION_BREAK to avoid optimizations in ValidateTree - * that assume the root borderClip can't change well, normally - * it doesn't...) - */ - if (enable) - { - box.x1 = 0; - box.y1 = 0; - box.x2 = pScreen->width; - box.y2 = pScreen->height; - REGION_RESET(pScreen, &pWin->borderClip, &box); - REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); - } - else - { - REGION_EMPTY(pScreen, &pWin->borderClip); - REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); - } - - ResizeChildrenWinSize (pWin, 0, 0, 0, 0); - - if (WasViewable) - { - if (pWin->backStorage) - { - pOldClip = REGION_CREATE(pScreen, NullBox, 1); - REGION_COPY(pScreen, pOldClip, &pWin->clipList); - } - - if (pWin->firstChild) - { - anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild, - pWin->firstChild, - (WindowPtr *)NULL); - } - else - { - (*pScreen->MarkWindow) (pWin); - anyMarked = TRUE; - } - - - if (anyMarked) - (*pScreen->ValidateTree)(pWin, NullWindow, VTOther); - } - - if (pWin->backStorage && - ((pWin->backingStore == Always) || WasViewable)) - { - if (!WasViewable) - pOldClip = &pWin->clipList; /* a convenient empty region */ - bsExposed = (*pScreen->TranslateBackingStore) - (pWin, 0, 0, pOldClip, - pWin->drawable.x, pWin->drawable.y); - if (WasViewable) - REGION_DESTROY(pScreen, pOldClip); - if (bsExposed) - { - RegionPtr valExposed = NullRegion; - - if (pWin->valdata) - valExposed = &pWin->valdata->after.exposed; - (*pScreen->WindowExposures) (pWin, valExposed, bsExposed); - if (valExposed) - REGION_EMPTY(pScreen, valExposed); - REGION_DESTROY(pScreen, bsExposed); - } - } - if (WasViewable) - { - if (anyMarked) - (*pScreen->HandleExposures)(pWin); - if (anyMarked && pScreen->PostValidateTree) - (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther); - } - if (pWin->realized) - WindowsRestructured (); - FlushAllOutput (); -} +/************************************************************** + * + * Xquartz initialization code + * + * Copyright (c) 2007-2008 Apple Inc. + * Copyright (c) 2001-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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include +#include "os.h" +#include "servermd.h" +#include "inputstr.h" +#include "scrnintstr.h" +#include "mibstore.h" // mi backing store implementation +#include "mipointer.h" // mi software cursor +#include "micmap.h" // mi colormap code +#include "fb.h" // fb framebuffer code +#include "site.h" +#include "globals.h" +#include "dix.h" +#include "xkbsrv.h" + +#include +#include +#include "exevents.h" +#include "extinit.h" + +#include "xserver-properties.h" + +#include +#include +#include +#include +#include +#include + +#define HAS_UTSNAME 1 +#include + +#define NO_CFPLUGIN +#include + +#ifdef MITSHM +#include "shmint.h" +#endif + +#include "darwin.h" +#include "darwinEvents.h" +#include "quartzKeyboard.h" +#include "quartz.h" + +#ifdef ENABLE_DEBUG_LOG +FILE *debug_log_fp = NULL; +#endif + +/* + * X server shared global variables + */ +int darwinScreensFound = 0; +static int darwinScreenKeyIndex; +DevPrivateKey darwinScreenKey = &darwinScreenKeyIndex; +io_connect_t darwinParamConnect = 0; +int darwinEventReadFD = -1; +int darwinEventWriteFD = -1; +// int darwinMouseAccelChange = 1; +int darwinFakeButtons = 0; + +// location of X11's (0,0) point in global screen coordinates +int darwinMainScreenX = 0; +int darwinMainScreenY = 0; + +// parameters read from the command line or user preferences +int darwinDesiredDepth = -1; +int darwinSyncKeymap = FALSE; + +// modifier masks for faking mouse buttons - ANY of these bits trigger it (not all) +#ifdef NX_DEVICELCMDKEYMASK +int darwinFakeMouse2Mask = NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK; +int darwinFakeMouse3Mask = NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK; +#else +int darwinFakeMouse2Mask = NX_ALTERNATEMASK; +int darwinFakeMouse3Mask = NX_COMMANDMASK; +#endif + +// Modifier mask for overriding event delivery to appkit (might be useful to set this to rcommand for input menu +unsigned int darwinAppKitModMask = 0; // Any of these bits + +// Modifier mask for items in the Window menu (0 and -1 cause shortcuts to be disabled) +unsigned int windowItemModMask = NX_COMMANDMASK; + +// devices +DeviceIntPtr darwinKeyboard = NULL; +DeviceIntPtr darwinPointer = NULL; +DeviceIntPtr darwinTabletCurrent = NULL; +DeviceIntPtr darwinTabletStylus = NULL; +DeviceIntPtr darwinTabletCursor = NULL; +DeviceIntPtr darwinTabletEraser = NULL; + +// Common pixmap formats +static PixmapFormatRec formats[] = { + { 1, 1, BITMAP_SCANLINE_PAD }, + { 4, 8, BITMAP_SCANLINE_PAD }, + { 8, 8, BITMAP_SCANLINE_PAD }, + { 15, 16, BITMAP_SCANLINE_PAD }, + { 16, 16, BITMAP_SCANLINE_PAD }, + { 24, 32, BITMAP_SCANLINE_PAD }, + { 32, 32, BITMAP_SCANLINE_PAD } +}; +const int NUMFORMATS = sizeof(formats)/sizeof(formats[0]); + +#ifndef OSNAME +#define OSNAME " Darwin" +#endif +#ifndef OSVENDOR +#define OSVENDOR "" +#endif +#ifndef PRE_RELEASE +#define PRE_RELEASE XORG_VERSION_SNAP +#endif +#ifndef BUILD_DATE +#define BUILD_DATE "" +#endif +#ifndef XORG_RELEASE +#define XORG_RELEASE "?" +#endif + +void +DarwinPrintBanner(void) +{ + // this should change depending on which specific server we are building + ErrorF("Xquartz starting:\n"); + ErrorF("X.Org X Server %s\nBuild Date: %s\n", XSERVER_VERSION, BUILD_DATE ); +} + + +/* + * DarwinSaveScreen + * X screensaver support. Not implemented. + */ +static Bool DarwinSaveScreen(ScreenPtr pScreen, int on) +{ + // FIXME + if (on == SCREEN_SAVER_FORCER) { + } else if (on == SCREEN_SAVER_ON) { + } else { + } + return TRUE; +} + +/* + * DarwinScreenInit + * This is a callback from dix during AddScreen() from InitOutput(). + * Initialize the screen and communicate information about it back to dix. + */ +static Bool DarwinScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) { + int dpi; + static int foundIndex = 0; + Bool ret; + DarwinFramebufferPtr dfb; + + // reset index of found screens for each server generation + if (index == 0) { + foundIndex = 0; + + // reset the visual list + miClearVisualTypes(); + } + + // allocate space for private per screen storage + dfb = malloc(sizeof(DarwinFramebufferRec)); + + // SCREEN_PRIV(pScreen) = dfb; + dixSetPrivate(&pScreen->devPrivates, darwinScreenKey, dfb); + + // setup hardware/mode specific details + ret = QuartzAddScreen(foundIndex, pScreen); + foundIndex++; + if (! ret) + return FALSE; + + // setup a single visual appropriate for our pixel type + if(!miSetVisualTypesAndMasks(dfb->depth, dfb->visuals, dfb->bitsPerRGB, + dfb->preferredCVC, dfb->redMask, + dfb->greenMask, dfb->blueMask)) { + return FALSE; + } + +// TODO: Make PseudoColor visuals not suck in TrueColor mode +// if(dfb->depth > 8) +// miSetVisualTypesAndMasks(8, PseudoColorMask, 8, PseudoColor, 0, 0, 0); + if(dfb->depth > 15) + miSetVisualTypesAndMasks(15, TrueColorMask, 5, TrueColor, RM_ARGB(0,5,5,5), GM_ARGB(0,5,5,5), BM_ARGB(0,5,5,5)); + if(dfb->depth > 24) + miSetVisualTypesAndMasks(24, TrueColorMask, 8, TrueColor, RM_ARGB(0,8,8,8), GM_ARGB(0,8,8,8), BM_ARGB(0,8,8,8)); + + miSetPixmapDepths(); + + // machine independent screen init + // setup _Screen structure in pScreen + if (monitorResolution) + dpi = monitorResolution; + else + dpi = 96; + + // initialize fb + if (! fbScreenInit(pScreen, + dfb->framebuffer, // pointer to screen bitmap + dfb->width, dfb->height, // screen size in pixels + dpi, dpi, // dots per inch + dfb->pitch/(dfb->bitsPerPixel/8), // pixel width of framebuffer + dfb->bitsPerPixel)) // bits per pixel for screen + { + return FALSE; + } + + if (! fbPictureInit(pScreen, 0, 0)) { + return FALSE; + } + +#ifdef MITSHM + ShmRegisterFbFuncs(pScreen); +#endif + + // this must be initialized (why doesn't X have a default?) + pScreen->SaveScreen = DarwinSaveScreen; + + // finish mode dependent screen setup including cursor support + if (!QuartzSetupScreen(index, pScreen)) { + return FALSE; + } + + // create and install the default colormap and + // set pScreen->blackPixel / pScreen->white + if (!miCreateDefColormap( pScreen )) { + return FALSE; + } + + dixScreenOrigins[index].x = dfb->x; + dixScreenOrigins[index].y = dfb->y; + + /* ErrorF("Screen %d added: %dx%d @ (%d,%d)\n", + index, dfb->width, dfb->height, dfb->x, dfb->y); */ + + return TRUE; +} + +/* + ============================================================================= + + mouse and keyboard callbacks + + ============================================================================= +*/ + +/* + * DarwinMouseProc: Handle the initialization, etc. of a mouse + */ +static int DarwinMouseProc(DeviceIntPtr pPointer, int what) { +#define NBUTTONS 7 +#define NAXES 2 + // 7 buttons: left, right, middle, then four scroll wheel "buttons" + CARD8 map[NBUTTONS + 1] = {0, 1, 2, 3, 4, 5, 6, 7}; + Atom btn_labels[NBUTTONS] = {0}; + Atom axes_labels[NAXES] = {0}; + + switch (what) { + case DEVICE_INIT: + pPointer->public.on = FALSE; + + btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); + btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); + btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); + btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); + btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); + btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); + btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); + + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); + + + // Set button map. + InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS, + btn_labels, + (PtrCtrlProcPtr)NoopDDA, + GetMotionHistorySize(), NAXES, + axes_labels); + pPointer->valuator->mode = Absolute; // Relative + InitAbsoluteClassDeviceStruct(pPointer); +// InitValuatorAxisStruct(pPointer, 0, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); +// InitValuatorAxisStruct(pPointer, 1, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); + break; + case DEVICE_ON: + pPointer->public.on = TRUE; + AddEnabledDevice( darwinEventReadFD ); + return Success; + case DEVICE_CLOSE: + case DEVICE_OFF: + pPointer->public.on = FALSE; + RemoveEnabledDevice(darwinEventReadFD); + return Success; + } + + return Success; +#undef NBUTTONS +#undef NAXES +} + +static int DarwinTabletProc(DeviceIntPtr pPointer, int what) { +#define NBUTTONS 3 +#define NAXES 5 + CARD8 map[NBUTTONS + 1] = {0, 1, 2, 3}; + Atom btn_labels[NBUTTONS] = {0}; + Atom axes_labels[NAXES] = {0}; + + switch (what) { + case DEVICE_INIT: + pPointer->public.on = FALSE; + + btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); + btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); + btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); + + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y); + axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE); + axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X); + axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y); + + // Set button map. + InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS, + btn_labels, + (PtrCtrlProcPtr)NoopDDA, + GetMotionHistorySize(), NAXES, + axes_labels); + pPointer->valuator->mode = Absolute; // Relative + InitProximityClassDeviceStruct(pPointer); + InitAbsoluteClassDeviceStruct(pPointer); + + InitValuatorAxisStruct(pPointer, 0, axes_labels[0], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); + InitValuatorAxisStruct(pPointer, 1, axes_labels[1], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); + InitValuatorAxisStruct(pPointer, 2, axes_labels[2], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); + InitValuatorAxisStruct(pPointer, 3, axes_labels[3], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); + InitValuatorAxisStruct(pPointer, 4, axes_labels[4], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1); +// pPointer->use = IsXExtensionDevice; + break; + case DEVICE_ON: + pPointer->public.on = TRUE; + AddEnabledDevice( darwinEventReadFD ); + return Success; + case DEVICE_CLOSE: + case DEVICE_OFF: + pPointer->public.on = FALSE; + RemoveEnabledDevice(darwinEventReadFD); + return Success; + } + return Success; +#undef NBUTTONS +#undef NAXES +} + +/* + * DarwinKeybdProc + * Callback from X + */ +static int DarwinKeybdProc( DeviceIntPtr pDev, int onoff ) +{ + switch ( onoff ) { + case DEVICE_INIT: + DarwinKeyboardInit( pDev ); + break; + case DEVICE_ON: + pDev->public.on = TRUE; + AddEnabledDevice( darwinEventReadFD ); + break; + case DEVICE_OFF: + pDev->public.on = FALSE; + RemoveEnabledDevice( darwinEventReadFD ); + break; + case DEVICE_CLOSE: + break; + } + + return Success; +} + +/* +=========================================================================== + + Utility routines + +=========================================================================== +*/ + +/* + * DarwinParseModifierList + * Parse a list of modifier names and return a corresponding modifier mask + */ +int DarwinParseModifierList(const char *constmodifiers, int separatelr) +{ + int result = 0; + + if (constmodifiers) { + char *modifiers = strdup(constmodifiers); + char *modifier; + int nxkey; + char *p = modifiers; + + while (p) { + modifier = strsep(&p, " ,+&|/"); // allow lots of separators + nxkey = DarwinModifierStringToNXMask(modifier, separatelr); + if(nxkey) + result |= nxkey; + else + ErrorF("fakebuttons: Unknown modifier \"%s\"\n", modifier); + } + free(modifiers); + } + return result; +} + +/* +=========================================================================== + + Functions needed to link against device independent X + +=========================================================================== +*/ + +/* + * InitInput + * Register the keyboard and mouse devices + */ +void InitInput( int argc, char **argv ) +{ + XkbRMLVOSet rmlvo = { .rules = "base", .model = "empty", .layout = "empty", + .variant = NULL, .options = NULL }; + /* We need to really have rules... or something... */ + XkbSetRulesDflts(&rmlvo); + + darwinKeyboard = AddInputDevice(serverClient, DarwinKeybdProc, TRUE); + RegisterKeyboardDevice( darwinKeyboard ); + darwinKeyboard->name = strdup("keyboard"); + + /* here's the snippet from the current gdk sources: + if (!strcmp (tmp_name, "pointer")) + gdkdev->info.source = GDK_SOURCE_MOUSE; + else if (!strcmp (tmp_name, "wacom") || + !strcmp (tmp_name, "pen")) + gdkdev->info.source = GDK_SOURCE_PEN; + else if (!strcmp (tmp_name, "eraser")) + gdkdev->info.source = GDK_SOURCE_ERASER; + else if (!strcmp (tmp_name, "cursor")) + gdkdev->info.source = GDK_SOURCE_CURSOR; + else + gdkdev->info.source = GDK_SOURCE_PEN; + */ + + darwinPointer = AddInputDevice(serverClient, DarwinMouseProc, TRUE); + RegisterPointerDevice( darwinPointer ); + darwinPointer->name = strdup("pointer"); + + darwinTabletStylus = AddInputDevice(serverClient, DarwinTabletProc, TRUE); + RegisterPointerDevice( darwinTabletStylus ); + darwinTabletStylus->name = strdup("pen"); + + darwinTabletCursor = AddInputDevice(serverClient, DarwinTabletProc, TRUE); + RegisterPointerDevice( darwinTabletCursor ); + darwinTabletCursor->name = strdup("cursor"); + + darwinTabletEraser = AddInputDevice(serverClient, DarwinTabletProc, TRUE); + RegisterPointerDevice( darwinTabletEraser ); + darwinTabletEraser->name = strdup("eraser"); + + darwinTabletCurrent = darwinTabletStylus; + + DarwinEQInit(); + + QuartzInitInput(argc, argv); +} + + +/* + * DarwinAdjustScreenOrigins + * Shift all screens so the X11 (0, 0) coordinate is at the top + * left of the global screen coordinates. + * + * Screens can be arranged so the top left isn't on any screen, so + * instead use the top left of the leftmost screen as (0,0). This + * may mean some screen space is in -y, but it's better that (0,0) + * be onscreen, or else default xterms disappear. It's better that + * -y be used than -x, because when popup menus are forced + * "onscreen" by dumb window managers like twm, they'll shift the + * menus down instead of left, which still looks funny but is an + * easier target to hit. + */ +void +DarwinAdjustScreenOrigins(ScreenInfo *pScreenInfo) +{ + int i, left, top; + + left = dixScreenOrigins[0].x; + top = dixScreenOrigins[0].y; + + /* Find leftmost screen. If there's a tie, take the topmost of the two. */ + for (i = 1; i < pScreenInfo->numScreens; i++) { + if (dixScreenOrigins[i].x < left || + (dixScreenOrigins[i].x == left && dixScreenOrigins[i].y < top)) + { + left = dixScreenOrigins[i].x; + top = dixScreenOrigins[i].y; + } + } + + darwinMainScreenX = left; + darwinMainScreenY = top; + + DEBUG_LOG("top = %d, left=%d\n", top, left); + + /* Shift all screens so that there is a screen whose top left + * is at X11 (0,0) and at global screen coordinate + * (darwinMainScreenX, darwinMainScreenY). + */ + + if (darwinMainScreenX != 0 || darwinMainScreenY != 0) { + for (i = 0; i < pScreenInfo->numScreens; i++) { + dixScreenOrigins[i].x -= darwinMainScreenX; + dixScreenOrigins[i].y -= darwinMainScreenY; + DEBUG_LOG("Screen %d placed at X11 coordinate (%d,%d).\n", + i, dixScreenOrigins[i].x, dixScreenOrigins[i].y); + } + } +} + + +/* + * InitOutput + * Initialize screenInfo for all actually accessible framebuffers. + * + * The display mode dependent code gets called three times. The mode + * specific InitOutput routines are expected to discover the number + * of potentially useful screens and cache routes to them internally. + * Inside DarwinScreenInit are two other mode specific calls. + * A mode specific AddScreen routine is called for each screen to + * actually initialize the screen with the ScreenPtr structure. + * After other screen setup has been done, a mode specific + * SetupScreen function can be called to finalize screen setup. + */ +void InitOutput( ScreenInfo *pScreenInfo, int argc, char **argv ) +{ + int i; + + pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER; + pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; + pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; + pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; + + // List how we want common pixmap formats to be padded + pScreenInfo->numPixmapFormats = NUMFORMATS; + for (i = 0; i < NUMFORMATS; i++) + pScreenInfo->formats[i] = formats[i]; + + // Discover screens and do mode specific initialization + QuartzInitOutput(argc, argv); + + // Add screens + for (i = 0; i < darwinScreensFound; i++) { + AddScreen(DarwinScreenInit, argc, argv); + } + + DarwinAdjustScreenOrigins(pScreenInfo); +} + + +/* + * OsVendorFatalError + */ +void OsVendorFatalError( void ) +{ + ErrorF( " OsVendorFatalError\n" ); +} + + +/* + * OsVendorInit + * Initialization of Darwin OS support. + */ +void OsVendorInit(void) +{ + if (serverGeneration == 1) { + DarwinPrintBanner(); +#ifdef ENABLE_DEBUG_LOG + { + char *home_dir=NULL, *log_file_path=NULL; + home_dir = getenv("HOME"); + if (home_dir) asprintf(&log_file_path, "%s/%s", home_dir, DEBUG_LOG_NAME); + if (log_file_path) { + if (!access(log_file_path, F_OK)) { + debug_log_fp = fopen(log_file_path, "a"); + if (debug_log_fp) ErrorF("Debug logging enabled to %s\n", log_file_path); + } + free(log_file_path); + } + } +#endif + } +} + + +/* + * ddxProcessArgument + * Process device-dependent command line args. Returns 0 if argument is + * not device dependent, otherwise Count of number of elements of argv + * that are part of a device dependent commandline option. + */ +int ddxProcessArgument( int argc, char *argv[], int i ) +{ +// if ( !strcmp( argv[i], "-fullscreen" ) ) { +// ErrorF( "Running full screen in parallel with Mac OS X Quartz window server.\n" ); +// return 1; +// } + +// if ( !strcmp( argv[i], "-rootless" ) ) { +// ErrorF( "Running rootless inside Mac OS X window server.\n" ); +// return 1; +// } + + // This command line arg is passed when launched from the Aqua GUI. + if ( !strncmp( argv[i], "-psn_", 5 ) ) { + return 1; + } + + if ( !strcmp( argv[i], "-fakebuttons" ) ) { + darwinFakeButtons = TRUE; + ErrorF( "Faking a three button mouse\n" ); + return 1; + } + + if ( !strcmp( argv[i], "-nofakebuttons" ) ) { + darwinFakeButtons = FALSE; + ErrorF( "Not faking a three button mouse\n" ); + return 1; + } + + if (!strcmp( argv[i], "-fakemouse2" ) ) { + if ( i == argc-1 ) { + FatalError( "-fakemouse2 must be followed by a modifer list\n" ); + } + if (!strcasecmp(argv[i+1], "none") || !strcmp(argv[i+1], "")) + darwinFakeMouse2Mask = 0; + else + darwinFakeMouse2Mask = DarwinParseModifierList(argv[i+1], 1); + ErrorF("Modifier mask to fake mouse button 2 = 0x%x\n", + darwinFakeMouse2Mask); + return 2; + } + + if (!strcmp( argv[i], "-fakemouse3" ) ) { + if ( i == argc-1 ) { + FatalError( "-fakemouse3 must be followed by a modifer list\n" ); + } + if (!strcasecmp(argv[i+1], "none") || !strcmp(argv[i+1], "")) + darwinFakeMouse3Mask = 0; + else + darwinFakeMouse3Mask = DarwinParseModifierList(argv[i+1], 1); + ErrorF("Modifier mask to fake mouse button 3 = 0x%x\n", + darwinFakeMouse3Mask); + return 2; + } + + if ( !strcmp( argv[i], "+synckeymap" ) ) { + darwinSyncKeymap = TRUE; + return 1; + } + + if ( !strcmp( argv[i], "-synckeymap" ) ) { + darwinSyncKeymap = FALSE; + return 1; + } + + if ( !strcmp( argv[i], "-depth" ) ) { + if ( i == argc-1 ) { + FatalError( "-depth must be followed by a number\n" ); + } + darwinDesiredDepth = atoi( argv[i+1] ); + if(darwinDesiredDepth != -1 && + darwinDesiredDepth != 8 && + darwinDesiredDepth != 15 && + darwinDesiredDepth != 24) { + FatalError( "Unsupported pixel depth. Use 8, 15, or 24 bits\n" ); + } + + ErrorF( "Attempting to use pixel depth of %i\n", darwinDesiredDepth ); + return 2; + } + + if (!strcmp( argv[i], "-showconfig" ) || !strcmp( argv[i], "-version" )) { + DarwinPrintBanner(); + exit(0); + } + + return 0; +} + + +/* + * ddxUseMsg -- + * Print out correct use of device dependent commandline options. + * Maybe the user now knows what really to do ... + */ +void ddxUseMsg( void ) +{ + ErrorF("\n"); + ErrorF("\n"); + ErrorF("Device Dependent Usage:\n"); + ErrorF("\n"); + ErrorF("-depth <8,15,24> : use this bit depth.\n"); + ErrorF("-fakebuttons : fake a three button mouse with Command and Option keys.\n"); + ErrorF("-nofakebuttons : don't fake a three button mouse.\n"); + ErrorF("-fakemouse2 : fake middle mouse button with modifier keys.\n"); + ErrorF("-fakemouse3 : fake right mouse button with modifier keys.\n"); + ErrorF(" ex: -fakemouse2 \"option,shift\" = option-shift-click is middle button.\n"); + ErrorF("-version : show the server version.\n"); + ErrorF("\n"); +} + + +/* + * ddxGiveUp -- + * Device dependent cleanup. Called by dix before normal server death. + */ +void ddxGiveUp( void ) +{ + ErrorF( "Quitting Xquartz\n" ); +} + + +/* + * AbortDDX -- + * DDX - specific abort routine. Called by AbortServer(). The attempt is + * made to restore all original setting of the displays. Also all devices + * are closed. + */ +void AbortDDX( void ) +{ + ErrorF( " AbortDDX\n" ); + OsAbort(); +} + +#include "mivalidate.h" // for union _Validate used by windowstr.h +#include "windowstr.h" // for struct _Window +#include "scrnintstr.h" // for struct _Screen + +// This is copied from Xserver/hw/xfree86/common/xf86Helper.c. +// Quartz mode uses this when switching in and out of Quartz. +// Quartz or IOKit can use this when waking from sleep. +// Copyright (c) 1997-1998 by The XFree86 Project, Inc. + +/* + * xf86SetRootClip -- + * Enable or disable rendering to the screen by + * setting the root clip list and revalidating + * all of the windows + */ + +void +xf86SetRootClip (ScreenPtr pScreen, int enable) +{ + WindowPtr pWin = WindowTable[pScreen->myNum]; + WindowPtr pChild; + Bool WasViewable = (Bool)(pWin->viewable); + Bool anyMarked = TRUE; + RegionPtr pOldClip = NULL, bsExposed; + WindowPtr pLayerWin; + BoxRec box; + + if (WasViewable) + { + for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) + { + (void) (*pScreen->MarkOverlappedWindows)(pChild, + pChild, + &pLayerWin); + } + (*pScreen->MarkWindow) (pWin); + anyMarked = TRUE; + if (pWin->valdata) + { + if (HasBorder (pWin)) + { + RegionPtr borderVisible; + + borderVisible = REGION_CREATE(pScreen, NullBox, 1); + REGION_SUBTRACT(pScreen, borderVisible, + &pWin->borderClip, &pWin->winSize); + pWin->valdata->before.borderVisible = borderVisible; + } + pWin->valdata->before.resized = TRUE; + } + } + + /* + * Use REGION_BREAK to avoid optimizations in ValidateTree + * that assume the root borderClip can't change well, normally + * it doesn't...) + */ + if (enable) + { + box.x1 = 0; + box.y1 = 0; + box.x2 = pScreen->width; + box.y2 = pScreen->height; + REGION_RESET(pScreen, &pWin->borderClip, &box); + REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); + } + else + { + REGION_EMPTY(pScreen, &pWin->borderClip); + REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); + } + + ResizeChildrenWinSize (pWin, 0, 0, 0, 0); + + if (WasViewable) + { + if (pWin->backStorage) + { + pOldClip = REGION_CREATE(pScreen, NullBox, 1); + REGION_COPY(pScreen, pOldClip, &pWin->clipList); + } + + if (pWin->firstChild) + { + anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild, + pWin->firstChild, + (WindowPtr *)NULL); + } + else + { + (*pScreen->MarkWindow) (pWin); + anyMarked = TRUE; + } + + + if (anyMarked) + (*pScreen->ValidateTree)(pWin, NullWindow, VTOther); + } + + if (pWin->backStorage && + ((pWin->backingStore == Always) || WasViewable)) + { + if (!WasViewable) + pOldClip = &pWin->clipList; /* a convenient empty region */ + bsExposed = (*pScreen->TranslateBackingStore) + (pWin, 0, 0, pOldClip, + pWin->drawable.x, pWin->drawable.y); + if (WasViewable) + REGION_DESTROY(pScreen, pOldClip); + if (bsExposed) + { + RegionPtr valExposed = NullRegion; + + if (pWin->valdata) + valExposed = &pWin->valdata->after.exposed; + (*pScreen->WindowExposures) (pWin, valExposed, bsExposed); + if (valExposed) + REGION_EMPTY(pScreen, valExposed); + REGION_DESTROY(pScreen, bsExposed); + } + } + if (WasViewable) + { + if (anyMarked) + (*pScreen->HandleExposures)(pWin); + if (anyMarked && pScreen->PostValidateTree) + (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther); + } + if (pWin->realized) + WindowsRestructured (); + FlushAllOutput (); +} diff --git a/xorg-server/hw/xquartz/pseudoramiX.c b/xorg-server/hw/xquartz/pseudoramiX.c index 1de7af6dc..1a357528c 100644 --- a/xorg-server/hw/xquartz/pseudoramiX.c +++ b/xorg-server/hw/xquartz/pseudoramiX.c @@ -1,471 +1,471 @@ -/* - * Minimal implementation of PanoramiX/Xinerama - * - * This is used in rootless mode where the underlying window server - * already provides an abstracted view of multiple screens as one - * large screen area. - * - * This code is largely based on panoramiX.c, which contains the - * following copyright notice: - */ -/***************************************************************** -Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. -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. - -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 -DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, -BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 of Digital Equipment Corporation -shall not be used in advertising or otherwise to promote the sale, use or other -dealings in this Software without prior written authorization from Digital -Equipment Corporation. -******************************************************************/ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "darwin.h" -#include "pseudoramiX.h" -#include "extnsionst.h" -#include "dixstruct.h" -#include "window.h" -#include -#include "globals.h" - -Bool noPseudoramiXExtension = FALSE; - -extern int ProcPanoramiXQueryVersion (ClientPtr client); - -static void PseudoramiXResetProc(ExtensionEntry *extEntry); - -static int ProcPseudoramiXQueryVersion(ClientPtr client); -static int ProcPseudoramiXGetState(ClientPtr client); -static int ProcPseudoramiXGetScreenCount(ClientPtr client); -static int ProcPseudoramiXGetScreenSize(ClientPtr client); -static int ProcPseudoramiXIsActive(ClientPtr client); -static int ProcPseudoramiXQueryScreens(ClientPtr client); -static int ProcPseudoramiXDispatch(ClientPtr client); - -static int SProcPseudoramiXQueryVersion(ClientPtr client); -static int SProcPseudoramiXGetState(ClientPtr client); -static int SProcPseudoramiXGetScreenCount(ClientPtr client); -static int SProcPseudoramiXGetScreenSize(ClientPtr client); -static int SProcPseudoramiXIsActive(ClientPtr client); -static int SProcPseudoramiXQueryScreens(ClientPtr client); -static int SProcPseudoramiXDispatch(ClientPtr client); - - -typedef struct { - int x; - int y; - int w; - int h; -} PseudoramiXScreenRec; - -static PseudoramiXScreenRec *pseudoramiXScreens = NULL; -static int pseudoramiXScreensAllocated = 0; -static int pseudoramiXNumScreens = 0; -static unsigned long pseudoramiXGeneration = 0; - - -// Add a PseudoramiX screen. -// The rest of the X server will know nothing about this screen. -// Can be called before or after extension init. -// Screens must be re-added once per generation. -void -PseudoramiXAddScreen(int x, int y, int w, int h) -{ - PseudoramiXScreenRec *s; - - if (noPseudoramiXExtension) return; - - if (pseudoramiXNumScreens == pseudoramiXScreensAllocated) { - pseudoramiXScreensAllocated += pseudoramiXScreensAllocated + 1; - pseudoramiXScreens = xrealloc(pseudoramiXScreens, - pseudoramiXScreensAllocated * - sizeof(PseudoramiXScreenRec)); - } - - DEBUG_LOG("x: %d, y: %d, w: %d, h: %d\n", x, y, w, h); - - s = &pseudoramiXScreens[pseudoramiXNumScreens++]; - s->x = x; - s->y = y; - s->w = w; - s->h = h; -} - - -// Initialize PseudoramiX. -// Copied from PanoramiXExtensionInit -void PseudoramiXExtensionInit(int argc, char *argv[]) -{ - Bool success = FALSE; - ExtensionEntry *extEntry; - - if (noPseudoramiXExtension) return; - - TRACE(); - - /* Even with only one screen we need to enable PseudoramiX to allow - dynamic screen configuration changes. */ -#if 0 - if (pseudoramiXNumScreens == 1) { - // Only one screen - disable Xinerama extension. - noPseudoramiXExtension = TRUE; - return; - } -#endif - - if (pseudoramiXGeneration != serverGeneration) { - extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0, - ProcPseudoramiXDispatch, - SProcPseudoramiXDispatch, - PseudoramiXResetProc, - StandardMinorOpcode); - if (!extEntry) { - ErrorF("PseudoramiXExtensionInit(): AddExtension failed\n"); - } else { - pseudoramiXGeneration = serverGeneration; - success = TRUE; - } - } - - if (!success) { - ErrorF("%s Extension (PseudoramiX) failed to initialize\n", - PANORAMIX_PROTOCOL_NAME); - return; - } -} - - -void PseudoramiXResetScreens(void) -{ - TRACE(); - - pseudoramiXNumScreens = 0; -} - - -static void PseudoramiXResetProc(ExtensionEntry *extEntry) -{ - TRACE(); - - PseudoramiXResetScreens(); -} - - -// was PanoramiX -static int ProcPseudoramiXQueryVersion(ClientPtr client) -{ - TRACE(); - - return ProcPanoramiXQueryVersion(client); -} - - -// was PanoramiX -static int ProcPseudoramiXGetState(ClientPtr client) -{ - REQUEST(xPanoramiXGetStateReq); - WindowPtr pWin; - xPanoramiXGetStateReply rep; - register int n, rc; - - TRACE(); - - REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.state = !noPseudoramiXExtension; - if (client->swapped) { - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swaps (&rep.state, n); - } - WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep); - return client->noClientException; -} - - -// was PanoramiX -static int ProcPseudoramiXGetScreenCount(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenCountReq); - WindowPtr pWin; - xPanoramiXGetScreenCountReply rep; - register int n, rc; - - TRACE(); - - REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.ScreenCount = pseudoramiXNumScreens; - if (client->swapped) { - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swaps (&rep.ScreenCount, n); - } - WriteToClient (client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep); - return client->noClientException; -} - - -// was PanoramiX -static int ProcPseudoramiXGetScreenSize(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenSizeReq); - WindowPtr pWin; - xPanoramiXGetScreenSizeReply rep; - register int n, rc; - - TRACE(); - - REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - /* screen dimensions */ - rep.width = pseudoramiXScreens[stuff->screen].w; - // was panoramiXdataPtr[stuff->screen].width; - rep.height = pseudoramiXScreens[stuff->screen].h; - // was panoramiXdataPtr[stuff->screen].height; - if (client->swapped) { - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swaps (&rep.width, n); - swaps (&rep.height, n); - } - WriteToClient (client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep); - return client->noClientException; -} - - -// was Xinerama -static int ProcPseudoramiXIsActive(ClientPtr client) -{ - /* REQUEST(xXineramaIsActiveReq); */ - xXineramaIsActiveReply rep; - - TRACE(); - - REQUEST_SIZE_MATCH(xXineramaIsActiveReq); - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.state = !noPseudoramiXExtension; - if (client->swapped) { - register int n; - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swapl (&rep.state, n); - } - WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep); - return client->noClientException; -} - - -// was Xinerama -static int ProcPseudoramiXQueryScreens(ClientPtr client) -{ - /* REQUEST(xXineramaQueryScreensReq); */ - xXineramaQueryScreensReply rep; - - DEBUG_LOG("noPseudoramiXExtension=%d, pseudoramiXNumScreens=%d\n", noPseudoramiXExtension, pseudoramiXNumScreens); - - REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.number = noPseudoramiXExtension ? 0 : pseudoramiXNumScreens; - rep.length = bytes_to_int32(rep.number * sz_XineramaScreenInfo); - if (client->swapped) { - register int n; - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swapl (&rep.number, n); - } - WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep); - - if (!noPseudoramiXExtension) { - xXineramaScreenInfo scratch; - int i; - - for(i = 0; i < pseudoramiXNumScreens; i++) { - scratch.x_org = pseudoramiXScreens[i].x; - scratch.y_org = pseudoramiXScreens[i].y; - scratch.width = pseudoramiXScreens[i].w; - scratch.height = pseudoramiXScreens[i].h; - - if(client->swapped) { - register int n; - swaps (&scratch.x_org, n); - swaps (&scratch.y_org, n); - swaps (&scratch.width, n); - swaps (&scratch.height, n); - } - WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch); - } - } - - return client->noClientException; -} - - -// was PanoramiX -static int ProcPseudoramiXDispatch (ClientPtr client) -{ REQUEST(xReq); - TRACE(); - switch (stuff->data) - { - case X_PanoramiXQueryVersion: - return ProcPseudoramiXQueryVersion(client); - case X_PanoramiXGetState: - return ProcPseudoramiXGetState(client); - case X_PanoramiXGetScreenCount: - return ProcPseudoramiXGetScreenCount(client); - case X_PanoramiXGetScreenSize: - return ProcPseudoramiXGetScreenSize(client); - case X_XineramaIsActive: - return ProcPseudoramiXIsActive(client); - case X_XineramaQueryScreens: - return ProcPseudoramiXQueryScreens(client); - } - return BadRequest; -} - - - -static int -SProcPseudoramiXQueryVersion (ClientPtr client) -{ - REQUEST(xPanoramiXQueryVersionReq); - register int n; - - TRACE(); - - swaps(&stuff->length,n); - REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); - return ProcPseudoramiXQueryVersion(client); -} - -static int -SProcPseudoramiXGetState(ClientPtr client) -{ - REQUEST(xPanoramiXGetStateReq); - register int n; - - TRACE(); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); - return ProcPseudoramiXGetState(client); -} - -static int -SProcPseudoramiXGetScreenCount(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenCountReq); - register int n; - - TRACE(); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); - return ProcPseudoramiXGetScreenCount(client); -} - -static int -SProcPseudoramiXGetScreenSize(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenSizeReq); - register int n; - - TRACE(); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); - return ProcPseudoramiXGetScreenSize(client); -} - - -static int -SProcPseudoramiXIsActive(ClientPtr client) -{ - REQUEST(xXineramaIsActiveReq); - register int n; - - TRACE(); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXineramaIsActiveReq); - return ProcPseudoramiXIsActive(client); -} - - -static int -SProcPseudoramiXQueryScreens(ClientPtr client) -{ - REQUEST(xXineramaQueryScreensReq); - register int n; - - TRACE(); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); - return ProcPseudoramiXQueryScreens(client); -} - - -static int -SProcPseudoramiXDispatch (ClientPtr client) -{ REQUEST(xReq); - - TRACE(); - - switch (stuff->data) - { - case X_PanoramiXQueryVersion: - return SProcPseudoramiXQueryVersion(client); - case X_PanoramiXGetState: - return SProcPseudoramiXGetState(client); - case X_PanoramiXGetScreenCount: - return SProcPseudoramiXGetScreenCount(client); - case X_PanoramiXGetScreenSize: - return SProcPseudoramiXGetScreenSize(client); - case X_XineramaIsActive: - return SProcPseudoramiXIsActive(client); - case X_XineramaQueryScreens: - return SProcPseudoramiXQueryScreens(client); - } - return BadRequest; -} +/* + * Minimal implementation of PanoramiX/Xinerama + * + * This is used in rootless mode where the underlying window server + * already provides an abstracted view of multiple screens as one + * large screen area. + * + * This code is largely based on panoramiX.c, which contains the + * following copyright notice: + */ +/***************************************************************** +Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. +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. + +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 +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, +BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 of Digital Equipment Corporation +shall not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from Digital +Equipment Corporation. +******************************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "darwin.h" +#include "pseudoramiX.h" +#include "extnsionst.h" +#include "dixstruct.h" +#include "window.h" +#include +#include "globals.h" + +Bool noPseudoramiXExtension = FALSE; + +extern int ProcPanoramiXQueryVersion (ClientPtr client); + +static void PseudoramiXResetProc(ExtensionEntry *extEntry); + +static int ProcPseudoramiXQueryVersion(ClientPtr client); +static int ProcPseudoramiXGetState(ClientPtr client); +static int ProcPseudoramiXGetScreenCount(ClientPtr client); +static int ProcPseudoramiXGetScreenSize(ClientPtr client); +static int ProcPseudoramiXIsActive(ClientPtr client); +static int ProcPseudoramiXQueryScreens(ClientPtr client); +static int ProcPseudoramiXDispatch(ClientPtr client); + +static int SProcPseudoramiXQueryVersion(ClientPtr client); +static int SProcPseudoramiXGetState(ClientPtr client); +static int SProcPseudoramiXGetScreenCount(ClientPtr client); +static int SProcPseudoramiXGetScreenSize(ClientPtr client); +static int SProcPseudoramiXIsActive(ClientPtr client); +static int SProcPseudoramiXQueryScreens(ClientPtr client); +static int SProcPseudoramiXDispatch(ClientPtr client); + + +typedef struct { + int x; + int y; + int w; + int h; +} PseudoramiXScreenRec; + +static PseudoramiXScreenRec *pseudoramiXScreens = NULL; +static int pseudoramiXScreensAllocated = 0; +static int pseudoramiXNumScreens = 0; +static unsigned long pseudoramiXGeneration = 0; + + +// Add a PseudoramiX screen. +// The rest of the X server will know nothing about this screen. +// Can be called before or after extension init. +// Screens must be re-added once per generation. +void +PseudoramiXAddScreen(int x, int y, int w, int h) +{ + PseudoramiXScreenRec *s; + + if (noPseudoramiXExtension) return; + + if (pseudoramiXNumScreens == pseudoramiXScreensAllocated) { + pseudoramiXScreensAllocated += pseudoramiXScreensAllocated + 1; + pseudoramiXScreens = realloc(pseudoramiXScreens, + pseudoramiXScreensAllocated * + sizeof(PseudoramiXScreenRec)); + } + + DEBUG_LOG("x: %d, y: %d, w: %d, h: %d\n", x, y, w, h); + + s = &pseudoramiXScreens[pseudoramiXNumScreens++]; + s->x = x; + s->y = y; + s->w = w; + s->h = h; +} + + +// Initialize PseudoramiX. +// Copied from PanoramiXExtensionInit +void PseudoramiXExtensionInit(int argc, char *argv[]) +{ + Bool success = FALSE; + ExtensionEntry *extEntry; + + if (noPseudoramiXExtension) return; + + TRACE(); + + /* Even with only one screen we need to enable PseudoramiX to allow + dynamic screen configuration changes. */ +#if 0 + if (pseudoramiXNumScreens == 1) { + // Only one screen - disable Xinerama extension. + noPseudoramiXExtension = TRUE; + return; + } +#endif + + if (pseudoramiXGeneration != serverGeneration) { + extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0, + ProcPseudoramiXDispatch, + SProcPseudoramiXDispatch, + PseudoramiXResetProc, + StandardMinorOpcode); + if (!extEntry) { + ErrorF("PseudoramiXExtensionInit(): AddExtension failed\n"); + } else { + pseudoramiXGeneration = serverGeneration; + success = TRUE; + } + } + + if (!success) { + ErrorF("%s Extension (PseudoramiX) failed to initialize\n", + PANORAMIX_PROTOCOL_NAME); + return; + } +} + + +void PseudoramiXResetScreens(void) +{ + TRACE(); + + pseudoramiXNumScreens = 0; +} + + +static void PseudoramiXResetProc(ExtensionEntry *extEntry) +{ + TRACE(); + + PseudoramiXResetScreens(); +} + + +// was PanoramiX +static int ProcPseudoramiXQueryVersion(ClientPtr client) +{ + TRACE(); + + return ProcPanoramiXQueryVersion(client); +} + + +// was PanoramiX +static int ProcPseudoramiXGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + WindowPtr pWin; + xPanoramiXGetStateReply rep; + register int n, rc; + + TRACE(); + + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = !noPseudoramiXExtension; + if (client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swaps (&rep.state, n); + } + WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep); + return Success; +} + + +// was PanoramiX +static int ProcPseudoramiXGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + WindowPtr pWin; + xPanoramiXGetScreenCountReply rep; + register int n, rc; + + TRACE(); + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.ScreenCount = pseudoramiXNumScreens; + if (client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swaps (&rep.ScreenCount, n); + } + WriteToClient (client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep); + return Success; +} + + +// was PanoramiX +static int ProcPseudoramiXGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + WindowPtr pWin; + xPanoramiXGetScreenSizeReply rep; + register int n, rc; + + TRACE(); + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + /* screen dimensions */ + rep.width = pseudoramiXScreens[stuff->screen].w; + // was panoramiXdataPtr[stuff->screen].width; + rep.height = pseudoramiXScreens[stuff->screen].h; + // was panoramiXdataPtr[stuff->screen].height; + if (client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swaps (&rep.width, n); + swaps (&rep.height, n); + } + WriteToClient (client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep); + return Success; +} + + +// was Xinerama +static int ProcPseudoramiXIsActive(ClientPtr client) +{ + /* REQUEST(xXineramaIsActiveReq); */ + xXineramaIsActiveReply rep; + + TRACE(); + + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = !noPseudoramiXExtension; + if (client->swapped) { + register int n; + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.state, n); + } + WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep); + return Success; +} + + +// was Xinerama +static int ProcPseudoramiXQueryScreens(ClientPtr client) +{ + /* REQUEST(xXineramaQueryScreensReq); */ + xXineramaQueryScreensReply rep; + + DEBUG_LOG("noPseudoramiXExtension=%d, pseudoramiXNumScreens=%d\n", noPseudoramiXExtension, pseudoramiXNumScreens); + + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.number = noPseudoramiXExtension ? 0 : pseudoramiXNumScreens; + rep.length = bytes_to_int32(rep.number * sz_XineramaScreenInfo); + if (client->swapped) { + register int n; + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.number, n); + } + WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep); + + if (!noPseudoramiXExtension) { + xXineramaScreenInfo scratch; + int i; + + for(i = 0; i < pseudoramiXNumScreens; i++) { + scratch.x_org = pseudoramiXScreens[i].x; + scratch.y_org = pseudoramiXScreens[i].y; + scratch.width = pseudoramiXScreens[i].w; + scratch.height = pseudoramiXScreens[i].h; + + if(client->swapped) { + register int n; + swaps (&scratch.x_org, n); + swaps (&scratch.y_org, n); + swaps (&scratch.width, n); + swaps (&scratch.height, n); + } + WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch); + } + } + + return Success; +} + + +// was PanoramiX +static int ProcPseudoramiXDispatch (ClientPtr client) +{ REQUEST(xReq); + TRACE(); + switch (stuff->data) + { + case X_PanoramiXQueryVersion: + return ProcPseudoramiXQueryVersion(client); + case X_PanoramiXGetState: + return ProcPseudoramiXGetState(client); + case X_PanoramiXGetScreenCount: + return ProcPseudoramiXGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return ProcPseudoramiXGetScreenSize(client); + case X_XineramaIsActive: + return ProcPseudoramiXIsActive(client); + case X_XineramaQueryScreens: + return ProcPseudoramiXQueryScreens(client); + } + return BadRequest; +} + + + +static int +SProcPseudoramiXQueryVersion (ClientPtr client) +{ + REQUEST(xPanoramiXQueryVersionReq); + register int n; + + TRACE(); + + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); + return ProcPseudoramiXQueryVersion(client); +} + +static int +SProcPseudoramiXGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + register int n; + + TRACE(); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + return ProcPseudoramiXGetState(client); +} + +static int +SProcPseudoramiXGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + register int n; + + TRACE(); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + return ProcPseudoramiXGetScreenCount(client); +} + +static int +SProcPseudoramiXGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + register int n; + + TRACE(); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + return ProcPseudoramiXGetScreenSize(client); +} + + +static int +SProcPseudoramiXIsActive(ClientPtr client) +{ + REQUEST(xXineramaIsActiveReq); + register int n; + + TRACE(); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + return ProcPseudoramiXIsActive(client); +} + + +static int +SProcPseudoramiXQueryScreens(ClientPtr client) +{ + REQUEST(xXineramaQueryScreensReq); + register int n; + + TRACE(); + + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + return ProcPseudoramiXQueryScreens(client); +} + + +static int +SProcPseudoramiXDispatch (ClientPtr client) +{ REQUEST(xReq); + + TRACE(); + + switch (stuff->data) + { + case X_PanoramiXQueryVersion: + return SProcPseudoramiXQueryVersion(client); + case X_PanoramiXGetState: + return SProcPseudoramiXGetState(client); + case X_PanoramiXGetScreenCount: + return SProcPseudoramiXGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return SProcPseudoramiXGetScreenSize(client); + case X_XineramaIsActive: + return SProcPseudoramiXIsActive(client); + case X_XineramaQueryScreens: + return SProcPseudoramiXQueryScreens(client); + } + return BadRequest; +} diff --git a/xorg-server/hw/xquartz/quartz.c b/xorg-server/hw/xquartz/quartz.c index a8c0d4b47..e073b0586 100644 --- a/xorg-server/hw/xquartz/quartz.c +++ b/xorg-server/hw/xquartz/quartz.c @@ -1,449 +1,448 @@ -/* - * - * Quartz-specific support for the Darwin X Server - * - * Copyright (c) 2001-2004 Greg Parker and 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 -#endif - -#include "quartzCommon.h" -#include "inputstr.h" -#include "quartz.h" -#include "darwin.h" -#include "darwinEvents.h" -#include "pseudoramiX.h" -#define _APPLEWM_SERVER_ -#include "applewmExt.h" - -#include "X11Application.h" - -#include -#include - -// X headers -#include "scrnintstr.h" -#include "windowstr.h" -#include "colormapst.h" -#include "globals.h" -#include "mi.h" - -// System headers -#include -#include -#include -#include - -#include -#include - -#define FAKE_RANDR 1 - -// Shared global variables for Quartz modes -int quartzEventWriteFD = -1; -int quartzUseSysBeep = 0; -int quartzUseAGL = 1; -int quartzEnableKeyEquivalents = 1; -int quartzServerVisible = FALSE; -int quartzServerQuitting = FALSE; -static int quartzScreenKeyIndex; -DevPrivateKey quartzScreenKey = &quartzScreenKeyIndex; -int aquaMenuBarHeight = 0; -QuartzModeProcsPtr quartzProcs = NULL; -const char *quartzOpenGLBundle = NULL; -int quartzFullscreenDisableHotkeys = TRUE; -int quartzOptionSendsAlt = FALSE; - -#if defined(RANDR) && !defined(FAKE_RANDR) -Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) { - return FALSE; -} - -Bool QuartzRandRSetConfig (ScreenPtr pScreen, - Rotation randr, - int rate, - RRScreenSizePtr pSize) { - return FALSE; -} - -Bool QuartzRandRInit (ScreenPtr pScreen) { - rrScrPrivPtr pScrPriv; - - if (!RRScreenInit (pScreen)) return FALSE; - - pScrPriv = rrGetScrPriv(pScreen); - pScrPriv->rrGetInfo = QuartzRandRGetInfo; - pScrPriv->rrSetConfig = QuartzRandRSetConfig; - return TRUE; -} -#endif - -/* -=========================================================================== - - Screen functions - -=========================================================================== -*/ - -/* - * QuartzAddScreen - * Do mode dependent initialization of each screen for Quartz. - */ -Bool QuartzAddScreen( - int index, - ScreenPtr pScreen) -{ - // allocate space for private per screen Quartz specific storage - QuartzScreenPtr displayInfo = xcalloc(sizeof(QuartzScreenRec), 1); - - // QUARTZ_PRIV(pScreen) = displayInfo; - dixSetPrivate(&pScreen->devPrivates, quartzScreenKey, displayInfo); - - // do Quartz mode specific initialization - return quartzProcs->AddScreen(index, pScreen); -} - - -/* - * QuartzSetupScreen - * Finalize mode specific setup of each screen. - */ -Bool QuartzSetupScreen( - int index, - ScreenPtr pScreen) -{ - // do Quartz mode specific setup - if (! quartzProcs->SetupScreen(index, pScreen)) - return FALSE; - - // setup cursor support - if (! quartzProcs->InitCursor(pScreen)) - return FALSE; - - return TRUE; -} - - -/* - * QuartzInitOutput - * Quartz display initialization. - */ -void QuartzInitOutput( - int argc, - char **argv ) -{ - if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler, - QuartzWakeupHandler, - NULL)) - { - FatalError("Could not register block and wakeup handlers."); - } - -#if defined(RANDR) && !defined(FAKE_RANDR) - if(!QuartzRandRInit(pScreen)) - FatalError("Failed to init RandR extension.\n"); -#endif - - // Do display mode specific initialization - quartzProcs->DisplayInit(); -} - - -/* - * QuartzInitInput - * Inform the main thread the X server is ready to handle events. - */ -void QuartzInitInput( - int argc, - char **argv ) -{ - X11ApplicationSetCanQuit(0); - X11ApplicationServerReady(); - // Do final display mode specific initialization before handling events - if (quartzProcs->InitInput) - quartzProcs->InitInput(argc, argv); -} - - -#ifdef FAKE_RANDR - -static const int padlength[4] = {0, 3, 2, 1}; - -static void -RREditConnectionInfo (ScreenPtr pScreen) -{ - xConnSetup *connSetup; - char *vendor; - xPixmapFormat *formats; - xWindowRoot *root; - xDepth *depth; - xVisualType *visual; - int screen = 0; - int d; - - connSetup = (xConnSetup *) ConnectionInfo; - vendor = (char *) connSetup + sizeof (xConnSetup); - formats = (xPixmapFormat *) ((char *) vendor + - connSetup->nbytesVendor + - padlength[connSetup->nbytesVendor & 3]); - root = (xWindowRoot *) ((char *) formats + - sizeof (xPixmapFormat) * screenInfo.numPixmapFormats); - while (screen != pScreen->myNum) - { - depth = (xDepth *) ((char *) root + - sizeof (xWindowRoot)); - for (d = 0; d < root->nDepths; d++) - { - visual = (xVisualType *) ((char *) depth + - sizeof (xDepth)); - depth = (xDepth *) ((char *) visual + - depth->nVisuals * sizeof (xVisualType)); - } - root = (xWindowRoot *) ((char *) depth); - screen++; - } - root->pixWidth = pScreen->width; - root->pixHeight = pScreen->height; - root->mmWidth = pScreen->mmWidth; - root->mmHeight = pScreen->mmHeight; -} -#endif - -void QuartzUpdateScreens(void) { - ScreenPtr pScreen; - WindowPtr pRoot; - int x, y, width, height, sx, sy; - xEvent e; - BoxRec bounds; - - if (noPseudoramiXExtension || screenInfo.numScreens != 1) - { - /* FIXME: if not using Xinerama, we have multiple screens, and - to do this properly may need to add or remove screens. Which - isn't possible. So don't do anything. Another reason why - we default to running with Xinerama. */ - - return; - } - - pScreen = screenInfo.screens[0]; - - PseudoramiXResetScreens(); - quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height); - - dixScreenOrigins[pScreen->myNum].x = x; - dixScreenOrigins[pScreen->myNum].y = y; - pScreen->mmWidth = pScreen->mmWidth * ((double) width / pScreen->width); - pScreen->mmHeight = pScreen->mmHeight * ((double) height / pScreen->height); - pScreen->width = width; - pScreen->height = height; - - DarwinAdjustScreenOrigins(&screenInfo); - quartzProcs->UpdateScreen(pScreen); - - /* DarwinAdjustScreenOrigins or UpdateScreen may change dixScreenOrigins, - * so use it rather than x/y - */ - sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX; - sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY; - - /* Adjust the root window. */ - pRoot = WindowTable[pScreen->myNum]; - AppleWMSetScreenOrigin(pRoot); - pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL); - //pScreen->PaintWindowBackground (pRoot, &pRoot->borderClip, PW_BACKGROUND); - miPaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND); - - /* pointer events are clipped to old display region after display reconfiguration - * http://xquartz.macosforge.org/trac/ticket/346 - */ - bounds.x1 = 0; - bounds.x2 = width; - bounds.y1 = 0; - bounds.y2 = height; - pScreen->ConstrainCursor(inputInfo.pointer, pScreen, &bounds); - inputInfo.pointer->spriteInfo->sprite->physLimits = bounds; - inputInfo.pointer->spriteInfo->sprite->hotLimits = bounds; - - DEBUG_LOG("Root Window: %dx%d @ (%d, %d) darwinMainScreen (%d, %d) xy (%d, %d) dixScreenOrigins (%d, %d)\n", width, height, x - sx, y - sy, darwinMainScreenX, darwinMainScreenY, x, y, dixScreenOrigins[pScreen->myNum].x, dixScreenOrigins[pScreen->myNum].y); - - /* Send an event for the root reconfigure */ - e.u.u.type = ConfigureNotify; - e.u.configureNotify.window = pRoot->drawable.id; - e.u.configureNotify.aboveSibling = None; - e.u.configureNotify.x = x - sx; - e.u.configureNotify.y = y - sy; - e.u.configureNotify.width = width; - e.u.configureNotify.height = height; - e.u.configureNotify.borderWidth = wBorderWidth(pRoot); - e.u.configureNotify.override = pRoot->overrideRedirect; - DeliverEvents(pRoot, &e, 1, NullWindow); - -#ifdef FAKE_RANDR - RREditConnectionInfo(pScreen); -#endif -} - -void QuartzSetFullscreen(Bool state) { - - DEBUG_LOG("QuartzSetFullscreen: state=%d\n", state); - - if(quartzHasRoot == state) - return; - - quartzHasRoot = state; - - xp_disable_update (); - - if (!quartzHasRoot && !quartzEnableRootless) - RootlessHideAllWindows(); - - RootlessUpdateRooted(quartzHasRoot); - - if (quartzHasRoot && !quartzEnableRootless) - RootlessShowAllWindows (); - - if (quartzHasRoot || quartzEnableRootless) { - RootlessRepositionWindows(screenInfo.screens[0]); - } - - /* Somehow the menubar manages to interfere with our event stream - * in fullscreen mode, even though it's not visible. - */ - X11ApplicationShowHideMenubar(!quartzHasRoot); - - xp_reenable_update (); - - if (quartzFullscreenDisableHotkeys) - xp_disable_hot_keys(quartzHasRoot); -} - -void QuartzSetRootless(Bool state) { - if(quartzEnableRootless == state) - return; - - quartzEnableRootless = state; - - xp_disable_update(); - - /* When in rootless, the menubar is not part of the screen, so we need to update our screens on toggle */ - QuartzUpdateScreens(); - - if(!quartzHasRoot) { - if(!quartzEnableRootless) { - RootlessHideAllWindows(); - } else { - RootlessShowAllWindows(); - } - } - - X11ApplicationShowHideMenubar(!quartzHasRoot); - - xp_reenable_update(); - - if (!quartzEnableRootless && quartzFullscreenDisableHotkeys) - xp_disable_hot_keys(quartzHasRoot); -} - -/* - * QuartzShow - * Show the X server on screen. Does nothing if already shown. - * Calls mode specific screen resume to restore the X clip regions - * (if needed) and the X server cursor state. - */ -void QuartzShow(void) { - int i; - - if (quartzServerVisible) - return; - - quartzServerVisible = TRUE; - for (i = 0; i < screenInfo.numScreens; i++) { - if (screenInfo.screens[i]) { - quartzProcs->ResumeScreen(screenInfo.screens[i]); - } - } - - if (!quartzEnableRootless) - QuartzSetFullscreen(TRUE); -} - - -/* - * QuartzHide - * Remove the X server display from the screen. Does nothing if already - * hidden. Calls mode specific screen suspend to set X clip regions to - * prevent drawing (if needed) and restore the Aqua cursor. - */ -void QuartzHide(void) -{ - int i; - - if (quartzServerVisible) { - for (i = 0; i < screenInfo.numScreens; i++) { - if (screenInfo.screens[i]) { - quartzProcs->SuspendScreen(screenInfo.screens[i]); - } - } - } - - QuartzSetFullscreen(FALSE); - quartzServerVisible = FALSE; -} - - -/* - * QuartzSetRootClip - * Enable or disable rendering to the X screen. - */ -void QuartzSetRootClip( - BOOL enable) -{ - int i; - - if (!quartzServerVisible) - return; - - for (i = 0; i < screenInfo.numScreens; i++) { - if (screenInfo.screens[i]) { - xf86SetRootClip(screenInfo.screens[i], enable); - } - } -} - -/* - * QuartzSpaceChanged - * Unmap offscreen windows, map onscreen windows - */ -void QuartzSpaceChanged(uint32_t space_id) { - /* Do something special here, so we don't depend on quartz-wm for spaces to work... */ - DEBUG_LOG("Space Changed (%u) ... do something interesting...\n", space_id); -} +/* + * + * Quartz-specific support for the Darwin X Server + * + * Copyright (c) 2001-2004 Greg Parker and 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 +#endif + +#include "quartzCommon.h" +#include "inputstr.h" +#include "quartz.h" +#include "darwin.h" +#include "darwinEvents.h" +#include "pseudoramiX.h" +#define _APPLEWM_SERVER_ +#include "applewmExt.h" + +#include "X11Application.h" + +#include +#include + +// X headers +#include "scrnintstr.h" +#include "windowstr.h" +#include "colormapst.h" +#include "globals.h" +#include "mi.h" + +// System headers +#include +#include +#include +#include + +#include +#include + +#define FAKE_RANDR 1 + +// Shared global variables for Quartz modes +int quartzEventWriteFD = -1; +int quartzUseSysBeep = 0; +int quartzUseAGL = 1; +int quartzEnableKeyEquivalents = 1; +int quartzServerVisible = FALSE; +int quartzServerQuitting = FALSE; +static int quartzScreenKeyIndex; +DevPrivateKey quartzScreenKey = &quartzScreenKeyIndex; +int aquaMenuBarHeight = 0; +QuartzModeProcsPtr quartzProcs = NULL; +const char *quartzOpenGLBundle = NULL; +int quartzFullscreenDisableHotkeys = TRUE; +int quartzOptionSendsAlt = FALSE; + +#if defined(RANDR) && !defined(FAKE_RANDR) +Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) { + return FALSE; +} + +Bool QuartzRandRSetConfig (ScreenPtr pScreen, + Rotation randr, + int rate, + RRScreenSizePtr pSize) { + return FALSE; +} + +Bool QuartzRandRInit (ScreenPtr pScreen) { + rrScrPrivPtr pScrPriv; + + if (!RRScreenInit (pScreen)) return FALSE; + + pScrPriv = rrGetScrPriv(pScreen); + pScrPriv->rrGetInfo = QuartzRandRGetInfo; + pScrPriv->rrSetConfig = QuartzRandRSetConfig; + return TRUE; +} +#endif + +/* +=========================================================================== + + Screen functions + +=========================================================================== +*/ + +/* + * QuartzAddScreen + * Do mode dependent initialization of each screen for Quartz. + */ +Bool QuartzAddScreen( + int index, + ScreenPtr pScreen) +{ + // allocate space for private per screen Quartz specific storage + QuartzScreenPtr displayInfo = calloc(sizeof(QuartzScreenRec), 1); + + // QUARTZ_PRIV(pScreen) = displayInfo; + dixSetPrivate(&pScreen->devPrivates, quartzScreenKey, displayInfo); + + // do Quartz mode specific initialization + return quartzProcs->AddScreen(index, pScreen); +} + + +/* + * QuartzSetupScreen + * Finalize mode specific setup of each screen. + */ +Bool QuartzSetupScreen( + int index, + ScreenPtr pScreen) +{ + // do Quartz mode specific setup + if (! quartzProcs->SetupScreen(index, pScreen)) + return FALSE; + + // setup cursor support + if (! quartzProcs->InitCursor(pScreen)) + return FALSE; + + return TRUE; +} + + +/* + * QuartzInitOutput + * Quartz display initialization. + */ +void QuartzInitOutput( + int argc, + char **argv ) +{ + if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler, + QuartzWakeupHandler, + NULL)) + { + FatalError("Could not register block and wakeup handlers."); + } + +#if defined(RANDR) && !defined(FAKE_RANDR) + if(!QuartzRandRInit(pScreen)) + FatalError("Failed to init RandR extension.\n"); +#endif + + // Do display mode specific initialization + quartzProcs->DisplayInit(); +} + + +/* + * QuartzInitInput + * Inform the main thread the X server is ready to handle events. + */ +void QuartzInitInput( + int argc, + char **argv ) +{ + X11ApplicationSetCanQuit(0); + X11ApplicationServerReady(); + // Do final display mode specific initialization before handling events + if (quartzProcs->InitInput) + quartzProcs->InitInput(argc, argv); +} + + +#ifdef FAKE_RANDR + +static const int padlength[4] = {0, 3, 2, 1}; + +static void +RREditConnectionInfo (ScreenPtr pScreen) +{ + xConnSetup *connSetup; + char *vendor; + xPixmapFormat *formats; + xWindowRoot *root; + xDepth *depth; + xVisualType *visual; + int screen = 0; + int d; + + connSetup = (xConnSetup *) ConnectionInfo; + vendor = (char *) connSetup + sizeof (xConnSetup); + formats = (xPixmapFormat *) ((char *) vendor + + connSetup->nbytesVendor + + padlength[connSetup->nbytesVendor & 3]); + root = (xWindowRoot *) ((char *) formats + + sizeof (xPixmapFormat) * screenInfo.numPixmapFormats); + while (screen != pScreen->myNum) + { + depth = (xDepth *) ((char *) root + + sizeof (xWindowRoot)); + for (d = 0; d < root->nDepths; d++) + { + visual = (xVisualType *) ((char *) depth + + sizeof (xDepth)); + depth = (xDepth *) ((char *) visual + + depth->nVisuals * sizeof (xVisualType)); + } + root = (xWindowRoot *) ((char *) depth); + screen++; + } + root->pixWidth = pScreen->width; + root->pixHeight = pScreen->height; + root->mmWidth = pScreen->mmWidth; + root->mmHeight = pScreen->mmHeight; +} +#endif + +void QuartzUpdateScreens(void) { + ScreenPtr pScreen; + WindowPtr pRoot; + int x, y, width, height, sx, sy; + xEvent e; + BoxRec bounds; + + if (noPseudoramiXExtension || screenInfo.numScreens != 1) + { + /* FIXME: if not using Xinerama, we have multiple screens, and + to do this properly may need to add or remove screens. Which + isn't possible. So don't do anything. Another reason why + we default to running with Xinerama. */ + + return; + } + + pScreen = screenInfo.screens[0]; + + PseudoramiXResetScreens(); + quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height); + + dixScreenOrigins[pScreen->myNum].x = x; + dixScreenOrigins[pScreen->myNum].y = y; + pScreen->mmWidth = pScreen->mmWidth * ((double) width / pScreen->width); + pScreen->mmHeight = pScreen->mmHeight * ((double) height / pScreen->height); + pScreen->width = width; + pScreen->height = height; + + DarwinAdjustScreenOrigins(&screenInfo); + quartzProcs->UpdateScreen(pScreen); + + /* DarwinAdjustScreenOrigins or UpdateScreen may change dixScreenOrigins, + * so use it rather than x/y + */ + sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX; + sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY; + + /* Adjust the root window. */ + pRoot = WindowTable[pScreen->myNum]; + AppleWMSetScreenOrigin(pRoot); + pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL); + miPaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND); + + /* pointer events are clipped to old display region after display reconfiguration + * http://xquartz.macosforge.org/trac/ticket/346 + */ + bounds.x1 = 0; + bounds.x2 = width; + bounds.y1 = 0; + bounds.y2 = height; + pScreen->ConstrainCursor(inputInfo.pointer, pScreen, &bounds); + inputInfo.pointer->spriteInfo->sprite->physLimits = bounds; + inputInfo.pointer->spriteInfo->sprite->hotLimits = bounds; + + DEBUG_LOG("Root Window: %dx%d @ (%d, %d) darwinMainScreen (%d, %d) xy (%d, %d) dixScreenOrigins (%d, %d)\n", width, height, x - sx, y - sy, darwinMainScreenX, darwinMainScreenY, x, y, dixScreenOrigins[pScreen->myNum].x, dixScreenOrigins[pScreen->myNum].y); + + /* Send an event for the root reconfigure */ + e.u.u.type = ConfigureNotify; + e.u.configureNotify.window = pRoot->drawable.id; + e.u.configureNotify.aboveSibling = None; + e.u.configureNotify.x = x - sx; + e.u.configureNotify.y = y - sy; + e.u.configureNotify.width = width; + e.u.configureNotify.height = height; + e.u.configureNotify.borderWidth = wBorderWidth(pRoot); + e.u.configureNotify.override = pRoot->overrideRedirect; + DeliverEvents(pRoot, &e, 1, NullWindow); + +#ifdef FAKE_RANDR + RREditConnectionInfo(pScreen); +#endif +} + +void QuartzSetFullscreen(Bool state) { + + DEBUG_LOG("QuartzSetFullscreen: state=%d\n", state); + + if(quartzHasRoot == state) + return; + + quartzHasRoot = state; + + xp_disable_update (); + + if (!quartzHasRoot && !quartzEnableRootless) + RootlessHideAllWindows(); + + RootlessUpdateRooted(quartzHasRoot); + + if (quartzHasRoot && !quartzEnableRootless) + RootlessShowAllWindows (); + + if (quartzHasRoot || quartzEnableRootless) { + RootlessRepositionWindows(screenInfo.screens[0]); + } + + /* Somehow the menubar manages to interfere with our event stream + * in fullscreen mode, even though it's not visible. + */ + X11ApplicationShowHideMenubar(!quartzHasRoot); + + xp_reenable_update (); + + if (quartzFullscreenDisableHotkeys) + xp_disable_hot_keys(quartzHasRoot); +} + +void QuartzSetRootless(Bool state) { + if(quartzEnableRootless == state) + return; + + quartzEnableRootless = state; + + xp_disable_update(); + + /* When in rootless, the menubar is not part of the screen, so we need to update our screens on toggle */ + QuartzUpdateScreens(); + + if(!quartzHasRoot) { + if(!quartzEnableRootless) { + RootlessHideAllWindows(); + } else { + RootlessShowAllWindows(); + } + } + + X11ApplicationShowHideMenubar(!quartzHasRoot); + + xp_reenable_update(); + + if (!quartzEnableRootless && quartzFullscreenDisableHotkeys) + xp_disable_hot_keys(quartzHasRoot); +} + +/* + * QuartzShow + * Show the X server on screen. Does nothing if already shown. + * Calls mode specific screen resume to restore the X clip regions + * (if needed) and the X server cursor state. + */ +void QuartzShow(void) { + int i; + + if (quartzServerVisible) + return; + + quartzServerVisible = TRUE; + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + quartzProcs->ResumeScreen(screenInfo.screens[i]); + } + } + + if (!quartzEnableRootless) + QuartzSetFullscreen(TRUE); +} + + +/* + * QuartzHide + * Remove the X server display from the screen. Does nothing if already + * hidden. Calls mode specific screen suspend to set X clip regions to + * prevent drawing (if needed) and restore the Aqua cursor. + */ +void QuartzHide(void) +{ + int i; + + if (quartzServerVisible) { + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + quartzProcs->SuspendScreen(screenInfo.screens[i]); + } + } + } + + QuartzSetFullscreen(FALSE); + quartzServerVisible = FALSE; +} + + +/* + * QuartzSetRootClip + * Enable or disable rendering to the X screen. + */ +void QuartzSetRootClip( + BOOL enable) +{ + int i; + + if (!quartzServerVisible) + return; + + for (i = 0; i < screenInfo.numScreens; i++) { + if (screenInfo.screens[i]) { + xf86SetRootClip(screenInfo.screens[i], enable); + } + } +} + +/* + * QuartzSpaceChanged + * Unmap offscreen windows, map onscreen windows + */ +void QuartzSpaceChanged(uint32_t space_id) { + /* Do something special here, so we don't depend on quartz-wm for spaces to work... */ + DEBUG_LOG("Space Changed (%u) ... do something interesting...\n", space_id); +} diff --git a/xorg-server/hw/xquartz/xpr/appledri.c b/xorg-server/hw/xquartz/xpr/appledri.c index 74a4ec315..87cb9016a 100644 --- a/xorg-server/hw/xquartz/xpr/appledri.c +++ b/xorg-server/hw/xquartz/xpr/appledri.c @@ -1,429 +1,429 @@ -/************************************************************************** - -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: - * Kevin E. Martin - * Jens Owen - * Rickard E. (Rik) Faith - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include -#include -#include "misc.h" -#include "dixstruct.h" -#include "extnsionst.h" -#include "colormapst.h" -#include "cursorstr.h" -#include "scrnintstr.h" -#include "servermd.h" -#define _APPLEDRI_SERVER_ -#include "appledristr.h" -#include "swaprep.h" -#include "dri.h" -#include "dristruct.h" -#include "xpr.h" -#include "x-hash.h" -#include "protocol-versions.h" - -static int DRIErrorBase = 0; - -static DISPATCH_PROC(ProcAppleDRIDispatch); -static DISPATCH_PROC(SProcAppleDRIDispatch); - -static void AppleDRIResetProc(ExtensionEntry* extEntry); -static int ProcAppleDRICreatePixmap(ClientPtr client); - -static unsigned char DRIReqCode = 0; -static int DRIEventBase = 0; - -static void SNotifyEvent(xAppleDRINotifyEvent *from, xAppleDRINotifyEvent *to); - -typedef struct _DRIEvent *DRIEventPtr; -typedef struct _DRIEvent { - DRIEventPtr next; - ClientPtr client; - XID clientResource; - unsigned int mask; -} DRIEventRec; - - -void -AppleDRIExtensionInit(void) -{ - ExtensionEntry* extEntry; - - if (DRIExtensionInit() && - (extEntry = AddExtension(APPLEDRINAME, - AppleDRINumberEvents, - AppleDRINumberErrors, - ProcAppleDRIDispatch, - SProcAppleDRIDispatch, - AppleDRIResetProc, - StandardMinorOpcode))) { - DRIReqCode = (unsigned char)extEntry->base; - DRIErrorBase = extEntry->errorBase; - DRIEventBase = extEntry->eventBase; - EventSwapVector[DRIEventBase] = (EventSwapPtr) SNotifyEvent; - } -} - -/*ARGSUSED*/ -static void -AppleDRIResetProc ( - ExtensionEntry* extEntry -) -{ - DRIReset(); -} - -static int -ProcAppleDRIQueryVersion( - register ClientPtr client -) -{ - xAppleDRIQueryVersionReply rep; - register int n; - - REQUEST_SIZE_MATCH(xAppleDRIQueryVersionReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.majorVersion = SERVER_APPLEDRI_MAJOR_VERSION; - rep.minorVersion = SERVER_APPLEDRI_MINOR_VERSION; - rep.patchVersion = SERVER_APPLEDRI_PATCH_VERSION; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - } - WriteToClient(client, sizeof(xAppleDRIQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - - -/* surfaces */ - -static int -ProcAppleDRIQueryDirectRenderingCapable( - register ClientPtr client -) -{ - xAppleDRIQueryDirectRenderingCapableReply rep; - Bool isCapable; - - REQUEST(xAppleDRIQueryDirectRenderingCapableReq); - REQUEST_SIZE_MATCH(xAppleDRIQueryDirectRenderingCapableReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - if (!DRIQueryDirectRenderingCapable( screenInfo.screens[stuff->screen], - &isCapable)) { - return BadValue; - } - rep.isCapable = isCapable; - - if (!LocalClient(client)) - rep.isCapable = 0; - - WriteToClient(client, - sizeof(xAppleDRIQueryDirectRenderingCapableReply), (char *)&rep); - return (client->noClientException); -} - -static int -ProcAppleDRIAuthConnection( - register ClientPtr client -) -{ - xAppleDRIAuthConnectionReply rep; - - REQUEST(xAppleDRIAuthConnectionReq); - REQUEST_SIZE_MATCH(xAppleDRIAuthConnectionReq); - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.authenticated = 1; - - if (!DRIAuthConnection( screenInfo.screens[stuff->screen], stuff->magic)) { - ErrorF("Failed to authenticate %u\n", (unsigned int)stuff->magic); - rep.authenticated = 0; - } - WriteToClient(client, sizeof(xAppleDRIAuthConnectionReply), (char *)&rep); - return (client->noClientException); -} - -static void surface_notify( - void *_arg, - void *data -) -{ - DRISurfaceNotifyArg *arg = _arg; - int client_index = (int) x_cvt_vptr_to_uint(data); - ClientPtr client; - xAppleDRINotifyEvent se; - - if (client_index < 0 || client_index >= currentMaxClients) - return; - - client = clients[client_index]; - if (client == NULL || client == serverClient || client->clientGone) - return; - - se.type = DRIEventBase + AppleDRISurfaceNotify; - se.kind = arg->kind; - se.arg = arg->id; - se.sequenceNumber = client->sequence; - se.time = currentTime.milliseconds; - WriteEventsToClient (client, 1, (xEvent *) &se); -} - -static int -ProcAppleDRICreateSurface( - ClientPtr client -) -{ - xAppleDRICreateSurfaceReply rep; - DrawablePtr pDrawable; - xp_surface_id sid; - unsigned int key[2]; - int rc; - - REQUEST(xAppleDRICreateSurfaceReq); - REQUEST_SIZE_MATCH(xAppleDRICreateSurfaceReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, - DixReadAccess); - if (rc != Success) - return rc; - - rep.key_0 = rep.key_1 = rep.uid = 0; - - if (!DRICreateSurface( screenInfo.screens[stuff->screen], - (Drawable)stuff->drawable, pDrawable, - stuff->client_id, &sid, key, - surface_notify, - x_cvt_uint_to_vptr(client->index))) { - return BadValue; - } - - rep.key_0 = key[0]; - rep.key_1 = key[1]; - rep.uid = sid; - - WriteToClient(client, sizeof(xAppleDRICreateSurfaceReply), (char *)&rep); - return (client->noClientException); -} - -static int -ProcAppleDRIDestroySurface( - register ClientPtr client -) -{ - int rc; - REQUEST(xAppleDRIDestroySurfaceReq); - DrawablePtr pDrawable; - REQUEST_SIZE_MATCH(xAppleDRIDestroySurfaceReq); - - rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, - DixReadAccess); - if (rc != Success) - return rc; - - if (!DRIDestroySurface( screenInfo.screens[stuff->screen], - (Drawable)stuff->drawable, - pDrawable, NULL, NULL)) { - return BadValue; - } - - return (client->noClientException); -} - -static int -ProcAppleDRICreatePixmap(ClientPtr client) -{ - REQUEST(xAppleDRICreatePixmapReq); - DrawablePtr pDrawable; - int rc; - char path[PATH_MAX]; - xAppleDRICreatePixmapReply rep; - int width, height, pitch, bpp; - void *ptr; - - REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq); - - rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, - DixReadAccess); - - if(rc != Success) - return rc; - - if(!DRICreatePixmap(screenInfo.screens[stuff->screen], - (Drawable)stuff->drawable, - pDrawable, - path, PATH_MAX)) { - return BadValue; - } - - if(!DRIGetPixmapData(pDrawable, &width, &height, - &pitch, &bpp, &ptr)) { - return BadValue; - } - - rep.stringLength = strlen(path) + 1; - - /* No need for swapping, because this only runs if LocalClient is true. */ - rep.type = X_Reply; - rep.length = sizeof(rep) + rep.stringLength; - rep.sequenceNumber = client->sequence; - rep.width = width; - rep.height = height; - rep.pitch = pitch; - rep.bpp = bpp; - rep.size = pitch * height; - - if(sizeof(rep) != sz_xAppleDRICreatePixmapReply) - ErrorF("error sizeof(rep) is %zu\n", sizeof(rep)); - - WriteReplyToClient(client, sizeof(rep), &rep); - (void)WriteToClient(client, rep.stringLength, path); - - return (client->noClientException); -} - -static int -ProcAppleDRIDestroyPixmap(ClientPtr client) -{ - DrawablePtr pDrawable; - int rc; - REQUEST(xAppleDRIDestroyPixmapReq); - REQUEST_SIZE_MATCH(xAppleDRIDestroyPixmapReq); - - rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, - DixReadAccess); - - if(rc != Success) - return rc; - - DRIDestroyPixmap(pDrawable); - - return (client->noClientException); -} - -/* dispatch */ - -static int -ProcAppleDRIDispatch ( - register ClientPtr client -) -{ - REQUEST(xReq); - - switch (stuff->data) - { - case X_AppleDRIQueryVersion: - return ProcAppleDRIQueryVersion(client); - case X_AppleDRIQueryDirectRenderingCapable: - return ProcAppleDRIQueryDirectRenderingCapable(client); - } - - if (!LocalClient(client)) - return DRIErrorBase + AppleDRIClientNotLocal; - - switch (stuff->data) - { - case X_AppleDRIAuthConnection: - return ProcAppleDRIAuthConnection(client); - case X_AppleDRICreateSurface: - return ProcAppleDRICreateSurface(client); - case X_AppleDRIDestroySurface: - return ProcAppleDRIDestroySurface(client); - case X_AppleDRICreatePixmap: - return ProcAppleDRICreatePixmap(client); - case X_AppleDRIDestroyPixmap: - return ProcAppleDRIDestroyPixmap(client); - - default: - return BadRequest; - } -} - -static void -SNotifyEvent( - xAppleDRINotifyEvent *from, - xAppleDRINotifyEvent *to -) -{ - to->type = from->type; - to->kind = from->kind; - cpswaps (from->sequenceNumber, to->sequenceNumber); - cpswapl (from->time, to->time); - cpswapl (from->arg, to->arg); -} - -static int -SProcAppleDRIQueryVersion( - register ClientPtr client -) -{ - register int n; - REQUEST(xAppleDRIQueryVersionReq); - swaps(&stuff->length, n); - return ProcAppleDRIQueryVersion(client); -} - -static int -SProcAppleDRIDispatch ( - register ClientPtr client -) -{ - REQUEST(xReq); - - /* It is bound to be non-local when there is byte swapping */ - if (!LocalClient(client)) - return DRIErrorBase + AppleDRIClientNotLocal; - - /* only local clients are allowed DRI access */ - switch (stuff->data) - { - case X_AppleDRIQueryVersion: - return SProcAppleDRIQueryVersion(client); - default: - return BadRequest; - } -} +/************************************************************************** + +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: + * Kevin E. Martin + * Jens Owen + * Rickard E. (Rik) Faith + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include +#include "misc.h" +#include "dixstruct.h" +#include "extnsionst.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "scrnintstr.h" +#include "servermd.h" +#define _APPLEDRI_SERVER_ +#include "appledristr.h" +#include "swaprep.h" +#include "dri.h" +#include "dristruct.h" +#include "xpr.h" +#include "x-hash.h" +#include "protocol-versions.h" + +static int DRIErrorBase = 0; + +static DISPATCH_PROC(ProcAppleDRIDispatch); +static DISPATCH_PROC(SProcAppleDRIDispatch); + +static void AppleDRIResetProc(ExtensionEntry* extEntry); +static int ProcAppleDRICreatePixmap(ClientPtr client); + +static unsigned char DRIReqCode = 0; +static int DRIEventBase = 0; + +static void SNotifyEvent(xAppleDRINotifyEvent *from, xAppleDRINotifyEvent *to); + +typedef struct _DRIEvent *DRIEventPtr; +typedef struct _DRIEvent { + DRIEventPtr next; + ClientPtr client; + XID clientResource; + unsigned int mask; +} DRIEventRec; + + +void +AppleDRIExtensionInit(void) +{ + ExtensionEntry* extEntry; + + if (DRIExtensionInit() && + (extEntry = AddExtension(APPLEDRINAME, + AppleDRINumberEvents, + AppleDRINumberErrors, + ProcAppleDRIDispatch, + SProcAppleDRIDispatch, + AppleDRIResetProc, + StandardMinorOpcode))) { + DRIReqCode = (unsigned char)extEntry->base; + DRIErrorBase = extEntry->errorBase; + DRIEventBase = extEntry->eventBase; + EventSwapVector[DRIEventBase] = (EventSwapPtr) SNotifyEvent; + } +} + +/*ARGSUSED*/ +static void +AppleDRIResetProc ( + ExtensionEntry* extEntry +) +{ + DRIReset(); +} + +static int +ProcAppleDRIQueryVersion( + register ClientPtr client +) +{ + xAppleDRIQueryVersionReply rep; + register int n; + + REQUEST_SIZE_MATCH(xAppleDRIQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = SERVER_APPLEDRI_MAJOR_VERSION; + rep.minorVersion = SERVER_APPLEDRI_MINOR_VERSION; + rep.patchVersion = SERVER_APPLEDRI_PATCH_VERSION; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + } + WriteToClient(client, sizeof(xAppleDRIQueryVersionReply), (char *)&rep); + return Success; +} + + +/* surfaces */ + +static int +ProcAppleDRIQueryDirectRenderingCapable( + register ClientPtr client +) +{ + xAppleDRIQueryDirectRenderingCapableReply rep; + Bool isCapable; + + REQUEST(xAppleDRIQueryDirectRenderingCapableReq); + REQUEST_SIZE_MATCH(xAppleDRIQueryDirectRenderingCapableReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if (!DRIQueryDirectRenderingCapable( screenInfo.screens[stuff->screen], + &isCapable)) { + return BadValue; + } + rep.isCapable = isCapable; + + if (!LocalClient(client)) + rep.isCapable = 0; + + WriteToClient(client, + sizeof(xAppleDRIQueryDirectRenderingCapableReply), (char *)&rep); + return Success; +} + +static int +ProcAppleDRIAuthConnection( + register ClientPtr client +) +{ + xAppleDRIAuthConnectionReply rep; + + REQUEST(xAppleDRIAuthConnectionReq); + REQUEST_SIZE_MATCH(xAppleDRIAuthConnectionReq); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.authenticated = 1; + + if (!DRIAuthConnection( screenInfo.screens[stuff->screen], stuff->magic)) { + ErrorF("Failed to authenticate %u\n", (unsigned int)stuff->magic); + rep.authenticated = 0; + } + WriteToClient(client, sizeof(xAppleDRIAuthConnectionReply), (char *)&rep); + return Success; +} + +static void surface_notify( + void *_arg, + void *data +) +{ + DRISurfaceNotifyArg *arg = _arg; + int client_index = (int) x_cvt_vptr_to_uint(data); + ClientPtr client; + xAppleDRINotifyEvent se; + + if (client_index < 0 || client_index >= currentMaxClients) + return; + + client = clients[client_index]; + if (client == NULL || client == serverClient || client->clientGone) + return; + + se.type = DRIEventBase + AppleDRISurfaceNotify; + se.kind = arg->kind; + se.arg = arg->id; + se.sequenceNumber = client->sequence; + se.time = currentTime.milliseconds; + WriteEventsToClient (client, 1, (xEvent *) &se); +} + +static int +ProcAppleDRICreateSurface( + ClientPtr client +) +{ + xAppleDRICreateSurfaceReply rep; + DrawablePtr pDrawable; + xp_surface_id sid; + unsigned int key[2]; + int rc; + + REQUEST(xAppleDRICreateSurfaceReq); + REQUEST_SIZE_MATCH(xAppleDRICreateSurfaceReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + + rep.key_0 = rep.key_1 = rep.uid = 0; + + if (!DRICreateSurface( screenInfo.screens[stuff->screen], + (Drawable)stuff->drawable, pDrawable, + stuff->client_id, &sid, key, + surface_notify, + x_cvt_uint_to_vptr(client->index))) { + return BadValue; + } + + rep.key_0 = key[0]; + rep.key_1 = key[1]; + rep.uid = sid; + + WriteToClient(client, sizeof(xAppleDRICreateSurfaceReply), (char *)&rep); + return Success; +} + +static int +ProcAppleDRIDestroySurface( + register ClientPtr client +) +{ + int rc; + REQUEST(xAppleDRIDestroySurfaceReq); + DrawablePtr pDrawable; + REQUEST_SIZE_MATCH(xAppleDRIDestroySurfaceReq); + + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + + if (!DRIDestroySurface( screenInfo.screens[stuff->screen], + (Drawable)stuff->drawable, + pDrawable, NULL, NULL)) { + return BadValue; + } + + return Success; +} + +static int +ProcAppleDRICreatePixmap(ClientPtr client) +{ + REQUEST(xAppleDRICreatePixmapReq); + DrawablePtr pDrawable; + int rc; + char path[PATH_MAX]; + xAppleDRICreatePixmapReply rep; + int width, height, pitch, bpp; + void *ptr; + + REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq); + + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixReadAccess); + + if(rc != Success) + return rc; + + if(!DRICreatePixmap(screenInfo.screens[stuff->screen], + (Drawable)stuff->drawable, + pDrawable, + path, PATH_MAX)) { + return BadValue; + } + + if(!DRIGetPixmapData(pDrawable, &width, &height, + &pitch, &bpp, &ptr)) { + return BadValue; + } + + rep.stringLength = strlen(path) + 1; + + /* No need for swapping, because this only runs if LocalClient is true. */ + rep.type = X_Reply; + rep.length = sizeof(rep) + rep.stringLength; + rep.sequenceNumber = client->sequence; + rep.width = width; + rep.height = height; + rep.pitch = pitch; + rep.bpp = bpp; + rep.size = pitch * height; + + if(sizeof(rep) != sz_xAppleDRICreatePixmapReply) + ErrorF("error sizeof(rep) is %zu\n", sizeof(rep)); + + WriteReplyToClient(client, sizeof(rep), &rep); + (void)WriteToClient(client, rep.stringLength, path); + + return Success; +} + +static int +ProcAppleDRIDestroyPixmap(ClientPtr client) +{ + DrawablePtr pDrawable; + int rc; + REQUEST(xAppleDRIDestroyPixmapReq); + REQUEST_SIZE_MATCH(xAppleDRIDestroyPixmapReq); + + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixReadAccess); + + if(rc != Success) + return rc; + + DRIDestroyPixmap(pDrawable); + + return Success; +} + +/* dispatch */ + +static int +ProcAppleDRIDispatch ( + register ClientPtr client +) +{ + REQUEST(xReq); + + switch (stuff->data) + { + case X_AppleDRIQueryVersion: + return ProcAppleDRIQueryVersion(client); + case X_AppleDRIQueryDirectRenderingCapable: + return ProcAppleDRIQueryDirectRenderingCapable(client); + } + + if (!LocalClient(client)) + return DRIErrorBase + AppleDRIClientNotLocal; + + switch (stuff->data) + { + case X_AppleDRIAuthConnection: + return ProcAppleDRIAuthConnection(client); + case X_AppleDRICreateSurface: + return ProcAppleDRICreateSurface(client); + case X_AppleDRIDestroySurface: + return ProcAppleDRIDestroySurface(client); + case X_AppleDRICreatePixmap: + return ProcAppleDRICreatePixmap(client); + case X_AppleDRIDestroyPixmap: + return ProcAppleDRIDestroyPixmap(client); + + default: + return BadRequest; + } +} + +static void +SNotifyEvent( + xAppleDRINotifyEvent *from, + xAppleDRINotifyEvent *to +) +{ + to->type = from->type; + to->kind = from->kind; + cpswaps (from->sequenceNumber, to->sequenceNumber); + cpswapl (from->time, to->time); + cpswapl (from->arg, to->arg); +} + +static int +SProcAppleDRIQueryVersion( + register ClientPtr client +) +{ + register int n; + REQUEST(xAppleDRIQueryVersionReq); + swaps(&stuff->length, n); + return ProcAppleDRIQueryVersion(client); +} + +static int +SProcAppleDRIDispatch ( + register ClientPtr client +) +{ + REQUEST(xReq); + + /* It is bound to be non-local when there is byte swapping */ + if (!LocalClient(client)) + return DRIErrorBase + AppleDRIClientNotLocal; + + /* only local clients are allowed DRI access */ + switch (stuff->data) + { + case X_AppleDRIQueryVersion: + return SProcAppleDRIQueryVersion(client); + default: + return BadRequest; + } +} diff --git a/xorg-server/hw/xquartz/xpr/dri.c b/xorg-server/hw/xquartz/xpr/dri.c index 0a58b29f3..363809d0d 100644 --- a/xorg-server/hw/xquartz/xpr/dri.c +++ b/xorg-server/hw/xquartz/xpr/dri.c @@ -1,953 +1,953 @@ -/************************************************************************** - -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 - * Rickard E. (Rik) Faith - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#ifdef XFree86LOADER -#include "xf86.h" -#include "xf86_ansic.h" -#else -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#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 - -static int DRIScreenPrivKeyIndex; -static DevPrivateKey DRIScreenPrivKey = &DRIScreenPrivKeyIndex; -static int DRIWindowPrivKeyIndex; -static DevPrivateKey DRIWindowPrivKey = &DRIWindowPrivKeyIndex; -static int DRIPixmapPrivKeyIndex; -static DevPrivateKey DRIPixmapPrivKey = &DRIPixmapPrivKeyIndex; -static int DRIPixmapBufferPrivKeyIndex; -static DevPrivateKey DRIPixmapBufferPrivKey = &DRIPixmapBufferPrivKeyIndex; - -static RESTYPE DRIDrawablePrivResType; - -static x_hash_table *surface_hash; /* maps surface ids -> drawablePrivs */ - -static Bool DRIFreePixmapImp(DrawablePtr pDrawable); - -/* FIXME: don't hardcode this? */ -#define CG_INFO_FILE "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Resources/Info-macos.plist" - -/* Corresponds to SU Jaguar Green */ -#define CG_REQUIRED_MAJOR 1 -#define CG_REQUIRED_MINOR 157 -#define CG_REQUIRED_MICRO 11 - -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; - -/* Returns version as major.minor.micro in 10.10.10 fixed form */ -static unsigned int -get_cg_version (void) -{ - static unsigned int version; - - FILE *fh; - char *ptr; - - if (version != 0) - return version; - - /* I tried CFBundleGetVersion, but it returns zero, so.. */ - - fh = fopen (CG_INFO_FILE, "r"); - if (fh != NULL) - { - char buf[256]; - - while (fgets (buf, sizeof (buf), fh) != NULL) - { - unsigned char c; - - if (!strstr (buf, "CFBundleShortVersionString") - || fgets (buf, sizeof (buf), fh) == NULL) - { - continue; - } - - ptr = strstr (buf, ""); - if (ptr == NULL) - continue; - - ptr += strlen (""); - - /* Now PTR points to "MAJOR.MINOR.MICRO". */ - - version = 0; - - again: - switch ((c = *ptr++)) - { - case '.': - version = version * 1024; - goto again; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - version = ((version & ~0x3ff) - + (version & 0x3ff) * 10 + (c - '0')); - goto again; - } - break; - } - - fclose (fh); - } - - return version; -} - -static Bool -test_cg_version (unsigned int major, unsigned int minor, unsigned int micro) -{ - unsigned int cg_ver = get_cg_version (); - - unsigned int cg_major = (cg_ver >> 20) & 0x3ff; - unsigned int cg_minor = (cg_ver >> 10) & 0x3ff; - unsigned int cg_micro = cg_ver & 0x3ff; - - if (cg_major > major) - return TRUE; - else if (cg_major < major) - return FALSE; - - /* cg_major == major */ - - if (cg_minor > minor) - return TRUE; - else if (cg_minor < minor) - return FALSE; - - /* cg_minor == minor */ - - if (cg_micro < micro) - return FALSE; - - return TRUE; -} - -Bool -DRIScreenInit(ScreenPtr pScreen) -{ - DRIScreenPrivPtr pDRIPriv; - int i; - - pDRIPriv = (DRIScreenPrivPtr) xcalloc(1, sizeof(DRIScreenPrivRec)); - if (!pDRIPriv) { - dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL); - return FALSE; - } - - dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, pDRIPriv); - pDRIPriv->directRenderingSupport = TRUE; - pDRIPriv->nrWindows = 0; - - /* Need recent cg for window access update */ - if (!test_cg_version (CG_REQUIRED_MAJOR, - CG_REQUIRED_MINOR, - CG_REQUIRED_MICRO)) - { - ErrorF ("[DRI] disabled direct rendering; requires CoreGraphics %d.%d.%d\n", - CG_REQUIRED_MAJOR, CG_REQUIRED_MINOR, CG_REQUIRED_MICRO); - - pDRIPriv->directRenderingSupport = FALSE; - - /* Note we don't nuke the dri private, since we need it for - managing indirect surfaces. */ - } - - /* Initialize drawable tables */ - for (i = 0; i < DRI_MAX_DRAWABLES; i++) { - pDRIPriv->DRIDrawables[i] = NULL; - } - - return TRUE; -} - -Bool -DRIFinishScreenInit(ScreenPtr pScreen) -{ - DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - - /* 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) { - xfree(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 = REGION_NUM_RECTS(&pWin->clipList); - wc.shape_rects = REGION_RECTS(&pWin->clipList); - wc.shape_tx = - (pTopWin->drawable.x - pTopWin->borderWidth); - wc.shape_ty = - (pTopWin->drawable.y - pTopWin->borderWidth); - - flags |= XP_BOUNDS | XP_SHAPE; - - } else if (pDraw->type == DRAWABLE_PIXMAP) { - wc.x = 0; - wc.y = 0; - wc.width = pDraw->width; - wc.height = pDraw->height; - wc.bit_gravity = XP_GRAVITY_NONE; - flags |= XP_BOUNDS; - } - - 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 = xalloc(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) { - xfree(pDRIDrawablePriv); - return NULL; - } - - /* allocate the physical surface */ - err = xp_create_surface(wid, &pDRIDrawablePriv->sid); - - if (err != Success) { - xfree(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); - xfree(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 = xcalloc(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) { - xfree(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 { /* for GLX 1.3, a PBuffer */ - /* NOT_DONE */ - 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); - xfree(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) { - if (notify != NULL) { - pDRIDrawablePriv->notifiers = x_hook_remove(pDRIDrawablePriv->notifiers, - notify, notify_data); - } - if (--pDRIDrawablePriv->refCount <= 0) { - /* This calls back to DRIDrawablePrivDelete - which frees the private area */ - FreeResourceByType(id, DRIDrawablePrivResType, FALSE); - } - } - - return TRUE; -} - -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) { - return DRIFreePixmapImp(pDrawable); - } - - if (pDRIDrawablePriv->drawableIndex != -1) { - /* release drawable table entry */ - pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL; - } - - if (pDRIDrawablePriv->sid != 0) { - xp_destroy_surface(pDRIDrawablePriv->sid); - x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(pDRIDrawablePriv->sid)); - } - - if (pDRIDrawablePriv->notifiers != NULL) - x_hook_free(pDRIDrawablePriv->notifiers); - - xfree(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); - - pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures; - pScreen->WindowExposures = DRIWindowExposures; -} - -void -DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - DRIDrawablePrivPtr pDRIDrawablePriv; - - if (pDRIPriv->nrWindows > 0) { - 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 */ - pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow; - pScreen->CopyWindow = DRICopyWindow; -} - -int -DRIValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) -{ - ScreenPtr pScreen = pParent->drawable.pScreen; - DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - int returnValue; - - /* unwrap */ - pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree; - - /* call lower layers */ - returnValue = (*pScreen->ValidateTree)(pParent, pChild, kind); - - /* rewrap */ - pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree; - pScreen->ValidateTree = DRIValidateTree; - - return returnValue; -} - -void -DRIPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) -{ - ScreenPtr pScreen; - DRIScreenPrivPtr pDRIPriv; - - if (pParent) { - pScreen = pParent->drawable.pScreen; - } else { - pScreen = pChild->drawable.pScreen; - } - pDRIPriv = DRI_SCREEN_PRIV(pScreen); - - if (pDRIPriv->wrap.PostValidateTree) { - /* unwrap */ - pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree; - - /* call lower layers */ - (*pScreen->PostValidateTree)(pParent, pChild, kind); - - /* rewrap */ - pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree; - pScreen->PostValidateTree = DRIPostValidateTree; - } -} - -void -DRIClipNotify(WindowPtr pWin, int dx, int dy) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - 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); - - pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify; - pScreen->ClipNotify = DRIClipNotify; - } -} - -/* This lets us get at the unwrapped functions so that they can correctly - * call the lower level functions, and choose whether they will be - * called at every level of recursion (eg in validatetree). - */ -DRIWrappedFuncsRec * -DRIGetWrappedFuncs(ScreenPtr pScreen) -{ - return &(DRI_SCREEN_PRIV(pScreen)->wrap); -} - -void -DRIQueryVersion(int *majorVersion, - int *minorVersion, - int *patchVersion) -{ - *majorVersion = APPLE_DRI_MAJOR_VERSION; - *minorVersion = APPLE_DRI_MINOR_VERSION; - *patchVersion = APPLE_DRI_PATCH_VERSION; -} - -void -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) - { - pDRIDrawablePriv->sid = 0; - x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(id)); - } - - x_hook_run(pDRIDrawablePriv->notifiers, &arg); - - if (kind == AppleDRISurfaceNotifyDestroyed) - { - /* Kill off the handle. */ - - FreeResourceByType(pDRIDrawablePriv->pDraw->id, - DRIDrawablePrivResType, FALSE); - } -} - -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 = xalloc(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) { - xfree(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); - xfree(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); - xfree(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); - xfree(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 + * Rickard E. (Rik) Faith + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#ifdef XFree86LOADER +#include "xf86.h" +#include "xf86_ansic.h" +#else +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#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 + +static int DRIScreenPrivKeyIndex; +static DevPrivateKey DRIScreenPrivKey = &DRIScreenPrivKeyIndex; +static int DRIWindowPrivKeyIndex; +static DevPrivateKey DRIWindowPrivKey = &DRIWindowPrivKeyIndex; +static int DRIPixmapPrivKeyIndex; +static DevPrivateKey DRIPixmapPrivKey = &DRIPixmapPrivKeyIndex; +static int DRIPixmapBufferPrivKeyIndex; +static DevPrivateKey DRIPixmapBufferPrivKey = &DRIPixmapBufferPrivKeyIndex; + +static RESTYPE DRIDrawablePrivResType; + +static x_hash_table *surface_hash; /* maps surface ids -> drawablePrivs */ + +static Bool DRIFreePixmapImp(DrawablePtr pDrawable); + +/* FIXME: don't hardcode this? */ +#define CG_INFO_FILE "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Resources/Info-macos.plist" + +/* Corresponds to SU Jaguar Green */ +#define CG_REQUIRED_MAJOR 1 +#define CG_REQUIRED_MINOR 157 +#define CG_REQUIRED_MICRO 11 + +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; + +/* Returns version as major.minor.micro in 10.10.10 fixed form */ +static unsigned int +get_cg_version (void) +{ + static unsigned int version; + + FILE *fh; + char *ptr; + + if (version != 0) + return version; + + /* I tried CFBundleGetVersion, but it returns zero, so.. */ + + fh = fopen (CG_INFO_FILE, "r"); + if (fh != NULL) + { + char buf[256]; + + while (fgets (buf, sizeof (buf), fh) != NULL) + { + unsigned char c; + + if (!strstr (buf, "CFBundleShortVersionString") + || fgets (buf, sizeof (buf), fh) == NULL) + { + continue; + } + + ptr = strstr (buf, ""); + if (ptr == NULL) + continue; + + ptr += strlen (""); + + /* Now PTR points to "MAJOR.MINOR.MICRO". */ + + version = 0; + + again: + switch ((c = *ptr++)) + { + case '.': + version = version * 1024; + goto again; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + version = ((version & ~0x3ff) + + (version & 0x3ff) * 10 + (c - '0')); + goto again; + } + break; + } + + fclose (fh); + } + + return version; +} + +static Bool +test_cg_version (unsigned int major, unsigned int minor, unsigned int micro) +{ + unsigned int cg_ver = get_cg_version (); + + unsigned int cg_major = (cg_ver >> 20) & 0x3ff; + unsigned int cg_minor = (cg_ver >> 10) & 0x3ff; + unsigned int cg_micro = cg_ver & 0x3ff; + + if (cg_major > major) + return TRUE; + else if (cg_major < major) + return FALSE; + + /* cg_major == major */ + + if (cg_minor > minor) + return TRUE; + else if (cg_minor < minor) + return FALSE; + + /* cg_minor == minor */ + + if (cg_micro < micro) + return FALSE; + + return TRUE; +} + +Bool +DRIScreenInit(ScreenPtr pScreen) +{ + DRIScreenPrivPtr pDRIPriv; + int i; + + pDRIPriv = (DRIScreenPrivPtr) calloc(1, sizeof(DRIScreenPrivRec)); + if (!pDRIPriv) { + dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL); + return FALSE; + } + + dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, pDRIPriv); + pDRIPriv->directRenderingSupport = TRUE; + pDRIPriv->nrWindows = 0; + + /* Need recent cg for window access update */ + if (!test_cg_version (CG_REQUIRED_MAJOR, + CG_REQUIRED_MINOR, + CG_REQUIRED_MICRO)) + { + ErrorF ("[DRI] disabled direct rendering; requires CoreGraphics %d.%d.%d\n", + CG_REQUIRED_MAJOR, CG_REQUIRED_MINOR, CG_REQUIRED_MICRO); + + pDRIPriv->directRenderingSupport = FALSE; + + /* Note we don't nuke the dri private, since we need it for + managing indirect surfaces. */ + } + + /* Initialize drawable tables */ + for (i = 0; i < DRI_MAX_DRAWABLES; i++) { + pDRIPriv->DRIDrawables[i] = NULL; + } + + return TRUE; +} + +Bool +DRIFinishScreenInit(ScreenPtr pScreen) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + /* 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 = REGION_NUM_RECTS(&pWin->clipList); + wc.shape_rects = REGION_RECTS(&pWin->clipList); + wc.shape_tx = - (pTopWin->drawable.x - pTopWin->borderWidth); + wc.shape_ty = - (pTopWin->drawable.y - pTopWin->borderWidth); + + flags |= XP_BOUNDS | XP_SHAPE; + + } else if (pDraw->type == DRAWABLE_PIXMAP) { + wc.x = 0; + wc.y = 0; + wc.width = pDraw->width; + wc.height = pDraw->height; + wc.bit_gravity = XP_GRAVITY_NONE; + flags |= XP_BOUNDS; + } + + 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 { /* for GLX 1.3, a PBuffer */ + /* NOT_DONE */ + 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) { + if (notify != NULL) { + pDRIDrawablePriv->notifiers = x_hook_remove(pDRIDrawablePriv->notifiers, + notify, notify_data); + } + if (--pDRIDrawablePriv->refCount <= 0) { + /* This calls back to DRIDrawablePrivDelete + which frees the private area */ + FreeResourceByType(id, DRIDrawablePrivResType, FALSE); + } + } + + return TRUE; +} + +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) { + return DRIFreePixmapImp(pDrawable); + } + + if (pDRIDrawablePriv->drawableIndex != -1) { + /* release drawable table entry */ + pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL; + } + + if (pDRIDrawablePriv->sid != 0) { + xp_destroy_surface(pDRIDrawablePriv->sid); + x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(pDRIDrawablePriv->sid)); + } + + 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); + + pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures; + pScreen->WindowExposures = DRIWindowExposures; +} + +void +DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + DRIDrawablePrivPtr pDRIDrawablePriv; + + if (pDRIPriv->nrWindows > 0) { + 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 */ + pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow; + pScreen->CopyWindow = DRICopyWindow; +} + +int +DRIValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) +{ + ScreenPtr pScreen = pParent->drawable.pScreen; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + int returnValue; + + /* unwrap */ + pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree; + + /* call lower layers */ + returnValue = (*pScreen->ValidateTree)(pParent, pChild, kind); + + /* rewrap */ + pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree; + pScreen->ValidateTree = DRIValidateTree; + + return returnValue; +} + +void +DRIPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) +{ + ScreenPtr pScreen; + DRIScreenPrivPtr pDRIPriv; + + if (pParent) { + pScreen = pParent->drawable.pScreen; + } else { + pScreen = pChild->drawable.pScreen; + } + pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + if (pDRIPriv->wrap.PostValidateTree) { + /* unwrap */ + pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree; + + /* call lower layers */ + (*pScreen->PostValidateTree)(pParent, pChild, kind); + + /* rewrap */ + pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree; + pScreen->PostValidateTree = DRIPostValidateTree; + } +} + +void +DRIClipNotify(WindowPtr pWin, int dx, int dy) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + 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); + + pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify; + pScreen->ClipNotify = DRIClipNotify; + } +} + +/* This lets us get at the unwrapped functions so that they can correctly + * call the lower level functions, and choose whether they will be + * called at every level of recursion (eg in validatetree). + */ +DRIWrappedFuncsRec * +DRIGetWrappedFuncs(ScreenPtr pScreen) +{ + return &(DRI_SCREEN_PRIV(pScreen)->wrap); +} + +void +DRIQueryVersion(int *majorVersion, + int *minorVersion, + int *patchVersion) +{ + *majorVersion = APPLE_DRI_MAJOR_VERSION; + *minorVersion = APPLE_DRI_MINOR_VERSION; + *patchVersion = APPLE_DRI_PATCH_VERSION; +} + +void +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) + { + pDRIDrawablePriv->sid = 0; + x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(id)); + } + + x_hook_run(pDRIDrawablePriv->notifiers, &arg); + + if (kind == AppleDRISurfaceNotifyDestroyed) + { + /* Kill off the handle. */ + + FreeResourceByType(pDRIDrawablePriv->pDraw->id, + DRIDrawablePrivResType, FALSE); + } +} + +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/driWrap.c b/xorg-server/hw/xquartz/xpr/driWrap.c index 8c57fd4bd..2e23cbbf5 100644 --- a/xorg-server/hw/xquartz/xpr/driWrap.c +++ b/xorg-server/hw/xquartz/xpr/driWrap.c @@ -1,547 +1,547 @@ -/* -Copyright (c) 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. -*/ -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include -#include "mi.h" -#include "scrnintstr.h" -#include "gcstruct.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "dixfontstr.h" -#include "mivalidate.h" -#include "driWrap.h" -#include "dri.h" - -#include - -typedef struct { - GCOps *originalOps; - GCOps *driOps; -} DRIGCRec; - -typedef struct { - GCOps *originalOps; - CreateGCProcPtr CreateGC; -} DRIWrapScreenRec; - -typedef struct { - Bool didSave; - int devKind; - DevUnion devPrivate; -} DRISavedDrawableState; - -static int driGCKeyIndex; -static DevPrivateKey driGCKey = &driGCKeyIndex; - -static int driWrapScreenKeyIndex; -static DevPrivateKey driWrapScreenKey = &driWrapScreenKeyIndex; - -static GCOps driGCOps; - -#define wrap(priv, real, member, func) { \ - priv->member = real->member; \ - real->member = func; \ - } - -#define unwrap(priv, real, member) { \ - real->member = priv->member; \ - } - -static DRIGCRec * -DRIGetGCPriv(GCPtr pGC) { - return dixLookupPrivate(&pGC->devPrivates, driGCKey); -} - -static void -DRIUnwrapGC(GCPtr pGC) { - DRIGCRec *pGCPriv = DRIGetGCPriv(pGC); - - pGC->ops = pGCPriv->originalOps; -} - -static void -DRIWrapGC(GCPtr pGC) { - DRIGCRec *pGCPriv = DRIGetGCPriv(pGC); - - pGC->ops = pGCPriv->driOps; -} - -static void -DRISurfaceSetDrawable(DrawablePtr pDraw, - DRISavedDrawableState *saved) { - saved->didSave = FALSE; - - if(pDraw->type == DRAWABLE_PIXMAP) { - int pitch, width, height, bpp; - void *buffer; - - if(DRIGetPixmapData(pDraw, &width, &height, &pitch, &bpp, &buffer)) { - PixmapPtr pPix = (PixmapPtr)pDraw; - - saved->devKind = pPix->devKind; - saved->devPrivate.ptr = pPix->devPrivate.ptr; - saved->didSave = TRUE; - - pPix->devKind = pitch; - pPix->devPrivate.ptr = buffer; - } - } -} - -static void -DRISurfaceRestoreDrawable(DrawablePtr pDraw, - DRISavedDrawableState *saved) { - PixmapPtr pPix = (PixmapPtr)pDraw; - - if(!saved->didSave) - return; - - pPix->devKind = saved->devKind; - pPix->devPrivate.ptr = saved->devPrivate.ptr; -} - -static void -DRIFillSpans(DrawablePtr dst, GCPtr pGC, int nInit, - DDXPointPtr pptInit, int *pwidthInit, - int sorted) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static void -DRISetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc, - DDXPointPtr pptInit, int *pwidthInit, - int nspans, int sorted) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit, nspans, sorted); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static void -DRIPutImage(DrawablePtr dst, GCPtr pGC, - int depth, int x, int y, int w, int h, - int leftPad, int format, char *pBits) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->PutImage(dst, pGC, depth, x, y, w, h, leftPad, format, pBits); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static RegionPtr -DRICopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC, - int srcx, int srcy, int w, int h, - int dstx, int dsty) { - RegionPtr pReg; - DRISavedDrawableState pSrcSaved, dstSaved; - - DRISurfaceSetDrawable(pSrc, &pSrcSaved); - DRISurfaceSetDrawable(dst, &dstSaved); - - DRIUnwrapGC(pGC); - - pReg = pGC->ops->CopyArea(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(pSrc, &pSrcSaved); - DRISurfaceRestoreDrawable(dst, &dstSaved); - - return pReg; -} - -static RegionPtr -DRICopyPlane(DrawablePtr pSrc, DrawablePtr dst, - GCPtr pGC, int srcx, int srcy, - int w, int h, int dstx, int dsty, - unsigned long plane) { - RegionPtr pReg; - DRISavedDrawableState pSrcSaved, dstSaved; - - DRISurfaceSetDrawable(pSrc, &pSrcSaved); - DRISurfaceSetDrawable(dst, &dstSaved); - - - DRIUnwrapGC(pGC); - - pReg = pGC->ops->CopyPlane(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty, - plane); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(pSrc, &pSrcSaved); - DRISurfaceRestoreDrawable(dst, &dstSaved); - - return pReg; -} - -static void -DRIPolyPoint(DrawablePtr dst, GCPtr pGC, - int mode, int npt, DDXPointPtr pptInit) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->PolyPoint(dst, pGC, mode, npt, pptInit); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static void -DRIPolylines(DrawablePtr dst, GCPtr pGC, - int mode, int npt, DDXPointPtr pptInit) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->Polylines(dst, pGC, mode, npt, pptInit); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static void -DRIPolySegment(DrawablePtr dst, GCPtr pGC, - int nseg, xSegment *pSeg) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->PolySegment(dst, pGC, nseg, pSeg); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static void -DRIPolyRectangle(DrawablePtr dst, GCPtr pGC, - int nRects, xRectangle *pRects) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->PolyRectangle(dst, pGC, nRects, pRects); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} -static void -DRIPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, xArc *parcs) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->PolyArc(dst, pGC, narcs, parcs); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static void -DRIFillPolygon(DrawablePtr dst, GCPtr pGC, - int shape, int mode, int count, - DDXPointPtr pptInit) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static void -DRIPolyFillRect(DrawablePtr dst, GCPtr pGC, - int nRectsInit, xRectangle *pRectsInit) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static void -DRIPolyFillArc(DrawablePtr dst, GCPtr pGC, - int narcsInit, xArc *parcsInit) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->PolyFillArc(dst, pGC, narcsInit, parcsInit); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static int -DRIPolyText8(DrawablePtr dst, GCPtr pGC, - int x, int y, int count, char *chars) { - int ret; - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - ret = pGC->ops->PolyText8(dst, pGC, x, y, count, chars); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); - - return ret; -} - -static int -DRIPolyText16(DrawablePtr dst, GCPtr pGC, - int x, int y, int count, unsigned short *chars) { - int ret; - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - ret = pGC->ops->PolyText16(dst, pGC, x, y, count, chars); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); - - return ret; -} - -static void -DRIImageText8(DrawablePtr dst, GCPtr pGC, - int x, int y, int count, char *chars) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->ImageText8(dst, pGC, x, y, count, chars); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static void -DRIImageText16(DrawablePtr dst, GCPtr pGC, - int x, int y, int count, unsigned short *chars) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->ImageText16(dst, pGC, x, y, count, chars); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static void -DRIImageGlyphBlt(DrawablePtr dst, GCPtr pGC, - int x, int y, unsigned int nglyphInit, - CharInfoPtr *ppciInit, pointer unused) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyphInit, ppciInit, unused); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static void DRIPolyGlyphBlt(DrawablePtr dst, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase) { - DRISavedDrawableState saved; - - DRISurfaceSetDrawable(dst, &saved); - - DRIUnwrapGC(pGC); - - pGC->ops->PolyGlyphBlt(dst, pGC, x, y, nglyph, ppci, pglyphBase); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(dst, &saved); -} - -static void -DRIPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst, - int dx, int dy, int xOrg, int yOrg) { - DRISavedDrawableState bitMapSaved, dstSaved; - - DRISurfaceSetDrawable(&pBitMap->drawable, &bitMapSaved); - DRISurfaceSetDrawable(dst, &dstSaved); - - DRIUnwrapGC(pGC); - - pGC->ops->PushPixels(pGC, pBitMap, dst, dx, dy, xOrg, yOrg); - - DRIWrapGC(pGC); - - DRISurfaceRestoreDrawable(&pBitMap->drawable, &bitMapSaved); - DRISurfaceRestoreDrawable(dst, &dstSaved); -} - - -static GCOps driGCOps = { - DRIFillSpans, - DRISetSpans, - DRIPutImage, - DRICopyArea, - DRICopyPlane, - DRIPolyPoint, - DRIPolylines, - DRIPolySegment, - DRIPolyRectangle, - DRIPolyArc, - DRIFillPolygon, - DRIPolyFillRect, - DRIPolyFillArc, - DRIPolyText8, - DRIPolyText16, - DRIImageText8, - DRIImageText16, - DRIImageGlyphBlt, - DRIPolyGlyphBlt, - DRIPushPixels -}; - - -static Bool -DRICreateGC(GCPtr pGC) { - ScreenPtr pScreen = pGC->pScreen; - DRIWrapScreenRec *pScreenPriv; - DRIGCRec *pGCPriv; - Bool ret; - - pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, driWrapScreenKey); - - pGCPriv = DRIGetGCPriv(pGC); - - unwrap(pScreenPriv, pScreen, CreateGC); - ret = pScreen->CreateGC(pGC); - - if(ret) { - pGCPriv->originalOps = pGC->ops; - pGC->ops = &driGCOps; - pGCPriv->driOps = &driGCOps; - } - - wrap(pScreenPriv, pScreen, CreateGC, DRICreateGC); - - return ret; -} - - -/* Return false if an error occurred. */ -Bool -DRIWrapInit(ScreenPtr pScreen) { - DRIWrapScreenRec *pScreenPriv; - - if(!dixRequestPrivate(driGCKey, sizeof(DRIGCRec))) - return FALSE; - - if(!dixRequestPrivate(driWrapScreenKey, sizeof(DRIWrapScreenRec))) - return FALSE; - - pScreenPriv = xalloc(sizeof(*pScreenPriv)); - - if(NULL == pScreenPriv) - return FALSE; - - pScreenPriv->CreateGC = pScreen->CreateGC; - pScreen->CreateGC = DRICreateGC; - - dixSetPrivate(&pScreen->devPrivates, driWrapScreenKey, pScreenPriv); - - return TRUE; -} +/* +Copyright (c) 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. +*/ +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include "mi.h" +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "dixfontstr.h" +#include "mivalidate.h" +#include "driWrap.h" +#include "dri.h" + +#include + +typedef struct { + GCOps *originalOps; + GCOps *driOps; +} DRIGCRec; + +typedef struct { + GCOps *originalOps; + CreateGCProcPtr CreateGC; +} DRIWrapScreenRec; + +typedef struct { + Bool didSave; + int devKind; + DevUnion devPrivate; +} DRISavedDrawableState; + +static int driGCKeyIndex; +static DevPrivateKey driGCKey = &driGCKeyIndex; + +static int driWrapScreenKeyIndex; +static DevPrivateKey driWrapScreenKey = &driWrapScreenKeyIndex; + +static GCOps driGCOps; + +#define wrap(priv, real, member, func) { \ + priv->member = real->member; \ + real->member = func; \ + } + +#define unwrap(priv, real, member) { \ + real->member = priv->member; \ + } + +static DRIGCRec * +DRIGetGCPriv(GCPtr pGC) { + return dixLookupPrivate(&pGC->devPrivates, driGCKey); +} + +static void +DRIUnwrapGC(GCPtr pGC) { + DRIGCRec *pGCPriv = DRIGetGCPriv(pGC); + + pGC->ops = pGCPriv->originalOps; +} + +static void +DRIWrapGC(GCPtr pGC) { + DRIGCRec *pGCPriv = DRIGetGCPriv(pGC); + + pGC->ops = pGCPriv->driOps; +} + +static void +DRISurfaceSetDrawable(DrawablePtr pDraw, + DRISavedDrawableState *saved) { + saved->didSave = FALSE; + + if(pDraw->type == DRAWABLE_PIXMAP) { + int pitch, width, height, bpp; + void *buffer; + + if(DRIGetPixmapData(pDraw, &width, &height, &pitch, &bpp, &buffer)) { + PixmapPtr pPix = (PixmapPtr)pDraw; + + saved->devKind = pPix->devKind; + saved->devPrivate.ptr = pPix->devPrivate.ptr; + saved->didSave = TRUE; + + pPix->devKind = pitch; + pPix->devPrivate.ptr = buffer; + } + } +} + +static void +DRISurfaceRestoreDrawable(DrawablePtr pDraw, + DRISavedDrawableState *saved) { + PixmapPtr pPix = (PixmapPtr)pDraw; + + if(!saved->didSave) + return; + + pPix->devKind = saved->devKind; + pPix->devPrivate.ptr = saved->devPrivate.ptr; +} + +static void +DRIFillSpans(DrawablePtr dst, GCPtr pGC, int nInit, + DDXPointPtr pptInit, int *pwidthInit, + int sorted) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static void +DRISetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc, + DDXPointPtr pptInit, int *pwidthInit, + int nspans, int sorted) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit, nspans, sorted); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static void +DRIPutImage(DrawablePtr dst, GCPtr pGC, + int depth, int x, int y, int w, int h, + int leftPad, int format, char *pBits) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->PutImage(dst, pGC, depth, x, y, w, h, leftPad, format, pBits); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static RegionPtr +DRICopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC, + int srcx, int srcy, int w, int h, + int dstx, int dsty) { + RegionPtr pReg; + DRISavedDrawableState pSrcSaved, dstSaved; + + DRISurfaceSetDrawable(pSrc, &pSrcSaved); + DRISurfaceSetDrawable(dst, &dstSaved); + + DRIUnwrapGC(pGC); + + pReg = pGC->ops->CopyArea(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(pSrc, &pSrcSaved); + DRISurfaceRestoreDrawable(dst, &dstSaved); + + return pReg; +} + +static RegionPtr +DRICopyPlane(DrawablePtr pSrc, DrawablePtr dst, + GCPtr pGC, int srcx, int srcy, + int w, int h, int dstx, int dsty, + unsigned long plane) { + RegionPtr pReg; + DRISavedDrawableState pSrcSaved, dstSaved; + + DRISurfaceSetDrawable(pSrc, &pSrcSaved); + DRISurfaceSetDrawable(dst, &dstSaved); + + + DRIUnwrapGC(pGC); + + pReg = pGC->ops->CopyPlane(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty, + plane); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(pSrc, &pSrcSaved); + DRISurfaceRestoreDrawable(dst, &dstSaved); + + return pReg; +} + +static void +DRIPolyPoint(DrawablePtr dst, GCPtr pGC, + int mode, int npt, DDXPointPtr pptInit) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->PolyPoint(dst, pGC, mode, npt, pptInit); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static void +DRIPolylines(DrawablePtr dst, GCPtr pGC, + int mode, int npt, DDXPointPtr pptInit) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->Polylines(dst, pGC, mode, npt, pptInit); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static void +DRIPolySegment(DrawablePtr dst, GCPtr pGC, + int nseg, xSegment *pSeg) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->PolySegment(dst, pGC, nseg, pSeg); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static void +DRIPolyRectangle(DrawablePtr dst, GCPtr pGC, + int nRects, xRectangle *pRects) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->PolyRectangle(dst, pGC, nRects, pRects); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} +static void +DRIPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, xArc *parcs) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->PolyArc(dst, pGC, narcs, parcs); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static void +DRIFillPolygon(DrawablePtr dst, GCPtr pGC, + int shape, int mode, int count, + DDXPointPtr pptInit) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static void +DRIPolyFillRect(DrawablePtr dst, GCPtr pGC, + int nRectsInit, xRectangle *pRectsInit) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static void +DRIPolyFillArc(DrawablePtr dst, GCPtr pGC, + int narcsInit, xArc *parcsInit) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->PolyFillArc(dst, pGC, narcsInit, parcsInit); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static int +DRIPolyText8(DrawablePtr dst, GCPtr pGC, + int x, int y, int count, char *chars) { + int ret; + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + ret = pGC->ops->PolyText8(dst, pGC, x, y, count, chars); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); + + return ret; +} + +static int +DRIPolyText16(DrawablePtr dst, GCPtr pGC, + int x, int y, int count, unsigned short *chars) { + int ret; + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + ret = pGC->ops->PolyText16(dst, pGC, x, y, count, chars); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); + + return ret; +} + +static void +DRIImageText8(DrawablePtr dst, GCPtr pGC, + int x, int y, int count, char *chars) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->ImageText8(dst, pGC, x, y, count, chars); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static void +DRIImageText16(DrawablePtr dst, GCPtr pGC, + int x, int y, int count, unsigned short *chars) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->ImageText16(dst, pGC, x, y, count, chars); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static void +DRIImageGlyphBlt(DrawablePtr dst, GCPtr pGC, + int x, int y, unsigned int nglyphInit, + CharInfoPtr *ppciInit, pointer unused) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyphInit, ppciInit, unused); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static void DRIPolyGlyphBlt(DrawablePtr dst, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, pointer pglyphBase) { + DRISavedDrawableState saved; + + DRISurfaceSetDrawable(dst, &saved); + + DRIUnwrapGC(pGC); + + pGC->ops->PolyGlyphBlt(dst, pGC, x, y, nglyph, ppci, pglyphBase); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(dst, &saved); +} + +static void +DRIPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst, + int dx, int dy, int xOrg, int yOrg) { + DRISavedDrawableState bitMapSaved, dstSaved; + + DRISurfaceSetDrawable(&pBitMap->drawable, &bitMapSaved); + DRISurfaceSetDrawable(dst, &dstSaved); + + DRIUnwrapGC(pGC); + + pGC->ops->PushPixels(pGC, pBitMap, dst, dx, dy, xOrg, yOrg); + + DRIWrapGC(pGC); + + DRISurfaceRestoreDrawable(&pBitMap->drawable, &bitMapSaved); + DRISurfaceRestoreDrawable(dst, &dstSaved); +} + + +static GCOps driGCOps = { + DRIFillSpans, + DRISetSpans, + DRIPutImage, + DRICopyArea, + DRICopyPlane, + DRIPolyPoint, + DRIPolylines, + DRIPolySegment, + DRIPolyRectangle, + DRIPolyArc, + DRIFillPolygon, + DRIPolyFillRect, + DRIPolyFillArc, + DRIPolyText8, + DRIPolyText16, + DRIImageText8, + DRIImageText16, + DRIImageGlyphBlt, + DRIPolyGlyphBlt, + DRIPushPixels +}; + + +static Bool +DRICreateGC(GCPtr pGC) { + ScreenPtr pScreen = pGC->pScreen; + DRIWrapScreenRec *pScreenPriv; + DRIGCRec *pGCPriv; + Bool ret; + + pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, driWrapScreenKey); + + pGCPriv = DRIGetGCPriv(pGC); + + unwrap(pScreenPriv, pScreen, CreateGC); + ret = pScreen->CreateGC(pGC); + + if(ret) { + pGCPriv->originalOps = pGC->ops; + pGC->ops = &driGCOps; + pGCPriv->driOps = &driGCOps; + } + + wrap(pScreenPriv, pScreen, CreateGC, DRICreateGC); + + return ret; +} + + +/* Return false if an error occurred. */ +Bool +DRIWrapInit(ScreenPtr pScreen) { + DRIWrapScreenRec *pScreenPriv; + + if(!dixRequestPrivate(driGCKey, sizeof(DRIGCRec))) + return FALSE; + + if(!dixRequestPrivate(driWrapScreenKey, sizeof(DRIWrapScreenRec))) + return FALSE; + + pScreenPriv = malloc(sizeof(*pScreenPriv)); + + if(NULL == pScreenPriv) + return FALSE; + + pScreenPriv->CreateGC = pScreen->CreateGC; + pScreen->CreateGC = DRICreateGC; + + dixSetPrivate(&pScreen->devPrivates, driWrapScreenKey, pScreenPriv); + + return TRUE; +} diff --git a/xorg-server/hw/xquartz/xpr/x-hook.c b/xorg-server/hw/xquartz/xpr/x-hook.c index 5b850fe88..c65b6fc68 100644 --- a/xorg-server/hw/xquartz/xpr/x-hook.c +++ b/xorg-server/hw/xquartz/xpr/x-hook.c @@ -1,120 +1,120 @@ -/* x-hook.c - - Copyright (c) 2003 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, 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 -#endif - -#include "x-hook.h" -#include -#include -#include "os.h" - -#define CELL_NEW(f,d) X_PFX (list_prepend) ((x_list *) (f), (d)) -#define CELL_FREE(c) X_PFX (list_free_1) (c) -#define CELL_FUN(c) ((x_hook_function *) ((c)->next)) -#define CELL_DATA(c) ((c)->data) - -X_EXTERN x_list * -X_PFX (hook_add) (x_list *lst, x_hook_function *fun, void *data) -{ - return X_PFX (list_prepend) (lst, CELL_NEW (fun, data)); -} - -X_EXTERN x_list * -X_PFX (hook_remove) (x_list *lst, x_hook_function *fun, void *data) -{ - x_list *node, *cell; - x_list *to_delete = NULL; - - for (node = lst; node != NULL; node = node->next) - { - cell = node->data; - if (CELL_FUN (cell) == fun && CELL_DATA (cell) == data) - to_delete = X_PFX (list_prepend) (to_delete, cell); - } - - for (node = to_delete; node != NULL; node = node->next) - { - cell = node->data; - lst = X_PFX (list_remove) (lst, cell); - CELL_FREE (cell); - } - - X_PFX (list_free) (to_delete); - return lst; -} - -X_EXTERN void -X_PFX (hook_run) (x_list *lst, void *arg) -{ - x_list *node, *cell; - x_hook_function **fun; - void **data; - int length, i; - - if(!lst) - return; - - length = X_PFX (list_length) (lst); - fun = xalloc (sizeof (x_hook_function *) * length); - data = xalloc (sizeof (void *) * length); - - if(!fun || !data) { - FatalError("Failed to allocate memory in %s\n", __func__); - } - - for (i = 0, node = lst; node != NULL; node = node->next, i++) - { - cell = node->data; - fun[i] = CELL_FUN (cell); - data[i] = CELL_DATA (cell); - } - - for (i = 0; i < length; i++) - { - (*fun[i]) (arg, data[i]); - } - - xfree(fun); - xfree(data); -} - -X_EXTERN void -X_PFX (hook_free) (x_list *lst) -{ - x_list *node; - - for (node = lst; node != NULL; node = node->next) - { - CELL_FREE (node->data); - } - - X_PFX (list_free) (lst); -} +/* x-hook.c + + Copyright (c) 2003 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, 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 +#endif + +#include "x-hook.h" +#include +#include +#include "os.h" + +#define CELL_NEW(f,d) X_PFX (list_prepend) ((x_list *) (f), (d)) +#define CELL_FREE(c) X_PFX (list_free_1) (c) +#define CELL_FUN(c) ((x_hook_function *) ((c)->next)) +#define CELL_DATA(c) ((c)->data) + +X_EXTERN x_list * +X_PFX (hook_add) (x_list *lst, x_hook_function *fun, void *data) +{ + return X_PFX (list_prepend) (lst, CELL_NEW (fun, data)); +} + +X_EXTERN x_list * +X_PFX (hook_remove) (x_list *lst, x_hook_function *fun, void *data) +{ + x_list *node, *cell; + x_list *to_delete = NULL; + + for (node = lst; node != NULL; node = node->next) + { + cell = node->data; + if (CELL_FUN (cell) == fun && CELL_DATA (cell) == data) + to_delete = X_PFX (list_prepend) (to_delete, cell); + } + + for (node = to_delete; node != NULL; node = node->next) + { + cell = node->data; + lst = X_PFX (list_remove) (lst, cell); + CELL_FREE (cell); + } + + X_PFX (list_free) (to_delete); + return lst; +} + +X_EXTERN void +X_PFX (hook_run) (x_list *lst, void *arg) +{ + x_list *node, *cell; + x_hook_function **fun; + void **data; + int length, i; + + if(!lst) + return; + + length = X_PFX (list_length) (lst); + fun = malloc(sizeof (x_hook_function *) * length); + data = malloc(sizeof (void *) * length); + + if(!fun || !data) { + FatalError("Failed to allocate memory in %s\n", __func__); + } + + for (i = 0, node = lst; node != NULL; node = node->next, i++) + { + cell = node->data; + fun[i] = CELL_FUN (cell); + data[i] = CELL_DATA (cell); + } + + for (i = 0; i < length; i++) + { + (*fun[i]) (arg, data[i]); + } + + free(fun); + free(data); +} + +X_EXTERN void +X_PFX (hook_free) (x_list *lst) +{ + x_list *node; + + for (node = lst; node != NULL; node = node->next) + { + CELL_FREE (node->data); + } + + X_PFX (list_free) (lst); +} diff --git a/xorg-server/hw/xquartz/xpr/xprCursor.c b/xorg-server/hw/xquartz/xpr/xprCursor.c index fbaf825de..df9eef95e 100644 --- a/xorg-server/hw/xquartz/xpr/xprCursor.c +++ b/xorg-server/hw/xquartz/xpr/xprCursor.c @@ -1,418 +1,418 @@ -/************************************************************** - * - * Xplugin cursor support - * - * Copyright (c) 2001 Torrey T. Lyons and Greg Parker. - * Copyright (c) 2002 Apple Computer, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, 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 -#endif - -#include "quartzCommon.h" -#include "xpr.h" -#include "darwin.h" -#include "darwinEvents.h" -#include - -#include "mi.h" -#include "scrnintstr.h" -#include "cursorstr.h" -#include "mipointrst.h" -#include "windowstr.h" -#include "globals.h" -#include "servermd.h" -#include "dixevents.h" -#include "x-hash.h" - -typedef struct { - int cursorVisible; - QueryBestSizeProcPtr QueryBestSize; - miPointerSpriteFuncPtr spriteFuncs; -} QuartzCursorScreenRec, *QuartzCursorScreenPtr; - -static int darwinCursorScreenKeyIndex; -static DevPrivateKey darwinCursorScreenKey = &darwinCursorScreenKeyIndex; - -#define CURSOR_PRIV(pScreen) ((QuartzCursorScreenPtr) \ - dixLookupPrivate(&pScreen->devPrivates, darwinCursorScreenKey)) - - -static Bool -load_cursor(CursorPtr src, int screen) -{ - uint32_t *data; - uint32_t rowbytes; - int width, height; - int hot_x, hot_y; - - uint32_t fg_color, bg_color; - uint8_t *srow, *sptr; - uint8_t *mrow, *mptr; - uint32_t *drow, *dptr; - unsigned xcount, ycount; - - xp_error err; - - width = src->bits->width; - height = src->bits->height; - hot_x = src->bits->xhot; - hot_y = src->bits->yhot; - -#ifdef ARGB_CURSOR - if (src->bits->argb != NULL) - { -#if BITMAP_BIT_ORDER == MSBFirst - rowbytes = src->bits->width * sizeof (CARD32); - data = (uint32_t *) src->bits->argb; -#else - const uint32_t *be_data=(uint32_t *) src->bits->argb; - unsigned i; - rowbytes = src->bits->width * sizeof (CARD32); - data = xalloc(rowbytes * src->bits->height); - if(!data) { - FatalError("Failed to allocate memory in %s\n", __func__); - } - for(i=0;i<(src->bits->width*src->bits->height);i++) - data[i]=ntohl(be_data[i]); -#endif - } - else -#endif - { - fg_color = 0xFF00 | (src->foreRed >> 8); - fg_color <<= 16; - fg_color |= src->foreGreen & 0xFF00; - fg_color |= src->foreBlue >> 8; - - bg_color = 0xFF00 | (src->backRed >> 8); - bg_color <<= 16; - bg_color |= src->backGreen & 0xFF00; - bg_color |= src->backBlue >> 8; - - fg_color = htonl(fg_color); - bg_color = htonl(bg_color); - - /* round up to 8 pixel boundary so we can convert whole bytes */ - rowbytes = ((src->bits->width * 4) + 31) & ~31; - data = xalloc(rowbytes * src->bits->height); - if(!data) { - FatalError("Failed to allocate memory in %s\n", __func__); - } - - if (!src->bits->emptyMask) - { - ycount = src->bits->height; - srow = src->bits->source; mrow = src->bits->mask; - drow = data; - - while (ycount-- > 0) - { - xcount = bits_to_bytes(src->bits->width); - sptr = srow; mptr = mrow; - dptr = drow; - - while (xcount-- > 0) - { - uint8_t s, m; - int i; - - s = *sptr++; m = *mptr++; - for (i = 0; i < 8; i++) - { -#if BITMAP_BIT_ORDER == MSBFirst - if (m & 128) - *dptr++ = (s & 128) ? fg_color : bg_color; - else - *dptr++ = 0; - s <<= 1; m <<= 1; -#else - if (m & 1) - *dptr++ = (s & 1) ? fg_color : bg_color; - else - *dptr++ = 0; - s >>= 1; m >>= 1; -#endif - } - } - - srow += BitmapBytePad(src->bits->width); - mrow += BitmapBytePad(src->bits->width); - drow = (uint32_t *) ((char *) drow + rowbytes); - } - } - else - { - memset(data, 0, src->bits->height * rowbytes); - } - } - - err = xp_set_cursor(width, height, hot_x, hot_y, data, rowbytes); - xfree(data); - return err == Success; -} - - -/* -=========================================================================== - - Pointer sprite functions - -=========================================================================== -*/ - -/* - * QuartzRealizeCursor - * Convert the X cursor representation to native format if possible. - */ -static Bool -QuartzRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) -{ - if(pCursor == NULL || pCursor->bits == NULL) - return FALSE; - - /* FIXME: cache ARGB8888 representation? */ - - return TRUE; -} - - -/* - * QuartzUnrealizeCursor - * Free the storage space associated with a realized cursor. - */ -static Bool -QuartzUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) -{ - return TRUE; -} - - -/* - * QuartzSetCursor - * Set the cursor sprite and position. - */ -static void -QuartzSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y) -{ - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - if (!quartzServerVisible) - return; - - if (pCursor == NULL) - { - if (ScreenPriv->cursorVisible) - { - xp_hide_cursor(); - ScreenPriv->cursorVisible = FALSE; - } - } - else - { - load_cursor(pCursor, pScreen->myNum); - - if (!ScreenPriv->cursorVisible) - { - xp_show_cursor(); - ScreenPriv->cursorVisible = TRUE; - } - } -} - -/* - * QuartzMoveCursor - * Move the cursor. This is a noop for us. - */ -static void -QuartzMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -{ -} - -/* -=========================================================================== - - Pointer screen functions - -=========================================================================== -*/ - -/* - * QuartzCursorOffScreen - */ -static Bool -QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y) -{ - return FALSE; -} - - -/* - * QuartzCrossScreen - */ -static void -QuartzCrossScreen(ScreenPtr pScreen, Bool entering) -{ - return; -} - - -/* - * QuartzWarpCursor - * Change the cursor position without generating an event or motion history. - * The input coordinates (x,y) are in pScreen-local X11 coordinates. - * - */ -static void -QuartzWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -{ - if (quartzServerVisible) - { - int sx, sy; - - sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX; - sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY; - - CGWarpMouseCursorPosition(CGPointMake(sx + x, sy + y)); - } - - miPointerWarpCursor(pDev, pScreen, x, y); - miPointerUpdateSprite(pDev); -} - - -static miPointerScreenFuncRec quartzScreenFuncsRec = { - QuartzCursorOffScreen, - QuartzCrossScreen, - QuartzWarpCursor, - NULL, - NULL -}; - - -/* -=========================================================================== - - Other screen functions - -=========================================================================== -*/ - -/* - * QuartzCursorQueryBestSize - * Handle queries for best cursor size - */ -static void -QuartzCursorQueryBestSize(int class, unsigned short *width, - unsigned short *height, ScreenPtr pScreen) -{ - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - if (class == CursorShape) - { - /* FIXME: query window server? */ - *width = 32; - *height = 32; - } - else - { - (*ScreenPriv->QueryBestSize)(class, width, height, pScreen); - } -} - -/* - * QuartzInitCursor - * Initialize cursor support - */ -Bool -QuartzInitCursor(ScreenPtr pScreen) -{ - QuartzCursorScreenPtr ScreenPriv; - miPointerScreenPtr PointPriv; - - /* initialize software cursor handling (always needed as backup) */ - if (!miDCInitialize(pScreen, &quartzScreenFuncsRec)) - return FALSE; - - ScreenPriv = xcalloc(1, sizeof(QuartzCursorScreenRec)); - if (ScreenPriv == NULL) - return FALSE; - - /* CURSOR_PRIV(pScreen) = ScreenPriv; */ - dixSetPrivate(&pScreen->devPrivates, darwinCursorScreenKey, ScreenPriv); - - /* override some screen procedures */ - ScreenPriv->QueryBestSize = pScreen->QueryBestSize; - pScreen->QueryBestSize = QuartzCursorQueryBestSize; - - PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); - - ScreenPriv->spriteFuncs = PointPriv->spriteFuncs; - - PointPriv->spriteFuncs->RealizeCursor = QuartzRealizeCursor; - PointPriv->spriteFuncs->UnrealizeCursor = QuartzUnrealizeCursor; - PointPriv->spriteFuncs->SetCursor = QuartzSetCursor; - PointPriv->spriteFuncs->MoveCursor = QuartzMoveCursor; - - ScreenPriv->cursorVisible = TRUE; - return TRUE; -} - -/* - * QuartzSuspendXCursor - * X server is hiding. Restore the Aqua cursor. - */ -void -QuartzSuspendXCursor(ScreenPtr pScreen) -{ -} - - -/* - * QuartzResumeXCursor - * X server is showing. Restore the X cursor. - */ -void -QuartzResumeXCursor(ScreenPtr pScreen) -{ - WindowPtr pWin; - CursorPtr pCursor; - - /* TODO: Tablet? */ - - pWin = GetSpriteWindow(darwinPointer); - if (pWin->drawable.pScreen != pScreen) - return; - - pCursor = GetSpriteCursor(darwinPointer); - if (pCursor == NULL) - return; - - QuartzSetCursor(darwinPointer, pScreen, pCursor, /* x */ 0, /* y */ 0); -} +/************************************************************** + * + * Xplugin cursor support + * + * Copyright (c) 2001 Torrey T. Lyons and Greg Parker. + * Copyright (c) 2002 Apple Computer, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, 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 +#endif + +#include "quartzCommon.h" +#include "xpr.h" +#include "darwin.h" +#include "darwinEvents.h" +#include + +#include "mi.h" +#include "scrnintstr.h" +#include "cursorstr.h" +#include "mipointrst.h" +#include "windowstr.h" +#include "globals.h" +#include "servermd.h" +#include "dixevents.h" +#include "x-hash.h" + +typedef struct { + int cursorVisible; + QueryBestSizeProcPtr QueryBestSize; + miPointerSpriteFuncPtr spriteFuncs; +} QuartzCursorScreenRec, *QuartzCursorScreenPtr; + +static int darwinCursorScreenKeyIndex; +static DevPrivateKey darwinCursorScreenKey = &darwinCursorScreenKeyIndex; + +#define CURSOR_PRIV(pScreen) ((QuartzCursorScreenPtr) \ + dixLookupPrivate(&pScreen->devPrivates, darwinCursorScreenKey)) + + +static Bool +load_cursor(CursorPtr src, int screen) +{ + uint32_t *data; + uint32_t rowbytes; + int width, height; + int hot_x, hot_y; + + uint32_t fg_color, bg_color; + uint8_t *srow, *sptr; + uint8_t *mrow, *mptr; + uint32_t *drow, *dptr; + unsigned xcount, ycount; + + xp_error err; + + width = src->bits->width; + height = src->bits->height; + hot_x = src->bits->xhot; + hot_y = src->bits->yhot; + +#ifdef ARGB_CURSOR + if (src->bits->argb != NULL) + { +#if BITMAP_BIT_ORDER == MSBFirst + rowbytes = src->bits->width * sizeof (CARD32); + data = (uint32_t *) src->bits->argb; +#else + const uint32_t *be_data=(uint32_t *) src->bits->argb; + unsigned i; + rowbytes = src->bits->width * sizeof (CARD32); + data = malloc(rowbytes * src->bits->height); + if(!data) { + FatalError("Failed to allocate memory in %s\n", __func__); + } + for(i=0;i<(src->bits->width*src->bits->height);i++) + data[i]=ntohl(be_data[i]); +#endif + } + else +#endif + { + fg_color = 0xFF00 | (src->foreRed >> 8); + fg_color <<= 16; + fg_color |= src->foreGreen & 0xFF00; + fg_color |= src->foreBlue >> 8; + + bg_color = 0xFF00 | (src->backRed >> 8); + bg_color <<= 16; + bg_color |= src->backGreen & 0xFF00; + bg_color |= src->backBlue >> 8; + + fg_color = htonl(fg_color); + bg_color = htonl(bg_color); + + /* round up to 8 pixel boundary so we can convert whole bytes */ + rowbytes = ((src->bits->width * 4) + 31) & ~31; + data = malloc(rowbytes * src->bits->height); + if(!data) { + FatalError("Failed to allocate memory in %s\n", __func__); + } + + if (!src->bits->emptyMask) + { + ycount = src->bits->height; + srow = src->bits->source; mrow = src->bits->mask; + drow = data; + + while (ycount-- > 0) + { + xcount = bits_to_bytes(src->bits->width); + sptr = srow; mptr = mrow; + dptr = drow; + + while (xcount-- > 0) + { + uint8_t s, m; + int i; + + s = *sptr++; m = *mptr++; + for (i = 0; i < 8; i++) + { +#if BITMAP_BIT_ORDER == MSBFirst + if (m & 128) + *dptr++ = (s & 128) ? fg_color : bg_color; + else + *dptr++ = 0; + s <<= 1; m <<= 1; +#else + if (m & 1) + *dptr++ = (s & 1) ? fg_color : bg_color; + else + *dptr++ = 0; + s >>= 1; m >>= 1; +#endif + } + } + + srow += BitmapBytePad(src->bits->width); + mrow += BitmapBytePad(src->bits->width); + drow = (uint32_t *) ((char *) drow + rowbytes); + } + } + else + { + memset(data, 0, src->bits->height * rowbytes); + } + } + + err = xp_set_cursor(width, height, hot_x, hot_y, data, rowbytes); + free(data); + return err == Success; +} + + +/* +=========================================================================== + + Pointer sprite functions + +=========================================================================== +*/ + +/* + * QuartzRealizeCursor + * Convert the X cursor representation to native format if possible. + */ +static Bool +QuartzRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) +{ + if(pCursor == NULL || pCursor->bits == NULL) + return FALSE; + + /* FIXME: cache ARGB8888 representation? */ + + return TRUE; +} + + +/* + * QuartzUnrealizeCursor + * Free the storage space associated with a realized cursor. + */ +static Bool +QuartzUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) +{ + return TRUE; +} + + +/* + * QuartzSetCursor + * Set the cursor sprite and position. + */ +static void +QuartzSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y) +{ + QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); + + if (!quartzServerVisible) + return; + + if (pCursor == NULL) + { + if (ScreenPriv->cursorVisible) + { + xp_hide_cursor(); + ScreenPriv->cursorVisible = FALSE; + } + } + else + { + load_cursor(pCursor, pScreen->myNum); + + if (!ScreenPriv->cursorVisible) + { + xp_show_cursor(); + ScreenPriv->cursorVisible = TRUE; + } + } +} + +/* + * QuartzMoveCursor + * Move the cursor. This is a noop for us. + */ +static void +QuartzMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) +{ +} + +/* +=========================================================================== + + Pointer screen functions + +=========================================================================== +*/ + +/* + * QuartzCursorOffScreen + */ +static Bool +QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y) +{ + return FALSE; +} + + +/* + * QuartzCrossScreen + */ +static void +QuartzCrossScreen(ScreenPtr pScreen, Bool entering) +{ + return; +} + + +/* + * QuartzWarpCursor + * Change the cursor position without generating an event or motion history. + * The input coordinates (x,y) are in pScreen-local X11 coordinates. + * + */ +static void +QuartzWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) +{ + if (quartzServerVisible) + { + int sx, sy; + + sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX; + sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY; + + CGWarpMouseCursorPosition(CGPointMake(sx + x, sy + y)); + } + + miPointerWarpCursor(pDev, pScreen, x, y); + miPointerUpdateSprite(pDev); +} + + +static miPointerScreenFuncRec quartzScreenFuncsRec = { + QuartzCursorOffScreen, + QuartzCrossScreen, + QuartzWarpCursor, + NULL, + NULL +}; + + +/* +=========================================================================== + + Other screen functions + +=========================================================================== +*/ + +/* + * QuartzCursorQueryBestSize + * Handle queries for best cursor size + */ +static void +QuartzCursorQueryBestSize(int class, unsigned short *width, + unsigned short *height, ScreenPtr pScreen) +{ + QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); + + if (class == CursorShape) + { + /* FIXME: query window server? */ + *width = 32; + *height = 32; + } + else + { + (*ScreenPriv->QueryBestSize)(class, width, height, pScreen); + } +} + +/* + * QuartzInitCursor + * Initialize cursor support + */ +Bool +QuartzInitCursor(ScreenPtr pScreen) +{ + QuartzCursorScreenPtr ScreenPriv; + miPointerScreenPtr PointPriv; + + /* initialize software cursor handling (always needed as backup) */ + if (!miDCInitialize(pScreen, &quartzScreenFuncsRec)) + return FALSE; + + ScreenPriv = calloc(1, sizeof(QuartzCursorScreenRec)); + if (ScreenPriv == NULL) + return FALSE; + + /* CURSOR_PRIV(pScreen) = ScreenPriv; */ + dixSetPrivate(&pScreen->devPrivates, darwinCursorScreenKey, ScreenPriv); + + /* override some screen procedures */ + ScreenPriv->QueryBestSize = pScreen->QueryBestSize; + pScreen->QueryBestSize = QuartzCursorQueryBestSize; + + PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); + + ScreenPriv->spriteFuncs = PointPriv->spriteFuncs; + + PointPriv->spriteFuncs->RealizeCursor = QuartzRealizeCursor; + PointPriv->spriteFuncs->UnrealizeCursor = QuartzUnrealizeCursor; + PointPriv->spriteFuncs->SetCursor = QuartzSetCursor; + PointPriv->spriteFuncs->MoveCursor = QuartzMoveCursor; + + ScreenPriv->cursorVisible = TRUE; + return TRUE; +} + +/* + * QuartzSuspendXCursor + * X server is hiding. Restore the Aqua cursor. + */ +void +QuartzSuspendXCursor(ScreenPtr pScreen) +{ +} + + +/* + * QuartzResumeXCursor + * X server is showing. Restore the X cursor. + */ +void +QuartzResumeXCursor(ScreenPtr pScreen) +{ + WindowPtr pWin; + CursorPtr pCursor; + + /* TODO: Tablet? */ + + pWin = GetSpriteWindow(darwinPointer); + if (pWin->drawable.pScreen != pScreen) + return; + + pCursor = GetSpriteCursor(darwinPointer); + if (pCursor == NULL) + return; + + QuartzSetCursor(darwinPointer, pScreen, pCursor, /* x */ 0, /* y */ 0); +} diff --git a/xorg-server/hw/xquartz/xpr/xprScreen.c b/xorg-server/hw/xquartz/xpr/xprScreen.c index 44067862f..bc68f7923 100644 --- a/xorg-server/hw/xquartz/xpr/xprScreen.c +++ b/xorg-server/hw/xquartz/xpr/xprScreen.c @@ -195,7 +195,7 @@ xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height) return; } - displayList = xalloc(displayCount * sizeof(CGDirectDisplayID)); + displayList = malloc(displayCount * sizeof(CGDirectDisplayID)); if(!displayList) FatalError("Unable to allocate memory for list of displays.\n"); CGGetActiveDisplayList(displayCount, displayList, &displayCount); @@ -232,7 +232,7 @@ xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height) frame.size.width, frame.size.height); } - xfree(displayList); + free(displayList); } /* -- cgit v1.2.3