diff options
author | marha <marha@users.sourceforge.net> | 2011-04-28 07:58:00 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-04-28 07:58:00 +0000 |
commit | 57a879849643e79d9674198a3a77c59532fb79b4 (patch) | |
tree | 19ece2254fadb6c2077aa09098dd8a51a5578d2a /xorg-server/hw | |
parent | 96d6df5da9cddedf4931bf8e17f96e242467c661 (diff) | |
download | vcxsrv-57a879849643e79d9674198a3a77c59532fb79b4.tar.gz vcxsrv-57a879849643e79d9674198a3a77c59532fb79b4.tar.bz2 vcxsrv-57a879849643e79d9674198a3a77c59532fb79b4.zip |
xserver xkeyboard-config mesa git update 28 Apr 2011
Diffstat (limited to 'xorg-server/hw')
55 files changed, 15065 insertions, 15191 deletions
diff --git a/xorg-server/hw/xfree86/ddc/ddcProperty.c b/xorg-server/hw/xfree86/ddc/ddcProperty.c index d4ae1006d..5d6eec927 100644 --- a/xorg-server/hw/xfree86/ddc/ddcProperty.c +++ b/xorg-server/hw/xfree86/ddc/ddcProperty.c @@ -1,125 +1,124 @@ -/*
- * Copyright 2006 Luc Verhaegen.
- *
- * 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
- * THE AUTHORS OR COPYRIGHT HOLDERS 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_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include <X11/Xatom.h>
-#include "property.h"
-#include "propertyst.h"
-#include "xf86DDC.h"
-#include <string.h>
-
-#define EDID1_ATOM_NAME "XFree86_DDC_EDID1_RAWDATA"
-#define EDID2_ATOM_NAME "XFree86_DDC_EDID2_RAWDATA"
-
-static void
-edidMakeAtom(int i, const char *name, CARD8 *data, int size)
-{
- Atom atom;
- unsigned char *atom_data;
-
- if (!(atom_data = malloc(size*sizeof(CARD8))))
- return;
-
- atom = MakeAtom(name, strlen(name), TRUE);
- memcpy(atom_data, data, size);
- xf86RegisterRootWindowProperty(i, atom, XA_INTEGER, 8, size, atom_data);
-}
-
-static void
-addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
-{
- int i, scrnIndex = pScrn->scrnIndex;
- Bool makeEDID1prop = FALSE;
- Bool makeEDID2prop = FALSE;
-
- if (DDC->flags & MONITOR_DISPLAYID) {
- /* Don't bother, use RANDR already */
- return;
- } else if (DDC->ver.version == 1) {
- makeEDID1prop = TRUE;
- } else if (DDC->ver.version == 2) {
- int checksum1;
- int checksum2;
- makeEDID2prop = TRUE;
-
- /* Some monitors (eg Panasonic PanaSync4)
- * report version==2 because they used EDID v2 spec document,
- * although they use EDID v1 data structure :-(
- *
- * Try using checksum to determine when we have such a monitor.
- */
- checksum2 = 0;
- for (i = 0; i < 256; i++)
- checksum2 += DDC->rawData[i];
- if (checksum2 % 256) {
- xf86DrvMsg(scrnIndex, X_INFO, "Monitor EDID v2 checksum failed\n");
- xf86DrvMsg(scrnIndex, X_INFO,
- "XFree86_DDC_EDID2_RAWDATA property may be bad\n");
- checksum1 = 0;
- for (i = 0; i < 128; i++)
- checksum1 += DDC->rawData[i];
- if (!(checksum1 % 256)) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "Monitor EDID v1 checksum passed,\n");
- xf86DrvMsg(scrnIndex, X_INFO,
- "XFree86_DDC_EDID1_RAWDATA property created\n");
- makeEDID1prop = TRUE;
- }
- }
- } else {
- xf86DrvMsg(scrnIndex, X_PROBED, "unexpected EDID version %d.%d\n",
- DDC->ver.version, DDC->ver.revision);
- return;
- }
-
- if (makeEDID1prop) {
- int size = 128 +
- (DDC->flags & EDID_COMPLETE_RAWDATA ? DDC->no_sections * 128 : 0);
-
- edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC->rawData, size);
- }
-
- if (makeEDID2prop)
- edidMakeAtom(scrnIndex, EDID2_ATOM_NAME, DDC->rawData, 256);
-}
-
-Bool
-xf86SetDDCproperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
-{
- if (!pScrn || !pScrn->monitor || !DDC)
- return FALSE;
-
- if (DDC->flags & MONITOR_DISPLAYID)
- ;
- else
- xf86EdidMonitorSet(pScrn->scrnIndex, pScrn->monitor, DDC);
-
- addRootWindowProperties(pScrn, DDC);
-
- return TRUE;
-}
+/* + * Copyright 2006 Luc Verhaegen. + * + * 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include "xf86.h" +#include "xf86DDC.h" +#include <X11/Xatom.h> +#include "property.h" +#include "propertyst.h" +#include <string.h> + +#define EDID1_ATOM_NAME "XFree86_DDC_EDID1_RAWDATA" +#define EDID2_ATOM_NAME "XFree86_DDC_EDID2_RAWDATA" + +static void +edidMakeAtom(int i, const char *name, CARD8 *data, int size) +{ + Atom atom; + unsigned char *atom_data; + + if (!(atom_data = malloc(size*sizeof(CARD8)))) + return; + + atom = MakeAtom(name, strlen(name), TRUE); + memcpy(atom_data, data, size); + xf86RegisterRootWindowProperty(i, atom, XA_INTEGER, 8, size, atom_data); +} + +static void +addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC) +{ + int i, scrnIndex = pScrn->scrnIndex; + Bool makeEDID1prop = FALSE; + Bool makeEDID2prop = FALSE; + + if (DDC->flags & MONITOR_DISPLAYID) { + /* Don't bother, use RANDR already */ + return; + } else if (DDC->ver.version == 1) { + makeEDID1prop = TRUE; + } else if (DDC->ver.version == 2) { + int checksum1; + int checksum2; + makeEDID2prop = TRUE; + + /* Some monitors (eg Panasonic PanaSync4) + * report version==2 because they used EDID v2 spec document, + * although they use EDID v1 data structure :-( + * + * Try using checksum to determine when we have such a monitor. + */ + checksum2 = 0; + for (i = 0; i < 256; i++) + checksum2 += DDC->rawData[i]; + if (checksum2 % 256) { + xf86DrvMsg(scrnIndex, X_INFO, "Monitor EDID v2 checksum failed\n"); + xf86DrvMsg(scrnIndex, X_INFO, + "XFree86_DDC_EDID2_RAWDATA property may be bad\n"); + checksum1 = 0; + for (i = 0; i < 128; i++) + checksum1 += DDC->rawData[i]; + if (!(checksum1 % 256)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Monitor EDID v1 checksum passed,\n"); + xf86DrvMsg(scrnIndex, X_INFO, + "XFree86_DDC_EDID1_RAWDATA property created\n"); + makeEDID1prop = TRUE; + } + } + } else { + xf86DrvMsg(scrnIndex, X_PROBED, "unexpected EDID version %d.%d\n", + DDC->ver.version, DDC->ver.revision); + return; + } + + if (makeEDID1prop) { + int size = 128 + + (DDC->flags & EDID_COMPLETE_RAWDATA ? DDC->no_sections * 128 : 0); + + edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC->rawData, size); + } + + if (makeEDID2prop) + edidMakeAtom(scrnIndex, EDID2_ATOM_NAME, DDC->rawData, 256); +} + +Bool +xf86SetDDCproperties(ScrnInfoPtr pScrn, xf86MonPtr DDC) +{ + if (!pScrn || !pScrn->monitor || !DDC) + return FALSE; + + if (DDC->flags & MONITOR_DISPLAYID) + ; + else + xf86EdidMonitorSet(pScrn->scrnIndex, pScrn->monitor, DDC); + + addRootWindowProperties(pScrn, DDC); + + return TRUE; +} diff --git a/xorg-server/hw/xfree86/dri/dri.c b/xorg-server/hw/xfree86/dri/dri.c index bb5482a0b..1726960ae 100644 --- a/xorg-server/hw/xfree86/dri/dri.c +++ b/xorg-server/hw/xfree86/dri/dri.c @@ -63,8 +63,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dri.h" #include "sarea.h" #include "dristruct.h" -#include "xf86.h" -#include "xf86drm.h" #include "mi.h" #include "mipointer.h" #include "xf86_OSproc.h" diff --git a/xorg-server/hw/xfree86/dri/xf86dri.c b/xorg-server/hw/xfree86/dri/xf86dri.c index cd1085b36..e02644a30 100644 --- a/xorg-server/hw/xfree86/dri/xf86dri.c +++ b/xorg-server/hw/xfree86/dri/xf86dri.c @@ -1,663 +1,662 @@ -/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, 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 <martin@valinux.com>
- * Jens Owen <jens@tungstengraphics.com>
- * Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "xf86.h"
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "servermd.h"
-#define _XF86DRI_SERVER_
-#include <X11/dri/xf86driproto.h>
-#include "swaprep.h"
-#include "xf86str.h"
-#include "dri.h"
-#include "sarea.h"
-#include "dristruct.h"
-#include "xf86.h"
-#include "xf86drm.h"
-#include "protocol-versions.h"
-
-static int DRIErrorBase;
-
-
-
-static void XF86DRIResetProc(ExtensionEntry* extEntry);
-
-static unsigned char DRIReqCode = 0;
-
-extern void XFree86DRIExtensionInit(void);
-
-/*ARGSUSED*/
-static void
-XF86DRIResetProc (
- ExtensionEntry* extEntry
-)
-{
- DRIReset();
-}
-
-static int
-ProcXF86DRIQueryVersion(
- register ClientPtr client
-)
-{
- xXF86DRIQueryVersionReply rep;
- register int n;
-
- REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION;
- rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION;
- rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.majorVersion, n);
- swaps(&rep.minorVersion, n);
- swapl(&rep.patchVersion, n);
- }
- WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXF86DRIQueryDirectRenderingCapable(
- register ClientPtr client
-)
-{
- xXF86DRIQueryDirectRenderingCapableReply rep;
- Bool isCapable;
- register int n;
-
- REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
- REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- 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) || client->swapped)
- rep.isCapable = 0;
-
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- }
-
- WriteToClient(client,
- sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXF86DRIOpenConnection(
- register ClientPtr client
-)
-{
- xXF86DRIOpenConnectionReply rep;
- drm_handle_t hSAREA;
- char* busIdString;
-
- REQUEST(xXF86DRIOpenConnectionReq);
- REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- if (!DRIOpenConnection( screenInfo.screens[stuff->screen],
- &hSAREA,
- &busIdString)) {
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.busIdStringLength = 0;
- if (busIdString)
- rep.busIdStringLength = strlen(busIdString);
- rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
- pad_to_int32(rep.busIdStringLength));
-
- rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff);
-#if defined(LONG64) && !defined(__linux__)
- rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
-#else
- rep.hSAREAHigh = 0;
-#endif
-
- WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
- if (rep.busIdStringLength)
- WriteToClient(client, rep.busIdStringLength, busIdString);
- return Success;
-}
-
-static int
-ProcXF86DRIAuthConnection(
- register ClientPtr client
-)
-{
- xXF86DRIAuthConnectionReply rep;
-
- REQUEST(xXF86DRIAuthConnectionReq);
- REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- 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 %lu\n", (unsigned long)stuff->magic);
- rep.authenticated = 0;
- }
- WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXF86DRICloseConnection(
- register ClientPtr client
-)
-{
- REQUEST(xXF86DRICloseConnectionReq);
- REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- DRICloseConnection( screenInfo.screens[stuff->screen]);
-
- return Success;
-}
-
-static int
-ProcXF86DRIGetClientDriverName(
- register ClientPtr client
-)
-{
- xXF86DRIGetClientDriverNameReply rep;
- char* clientDriverName;
-
- REQUEST(xXF86DRIGetClientDriverNameReq);
- REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- DRIGetClientDriverName( screenInfo.screens[stuff->screen],
- (int *)&rep.ddxDriverMajorVersion,
- (int *)&rep.ddxDriverMinorVersion,
- (int *)&rep.ddxDriverPatchVersion,
- &clientDriverName);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.clientDriverNameLength = 0;
- if (clientDriverName)
- rep.clientDriverNameLength = strlen(clientDriverName);
- rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) -
- SIZEOF(xGenericReply) +
- pad_to_int32(rep.clientDriverNameLength));
-
- WriteToClient(client,
- sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
- if (rep.clientDriverNameLength)
- WriteToClient(client,
- rep.clientDriverNameLength,
- clientDriverName);
- return Success;
-}
-
-static int
-ProcXF86DRICreateContext(
- register ClientPtr client
-)
-{
- xXF86DRICreateContextReply rep;
- ScreenPtr pScreen;
-
- REQUEST(xXF86DRICreateContextReq);
- REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- pScreen = screenInfo.screens[stuff->screen];
-
- if (!DRICreateContext( pScreen,
- NULL,
- stuff->context,
- (drm_context_t *)&rep.hHWContext)) {
- return BadValue;
- }
-
- WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXF86DRIDestroyContext(
- register ClientPtr client
-)
-{
- REQUEST(xXF86DRIDestroyContextReq);
- REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
- stuff->context)) {
- return BadValue;
- }
-
- return Success;
-}
-
-static int
-ProcXF86DRICreateDrawable(
- ClientPtr client
-)
-{
- xXF86DRICreateDrawableReply rep;
- DrawablePtr pDrawable;
- int rc;
-
- REQUEST(xXF86DRICreateDrawableReq);
- REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (!DRICreateDrawable(screenInfo.screens[stuff->screen], client,
- pDrawable, (drm_drawable_t *)&rep.hHWDrawable)) {
- return BadValue;
- }
-
- WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
- return Success;
-}
-
-static int
-ProcXF86DRIDestroyDrawable(
- register ClientPtr client
-)
-{
- REQUEST(xXF86DRIDestroyDrawableReq);
- DrawablePtr pDrawable;
- int rc;
- REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
-
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (!DRIDestroyDrawable(screenInfo.screens[stuff->screen], client,
- pDrawable)) {
- return BadValue;
- }
-
- return Success;
-}
-
-static int
-ProcXF86DRIGetDrawableInfo(
- register ClientPtr client
-)
-{
- xXF86DRIGetDrawableInfoReply rep;
- DrawablePtr pDrawable;
- int X, Y, W, H;
- drm_clip_rect_t * pClipRects, *pClippedRects;
- drm_clip_rect_t * pBackClipRects;
- int backX, backY, rc;
-
- REQUEST(xXF86DRIGetDrawableInfoReq);
- REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (!DRIGetDrawableInfo( screenInfo.screens[stuff->screen],
- pDrawable,
- (unsigned int*)&rep.drawableTableIndex,
- (unsigned int*)&rep.drawableTableStamp,
- (int*)&X,
- (int*)&Y,
- (int*)&W,
- (int*)&H,
- (int*)&rep.numClipRects,
- &pClipRects,
- &backX,
- &backY,
- (int*)&rep.numBackClipRects,
- &pBackClipRects)) {
- return BadValue;
- }
-
- rep.drawableX = X;
- rep.drawableY = Y;
- rep.drawableWidth = W;
- rep.drawableHeight = H;
- rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
- SIZEOF(xGenericReply));
-
- rep.backX = backX;
- rep.backY = backY;
-
- if (rep.numBackClipRects)
- rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
-
- pClippedRects = pClipRects;
-
- if (rep.numClipRects) {
- /* Clip cliprects to screen dimensions (redirected windows) */
- pClippedRects = malloc(rep.numClipRects * sizeof(drm_clip_rect_t));
-
- if (pClippedRects) {
- ScreenPtr pScreen = screenInfo.screens[stuff->screen];
- int i, j;
-
- for (i = 0, j = 0; i < rep.numClipRects; i++) {
- pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
- pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
- pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
- pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);
-
- if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
- pClippedRects[j].y1 < pClippedRects[j].y2) {
- j++;
- }
- }
-
- rep.numClipRects = j;
- } else {
- rep.numClipRects = 0;
- }
-
- rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
- }
-
- rep.length = bytes_to_int32(rep.length);
-
- WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
-
- if (rep.numClipRects) {
- WriteToClient(client,
- sizeof(drm_clip_rect_t) * rep.numClipRects,
- (char *)pClippedRects);
- free(pClippedRects);
- }
-
- if (rep.numBackClipRects) {
- WriteToClient(client,
- sizeof(drm_clip_rect_t) * rep.numBackClipRects,
- (char *)pBackClipRects);
- }
-
- return Success;
-}
-
-static int
-ProcXF86DRIGetDeviceInfo(
- register ClientPtr client
-)
-{
- xXF86DRIGetDeviceInfoReply rep;
- drm_handle_t hFrameBuffer;
- void *pDevPrivate;
-
- REQUEST(xXF86DRIGetDeviceInfoReq);
- REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!DRIGetDeviceInfo( screenInfo.screens[stuff->screen],
- &hFrameBuffer,
- (int*)&rep.framebufferOrigin,
- (int*)&rep.framebufferSize,
- (int*)&rep.framebufferStride,
- (int*)&rep.devPrivateSize,
- &pDevPrivate)) {
- return BadValue;
- }
-
- rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff);
-#if defined(LONG64) && !defined(__linux__)
- rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
-#else
- rep.hFrameBufferHigh = 0;
-#endif
-
- rep.length = 0;
- if (rep.devPrivateSize) {
- rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) -
- SIZEOF(xGenericReply) +
- pad_to_int32(rep.devPrivateSize));
- }
-
- WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
- if (rep.length) {
- WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
- }
- return Success;
-}
-
-static int
-ProcXF86DRIDispatch (
- register ClientPtr client
-)
-{
- REQUEST(xReq);
-
- switch (stuff->data)
- {
- case X_XF86DRIQueryVersion:
- return ProcXF86DRIQueryVersion(client);
- case X_XF86DRIQueryDirectRenderingCapable:
- return ProcXF86DRIQueryDirectRenderingCapable(client);
- }
-
- if (!LocalClient(client))
- return DRIErrorBase + XF86DRIClientNotLocal;
-
- switch (stuff->data)
- {
- case X_XF86DRIOpenConnection:
- return ProcXF86DRIOpenConnection(client);
- case X_XF86DRICloseConnection:
- return ProcXF86DRICloseConnection(client);
- case X_XF86DRIGetClientDriverName:
- return ProcXF86DRIGetClientDriverName(client);
- case X_XF86DRICreateContext:
- return ProcXF86DRICreateContext(client);
- case X_XF86DRIDestroyContext:
- return ProcXF86DRIDestroyContext(client);
- case X_XF86DRICreateDrawable:
- return ProcXF86DRICreateDrawable(client);
- case X_XF86DRIDestroyDrawable:
- return ProcXF86DRIDestroyDrawable(client);
- case X_XF86DRIGetDrawableInfo:
- return ProcXF86DRIGetDrawableInfo(client);
- case X_XF86DRIGetDeviceInfo:
- return ProcXF86DRIGetDeviceInfo(client);
- case X_XF86DRIAuthConnection:
- return ProcXF86DRIAuthConnection(client);
- /* {Open,Close}FullScreen are deprecated now */
- default:
- return BadRequest;
- }
-}
-
-static int
-SProcXF86DRIQueryVersion(
- register ClientPtr client
-)
-{
- register int n;
- REQUEST(xXF86DRIQueryVersionReq);
- swaps(&stuff->length, n);
- return ProcXF86DRIQueryVersion(client);
-}
-
-static int
-SProcXF86DRIQueryDirectRenderingCapable(
- register ClientPtr client
-)
-{
- register int n;
- REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
- swaps(&stuff->length, n);
- swapl(&stuff->screen, n);
- return ProcXF86DRIQueryDirectRenderingCapable(client);
-}
-
-static int
-SProcXF86DRIDispatch (
- register ClientPtr client
-)
-{
- REQUEST(xReq);
-
- /*
- * Only local clients are allowed DRI access, but remote clients still need
- * these requests to find out cleanly.
- */
- switch (stuff->data)
- {
- case X_XF86DRIQueryVersion:
- return SProcXF86DRIQueryVersion(client);
- case X_XF86DRIQueryDirectRenderingCapable:
- return SProcXF86DRIQueryDirectRenderingCapable(client);
- default:
- return DRIErrorBase + XF86DRIClientNotLocal;
- }
-}
-
-void
-XFree86DRIExtensionInit(void)
-{
- ExtensionEntry* extEntry;
-
-#ifdef XF86DRI_EVENTS
- EventType = CreateNewResourceType(XF86DRIFreeEvents, "DRIEvent");
-#endif
-
- if (
- DRIExtensionInit() &&
-#ifdef XF86DRI_EVENTS
- EventType && ScreenPrivateIndex != -1 &&
-#endif
- (extEntry = AddExtension(XF86DRINAME,
- XF86DRINumberEvents,
- XF86DRINumberErrors,
- ProcXF86DRIDispatch,
- SProcXF86DRIDispatch,
- XF86DRIResetProc,
- StandardMinorOpcode))) {
- DRIReqCode = (unsigned char)extEntry->base;
- DRIErrorBase = extEntry->errorBase;
- }
-}
+/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, 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 <martin@valinux.com> + * Jens Owen <jens@tungstengraphics.com> + * Rickard E. (Rik) Faith <faith@valinux.com> + * + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <string.h> + +#include "xf86.h" + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "dixstruct.h" +#include "extnsionst.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "scrnintstr.h" +#include "servermd.h" +#define _XF86DRI_SERVER_ +#include <X11/dri/xf86driproto.h> +#include "swaprep.h" +#include "xf86str.h" +#include "dri.h" +#include "sarea.h" +#include "dristruct.h" +#include "xf86drm.h" +#include "protocol-versions.h" + +static int DRIErrorBase; + + + +static void XF86DRIResetProc(ExtensionEntry* extEntry); + +static unsigned char DRIReqCode = 0; + +extern void XFree86DRIExtensionInit(void); + +/*ARGSUSED*/ +static void +XF86DRIResetProc ( + ExtensionEntry* extEntry +) +{ + DRIReset(); +} + +static int +ProcXF86DRIQueryVersion( + register ClientPtr client +) +{ + xXF86DRIQueryVersionReply rep; + register int n; + + REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION; + rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION; + rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.majorVersion, n); + swaps(&rep.minorVersion, n); + swapl(&rep.patchVersion, n); + } + WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep); + return Success; +} + +static int +ProcXF86DRIQueryDirectRenderingCapable( + register ClientPtr client +) +{ + xXF86DRIQueryDirectRenderingCapableReply rep; + Bool isCapable; + register int n; + + REQUEST(xXF86DRIQueryDirectRenderingCapableReq); + REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq); + if (stuff->screen >= screenInfo.numScreens) { + client->errorValue = stuff->screen; + return BadValue; + } + + 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) || client->swapped) + rep.isCapable = 0; + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + } + + WriteToClient(client, + sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep); + return Success; +} + +static int +ProcXF86DRIOpenConnection( + register ClientPtr client +) +{ + xXF86DRIOpenConnectionReply rep; + drm_handle_t hSAREA; + char* busIdString; + + REQUEST(xXF86DRIOpenConnectionReq); + REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq); + if (stuff->screen >= screenInfo.numScreens) { + client->errorValue = stuff->screen; + return BadValue; + } + + if (!DRIOpenConnection( screenInfo.screens[stuff->screen], + &hSAREA, + &busIdString)) { + return BadValue; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.busIdStringLength = 0; + if (busIdString) + rep.busIdStringLength = strlen(busIdString); + rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) + + pad_to_int32(rep.busIdStringLength)); + + rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff); +#if defined(LONG64) && !defined(__linux__) + rep.hSAREAHigh = (CARD32)(hSAREA >> 32); +#else + rep.hSAREAHigh = 0; +#endif + + WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep); + if (rep.busIdStringLength) + WriteToClient(client, rep.busIdStringLength, busIdString); + return Success; +} + +static int +ProcXF86DRIAuthConnection( + register ClientPtr client +) +{ + xXF86DRIAuthConnectionReply rep; + + REQUEST(xXF86DRIAuthConnectionReq); + REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq); + if (stuff->screen >= screenInfo.numScreens) { + client->errorValue = stuff->screen; + return BadValue; + } + + 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 %lu\n", (unsigned long)stuff->magic); + rep.authenticated = 0; + } + WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep); + return Success; +} + +static int +ProcXF86DRICloseConnection( + register ClientPtr client +) +{ + REQUEST(xXF86DRICloseConnectionReq); + REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq); + if (stuff->screen >= screenInfo.numScreens) { + client->errorValue = stuff->screen; + return BadValue; + } + + DRICloseConnection( screenInfo.screens[stuff->screen]); + + return Success; +} + +static int +ProcXF86DRIGetClientDriverName( + register ClientPtr client +) +{ + xXF86DRIGetClientDriverNameReply rep; + char* clientDriverName; + + REQUEST(xXF86DRIGetClientDriverNameReq); + REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq); + if (stuff->screen >= screenInfo.numScreens) { + client->errorValue = stuff->screen; + return BadValue; + } + + DRIGetClientDriverName( screenInfo.screens[stuff->screen], + (int *)&rep.ddxDriverMajorVersion, + (int *)&rep.ddxDriverMinorVersion, + (int *)&rep.ddxDriverPatchVersion, + &clientDriverName); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.clientDriverNameLength = 0; + if (clientDriverName) + rep.clientDriverNameLength = strlen(clientDriverName); + rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) - + SIZEOF(xGenericReply) + + pad_to_int32(rep.clientDriverNameLength)); + + WriteToClient(client, + sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep); + if (rep.clientDriverNameLength) + WriteToClient(client, + rep.clientDriverNameLength, + clientDriverName); + return Success; +} + +static int +ProcXF86DRICreateContext( + register ClientPtr client +) +{ + xXF86DRICreateContextReply rep; + ScreenPtr pScreen; + + REQUEST(xXF86DRICreateContextReq); + REQUEST_SIZE_MATCH(xXF86DRICreateContextReq); + if (stuff->screen >= screenInfo.numScreens) { + client->errorValue = stuff->screen; + return BadValue; + } + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + pScreen = screenInfo.screens[stuff->screen]; + + if (!DRICreateContext( pScreen, + NULL, + stuff->context, + (drm_context_t *)&rep.hHWContext)) { + return BadValue; + } + + WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep); + return Success; +} + +static int +ProcXF86DRIDestroyContext( + register ClientPtr client +) +{ + REQUEST(xXF86DRIDestroyContextReq); + REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq); + if (stuff->screen >= screenInfo.numScreens) { + client->errorValue = stuff->screen; + return BadValue; + } + + if (!DRIDestroyContext( screenInfo.screens[stuff->screen], + stuff->context)) { + return BadValue; + } + + return Success; +} + +static int +ProcXF86DRICreateDrawable( + ClientPtr client +) +{ + xXF86DRICreateDrawableReply rep; + DrawablePtr pDrawable; + int rc; + + REQUEST(xXF86DRICreateDrawableReq); + REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq); + if (stuff->screen >= screenInfo.numScreens) { + client->errorValue = stuff->screen; + return BadValue; + } + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + + if (!DRICreateDrawable(screenInfo.screens[stuff->screen], client, + pDrawable, (drm_drawable_t *)&rep.hHWDrawable)) { + return BadValue; + } + + WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep); + return Success; +} + +static int +ProcXF86DRIDestroyDrawable( + register ClientPtr client +) +{ + REQUEST(xXF86DRIDestroyDrawableReq); + DrawablePtr pDrawable; + int rc; + REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq); + + if (stuff->screen >= screenInfo.numScreens) { + client->errorValue = stuff->screen; + return BadValue; + } + + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + + if (!DRIDestroyDrawable(screenInfo.screens[stuff->screen], client, + pDrawable)) { + return BadValue; + } + + return Success; +} + +static int +ProcXF86DRIGetDrawableInfo( + register ClientPtr client +) +{ + xXF86DRIGetDrawableInfoReply rep; + DrawablePtr pDrawable; + int X, Y, W, H; + drm_clip_rect_t * pClipRects, *pClippedRects; + drm_clip_rect_t * pBackClipRects; + int backX, backY, rc; + + REQUEST(xXF86DRIGetDrawableInfoReq); + REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq); + if (stuff->screen >= screenInfo.numScreens) { + client->errorValue = stuff->screen; + return BadValue; + } + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixReadAccess); + if (rc != Success) + return rc; + + if (!DRIGetDrawableInfo( screenInfo.screens[stuff->screen], + pDrawable, + (unsigned int*)&rep.drawableTableIndex, + (unsigned int*)&rep.drawableTableStamp, + (int*)&X, + (int*)&Y, + (int*)&W, + (int*)&H, + (int*)&rep.numClipRects, + &pClipRects, + &backX, + &backY, + (int*)&rep.numBackClipRects, + &pBackClipRects)) { + return BadValue; + } + + rep.drawableX = X; + rep.drawableY = Y; + rep.drawableWidth = W; + rep.drawableHeight = H; + rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - + SIZEOF(xGenericReply)); + + rep.backX = backX; + rep.backY = backY; + + if (rep.numBackClipRects) + rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects; + + pClippedRects = pClipRects; + + if (rep.numClipRects) { + /* Clip cliprects to screen dimensions (redirected windows) */ + pClippedRects = malloc(rep.numClipRects * sizeof(drm_clip_rect_t)); + + if (pClippedRects) { + ScreenPtr pScreen = screenInfo.screens[stuff->screen]; + int i, j; + + for (i = 0, j = 0; i < rep.numClipRects; i++) { + pClippedRects[j].x1 = max(pClipRects[i].x1, 0); + pClippedRects[j].y1 = max(pClipRects[i].y1, 0); + pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width); + pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height); + + if (pClippedRects[j].x1 < pClippedRects[j].x2 && + pClippedRects[j].y1 < pClippedRects[j].y2) { + j++; + } + } + + rep.numClipRects = j; + } else { + rep.numClipRects = 0; + } + + rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects; + } + + rep.length = bytes_to_int32(rep.length); + + WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep); + + if (rep.numClipRects) { + WriteToClient(client, + sizeof(drm_clip_rect_t) * rep.numClipRects, + (char *)pClippedRects); + free(pClippedRects); + } + + if (rep.numBackClipRects) { + WriteToClient(client, + sizeof(drm_clip_rect_t) * rep.numBackClipRects, + (char *)pBackClipRects); + } + + return Success; +} + +static int +ProcXF86DRIGetDeviceInfo( + register ClientPtr client +) +{ + xXF86DRIGetDeviceInfoReply rep; + drm_handle_t hFrameBuffer; + void *pDevPrivate; + + REQUEST(xXF86DRIGetDeviceInfoReq); + REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq); + if (stuff->screen >= screenInfo.numScreens) { + client->errorValue = stuff->screen; + return BadValue; + } + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if (!DRIGetDeviceInfo( screenInfo.screens[stuff->screen], + &hFrameBuffer, + (int*)&rep.framebufferOrigin, + (int*)&rep.framebufferSize, + (int*)&rep.framebufferStride, + (int*)&rep.devPrivateSize, + &pDevPrivate)) { + return BadValue; + } + + rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff); +#if defined(LONG64) && !defined(__linux__) + rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32); +#else + rep.hFrameBufferHigh = 0; +#endif + + rep.length = 0; + if (rep.devPrivateSize) { + rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) - + SIZEOF(xGenericReply) + + pad_to_int32(rep.devPrivateSize)); + } + + WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep); + if (rep.length) { + WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate); + } + return Success; +} + +static int +ProcXF86DRIDispatch ( + register ClientPtr client +) +{ + REQUEST(xReq); + + switch (stuff->data) + { + case X_XF86DRIQueryVersion: + return ProcXF86DRIQueryVersion(client); + case X_XF86DRIQueryDirectRenderingCapable: + return ProcXF86DRIQueryDirectRenderingCapable(client); + } + + if (!LocalClient(client)) + return DRIErrorBase + XF86DRIClientNotLocal; + + switch (stuff->data) + { + case X_XF86DRIOpenConnection: + return ProcXF86DRIOpenConnection(client); + case X_XF86DRICloseConnection: + return ProcXF86DRICloseConnection(client); + case X_XF86DRIGetClientDriverName: + return ProcXF86DRIGetClientDriverName(client); + case X_XF86DRICreateContext: + return ProcXF86DRICreateContext(client); + case X_XF86DRIDestroyContext: + return ProcXF86DRIDestroyContext(client); + case X_XF86DRICreateDrawable: + return ProcXF86DRICreateDrawable(client); + case X_XF86DRIDestroyDrawable: + return ProcXF86DRIDestroyDrawable(client); + case X_XF86DRIGetDrawableInfo: + return ProcXF86DRIGetDrawableInfo(client); + case X_XF86DRIGetDeviceInfo: + return ProcXF86DRIGetDeviceInfo(client); + case X_XF86DRIAuthConnection: + return ProcXF86DRIAuthConnection(client); + /* {Open,Close}FullScreen are deprecated now */ + default: + return BadRequest; + } +} + +static int +SProcXF86DRIQueryVersion( + register ClientPtr client +) +{ + register int n; + REQUEST(xXF86DRIQueryVersionReq); + swaps(&stuff->length, n); + return ProcXF86DRIQueryVersion(client); +} + +static int +SProcXF86DRIQueryDirectRenderingCapable( + register ClientPtr client +) +{ + register int n; + REQUEST(xXF86DRIQueryDirectRenderingCapableReq); + swaps(&stuff->length, n); + swapl(&stuff->screen, n); + return ProcXF86DRIQueryDirectRenderingCapable(client); +} + +static int +SProcXF86DRIDispatch ( + register ClientPtr client +) +{ + REQUEST(xReq); + + /* + * Only local clients are allowed DRI access, but remote clients still need + * these requests to find out cleanly. + */ + switch (stuff->data) + { + case X_XF86DRIQueryVersion: + return SProcXF86DRIQueryVersion(client); + case X_XF86DRIQueryDirectRenderingCapable: + return SProcXF86DRIQueryDirectRenderingCapable(client); + default: + return DRIErrorBase + XF86DRIClientNotLocal; + } +} + +void +XFree86DRIExtensionInit(void) +{ + ExtensionEntry* extEntry; + +#ifdef XF86DRI_EVENTS + EventType = CreateNewResourceType(XF86DRIFreeEvents, "DRIEvent"); +#endif + + if ( + DRIExtensionInit() && +#ifdef XF86DRI_EVENTS + EventType && ScreenPrivateIndex != -1 && +#endif + (extEntry = AddExtension(XF86DRINAME, + XF86DRINumberEvents, + XF86DRINumberErrors, + ProcXF86DRIDispatch, + SProcXF86DRIDispatch, + XF86DRIResetProc, + StandardMinorOpcode))) { + DRIReqCode = (unsigned char)extEntry->base; + DRIErrorBase = extEntry->errorBase; + } +} diff --git a/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c b/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c index ef69d58bc..dee731be4 100644 --- a/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c +++ b/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c @@ -1,906 +1,905 @@ -/* all driver need this */
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-/* pci stuff */
-#include "xf86PciInfo.h"
-#include "xf86Pci.h"
-
-#include "xf86cmap.h"
-
-#include "fbdevhw.h"
-#include "fbpriv.h"
-#include "globals.h"
-#include <X11/extensions/dpmsconst.h>
-
-#define PAGE_MASK (~(getpagesize() - 1))
-
-static XF86ModuleVersionInfo fbdevHWVersRec =
-{
- "fbdevhw",
- MODULEVENDORSTRING,
- MODINFOSTRING1,
- MODINFOSTRING2,
- XORG_VERSION_CURRENT,
- 0, 0, 2,
- ABI_CLASS_VIDEODRV,
- ABI_VIDEODRV_VERSION,
- MOD_CLASS_NONE,
- {0,0,0,0}
-};
-
-_X_EXPORT XF86ModuleData fbdevhwModuleData = {
- &fbdevHWVersRec,
- NULL,
- NULL
-};
-
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-/* -------------------------------------------------------------------- */
-/* our private data, and two functions to allocate/free this */
-
-#define FBDEVHWPTRLVAL(p) (p)->privates[fbdevHWPrivateIndex].ptr
-#define FBDEVHWPTR(p) ((fbdevHWPtr)(FBDEVHWPTRLVAL(p)))
-
-static int fbdevHWPrivateIndex = -1;
-
-typedef struct {
- /* framebuffer device: filename (/dev/fb*), handle, more */
- char* device;
- int fd;
- void* fbmem;
- unsigned int fbmem_len;
- unsigned int fboff;
- char* mmio;
- unsigned int mmio_len;
-
- /* current hardware state */
- struct fb_fix_screeninfo fix;
- struct fb_var_screeninfo var;
-
- /* saved video mode */
- struct fb_var_screeninfo saved_var;
-
- /* buildin video mode */
- DisplayModeRec buildin;
-
-} fbdevHWRec, *fbdevHWPtr;
-
-Bool
-fbdevHWGetRec(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr;
-
- if (fbdevHWPrivateIndex < 0)
- fbdevHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
-
- if (FBDEVHWPTR(pScrn) != NULL)
- return TRUE;
-
- fPtr = FBDEVHWPTRLVAL(pScrn) = xnfcalloc(sizeof(fbdevHWRec), 1);
- return TRUE;
-}
-
-void
-fbdevHWFreeRec(ScrnInfoPtr pScrn)
-{
- if (fbdevHWPrivateIndex < 0)
- return;
- if (FBDEVHWPTR(pScrn) == NULL)
- return;
- free(FBDEVHWPTR(pScrn));
- FBDEVHWPTRLVAL(pScrn) = NULL;
-}
-
-int
-fbdevHWGetFD(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr;
-
- fbdevHWGetRec(pScrn);
- fPtr = FBDEVHWPTR(pScrn);
-
- return fPtr->fd;
-}
-
-/* -------------------------------------------------------------------- */
-/* some helpers for printing debug informations */
-
-#if DEBUG
-static void
-print_fbdev_mode(char *txt, struct fb_var_screeninfo *var)
-{
- ErrorF( "fbdev %s mode:\t%d %d %d %d %d %d %d %d %d %d %d:%d:%d\n",
- txt,var->pixclock,
- var->xres, var->right_margin, var->hsync_len, var->left_margin,
- var->yres, var->lower_margin, var->vsync_len, var->upper_margin,
- var->bits_per_pixel,
- var->red.length, var->green.length, var->blue.length);
-}
-
-static void
-print_xfree_mode(char *txt, DisplayModePtr mode)
-{
- ErrorF( "xfree %s mode:\t%d %d %d %d %d %d %d %d %d\n",
- txt,mode->Clock,
- mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal,
- mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal);
-}
-#endif
-
-/* -------------------------------------------------------------------- */
-/* Convert timings between the XFree and the Frame Buffer Device */
-
-static void
-xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var)
-{
- var->xres_virtual = pScrn->displayWidth ? pScrn->displayWidth :
- pScrn->virtualX;
- var->yres_virtual = pScrn->virtualY;
- var->bits_per_pixel = pScrn->bitsPerPixel;
- if (pScrn->defaultVisual == TrueColor ||
- pScrn->defaultVisual == DirectColor) {
- var->red.length = pScrn->weight.red;
- var->green.length = pScrn->weight.green;
- var->blue.length = pScrn->weight.blue;
- } else {
- var->red.length = 8;
- var->green.length = 8;
- var->blue.length = 8;
- }
-}
-
-static void
-xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var)
-{
- var->xres = mode->HDisplay;
- var->yres = mode->VDisplay;
- if (var->xres_virtual < var->xres)
- var->xres_virtual = var->xres;
- if (var->yres_virtual < var->yres)
- var->yres_virtual = var->yres;
- var->xoffset = var->yoffset = 0;
- var->pixclock = mode->Clock ? 1000000000/mode->Clock : 0;
- var->right_margin = mode->HSyncStart-mode->HDisplay;
- var->hsync_len = mode->HSyncEnd-mode->HSyncStart;
- var->left_margin = mode->HTotal-mode->HSyncEnd;
- var->lower_margin = mode->VSyncStart-mode->VDisplay;
- var->vsync_len = mode->VSyncEnd-mode->VSyncStart;
- var->upper_margin = mode->VTotal-mode->VSyncEnd;
- var->sync = 0;
- if (mode->Flags & V_PHSYNC)
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
- if (mode->Flags & V_PVSYNC)
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
- if (mode->Flags & V_PCSYNC)
- var->sync |= FB_SYNC_COMP_HIGH_ACT;
- if (mode->Flags & V_BCAST)
- var->sync |= FB_SYNC_BROADCAST;
- if (mode->Flags & V_INTERLACE)
- var->vmode = FB_VMODE_INTERLACED;
- else if (mode->Flags & V_DBLSCAN)
- var->vmode = FB_VMODE_DOUBLE;
- else
- var->vmode = FB_VMODE_NONINTERLACED;
-}
-
-static Bool
-fbdev_modes_equal(struct fb_var_screeninfo *set, struct fb_var_screeninfo *req)
-{
- return (set->xres_virtual >= req->xres_virtual &&
- set->yres_virtual >= req->yres_virtual &&
- set->bits_per_pixel == req->bits_per_pixel &&
- set->red.length == req->red.length &&
- set->green.length == req->green.length &&
- set->blue.length == req->blue.length &&
- set->xres == req->xres && set->yres == req->yres &&
- set->right_margin == req->right_margin &&
- set->hsync_len == req->hsync_len &&
- set->left_margin == req->left_margin &&
- set->lower_margin == req->lower_margin &&
- set->vsync_len == req->vsync_len &&
- set->upper_margin == req->upper_margin &&
- set->sync == req->sync && set->vmode == req->vmode);
-}
-
-static void
-fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode)
-{
- mode->Clock = var->pixclock ? 1000000000/var->pixclock : 0;
- mode->HDisplay = var->xres;
- mode->HSyncStart = mode->HDisplay+var->right_margin;
- mode->HSyncEnd = mode->HSyncStart+var->hsync_len;
- mode->HTotal = mode->HSyncEnd+var->left_margin;
- mode->VDisplay = var->yres;
- mode->VSyncStart = mode->VDisplay+var->lower_margin;
- mode->VSyncEnd = mode->VSyncStart+var->vsync_len;
- mode->VTotal = mode->VSyncEnd+var->upper_margin;
- mode->Flags = 0;
- mode->Flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC;
- mode->Flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC;
- mode->Flags |= var->sync & FB_SYNC_COMP_HIGH_ACT ? V_PCSYNC : V_NCSYNC;
- if (var->sync & FB_SYNC_BROADCAST)
- mode->Flags |= V_BCAST;
- if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
- mode->Flags |= V_INTERLACE;
- else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
- mode->Flags |= V_DBLSCAN;
- mode->SynthClock = mode->Clock;
- mode->CrtcHDisplay = mode->HDisplay;
- mode->CrtcHSyncStart = mode->HSyncStart;
- mode->CrtcHSyncEnd = mode->HSyncEnd;
- mode->CrtcHTotal = mode->HTotal;
- mode->CrtcVDisplay = mode->VDisplay;
- mode->CrtcVSyncStart = mode->VSyncStart;
- mode->CrtcVSyncEnd = mode->VSyncEnd;
- mode->CrtcVTotal = mode->VTotal;
- mode->CrtcHAdjusted = FALSE;
- mode->CrtcVAdjusted = FALSE;
-}
-
-
-/* -------------------------------------------------------------------- */
-/* open correct framebuffer device */
-
-/**
- * Try to find the framebuffer device for a given PCI device
- */
-static int
-fbdev_open_pci(struct pci_device * pPci, char **namep)
-{
- struct fb_fix_screeninfo fix;
- char filename[256];
- int fd, i;
-
- for (i = 0; i < 8; i++) {
- sprintf(filename,
- "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics/fb%d",
- pPci->domain, pPci->bus, pPci->dev, pPci->func, i);
-
- fd = open(filename, O_RDONLY, 0);
- if (fd < 0) {
- sprintf(filename,
- "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics:fb%d",
- pPci->domain, pPci->bus, pPci->dev, pPci->func, i);
- fd = open(filename, O_RDONLY, 0);
- }
- if (fd >= 0) {
- close(fd);
- sprintf(filename, "/dev/fb%d", i);
-
- fd = open(filename, O_RDWR, 0);
- if (fd != -1) {
- if (ioctl(fd, FBIOGET_FSCREENINFO, (void*) & fix) != -1) {
- if (namep) {
- *namep = xnfalloc(16);
- strncpy(*namep,fix.id,16);
- }
-
- return fd;
- }
- close(fd);
- }
- }
- }
-
- if (namep)
- *namep = NULL;
-
- xf86DrvMsg(-1, X_ERROR, "Unable to find a valid framebuffer device\n");
- return -1;
-}
-
-static int
-fbdev_open(int scrnIndex, char *dev, char** namep)
-{
- struct fb_fix_screeninfo fix;
- int fd;
-
- /* try argument (from XF86Config) first */
- if (dev) {
- fd = open(dev,O_RDWR,0);
- } else {
- /* second: environment variable */
- dev = getenv("FRAMEBUFFER");
- if ((NULL == dev) || ((fd = open(dev,O_RDWR,0)) == -1)) {
- /* last try: default device */
- dev = "/dev/fb0";
- fd = open(dev,O_RDWR,0);
- }
- }
-
- if (fd == -1) {
- xf86DrvMsg(scrnIndex, X_ERROR,
- "open %s: %s\n", dev, strerror(errno));
- return -1;
- }
-
- if (namep) {
- if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)(&fix))) {
- *namep = NULL;
- xf86DrvMsg(scrnIndex, X_ERROR,
- "FBIOGET_FSCREENINFO: %s\n", strerror(errno));
- return -1;
- } else {
- *namep = xnfalloc(16);
- strncpy(*namep,fix.id,16);
- }
- }
- return fd;
-}
-
-/* -------------------------------------------------------------------- */
-
-Bool
-fbdevHWProbe(struct pci_device * pPci, char *device,char **namep)
-{
- int fd;
-
- if (pPci)
- fd = fbdev_open_pci(pPci,namep);
- else
- fd = fbdev_open(-1,device,namep);
-
- if (-1 == fd)
- return FALSE;
- close(fd);
- return TRUE;
-}
-
-Bool
-fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device * pPci, char *device)
-{
- fbdevHWPtr fPtr;
-
- fbdevHWGetRec(pScrn);
- fPtr = FBDEVHWPTR(pScrn);
-
- /* open device */
- if (pPci)
- fPtr->fd = fbdev_open_pci(pPci,NULL);
- else
- fPtr->fd = fbdev_open(pScrn->scrnIndex,device,NULL);
- if (-1 == fPtr->fd) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to open framebuffer device, consult warnings"
- " and/or errors above for possible reasons\n"
- "\t(you may have to look at the server log to see"
- " warnings)\n");
- return FALSE;
- }
-
- /* get current fb device settings */
- if (-1 == ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ioctl FBIOGET_FSCREENINFO: %s\n",
- strerror(errno));
- return FALSE;
- }
- if (-1 == ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ioctl FBIOGET_VSCREENINFO: %s\n",
- strerror(errno));
- return FALSE;
- }
-
- /* we can use the current settings as "buildin mode" */
- fbdev2xfree_timing(&fPtr->var, &fPtr->buildin);
- fPtr->buildin.name = "current";
- fPtr->buildin.next = &fPtr->buildin;
- fPtr->buildin.prev = &fPtr->buildin;
- fPtr->buildin.type |= M_T_BUILTIN;
-
- return TRUE;
-}
-
-char*
-fbdevHWGetName(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- return fPtr->fix.id;
-}
-
-int
-fbdevHWGetDepth(ScrnInfoPtr pScrn, int *fbbpp)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (fbbpp)
- *fbbpp = fPtr->var.bits_per_pixel;
-
- if (fPtr->fix.visual == FB_VISUAL_TRUECOLOR ||
- fPtr->fix.visual == FB_VISUAL_DIRECTCOLOR)
- return fPtr->var.red.length+fPtr->var.green.length+
- fPtr->var.blue.length;
- else
- return fPtr->var.bits_per_pixel;
-}
-
-int
-fbdevHWGetLineLength(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (fPtr->fix.line_length)
- return fPtr->fix.line_length;
- else
- return fPtr->var.xres_virtual*fPtr->var.bits_per_pixel/8;
-}
-
-int
-fbdevHWGetType(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- return fPtr->fix.type;
-}
-
-int
-fbdevHWGetVidmem(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- return fPtr->fix.smem_len;
-}
-
-static Bool
-fbdevHWSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool check)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- struct fb_var_screeninfo req_var = fPtr->var, set_var;
-
- xfree2fbdev_fblayout(pScrn, &req_var);
- xfree2fbdev_timing(mode, &req_var);
-
-#if DEBUG
- print_xfree_mode("init", mode);
- print_fbdev_mode("init", &req_var);
-#endif
-
- set_var = req_var;
-
- if (check)
- set_var.activate = FB_ACTIVATE_TEST;
-
- if (0 != ioctl(fPtr->fd, FBIOPUT_VSCREENINFO, (void*)(&set_var))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
- return FALSE;
- }
-
- if (!fbdev_modes_equal(&set_var, &req_var)) {
- if (!check)
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO succeeded but modified "
- "mode\n");
-#if DEBUG
- print_fbdev_mode("returned", &set_var);
-#endif
- return FALSE;
- }
-
- if (!check)
- fPtr->var = set_var;
-
- return TRUE;
-}
-
-void
-fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
-{
- char **modename;
- DisplayModePtr mode,this,last = pScrn->modes;
-
- if (NULL == pScrn->display->modes)
- return;
-
- pScrn->virtualX = pScrn->display->virtualX;
- pScrn->virtualY = pScrn->display->virtualY;
-
- for (modename = pScrn->display->modes; *modename != NULL; modename++) {
- for (mode = pScrn->monitor->Modes; mode != NULL; mode = mode->next)
- if (0 == strcmp(mode->name,*modename))
- break;
- if (NULL == mode) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "\tmode \"%s\" not found\n", *modename);
- continue;
- }
-
- if (!fbdevHWSetMode(pScrn, mode, TRUE)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "\tmode \"%s\" test failed\n", *modename);
- continue;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "\tmode \"%s\" ok\n", *modename);
-
- if (pScrn->virtualX < mode->HDisplay)
- pScrn->virtualX = mode->HDisplay;
- if (pScrn->virtualY < mode->VDisplay)
- pScrn->virtualY = mode->VDisplay;
-
- if (NULL == pScrn->modes) {
- this = pScrn->modes = xf86DuplicateMode(mode);
- this->next = this;
- this->prev = this;
- } else {
- this = xf86DuplicateMode(mode);
- this->next = pScrn->modes;
- this->prev = last;
- last->next = this;
- pScrn->modes->prev = this;
- }
- last = this;
- }
-}
-
-DisplayModePtr
-fbdevHWGetBuildinMode(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- return &fPtr->buildin;
-}
-
-void
-fbdevHWUseBuildinMode(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- pScrn->modes = &fPtr->buildin;
- pScrn->virtualX = pScrn->display->virtualX;
- pScrn->virtualY = pScrn->display->virtualY;
- if (pScrn->virtualX < fPtr->buildin.HDisplay)
- pScrn->virtualX = fPtr->buildin.HDisplay;
- if (pScrn->virtualY < fPtr->buildin.VDisplay)
- pScrn->virtualY = fPtr->buildin.VDisplay;
-}
-
-/* -------------------------------------------------------------------- */
-
-static void
-calculateFbmem_len(fbdevHWPtr fPtr)
-{
- fPtr->fboff = (unsigned long) fPtr->fix.smem_start & ~PAGE_MASK;
- fPtr->fbmem_len = (fPtr->fboff+fPtr->fix.smem_len+~PAGE_MASK) &
- PAGE_MASK;
-}
-
-
-void*
-fbdevHWMapVidmem(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (NULL == fPtr->fbmem) {
- calculateFbmem_len(fPtr);
- fPtr->fbmem = mmap(NULL, fPtr->fbmem_len, PROT_READ | PROT_WRITE,
- MAP_SHARED, fPtr->fd, 0);
- if (-1 == (long)fPtr->fbmem) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "mmap fbmem: %s\n", strerror(errno));
- fPtr->fbmem = NULL;
- } else {
- /* Perhaps we'd better add fboff to fbmem and return 0 in
- fbdevHWLinearOffset()? Of course we then need to mask
- fPtr->fbmem with PAGE_MASK in fbdevHWUnmapVidmem() as
- well. [geert] */
- }
- }
- pScrn->memPhysBase = (unsigned long)fPtr->fix.smem_start & (unsigned long)(PAGE_MASK);
- pScrn->fbOffset = (unsigned long)fPtr->fix.smem_start & (unsigned long)(~PAGE_MASK);
- return fPtr->fbmem;
-}
-
-int
-fbdevHWLinearOffset(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- return fPtr->fboff;
-}
-
-Bool
-fbdevHWUnmapVidmem(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (NULL != fPtr->fbmem) {
- if (-1 == munmap(fPtr->fbmem, fPtr->fbmem_len))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "munmap fbmem: %s\n", strerror(errno));
- fPtr->fbmem = NULL;
- }
- return TRUE;
-}
-
-void*
-fbdevHWMapMMIO(ScrnInfoPtr pScrn)
-{
- unsigned int mmio_off;
-
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (NULL == fPtr->mmio) {
- /* tell the kernel not to use accels to speed up console scrolling */
- fPtr->var.accel_flags = 0;
- if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
- return FALSE;
- }
- mmio_off = (unsigned long) fPtr->fix.mmio_start & ~PAGE_MASK;
- fPtr->mmio_len = (mmio_off+fPtr->fix.mmio_len+~PAGE_MASK) &
- PAGE_MASK;
- if (NULL == fPtr->fbmem)
- calculateFbmem_len(fPtr);
- fPtr->mmio = mmap(NULL, fPtr->mmio_len, PROT_READ | PROT_WRITE,
- MAP_SHARED, fPtr->fd, fPtr->fbmem_len);
- if (-1 == (long)fPtr->mmio) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "mmap mmio: %s\n", strerror(errno));
- fPtr->mmio = NULL;
- } else
- fPtr->mmio += mmio_off;
- }
- return fPtr->mmio;
-}
-
-Bool
-fbdevHWUnmapMMIO(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (NULL != fPtr->mmio) {
- if (-1 == munmap((void *)((unsigned long)fPtr->mmio & PAGE_MASK), fPtr->mmio_len))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "munmap mmio: %s\n", strerror(errno));
- fPtr->mmio = NULL;
- /* FIXME: restore var.accel_flags [geert] */
- }
- return TRUE;
-}
-
-/* -------------------------------------------------------------------- */
-
-Bool
-fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- pScrn->vtSema = TRUE;
-
- /* set */
- if (!fbdevHWSetMode(pScrn, mode, FALSE))
- return FALSE;
-
- /* read back */
- if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOGET_FSCREENINFO: %s\n", strerror(errno));
- return FALSE;
- }
- if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOGET_VSCREENINFO: %s\n", strerror(errno));
- return FALSE;
- }
-
- if (pScrn->defaultVisual == TrueColor ||
- pScrn->defaultVisual == DirectColor) {
- /* XXX: This is a hack, but it should be a NOP for all the setups that
- * worked before and actually seems to fix some others...
- */
- pScrn->offset.red = fPtr->var.red.offset;
- pScrn->offset.green = fPtr->var.green.offset;
- pScrn->offset.blue = fPtr->var.blue.offset;
- pScrn->mask.red = ((1 << fPtr->var.red.length) - 1) << fPtr->var.red.offset;
- pScrn->mask.green = ((1 << fPtr->var.green.length) - 1) << fPtr->var.green.offset;
- pScrn->mask.blue = ((1 << fPtr->var.blue.length) - 1) << fPtr->var.blue.offset;
- }
-
- return TRUE;
-}
-
-/* -------------------------------------------------------------------- */
-/* video mode save/restore */
-void
-fbdevHWSave(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->saved_var)))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOGET_VSCREENINFO: %s\n", strerror(errno));
-}
-
-void
-fbdevHWRestore(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->saved_var)))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
-}
-
-/* -------------------------------------------------------------------- */
-/* callback for xf86HandleColormaps */
-
-void
-fbdevHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
- LOCO *colors, VisualPtr pVisual)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- struct fb_cmap cmap;
- unsigned short red,green,blue;
- int i;
-
- cmap.len = 1;
- cmap.red = &red;
- cmap.green = &green;
- cmap.blue = &blue;
- cmap.transp = NULL;
- for (i = 0; i < numColors; i++) {
- cmap.start = indices[i];
- red = (colors[indices[i]].red << 8) |
- colors[indices[i]].red;
- green = (colors[indices[i]].green << 8) |
- colors[indices[i]].green;
- blue = (colors[indices[i]].blue << 8) |
- colors[indices[i]].blue;
- if (-1 == ioctl(fPtr->fd,FBIOPUTCMAP,(void*)&cmap))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUTCMAP: %s\n", strerror(errno));
- }
-}
-
-/* -------------------------------------------------------------------- */
-/* these can be hooked directly into ScrnInfoRec */
-
-ModeStatus
-fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
- if (!fbdevHWSetMode(pScrn, mode, TRUE))
- return MODE_BAD;
-
- return MODE_OK;
-}
-
-Bool
-fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
-
- if (!fbdevHWSetMode(pScrn, mode, FALSE))
- return FALSE;
-
- return TRUE;
-}
-
-void
-fbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if ( x < 0 || x + fPtr->var.xres > fPtr->var.xres_virtual ||
- y < 0 || y + fPtr->var.yres > fPtr->var.yres_virtual )
- return;
-
- fPtr->var.xoffset = x;
- fPtr->var.yoffset = y;
- if (-1 == ioctl(fPtr->fd,FBIOPAN_DISPLAY,(void*)&fPtr->var))
- xf86DrvMsgVerb(scrnIndex, X_WARNING, 5,
- "FBIOPAN_DISPLAY: %s\n", strerror(errno));
-}
-
-Bool
-fbdevHWEnterVT(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
- if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
- return FALSE;
- fbdevHWAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
- return TRUE;
-}
-
-void
-fbdevHWLeaveVT(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
- fbdevHWRestore(pScrn);
-}
-
-void
-fbdevHWDPMSSet(ScrnInfoPtr pScrn, int mode, int flags)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- unsigned long fbmode;
-
- if (!pScrn->vtSema)
- return;
-
- switch (mode) {
- case DPMSModeOn:
- fbmode = 0;
- break;
- case DPMSModeStandby:
- fbmode = 2;
- break;
- case DPMSModeSuspend:
- fbmode = 3;
- break;
- case DPMSModeOff:
- fbmode = 4;
- break;
- default:
- return;
- }
-
- if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)fbmode))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOBLANK: %s\n", strerror(errno));
-}
-
-Bool
-fbdevHWSaveScreen(ScreenPtr pScreen, int mode)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- unsigned long unblank;
-
- if (!pScrn->vtSema)
- return TRUE;
-
- unblank = xf86IsUnblank(mode);
-
- if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)(1-unblank))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOBLANK: %s\n", strerror(errno));
- return FALSE;
- }
-
- return TRUE;
-}
-
-xf86SwitchModeProc *
-fbdevHWSwitchModeWeak(void) { return fbdevHWSwitchMode; }
-
-xf86AdjustFrameProc *
-fbdevHWAdjustFrameWeak(void) { return fbdevHWAdjustFrame; }
-
-xf86EnterVTProc *
-fbdevHWEnterVTWeak(void) { return fbdevHWEnterVT; }
-
-xf86LeaveVTProc *
-fbdevHWLeaveVTWeak(void) { return fbdevHWLeaveVT; }
-
-xf86ValidModeProc *
-fbdevHWValidModeWeak(void) { return fbdevHWValidMode; }
-
-xf86DPMSSetProc *
-fbdevHWDPMSSetWeak(void) { return fbdevHWDPMSSet; }
-
-xf86LoadPaletteProc *
-fbdevHWLoadPaletteWeak(void) { return fbdevHWLoadPalette; }
-
-SaveScreenProcPtr
-fbdevHWSaveScreenWeak(void) { return fbdevHWSaveScreen; }
+/* all driver need this */ +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <string.h> + +#include "xf86.h" +#include "xf86_OSproc.h" + +/* pci stuff */ +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "xf86cmap.h" + +#include "fbdevhw.h" +#include "fbpriv.h" +#include "globals.h" +#include <X11/extensions/dpmsconst.h> + +#define PAGE_MASK (~(getpagesize() - 1)) + +static XF86ModuleVersionInfo fbdevHWVersRec = +{ + "fbdevhw", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + 0, 0, 2, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_NONE, + {0,0,0,0} +}; + +_X_EXPORT XF86ModuleData fbdevhwModuleData = { + &fbdevHWVersRec, + NULL, + NULL +}; + +#include <fcntl.h> +#include <errno.h> +#include <sys/mman.h> +#include <sys/ioctl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +/* -------------------------------------------------------------------- */ +/* our private data, and two functions to allocate/free this */ + +#define FBDEVHWPTRLVAL(p) (p)->privates[fbdevHWPrivateIndex].ptr +#define FBDEVHWPTR(p) ((fbdevHWPtr)(FBDEVHWPTRLVAL(p))) + +static int fbdevHWPrivateIndex = -1; + +typedef struct { + /* framebuffer device: filename (/dev/fb*), handle, more */ + char* device; + int fd; + void* fbmem; + unsigned int fbmem_len; + unsigned int fboff; + char* mmio; + unsigned int mmio_len; + + /* current hardware state */ + struct fb_fix_screeninfo fix; + struct fb_var_screeninfo var; + + /* saved video mode */ + struct fb_var_screeninfo saved_var; + + /* buildin video mode */ + DisplayModeRec buildin; + +} fbdevHWRec, *fbdevHWPtr; + +Bool +fbdevHWGetRec(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr; + + if (fbdevHWPrivateIndex < 0) + fbdevHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); + + if (FBDEVHWPTR(pScrn) != NULL) + return TRUE; + + fPtr = FBDEVHWPTRLVAL(pScrn) = xnfcalloc(sizeof(fbdevHWRec), 1); + return TRUE; +} + +void +fbdevHWFreeRec(ScrnInfoPtr pScrn) +{ + if (fbdevHWPrivateIndex < 0) + return; + if (FBDEVHWPTR(pScrn) == NULL) + return; + free(FBDEVHWPTR(pScrn)); + FBDEVHWPTRLVAL(pScrn) = NULL; +} + +int +fbdevHWGetFD(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr; + + fbdevHWGetRec(pScrn); + fPtr = FBDEVHWPTR(pScrn); + + return fPtr->fd; +} + +/* -------------------------------------------------------------------- */ +/* some helpers for printing debug informations */ + +#if DEBUG +static void +print_fbdev_mode(char *txt, struct fb_var_screeninfo *var) +{ + ErrorF( "fbdev %s mode:\t%d %d %d %d %d %d %d %d %d %d %d:%d:%d\n", + txt,var->pixclock, + var->xres, var->right_margin, var->hsync_len, var->left_margin, + var->yres, var->lower_margin, var->vsync_len, var->upper_margin, + var->bits_per_pixel, + var->red.length, var->green.length, var->blue.length); +} + +static void +print_xfree_mode(char *txt, DisplayModePtr mode) +{ + ErrorF( "xfree %s mode:\t%d %d %d %d %d %d %d %d %d\n", + txt,mode->Clock, + mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal, + mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal); +} +#endif + +/* -------------------------------------------------------------------- */ +/* Convert timings between the XFree and the Frame Buffer Device */ + +static void +xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var) +{ + var->xres_virtual = pScrn->displayWidth ? pScrn->displayWidth : + pScrn->virtualX; + var->yres_virtual = pScrn->virtualY; + var->bits_per_pixel = pScrn->bitsPerPixel; + if (pScrn->defaultVisual == TrueColor || + pScrn->defaultVisual == DirectColor) { + var->red.length = pScrn->weight.red; + var->green.length = pScrn->weight.green; + var->blue.length = pScrn->weight.blue; + } else { + var->red.length = 8; + var->green.length = 8; + var->blue.length = 8; + } +} + +static void +xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var) +{ + var->xres = mode->HDisplay; + var->yres = mode->VDisplay; + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; + var->xoffset = var->yoffset = 0; + var->pixclock = mode->Clock ? 1000000000/mode->Clock : 0; + var->right_margin = mode->HSyncStart-mode->HDisplay; + var->hsync_len = mode->HSyncEnd-mode->HSyncStart; + var->left_margin = mode->HTotal-mode->HSyncEnd; + var->lower_margin = mode->VSyncStart-mode->VDisplay; + var->vsync_len = mode->VSyncEnd-mode->VSyncStart; + var->upper_margin = mode->VTotal-mode->VSyncEnd; + var->sync = 0; + if (mode->Flags & V_PHSYNC) + var->sync |= FB_SYNC_HOR_HIGH_ACT; + if (mode->Flags & V_PVSYNC) + var->sync |= FB_SYNC_VERT_HIGH_ACT; + if (mode->Flags & V_PCSYNC) + var->sync |= FB_SYNC_COMP_HIGH_ACT; + if (mode->Flags & V_BCAST) + var->sync |= FB_SYNC_BROADCAST; + if (mode->Flags & V_INTERLACE) + var->vmode = FB_VMODE_INTERLACED; + else if (mode->Flags & V_DBLSCAN) + var->vmode = FB_VMODE_DOUBLE; + else + var->vmode = FB_VMODE_NONINTERLACED; +} + +static Bool +fbdev_modes_equal(struct fb_var_screeninfo *set, struct fb_var_screeninfo *req) +{ + return (set->xres_virtual >= req->xres_virtual && + set->yres_virtual >= req->yres_virtual && + set->bits_per_pixel == req->bits_per_pixel && + set->red.length == req->red.length && + set->green.length == req->green.length && + set->blue.length == req->blue.length && + set->xres == req->xres && set->yres == req->yres && + set->right_margin == req->right_margin && + set->hsync_len == req->hsync_len && + set->left_margin == req->left_margin && + set->lower_margin == req->lower_margin && + set->vsync_len == req->vsync_len && + set->upper_margin == req->upper_margin && + set->sync == req->sync && set->vmode == req->vmode); +} + +static void +fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode) +{ + mode->Clock = var->pixclock ? 1000000000/var->pixclock : 0; + mode->HDisplay = var->xres; + mode->HSyncStart = mode->HDisplay+var->right_margin; + mode->HSyncEnd = mode->HSyncStart+var->hsync_len; + mode->HTotal = mode->HSyncEnd+var->left_margin; + mode->VDisplay = var->yres; + mode->VSyncStart = mode->VDisplay+var->lower_margin; + mode->VSyncEnd = mode->VSyncStart+var->vsync_len; + mode->VTotal = mode->VSyncEnd+var->upper_margin; + mode->Flags = 0; + mode->Flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC; + mode->Flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC; + mode->Flags |= var->sync & FB_SYNC_COMP_HIGH_ACT ? V_PCSYNC : V_NCSYNC; + if (var->sync & FB_SYNC_BROADCAST) + mode->Flags |= V_BCAST; + if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) + mode->Flags |= V_INTERLACE; + else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) + mode->Flags |= V_DBLSCAN; + mode->SynthClock = mode->Clock; + mode->CrtcHDisplay = mode->HDisplay; + mode->CrtcHSyncStart = mode->HSyncStart; + mode->CrtcHSyncEnd = mode->HSyncEnd; + mode->CrtcHTotal = mode->HTotal; + mode->CrtcVDisplay = mode->VDisplay; + mode->CrtcVSyncStart = mode->VSyncStart; + mode->CrtcVSyncEnd = mode->VSyncEnd; + mode->CrtcVTotal = mode->VTotal; + mode->CrtcHAdjusted = FALSE; + mode->CrtcVAdjusted = FALSE; +} + + +/* -------------------------------------------------------------------- */ +/* open correct framebuffer device */ + +/** + * Try to find the framebuffer device for a given PCI device + */ +static int +fbdev_open_pci(struct pci_device * pPci, char **namep) +{ + struct fb_fix_screeninfo fix; + char filename[256]; + int fd, i; + + for (i = 0; i < 8; i++) { + sprintf(filename, + "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics/fb%d", + pPci->domain, pPci->bus, pPci->dev, pPci->func, i); + + fd = open(filename, O_RDONLY, 0); + if (fd < 0) { + sprintf(filename, + "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics:fb%d", + pPci->domain, pPci->bus, pPci->dev, pPci->func, i); + fd = open(filename, O_RDONLY, 0); + } + if (fd >= 0) { + close(fd); + sprintf(filename, "/dev/fb%d", i); + + fd = open(filename, O_RDWR, 0); + if (fd != -1) { + if (ioctl(fd, FBIOGET_FSCREENINFO, (void*) & fix) != -1) { + if (namep) { + *namep = xnfalloc(16); + strncpy(*namep,fix.id,16); + } + + return fd; + } + close(fd); + } + } + } + + if (namep) + *namep = NULL; + + xf86DrvMsg(-1, X_ERROR, "Unable to find a valid framebuffer device\n"); + return -1; +} + +static int +fbdev_open(int scrnIndex, char *dev, char** namep) +{ + struct fb_fix_screeninfo fix; + int fd; + + /* try argument (from XF86Config) first */ + if (dev) { + fd = open(dev,O_RDWR,0); + } else { + /* second: environment variable */ + dev = getenv("FRAMEBUFFER"); + if ((NULL == dev) || ((fd = open(dev,O_RDWR,0)) == -1)) { + /* last try: default device */ + dev = "/dev/fb0"; + fd = open(dev,O_RDWR,0); + } + } + + if (fd == -1) { + xf86DrvMsg(scrnIndex, X_ERROR, + "open %s: %s\n", dev, strerror(errno)); + return -1; + } + + if (namep) { + if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)(&fix))) { + *namep = NULL; + xf86DrvMsg(scrnIndex, X_ERROR, + "FBIOGET_FSCREENINFO: %s\n", strerror(errno)); + return -1; + } else { + *namep = xnfalloc(16); + strncpy(*namep,fix.id,16); + } + } + return fd; +} + +/* -------------------------------------------------------------------- */ + +Bool +fbdevHWProbe(struct pci_device * pPci, char *device,char **namep) +{ + int fd; + + if (pPci) + fd = fbdev_open_pci(pPci,namep); + else + fd = fbdev_open(-1,device,namep); + + if (-1 == fd) + return FALSE; + close(fd); + return TRUE; +} + +Bool +fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device * pPci, char *device) +{ + fbdevHWPtr fPtr; + + fbdevHWGetRec(pScrn); + fPtr = FBDEVHWPTR(pScrn); + + /* open device */ + if (pPci) + fPtr->fd = fbdev_open_pci(pPci,NULL); + else + fPtr->fd = fbdev_open(pScrn->scrnIndex,device,NULL); + if (-1 == fPtr->fd) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to open framebuffer device, consult warnings" + " and/or errors above for possible reasons\n" + "\t(you may have to look at the server log to see" + " warnings)\n"); + return FALSE; + } + + /* get current fb device settings */ + if (-1 == ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ioctl FBIOGET_FSCREENINFO: %s\n", + strerror(errno)); + return FALSE; + } + if (-1 == ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ioctl FBIOGET_VSCREENINFO: %s\n", + strerror(errno)); + return FALSE; + } + + /* we can use the current settings as "buildin mode" */ + fbdev2xfree_timing(&fPtr->var, &fPtr->buildin); + fPtr->buildin.name = "current"; + fPtr->buildin.next = &fPtr->buildin; + fPtr->buildin.prev = &fPtr->buildin; + fPtr->buildin.type |= M_T_BUILTIN; + + return TRUE; +} + +char* +fbdevHWGetName(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + return fPtr->fix.id; +} + +int +fbdevHWGetDepth(ScrnInfoPtr pScrn, int *fbbpp) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + if (fbbpp) + *fbbpp = fPtr->var.bits_per_pixel; + + if (fPtr->fix.visual == FB_VISUAL_TRUECOLOR || + fPtr->fix.visual == FB_VISUAL_DIRECTCOLOR) + return fPtr->var.red.length+fPtr->var.green.length+ + fPtr->var.blue.length; + else + return fPtr->var.bits_per_pixel; +} + +int +fbdevHWGetLineLength(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + if (fPtr->fix.line_length) + return fPtr->fix.line_length; + else + return fPtr->var.xres_virtual*fPtr->var.bits_per_pixel/8; +} + +int +fbdevHWGetType(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + return fPtr->fix.type; +} + +int +fbdevHWGetVidmem(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + return fPtr->fix.smem_len; +} + +static Bool +fbdevHWSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool check) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + struct fb_var_screeninfo req_var = fPtr->var, set_var; + + xfree2fbdev_fblayout(pScrn, &req_var); + xfree2fbdev_timing(mode, &req_var); + +#if DEBUG + print_xfree_mode("init", mode); + print_fbdev_mode("init", &req_var); +#endif + + set_var = req_var; + + if (check) + set_var.activate = FB_ACTIVATE_TEST; + + if (0 != ioctl(fPtr->fd, FBIOPUT_VSCREENINFO, (void*)(&set_var))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FBIOPUT_VSCREENINFO: %s\n", strerror(errno)); + return FALSE; + } + + if (!fbdev_modes_equal(&set_var, &req_var)) { + if (!check) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FBIOPUT_VSCREENINFO succeeded but modified " + "mode\n"); +#if DEBUG + print_fbdev_mode("returned", &set_var); +#endif + return FALSE; + } + + if (!check) + fPtr->var = set_var; + + return TRUE; +} + +void +fbdevHWSetVideoModes(ScrnInfoPtr pScrn) +{ + char **modename; + DisplayModePtr mode,this,last = pScrn->modes; + + if (NULL == pScrn->display->modes) + return; + + pScrn->virtualX = pScrn->display->virtualX; + pScrn->virtualY = pScrn->display->virtualY; + + for (modename = pScrn->display->modes; *modename != NULL; modename++) { + for (mode = pScrn->monitor->Modes; mode != NULL; mode = mode->next) + if (0 == strcmp(mode->name,*modename)) + break; + if (NULL == mode) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "\tmode \"%s\" not found\n", *modename); + continue; + } + + if (!fbdevHWSetMode(pScrn, mode, TRUE)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "\tmode \"%s\" test failed\n", *modename); + continue; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "\tmode \"%s\" ok\n", *modename); + + if (pScrn->virtualX < mode->HDisplay) + pScrn->virtualX = mode->HDisplay; + if (pScrn->virtualY < mode->VDisplay) + pScrn->virtualY = mode->VDisplay; + + if (NULL == pScrn->modes) { + this = pScrn->modes = xf86DuplicateMode(mode); + this->next = this; + this->prev = this; + } else { + this = xf86DuplicateMode(mode); + this->next = pScrn->modes; + this->prev = last; + last->next = this; + pScrn->modes->prev = this; + } + last = this; + } +} + +DisplayModePtr +fbdevHWGetBuildinMode(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + return &fPtr->buildin; +} + +void +fbdevHWUseBuildinMode(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + pScrn->modes = &fPtr->buildin; + pScrn->virtualX = pScrn->display->virtualX; + pScrn->virtualY = pScrn->display->virtualY; + if (pScrn->virtualX < fPtr->buildin.HDisplay) + pScrn->virtualX = fPtr->buildin.HDisplay; + if (pScrn->virtualY < fPtr->buildin.VDisplay) + pScrn->virtualY = fPtr->buildin.VDisplay; +} + +/* -------------------------------------------------------------------- */ + +static void +calculateFbmem_len(fbdevHWPtr fPtr) +{ + fPtr->fboff = (unsigned long) fPtr->fix.smem_start & ~PAGE_MASK; + fPtr->fbmem_len = (fPtr->fboff+fPtr->fix.smem_len+~PAGE_MASK) & + PAGE_MASK; +} + + +void* +fbdevHWMapVidmem(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + if (NULL == fPtr->fbmem) { + calculateFbmem_len(fPtr); + fPtr->fbmem = mmap(NULL, fPtr->fbmem_len, PROT_READ | PROT_WRITE, + MAP_SHARED, fPtr->fd, 0); + if (-1 == (long)fPtr->fbmem) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "mmap fbmem: %s\n", strerror(errno)); + fPtr->fbmem = NULL; + } else { + /* Perhaps we'd better add fboff to fbmem and return 0 in + fbdevHWLinearOffset()? Of course we then need to mask + fPtr->fbmem with PAGE_MASK in fbdevHWUnmapVidmem() as + well. [geert] */ + } + } + pScrn->memPhysBase = (unsigned long)fPtr->fix.smem_start & (unsigned long)(PAGE_MASK); + pScrn->fbOffset = (unsigned long)fPtr->fix.smem_start & (unsigned long)(~PAGE_MASK); + return fPtr->fbmem; +} + +int +fbdevHWLinearOffset(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + return fPtr->fboff; +} + +Bool +fbdevHWUnmapVidmem(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + if (NULL != fPtr->fbmem) { + if (-1 == munmap(fPtr->fbmem, fPtr->fbmem_len)) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "munmap fbmem: %s\n", strerror(errno)); + fPtr->fbmem = NULL; + } + return TRUE; +} + +void* +fbdevHWMapMMIO(ScrnInfoPtr pScrn) +{ + unsigned int mmio_off; + + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + if (NULL == fPtr->mmio) { + /* tell the kernel not to use accels to speed up console scrolling */ + fPtr->var.accel_flags = 0; + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FBIOPUT_VSCREENINFO: %s\n", strerror(errno)); + return FALSE; + } + mmio_off = (unsigned long) fPtr->fix.mmio_start & ~PAGE_MASK; + fPtr->mmio_len = (mmio_off+fPtr->fix.mmio_len+~PAGE_MASK) & + PAGE_MASK; + if (NULL == fPtr->fbmem) + calculateFbmem_len(fPtr); + fPtr->mmio = mmap(NULL, fPtr->mmio_len, PROT_READ | PROT_WRITE, + MAP_SHARED, fPtr->fd, fPtr->fbmem_len); + if (-1 == (long)fPtr->mmio) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "mmap mmio: %s\n", strerror(errno)); + fPtr->mmio = NULL; + } else + fPtr->mmio += mmio_off; + } + return fPtr->mmio; +} + +Bool +fbdevHWUnmapMMIO(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + if (NULL != fPtr->mmio) { + if (-1 == munmap((void *)((unsigned long)fPtr->mmio & PAGE_MASK), fPtr->mmio_len)) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "munmap mmio: %s\n", strerror(errno)); + fPtr->mmio = NULL; + /* FIXME: restore var.accel_flags [geert] */ + } + return TRUE; +} + +/* -------------------------------------------------------------------- */ + +Bool +fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + pScrn->vtSema = TRUE; + + /* set */ + if (!fbdevHWSetMode(pScrn, mode, FALSE)) + return FALSE; + + /* read back */ + if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FBIOGET_FSCREENINFO: %s\n", strerror(errno)); + return FALSE; + } + if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FBIOGET_VSCREENINFO: %s\n", strerror(errno)); + return FALSE; + } + + if (pScrn->defaultVisual == TrueColor || + pScrn->defaultVisual == DirectColor) { + /* XXX: This is a hack, but it should be a NOP for all the setups that + * worked before and actually seems to fix some others... + */ + pScrn->offset.red = fPtr->var.red.offset; + pScrn->offset.green = fPtr->var.green.offset; + pScrn->offset.blue = fPtr->var.blue.offset; + pScrn->mask.red = ((1 << fPtr->var.red.length) - 1) << fPtr->var.red.offset; + pScrn->mask.green = ((1 << fPtr->var.green.length) - 1) << fPtr->var.green.offset; + pScrn->mask.blue = ((1 << fPtr->var.blue.length) - 1) << fPtr->var.blue.offset; + } + + return TRUE; +} + +/* -------------------------------------------------------------------- */ +/* video mode save/restore */ +void +fbdevHWSave(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->saved_var))) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FBIOGET_VSCREENINFO: %s\n", strerror(errno)); +} + +void +fbdevHWRestore(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->saved_var))) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FBIOPUT_VSCREENINFO: %s\n", strerror(errno)); +} + +/* -------------------------------------------------------------------- */ +/* callback for xf86HandleColormaps */ + +void +fbdevHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO *colors, VisualPtr pVisual) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + struct fb_cmap cmap; + unsigned short red,green,blue; + int i; + + cmap.len = 1; + cmap.red = &red; + cmap.green = &green; + cmap.blue = &blue; + cmap.transp = NULL; + for (i = 0; i < numColors; i++) { + cmap.start = indices[i]; + red = (colors[indices[i]].red << 8) | + colors[indices[i]].red; + green = (colors[indices[i]].green << 8) | + colors[indices[i]].green; + blue = (colors[indices[i]].blue << 8) | + colors[indices[i]].blue; + if (-1 == ioctl(fPtr->fd,FBIOPUTCMAP,(void*)&cmap)) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FBIOPUTCMAP: %s\n", strerror(errno)); + } +} + +/* -------------------------------------------------------------------- */ +/* these can be hooked directly into ScrnInfoRec */ + +ModeStatus +fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + if (!fbdevHWSetMode(pScrn, mode, TRUE)) + return MODE_BAD; + + return MODE_OK; +} + +Bool +fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + + if (!fbdevHWSetMode(pScrn, mode, FALSE)) + return FALSE; + + return TRUE; +} + +void +fbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + if ( x < 0 || x + fPtr->var.xres > fPtr->var.xres_virtual || + y < 0 || y + fPtr->var.yres > fPtr->var.yres_virtual ) + return; + + fPtr->var.xoffset = x; + fPtr->var.yoffset = y; + if (-1 == ioctl(fPtr->fd,FBIOPAN_DISPLAY,(void*)&fPtr->var)) + xf86DrvMsgVerb(scrnIndex, X_WARNING, 5, + "FBIOPAN_DISPLAY: %s\n", strerror(errno)); +} + +Bool +fbdevHWEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) + return FALSE; + fbdevHWAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + return TRUE; +} + +void +fbdevHWLeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + fbdevHWRestore(pScrn); +} + +void +fbdevHWDPMSSet(ScrnInfoPtr pScrn, int mode, int flags) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + unsigned long fbmode; + + if (!pScrn->vtSema) + return; + + switch (mode) { + case DPMSModeOn: + fbmode = 0; + break; + case DPMSModeStandby: + fbmode = 2; + break; + case DPMSModeSuspend: + fbmode = 3; + break; + case DPMSModeOff: + fbmode = 4; + break; + default: + return; + } + + if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)fbmode)) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FBIOBLANK: %s\n", strerror(errno)); +} + +Bool +fbdevHWSaveScreen(ScreenPtr pScreen, int mode) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + unsigned long unblank; + + if (!pScrn->vtSema) + return TRUE; + + unblank = xf86IsUnblank(mode); + + if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)(1-unblank))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FBIOBLANK: %s\n", strerror(errno)); + return FALSE; + } + + return TRUE; +} + +xf86SwitchModeProc * +fbdevHWSwitchModeWeak(void) { return fbdevHWSwitchMode; } + +xf86AdjustFrameProc * +fbdevHWAdjustFrameWeak(void) { return fbdevHWAdjustFrame; } + +xf86EnterVTProc * +fbdevHWEnterVTWeak(void) { return fbdevHWEnterVT; } + +xf86LeaveVTProc * +fbdevHWLeaveVTWeak(void) { return fbdevHWLeaveVT; } + +xf86ValidModeProc * +fbdevHWValidModeWeak(void) { return fbdevHWValidMode; } + +xf86DPMSSetProc * +fbdevHWDPMSSetWeak(void) { return fbdevHWDPMSSet; } + +xf86LoadPaletteProc * +fbdevHWLoadPaletteWeak(void) { return fbdevHWLoadPalette; } + +SaveScreenProcPtr +fbdevHWSaveScreenWeak(void) { return fbdevHWSaveScreen; } diff --git a/xorg-server/hw/xfree86/modes/xf86RandR12.c b/xorg-server/hw/xfree86/modes/xf86RandR12.c index bd8421713..cb20d1c35 100644 --- a/xorg-server/hw/xfree86/modes/xf86RandR12.c +++ b/xorg-server/hw/xfree86/modes/xf86RandR12.c @@ -1,1824 +1,1823 @@ -/*
- * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#else
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#endif
-
-#include "xf86.h"
-#include "os.h"
-#include "globals.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86DDC.h"
-#include "mipointer.h"
-#include "windowstr.h"
-#include "inputstr.h"
-#include <randrstr.h>
-#include <X11/extensions/render.h>
-
-#include "xf86Crtc.h"
-#include "xf86RandR12.h"
-
-typedef struct _xf86RandR12Info {
- int virtualX;
- int virtualY;
- int mmWidth;
- int mmHeight;
- int maxX;
- int maxY;
- int pointerX;
- int pointerY;
- Rotation rotation; /* current mode */
- Rotation supported_rotations; /* driver supported */
-
- /* Used to wrap EnterVT so we can re-probe the outputs when a laptop unsuspends
- * (actually, any time that we switch back into our VT).
- *
- * See https://bugs.freedesktop.org/show_bug.cgi?id=21554
- */
- xf86EnterVTProc *orig_EnterVT;
-} XF86RandRInfoRec, *XF86RandRInfoPtr;
-
-#ifdef RANDR_12_INTERFACE
-static Bool xf86RandR12Init12 (ScreenPtr pScreen);
-static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen);
-#endif
-
-static int xf86RandR12Generation;
-
-static DevPrivateKeyRec xf86RandR12KeyRec;
-static DevPrivateKey xf86RandR12Key;
-#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \
- dixLookupPrivate(&(p)->devPrivates, xf86RandR12Key))
-
-
-static int
-xf86RandR12ModeRefresh (DisplayModePtr mode)
-{
- if (mode->VRefresh)
- return (int) (mode->VRefresh + 0.5);
- else
- return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
-}
-
-/* Adapt panning area; return TRUE if panning area was valid without adaption */
-static int
-xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight)
-{
- int ret = TRUE;
-
- if (crtc->version < 2)
- return FALSE;
-
- if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1) {
- /* Panning in X is disabled */
- if (crtc->panningTotalArea.x1 || crtc->panningTotalArea.x2)
- /* Illegal configuration -> fail/disable */
- ret = FALSE;
- crtc->panningTotalArea.x1 = crtc->panningTotalArea.x2 = 0;
- crtc->panningTrackingArea.x1 = crtc->panningTrackingArea.x2 = 0;
- crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
- } else {
- /* Panning in X is enabled */
- if (crtc->panningTotalArea.x1 < 0) {
- /* Panning region outside screen -> move inside */
- crtc->panningTotalArea.x2 -= crtc->panningTotalArea.x1;
- crtc->panningTotalArea.x1 = 0;
- ret = FALSE;
- }
- if (crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay) {
- /* Panning region smaller than displayed area -> crop to displayed area */
- crtc->panningTotalArea.x2 = crtc->panningTotalArea.x1 + crtc->mode.HDisplay;
- ret = FALSE;
- }
- if (crtc->panningTotalArea.x2 > screenWidth) {
- /* Panning region larger than screen -> move inside, then crop to screen */
- crtc->panningTotalArea.x1 -= crtc->panningTotalArea.x2 - screenWidth;
- crtc->panningTotalArea.x2 = screenWidth;
- ret = FALSE;
- if (crtc->panningTotalArea.x1 < 0)
- crtc->panningTotalArea.x1 = 0;
- }
- if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay) {
- /* Borders too large -> set to 0 */
- crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
- ret = FALSE;
- }
- }
-
- if (crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) {
- /* Panning in Y is disabled */
- if (crtc->panningTotalArea.y1 || crtc->panningTotalArea.y2)
- /* Illegal configuration -> fail/disable */
- ret = FALSE;
- crtc->panningTotalArea.y1 = crtc->panningTotalArea.y2 = 0;
- crtc->panningTrackingArea.y1 = crtc->panningTrackingArea.y2 = 0;
- crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
- } else {
- /* Panning in Y is enabled */
- if (crtc->panningTotalArea.y1 < 0) {
- /* Panning region outside screen -> move inside */
- crtc->panningTotalArea.y2 -= crtc->panningTotalArea.y1;
- crtc->panningTotalArea.y1 = 0;
- ret = FALSE;
- }
- if (crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay) {
- /* Panning region smaller than displayed area -> crop to displayed area */
- crtc->panningTotalArea.y2 = crtc->panningTotalArea.y1 + crtc->mode.VDisplay;
- ret = FALSE;
- }
- if (crtc->panningTotalArea.y2 > screenHeight) {
- /* Panning region larger than screen -> move inside, then crop to screen */
- crtc->panningTotalArea.y1 -= crtc->panningTotalArea.y2 - screenHeight;
- crtc->panningTotalArea.y2 = screenHeight;
- ret = FALSE;
- if (crtc->panningTotalArea.y1 < 0)
- crtc->panningTotalArea.y1 = 0;
- }
- if (crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) {
- /* Borders too large -> set to 0 */
- crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
- ret = FALSE;
- }
- }
-
- return ret;
-}
-
-/*
- * The heart of the panning operation:
- *
- * Given a frame buffer position (fb_x, fb_y),
- * and a crtc position (crtc_x, crtc_y),
- * and a transform matrix which maps frame buffer to crtc,
- * compute a panning position (pan_x, pan_y) that
- * makes the resulting transform line those two up
- */
-
-static void
-xf86ComputeCrtcPan (Bool transform_in_use,
- struct pixman_f_transform *m,
- double screen_x, double screen_y,
- double crtc_x, double crtc_y,
- int old_pan_x, int old_pan_y,
- int *new_pan_x, int *new_pan_y)
-{
- if (transform_in_use) {
- /*
- * Given the current transform, M, the current position
- * on the Screen, S, and the desired position on the CRTC,
- * C, compute a translation, T, such that:
- *
- * M T S = C
- *
- * where T is of the form
- *
- * | 1 0 dx |
- * | 0 1 dy |
- * | 0 0 1 |
- *
- * M T S =
- * | M00 Sx + M01 Sy + M00 dx + M01 dy + M02 | | Cx F |
- * | M10 Sx + M11 Sy + M10 dx + M11 dy + M12 | = | Cy F |
- * | M20 Sx + M21 Sy + M20 dx + M21 dy + M22 | | F |
- *
- * R = M S
- *
- * Cx F = M00 dx + M01 dy + R0
- * Cy F = M10 dx + M11 dy + R1
- * F = M20 dx + M21 dy + R2
- *
- * Zero out dx, then dy
- *
- * F (Cx M10 - Cy M00) =
- * (M10 M01 - M00 M11) dy + M10 R0 - M00 R1
- * F (M10 - Cy M20) =
- * (M10 M21 - M20 M11) dy + M10 R2 - M20 R1
- *
- * F (Cx M11 - Cy M01) =
- * (M11 M00 - M01 M10) dx + M11 R0 - M01 R1
- * F (M11 - Cy M21) =
- * (M11 M20 - M21 M10) dx + M11 R2 - M21 R1
- *
- * Make some temporaries
- *
- * T = | Cx M10 - Cy M00 |
- * | Cx M11 - Cy M01 |
- *
- * U = | M10 M01 - M00 M11 |
- * | M11 M00 - M01 M10 |
- *
- * Q = | M10 R0 - M00 R1 |
- * | M11 R0 - M01 R1 |
- *
- * P = | M10 - Cy M20 |
- * | M11 - Cy M21 |
- *
- * W = | M10 M21 - M20 M11 |
- * | M11 M20 - M21 M10 |
- *
- * V = | M10 R2 - M20 R1 |
- * | M11 R2 - M21 R1 |
- *
- * Rewrite:
- *
- * F T0 = U0 dy + Q0
- * F P0 = W0 dy + V0
- * F T1 = U1 dx + Q1
- * F P1 = W1 dx + V1
- *
- * Solve for F (two ways)
- *
- * F (W0 T0 - U0 P0) = W0 Q0 - U0 V0
- *
- * W0 Q0 - U0 V0
- * F = -------------
- * W0 T0 - U0 P0
- *
- * F (W1 T1 - U1 P1) = W1 Q1 - U1 V1
- *
- * W1 Q1 - U1 V1
- * F = -------------
- * W1 T1 - U1 P1
- *
- * We'll use which ever solution works (denominator != 0)
- *
- * Finally, solve for dx and dy:
- *
- * dx = (F T1 - Q1) / U1
- * dx = (F P1 - V1) / W1
- *
- * dy = (F T0 - Q0) / U0
- * dy = (F P0 - V0) / W0
- */
- double r[3];
- double q[2], u[2], t[2], v[2], w[2], p[2];
- double f;
- struct pict_f_vector d;
- int i;
-
- /* Get the un-normalized crtc coordinates again */
- for (i = 0; i < 3; i++)
- r[i] = m->m[i][0] * screen_x + m->m[i][1] * screen_y + m->m[i][2];
-
- /* Combine values into temporaries */
- for (i = 0; i < 2; i++) {
- q[i] = m->m[1][i] * r[0] - m->m[0][i] * r[1];
- u[i] = m->m[1][i] * m->m[0][1-i] - m->m[0][i] * m->m[1][1-i];
- t[i] = m->m[1][i] * crtc_x - m->m[0][i] * crtc_y;
-
- v[i] = m->m[1][i] * r[2] - m->m[2][i] * r[1];
- w[i] = m->m[1][i] * m->m[2][1-i] - m->m[2][i] * m->m[1][1-i];
- p[i] = m->m[1][i] - m->m[2][i] * crtc_y;
- }
-
- /* Find a way to compute f */
- f = 0;
- for (i = 0; i < 2; i++) {
- double a = w[i] * q[i] - u[i] * v[i];
- double b = w[i] * t[i] - u[i] * p[i];
- if (b != 0) {
- f = a/b;
- break;
- }
- }
-
- /* Solve for the resulting transform vector */
- for (i = 0; i < 2; i++) {
- if (u[i])
- d.v[1-i] = (t[i] * f - q[i]) / u[i];
- else if (w[1])
- d.v[1-i] = (p[i] * f - v[i]) / w[i];
- else
- d.v[1-i] = 0;
- }
- *new_pan_x = old_pan_x - floor (d.v[0] + 0.5);
- *new_pan_y = old_pan_y - floor (d.v[1] + 0.5);
- } else {
- *new_pan_x = screen_x - crtc_x;
- *new_pan_y = screen_y - crtc_y;
- }
-}
-
-static void
-xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
-{
- int newX, newY;
- int width, height;
- Bool panned = FALSE;
-
- if (crtc->version < 2)
- return;
-
- if (! crtc->enabled ||
- (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 &&
- crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1))
- return;
-
- newX = crtc->x;
- newY = crtc->y;
- width = crtc->mode.HDisplay;
- height = crtc->mode.VDisplay;
-
- if ((crtc->panningTrackingArea.x2 <= crtc->panningTrackingArea.x1 ||
- (x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2)) &&
- (crtc->panningTrackingArea.y2 <= crtc->panningTrackingArea.y1 ||
- (y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2)))
- {
- struct pict_f_vector c;
-
- /*
- * Pre-clip the mouse position to the panning area so that we don't
- * push the crtc outside. This doesn't deal with changes to the
- * panning values, only mouse position changes.
- */
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1)
- {
- if (x < crtc->panningTotalArea.x1)
- x = crtc->panningTotalArea.x1;
- if (x >= crtc->panningTotalArea.x2)
- x = crtc->panningTotalArea.x2 - 1;
- }
- if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1)
- {
- if (y < crtc->panningTotalArea.y1)
- y = crtc->panningTotalArea.y1;
- if (y >= crtc->panningTotalArea.y2)
- y = crtc->panningTotalArea.y2 - 1;
- }
-
- c.v[0] = x;
- c.v[1] = y;
- c.v[2] = 1.0;
- if (crtc->transform_in_use) {
- pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &c);
- } else {
- c.v[0] -= crtc->x;
- c.v[1] -= crtc->y;
- }
-
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
- if (c.v[0] < crtc->panningBorder[0]) {
- c.v[0] = crtc->panningBorder[0];
- panned = TRUE;
- }
- if (c.v[0] >= width - crtc->panningBorder[2]) {
- c.v[0] = width - crtc->panningBorder[2] - 1;
- panned = TRUE;
- }
- }
- if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
- if (c.v[1] < crtc->panningBorder[1]) {
- c.v[1] = crtc->panningBorder[1];
- panned = TRUE;
- }
- if (c.v[1] >= height - crtc->panningBorder[3]) {
- c.v[1] = height - crtc->panningBorder[3] - 1;
- panned = TRUE;
- }
- }
- if (panned)
- xf86ComputeCrtcPan (crtc->transform_in_use,
- &crtc->f_framebuffer_to_crtc,
- x, y, c.v[0], c.v[1],
- newX, newY, &newX, &newY);
- }
-
- /*
- * Ensure that the crtc is within the panning region.
- *
- * XXX This computation only works when we do not have a transform
- * in use.
- */
- if (!crtc->transform_in_use)
- {
- /* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
- if (newX > crtc->panningTotalArea.x2 - width)
- newX = crtc->panningTotalArea.x2 - width;
- if (newX < crtc->panningTotalArea.x1)
- newX = crtc->panningTotalArea.x1;
- }
- if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
- if (newY > crtc->panningTotalArea.y2 - height)
- newY = crtc->panningTotalArea.y2 - height;
- if (newY < crtc->panningTotalArea.y1)
- newY = crtc->panningTotalArea.y1;
- }
- }
- if (newX != crtc->x || newY != crtc->y)
- xf86CrtcSetOrigin (crtc, newX, newY);
-}
-
-static Bool
-xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
-{
- RRScreenSizePtr pSize;
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int refresh0 = 60;
- int maxX = 0, maxY = 0;
-
- *rotations = randrp->supported_rotations;
-
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = scrp->virtualX;
- randrp->virtualY = scrp->virtualY;
- }
-
- /* Re-probe the outputs for new monitors or modes */
- if (scrp->vtSema)
- {
- xf86ProbeOutputModes (scrp, 0, 0);
- xf86SetScrnInfoModes (scrp);
- }
-
- for (mode = scrp->modes; ; mode = mode->next)
- {
- int refresh = xf86RandR12ModeRefresh (mode);
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- if (maxX < mode->HDisplay)
- maxX = mode->HDisplay;
- if (maxY < mode->VDisplay)
- maxY = mode->VDisplay;
- }
- if (mode == scrp->modes)
- refresh0 = refresh;
- pSize = RRRegisterSize (pScreen,
- mode->HDisplay, mode->VDisplay,
- randrp->mmWidth, randrp->mmHeight);
- if (!pSize)
- return FALSE;
- RRRegisterRate (pScreen, pSize, refresh);
-
- if (xf86ModesEqual(mode, scrp->currentMode))
- {
- RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
- }
- if (mode->next == scrp->modes)
- break;
- }
-
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- randrp->maxX = maxX;
- randrp->maxY = maxY;
- }
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12SetMode (ScreenPtr pScreen,
- DisplayModePtr mode,
- Bool useVirtual,
- int mmWidth,
- int mmHeight)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- int oldWidth = pScreen->width;
- int oldHeight = pScreen->height;
- int oldmmWidth = pScreen->mmWidth;
- int oldmmHeight = pScreen->mmHeight;
- WindowPtr pRoot = pScreen->root;
- DisplayModePtr currentMode = NULL;
- Bool ret = TRUE;
-
- if (pRoot)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
- if (useVirtual)
- {
- scrp->virtualX = randrp->virtualX;
- scrp->virtualY = randrp->virtualY;
- }
- else
- {
- scrp->virtualX = mode->HDisplay;
- scrp->virtualY = mode->VDisplay;
- }
-
- if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
- {
- /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
- pScreen->width = scrp->virtualY;
- pScreen->height = scrp->virtualX;
- pScreen->mmWidth = mmHeight;
- pScreen->mmHeight = mmWidth;
- }
- else
- {
- pScreen->width = scrp->virtualX;
- pScreen->height = scrp->virtualY;
- pScreen->mmWidth = mmWidth;
- pScreen->mmHeight = mmHeight;
- }
- if (scrp->currentMode == mode) {
- /* Save current mode */
- currentMode = scrp->currentMode;
- /* Reset, just so we ensure the drivers SwitchMode is called */
- scrp->currentMode = NULL;
- }
- /*
- * We know that if the driver failed to SwitchMode to the rotated
- * version, then it should revert back to it's prior mode.
- */
- if (!xf86SwitchMode (pScreen, mode))
- {
- ret = FALSE;
- scrp->virtualX = pScreen->width = oldWidth;
- scrp->virtualY = pScreen->height = oldHeight;
- pScreen->mmWidth = oldmmWidth;
- pScreen->mmHeight = oldmmHeight;
- scrp->currentMode = currentMode;
- }
-
- /*
- * Make sure the layout is correct
- */
- xf86ReconfigureLayout();
-
- /*
- * Make sure the whole screen is visible
- */
- xf86SetViewport (pScreen, pScreen->width, pScreen->height);
- xf86SetViewport (pScreen, 0, 0);
- if (pRoot)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
- return ret;
-}
-
-Bool
-xf86RandR12SetConfig (ScreenPtr pScreen,
- Rotation rotation,
- int rate,
- RRScreenSizePtr pSize)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int pos[MAXDEVICES][2];
- Bool useVirtual = FALSE;
- int maxX = 0, maxY = 0;
- Rotation oldRotation = randrp->rotation;
- DeviceIntPtr dev;
- Bool view_adjusted = FALSE;
-
- randrp->rotation = rotation;
-
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = scrp->virtualX;
- randrp->virtualY = scrp->virtualY;
- }
-
- for (dev = inputInfo.devices; dev; dev = dev->next)
- {
- if (!IsMaster(dev) && !IsFloating(dev))
- continue;
-
- miPointerGetPosition(dev, &pos[dev->id][0], &pos[dev->id][1]);
- }
-
- for (mode = scrp->modes; ; mode = mode->next)
- {
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- if (maxX < mode->HDisplay)
- maxX = mode->HDisplay;
- if (maxY < mode->VDisplay)
- maxY = mode->VDisplay;
- }
- if (mode->HDisplay == pSize->width &&
- mode->VDisplay == pSize->height &&
- (rate == 0 || xf86RandR12ModeRefresh (mode) == rate))
- break;
- if (mode->next == scrp->modes)
- {
- if (pSize->width == randrp->virtualX &&
- pSize->height == randrp->virtualY)
- {
- mode = scrp->modes;
- useVirtual = TRUE;
- break;
- }
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- randrp->maxX = maxX;
- randrp->maxY = maxY;
- }
- return FALSE;
- }
- }
-
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- randrp->maxX = maxX;
- randrp->maxY = maxY;
- }
-
- if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth,
- pSize->mmHeight)) {
- randrp->rotation = oldRotation;
- return FALSE;
- }
-
- /*
- * Move the cursor back where it belongs; SwitchMode repositions it
- * FIXME: duplicated code, see modes/xf86RandR12.c
- */
- for (dev = inputInfo.devices; dev; dev = dev->next)
- {
- if (!IsMaster(dev) && !IsFloating(dev))
- continue;
-
- if (pScreen == miPointerGetScreen(dev)) {
- int px = pos[dev->id][0];
- int py = pos[dev->id][1];
-
- px = (px >= pScreen->width ? (pScreen->width - 1) : px);
- py = (py >= pScreen->height ? (pScreen->height - 1) : py);
-
- /* Setting the viewpoint makes only sense on one device */
- if (!view_adjusted && IsMaster(dev)) {
- xf86SetViewport(pScreen, px, py);
- view_adjusted = TRUE;
- }
-
- (*pScreen->SetCursorPosition) (dev, pScreen, px, py, FALSE);
- }
- }
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12ScreenSetSize (ScreenPtr pScreen,
- CARD16 width,
- CARD16 height,
- CARD32 mmWidth,
- CARD32 mmHeight)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- WindowPtr pRoot = pScreen->root;
- PixmapPtr pScrnPix;
- Bool ret = FALSE;
- int c;
-
- if (xf86RandR12Key) {
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = pScrn->virtualX;
- randrp->virtualY = pScrn->virtualY;
- }
- }
- if (pRoot && pScrn->vtSema)
- (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
-
- /* Let the driver update virtualX and virtualY */
- if (!(*config->funcs->resize)(pScrn, width, height))
- goto finish;
-
- ret = TRUE;
- /* Update panning information */
- for (c = 0; c < config->num_crtc; c++) {
- xf86CrtcPtr crtc = config->crtc[c];
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 ||
- crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
- if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1)
- crtc->panningTotalArea.x2 += width - pScreen->width;
- if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1)
- crtc->panningTotalArea.y2 += height - pScreen->height;
- if (crtc->panningTrackingArea.x2 > crtc->panningTrackingArea.x1)
- crtc->panningTrackingArea.x2 += width - pScreen->width;
- if (crtc->panningTrackingArea.y2 > crtc->panningTrackingArea.y1)
- crtc->panningTrackingArea.y2 += height - pScreen->height;
- xf86RandR13VerifyPanningArea (crtc, width, height);
- xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
- }
- }
-
- pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
- pScreen->width = pScrnPix->drawable.width = width;
- pScreen->height = pScrnPix->drawable.height = height;
- randrp->mmWidth = pScreen->mmWidth = mmWidth;
- randrp->mmHeight = pScreen->mmHeight = mmHeight;
-
- xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
- xf86SetViewport (pScreen, 0, 0);
-
-finish:
- if (pRoot && pScrn->vtSema)
- (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
-#if RANDR_12_INTERFACE
- if (xf86RandR12Key && pScreen->root && ret)
- RRScreenSizeNotify (pScreen);
-#endif
- return ret;
-}
-
-Rotation
-xf86RandR12GetRotation(ScreenPtr pScreen)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
- return randrp->rotation;
-}
-
-Bool
-xf86RandR12CreateScreenResources (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config;
- XF86RandRInfoPtr randrp;
- int c;
- int width, height;
- int mmWidth, mmHeight;
-#ifdef PANORAMIX
- /* XXX disable RandR when using Xinerama */
- if (!noPanoramiXExtension)
- return TRUE;
-#endif
-
- config = XF86_CRTC_CONFIG_PTR(pScrn);
- randrp = XF86RANDRINFO(pScreen);
- /*
- * Compute size of screen
- */
- width = 0; height = 0;
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = config->crtc[c];
- int crtc_width = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
- int crtc_height = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
-
- if (crtc->enabled) {
- if (crtc_width > width)
- width = crtc_width;
- if (crtc_height > height)
- height = crtc_height;
- if (crtc->panningTotalArea.x2 > width)
- width = crtc->panningTotalArea.x2;
- if (crtc->panningTotalArea.y2 > height)
- height = crtc->panningTotalArea.y2;
- }
- }
-
- if (width && height)
- {
- /*
- * Compute physical size of screen
- */
- if (monitorResolution)
- {
- mmWidth = width * 25.4 / monitorResolution;
- mmHeight = height * 25.4 / monitorResolution;
- }
- else
- {
- xf86OutputPtr output = xf86CompatOutput(pScrn);
-
- if (output &&
- output->conf_monitor &&
- (output->conf_monitor->mon_width > 0 &&
- output->conf_monitor->mon_height > 0))
- {
- /*
- * Prefer user configured DisplaySize
- */
- mmWidth = output->conf_monitor->mon_width;
- mmHeight = output->conf_monitor->mon_height;
- }
- else
- {
- /*
- * Otherwise, just set the screen to DEFAULT_DPI
- */
- mmWidth = width * 25.4 / DEFAULT_DPI;
- mmHeight = height * 25.4 / DEFAULT_DPI;
- }
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Setting screen physical size to %d x %d\n",
- mmWidth, mmHeight);
- /*
- * This is the initial setting of the screen size.
- * We have to pre-set it here, otherwise panning would be adapted
- * to the new screen size.
- */
- pScreen->width = width;
- pScreen->height = height;
- xf86RandR12ScreenSetSize (pScreen,
- width,
- height,
- mmWidth,
- mmHeight);
- }
-
- if (xf86RandR12Key == NULL)
- return TRUE;
-
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = pScrn->virtualX;
- randrp->virtualY = pScrn->virtualY;
- }
- xf86CrtcSetScreenSubpixelOrder (pScreen);
-#if RANDR_12_INTERFACE
- if (xf86RandR12CreateScreenResources12 (pScreen))
- return TRUE;
-#endif
- return TRUE;
-}
-
-
-Bool
-xf86RandR12Init (ScreenPtr pScreen)
-{
- rrScrPrivPtr rp;
- XF86RandRInfoPtr randrp;
-
-#ifdef PANORAMIX
- /* XXX disable RandR when using Xinerama */
- if (!noPanoramiXExtension)
- {
- if (xf86NumScreens == 1)
- noPanoramiXExtension = TRUE;
- else
- return TRUE;
- }
-#endif
-
- if (xf86RandR12Generation != serverGeneration)
- xf86RandR12Generation = serverGeneration;
-
- xf86RandR12Key = &xf86RandR12KeyRec;
- if (!dixRegisterPrivateKey(&xf86RandR12KeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
-
- randrp = malloc(sizeof (XF86RandRInfoRec));
- if (!randrp)
- return FALSE;
-
- if (!RRScreenInit(pScreen))
- {
- free(randrp);
- return FALSE;
- }
- rp = rrGetScrPriv(pScreen);
- rp->rrGetInfo = xf86RandR12GetInfo;
- rp->rrSetConfig = xf86RandR12SetConfig;
-
- randrp->virtualX = -1;
- randrp->virtualY = -1;
- randrp->mmWidth = pScreen->mmWidth;
- randrp->mmHeight = pScreen->mmHeight;
-
- randrp->rotation = RR_Rotate_0; /* initial rotated mode */
-
- randrp->supported_rotations = RR_Rotate_0;
-
- randrp->maxX = randrp->maxY = 0;
-
- dixSetPrivate(&pScreen->devPrivates, xf86RandR12Key, randrp);
-
-#if RANDR_12_INTERFACE
- if (!xf86RandR12Init12 (pScreen))
- return FALSE;
-#endif
- return TRUE;
-}
-
-void
-xf86RandR12CloseScreen (ScreenPtr pScreen)
-{
- XF86RandRInfoPtr randrp;
-
- if (xf86RandR12Key == NULL)
- return;
-
- randrp = XF86RANDRINFO(pScreen);
-#if RANDR_12_INTERFACE
- xf86Screens[pScreen->myNum]->EnterVT = randrp->orig_EnterVT;
-#endif
-
- free(randrp);
-}
-
-void
-xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
-{
- XF86RandRInfoPtr randrp;
-#if RANDR_12_INTERFACE
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- int c;
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
-#endif
-
- if (xf86RandR12Key == NULL)
- return;
-
- randrp = XF86RANDRINFO(pScreen);
-#if RANDR_12_INTERFACE
- for (c = 0; c < config->num_crtc; c++) {
- xf86CrtcPtr crtc = config->crtc[c];
-
- RRCrtcSetRotations (crtc->randr_crtc, rotations);
- }
-#endif
- randrp->supported_rotations = rotations;
-}
-
-void
-xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms)
-{
- XF86RandRInfoPtr randrp;
-#if RANDR_13_INTERFACE
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- int c;
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
-#endif
-
- if (xf86RandR12Key == NULL)
- return;
-
- randrp = XF86RANDRINFO(pScreen);
-#if RANDR_13_INTERFACE
- for (c = 0; c < config->num_crtc; c++) {
- xf86CrtcPtr crtc = config->crtc[c];
-
- RRCrtcSetTransformSupport (crtc->randr_crtc, transforms);
- }
-#endif
-}
-
-void
-xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
-{
- ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-
- if (xf86RandR12Generation != serverGeneration ||
- XF86RANDRINFO(pScreen)->virtualX == -1)
- {
- *x = pScrn->virtualX;
- *y = pScrn->virtualY;
- } else {
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
- *x = randrp->virtualX;
- *y = randrp->virtualY;
- }
-}
-
-#if RANDR_12_INTERFACE
-
-#define FLAG_BITS (RR_HSyncPositive | \
- RR_HSyncNegative | \
- RR_VSyncPositive | \
- RR_VSyncNegative | \
- RR_Interlace | \
- RR_DoubleScan | \
- RR_CSync | \
- RR_CSyncPositive | \
- RR_CSyncNegative | \
- RR_HSkewPresent | \
- RR_BCast | \
- RR_PixelMultiplex | \
- RR_DoubleClock | \
- RR_ClockDivideBy2)
-
-static Bool
-xf86RandRModeMatches (RRModePtr randr_mode,
- DisplayModePtr mode)
-{
-#if 0
- if (match_name)
- {
- /* check for same name */
- int len = strlen (mode->name);
- if (randr_mode->mode.nameLength != len) return FALSE;
- if (memcmp (randr_mode->name, mode->name, len) != 0) return FALSE;
- }
-#endif
-
- /* check for same timings */
- if (randr_mode->mode.dotClock / 1000 != mode->Clock) return FALSE;
- if (randr_mode->mode.width != mode->HDisplay) return FALSE;
- if (randr_mode->mode.hSyncStart != mode->HSyncStart) return FALSE;
- if (randr_mode->mode.hSyncEnd != mode->HSyncEnd) return FALSE;
- if (randr_mode->mode.hTotal != mode->HTotal) return FALSE;
- if (randr_mode->mode.hSkew != mode->HSkew) return FALSE;
- if (randr_mode->mode.height != mode->VDisplay) return FALSE;
- if (randr_mode->mode.vSyncStart != mode->VSyncStart) return FALSE;
- if (randr_mode->mode.vSyncEnd != mode->VSyncEnd) return FALSE;
- if (randr_mode->mode.vTotal != mode->VTotal) return FALSE;
-
- /* check for same flags (using only the XF86 valid flag bits) */
- if ((randr_mode->mode.modeFlags & FLAG_BITS) != (mode->Flags & FLAG_BITS))
- return FALSE;
-
- /* everything matches */
- return TRUE;
-}
-
-static Bool
-xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
-{
- ScreenPtr pScreen = randr_crtc->pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- RRModePtr randr_mode = NULL;
- int x;
- int y;
- Rotation rotation;
- int numOutputs;
- RROutputPtr *randr_outputs;
- RROutputPtr randr_output;
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
- xf86OutputPtr output;
- int i, j;
- DisplayModePtr mode = &crtc->mode;
- Bool ret;
-
- randr_outputs = malloc(config->num_output * sizeof (RROutputPtr));
- if (!randr_outputs)
- return FALSE;
- x = crtc->x;
- y = crtc->y;
- rotation = crtc->rotation;
- numOutputs = 0;
- randr_mode = NULL;
- for (i = 0; i < config->num_output; i++)
- {
- output = config->output[i];
- if (output->crtc == crtc)
- {
- randr_output = output->randr_output;
- randr_outputs[numOutputs++] = randr_output;
- /*
- * We make copies of modes, so pointer equality
- * isn't sufficient
- */
- for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++)
- {
- RRModePtr m = (j < randr_output->numModes ?
- randr_output->modes[j] :
- randr_output->userModes[j-randr_output->numModes]);
-
- if (xf86RandRModeMatches (m, mode))
- {
- randr_mode = m;
- break;
- }
- }
- }
- }
- ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
- rotation,
- crtc->transformPresent ? &crtc->transform : NULL,
- numOutputs, randr_outputs);
- free(randr_outputs);
- return ret;
-}
-
-/*
- * Convert a RandR mode to a DisplayMode
- */
-static void
-xf86RandRModeConvert (ScrnInfoPtr scrn,
- RRModePtr randr_mode,
- DisplayModePtr mode)
-{
- memset(mode, 0, sizeof(DisplayModeRec));
- mode->status = MODE_OK;
-
- mode->Clock = randr_mode->mode.dotClock / 1000;
-
- mode->HDisplay = randr_mode->mode.width;
- mode->HSyncStart = randr_mode->mode.hSyncStart;
- mode->HSyncEnd = randr_mode->mode.hSyncEnd;
- mode->HTotal = randr_mode->mode.hTotal;
- mode->HSkew = randr_mode->mode.hSkew;
-
- mode->VDisplay = randr_mode->mode.height;
- mode->VSyncStart = randr_mode->mode.vSyncStart;
- mode->VSyncEnd = randr_mode->mode.vSyncEnd;
- mode->VTotal = randr_mode->mode.vTotal;
- mode->VScan = 0;
-
- mode->Flags = randr_mode->mode.modeFlags & FLAG_BITS;
-
- xf86SetModeCrtc (mode, scrn->adjustFlags);
-}
-
-static Bool
-xf86RandR12CrtcSet (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc,
- RRModePtr randr_mode,
- int x,
- int y,
- Rotation rotation,
- int num_randr_outputs,
- RROutputPtr *randr_outputs)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
- RRTransformPtr transform;
- Bool changed = FALSE;
- int o, ro;
- xf86CrtcPtr *save_crtcs;
- Bool save_enabled = crtc->enabled;
-
- if (!crtc->scrn->vtSema)
- return FALSE;
-
- save_crtcs = malloc(config->num_output * sizeof (xf86CrtcPtr));
- if ((randr_mode != NULL) != crtc->enabled)
- changed = TRUE;
- else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode))
- changed = TRUE;
-
- if (rotation != crtc->rotation)
- changed = TRUE;
-
- transform = RRCrtcGetTransform (randr_crtc);
- if ((transform != NULL) != crtc->transformPresent)
- changed = TRUE;
- else if (transform && memcmp (&transform->transform, &crtc->transform.transform,
- sizeof (transform->transform)) != 0)
- changed = TRUE;
-
- if (x != crtc->x || y != crtc->y)
- changed = TRUE;
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- xf86CrtcPtr new_crtc;
-
- save_crtcs[o] = output->crtc;
-
- if (output->crtc == crtc)
- new_crtc = NULL;
- else
- new_crtc = output->crtc;
- for (ro = 0; ro < num_randr_outputs; ro++)
- if (output->randr_output == randr_outputs[ro])
- {
- new_crtc = crtc;
- break;
- }
- if (new_crtc != output->crtc)
- {
- changed = TRUE;
- output->crtc = new_crtc;
- }
- }
- for (ro = 0; ro < num_randr_outputs; ro++)
- if (randr_outputs[ro]->pendingProperties)
- changed = TRUE;
-
- /* XXX need device-independent mode setting code through an API */
- if (changed)
- {
- crtc->enabled = randr_mode != NULL;
-
- if (randr_mode)
- {
- DisplayModeRec mode;
- RRTransformPtr transform = RRCrtcGetTransform (randr_crtc);
-
- xf86RandRModeConvert (pScrn, randr_mode, &mode);
- if (!xf86CrtcSetModeTransform (crtc, &mode, rotation, transform, x, y))
- {
- crtc->enabled = save_enabled;
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- output->crtc = save_crtcs[o];
- }
- free(save_crtcs);
- return FALSE;
- }
- xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height);
- xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
- /*
- * Save the last successful setting for EnterVT
- */
- crtc->desiredMode = mode;
- crtc->desiredRotation = rotation;
- if (transform) {
- crtc->desiredTransform = *transform;
- crtc->desiredTransformPresent = TRUE;
- } else
- crtc->desiredTransformPresent = FALSE;
-
- crtc->desiredX = x;
- crtc->desiredY = y;
- }
- xf86DisableUnusedFunctions (pScrn);
- }
- free(save_crtcs);
- return xf86RandR12CrtcNotify (randr_crtc);
-}
-
-static Bool
-xf86RandR12CrtcSetGamma (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc)
-{
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
-
- if (crtc->funcs->gamma_set == NULL)
- return FALSE;
-
- if (!crtc->scrn->vtSema)
- return TRUE;
-
- /* Realloc local gamma if needed. */
- if (randr_crtc->gammaSize != crtc->gamma_size) {
- CARD16 *tmp_ptr;
- tmp_ptr = realloc(crtc->gamma_red, 3 * crtc->gamma_size * sizeof (CARD16));
- if (!tmp_ptr)
- return FALSE;
- crtc->gamma_red = tmp_ptr;
- crtc->gamma_green = crtc->gamma_red + crtc->gamma_size;
- crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size;
- }
-
- crtc->gamma_size = randr_crtc->gammaSize;
- memcpy (crtc->gamma_red, randr_crtc->gammaRed, crtc->gamma_size * sizeof (CARD16));
- memcpy (crtc->gamma_green, randr_crtc->gammaGreen, crtc->gamma_size * sizeof (CARD16));
- memcpy (crtc->gamma_blue, randr_crtc->gammaBlue, crtc->gamma_size * sizeof (CARD16));
-
- /* Only set it when the crtc is actually running.
- * Otherwise it will be set when it's activated.
- */
- if (crtc->active)
- crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
- crtc->gamma_blue, crtc->gamma_size);
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12CrtcGetGamma (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc)
-{
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
-
- if (!crtc->gamma_size)
- return FALSE;
-
- if (!crtc->gamma_red || !crtc->gamma_green || !crtc->gamma_blue)
- return FALSE;
-
- /* Realloc randr gamma if needed. */
- if (randr_crtc->gammaSize != crtc->gamma_size) {
- CARD16 *tmp_ptr;
- tmp_ptr = realloc(randr_crtc->gammaRed, 3 * crtc->gamma_size * sizeof (CARD16));
- if (!tmp_ptr)
- return FALSE;
- randr_crtc->gammaRed = tmp_ptr;
- randr_crtc->gammaGreen = randr_crtc->gammaRed + crtc->gamma_size;
- randr_crtc->gammaBlue = randr_crtc->gammaGreen + crtc->gamma_size;
- }
- randr_crtc->gammaSize = crtc->gamma_size;
- memcpy (randr_crtc->gammaRed, crtc->gamma_red, crtc->gamma_size * sizeof (CARD16));
- memcpy (randr_crtc->gammaGreen, crtc->gamma_green, crtc->gamma_size * sizeof (CARD16));
- memcpy (randr_crtc->gammaBlue, crtc->gamma_blue, crtc->gamma_size * sizeof (CARD16));
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12OutputSetProperty (ScreenPtr pScreen,
- RROutputPtr randr_output,
- Atom property,
- RRPropertyValuePtr value)
-{
- xf86OutputPtr output = randr_output->devPrivate;
-
- /* If we don't have any property handler, then we don't care what the
- * user is setting properties to.
- */
- if (output->funcs->set_property == NULL)
- return TRUE;
-
- /*
- * This function gets called even when vtSema is FALSE, as
- * drivers will need to remember the correct value to apply
- * when the VT switch occurs
- */
- return output->funcs->set_property(output, property, value);
-}
-
-static Bool
-xf86RandR13OutputGetProperty (ScreenPtr pScreen,
- RROutputPtr randr_output,
- Atom property)
-{
- xf86OutputPtr output = randr_output->devPrivate;
-
- if (output->funcs->get_property == NULL)
- return TRUE;
-
- /* Should be safe even w/o vtSema */
- return output->funcs->get_property(output, property);
-}
-
-static Bool
-xf86RandR12OutputValidateMode (ScreenPtr pScreen,
- RROutputPtr randr_output,
- RRModePtr randr_mode)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86OutputPtr output = randr_output->devPrivate;
- DisplayModeRec mode;
-
- xf86RandRModeConvert (pScrn, randr_mode, &mode);
- /*
- * This function may be called when vtSema is FALSE, so
- * the underlying function must either avoid touching the hardware
- * or return FALSE when vtSema is FALSE
- */
- if (output->funcs->mode_valid (output, &mode) != MODE_OK)
- return FALSE;
- return TRUE;
-}
-
-static void
-xf86RandR12ModeDestroy (ScreenPtr pScreen, RRModePtr randr_mode)
-{
-}
-
-/**
- * Given a list of xf86 modes and a RandR Output object, construct
- * RandR modes and assign them to the output
- */
-static Bool
-xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
-{
- DisplayModePtr mode;
- RRModePtr *rrmodes = NULL;
- int nmode = 0;
- int npreferred = 0;
- Bool ret = TRUE;
- int pref;
-
- for (mode = modes; mode; mode = mode->next)
- nmode++;
-
- if (nmode) {
- rrmodes = malloc(nmode * sizeof (RRModePtr));
-
- if (!rrmodes)
- return FALSE;
- nmode = 0;
-
- for (pref = 1; pref >= 0; pref--) {
- for (mode = modes; mode; mode = mode->next) {
- if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) {
- xRRModeInfo modeInfo;
- RRModePtr rrmode;
-
- modeInfo.nameLength = strlen (mode->name);
- modeInfo.width = mode->HDisplay;
- modeInfo.dotClock = mode->Clock * 1000;
- modeInfo.hSyncStart = mode->HSyncStart;
- modeInfo.hSyncEnd = mode->HSyncEnd;
- modeInfo.hTotal = mode->HTotal;
- modeInfo.hSkew = mode->HSkew;
-
- modeInfo.height = mode->VDisplay;
- modeInfo.vSyncStart = mode->VSyncStart;
- modeInfo.vSyncEnd = mode->VSyncEnd;
- modeInfo.vTotal = mode->VTotal;
- modeInfo.modeFlags = mode->Flags;
-
- rrmode = RRModeGet (&modeInfo, mode->name);
- if (rrmode) {
- rrmodes[nmode++] = rrmode;
- npreferred += pref;
- }
- }
- }
- }
- }
-
- ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred);
- free(rrmodes);
- return ret;
-}
-
-/*
- * Mirror the current mode configuration to RandR
- */
-static Bool
-xf86RandR12SetInfo12 (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- RROutputPtr *clones;
- RRCrtcPtr *crtcs;
- int ncrtc;
- int o, c, l;
- RRCrtcPtr randr_crtc;
- int nclone;
-
- clones = malloc(config->num_output * sizeof (RROutputPtr));
- crtcs = malloc(config->num_crtc * sizeof (RRCrtcPtr));
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
-
- ncrtc = 0;
- for (c = 0; c < config->num_crtc; c++)
- if (output->possible_crtcs & (1 << c))
- crtcs[ncrtc++] = config->crtc[c]->randr_crtc;
-
- if (output->crtc)
- randr_crtc = output->crtc->randr_crtc;
- else
- randr_crtc = NULL;
-
- if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc))
- {
- free(crtcs);
- free(clones);
- return FALSE;
- }
-
- RROutputSetPhysicalSize(output->randr_output,
- output->mm_width,
- output->mm_height);
- xf86RROutputSetModes (output->randr_output, output->probed_modes);
-
- switch (output->status) {
- case XF86OutputStatusConnected:
- RROutputSetConnection (output->randr_output, RR_Connected);
- break;
- case XF86OutputStatusDisconnected:
- RROutputSetConnection (output->randr_output, RR_Disconnected);
- break;
- case XF86OutputStatusUnknown:
- RROutputSetConnection (output->randr_output, RR_UnknownConnection);
- break;
- }
-
- RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order);
-
- /*
- * Valid clones
- */
- nclone = 0;
- for (l = 0; l < config->num_output; l++)
- {
- xf86OutputPtr clone = config->output[l];
-
- if (l != o && (output->possible_clones & (1 << l)))
- clones[nclone++] = clone->randr_output;
- }
- if (!RROutputSetClones (output->randr_output, clones, nclone))
- {
- free(crtcs);
- free(clones);
- return FALSE;
- }
- }
- free(crtcs);
- free(clones);
- return TRUE;
-}
-
-
-
-/*
- * Query the hardware for the current state, then mirror
- * that to RandR
- */
-static Bool
-xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- if (!pScrn->vtSema)
- return TRUE;
- xf86ProbeOutputModes (pScrn, 0, 0);
- xf86SetScrnInfoModes (pScrn);
- return xf86RandR12SetInfo12 (pScreen);
-}
-
-static Bool
-xf86RandR12CreateObjects12 (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
- int o;
-
- if (!RRInit ())
- return FALSE;
-
- /*
- * Configure crtcs
- */
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = config->crtc[c];
-
- crtc->randr_crtc = RRCrtcCreate (pScreen, crtc);
- RRCrtcGammaSetSize (crtc->randr_crtc, 256);
- }
- /*
- * Configure outputs
- */
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
-
- output->randr_output = RROutputCreate (pScreen, output->name,
- strlen (output->name),
- output);
-
- if (output->funcs->create_resources != NULL)
- output->funcs->create_resources(output);
- RRPostPendingProperties (output->randr_output);
- }
- return TRUE;
-}
-
-static Bool
-xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
-{
- int c;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
-
- if (xf86RandR12Key == NULL)
- return TRUE;
-
- for (c = 0; c < config->num_crtc; c++)
- xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
-
- RRScreenSetSizeRange (pScreen, config->minWidth, config->minHeight,
- config->maxWidth, config->maxHeight);
- return TRUE;
-}
-
-/*
- * Something happened within the screen configuration due
- * to DGA, VidMode or hot key. Tell RandR
- */
-
-void
-xf86RandR12TellChanged (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
-
- if (xf86RandR12Key == NULL)
- return;
-
- xf86RandR12SetInfo12 (pScreen);
- for (c = 0; c < config->num_crtc; c++)
- xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
-
- RRTellChanged (pScreen);
-}
-
-static void
-xf86RandR12PointerMoved (int scrnIndex, int x, int y)
-{
- ScreenPtr pScreen = screenInfo.screens[scrnIndex];
- ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- int c;
-
- randrp->pointerX = x;
- randrp->pointerY = y;
- for (c = 0; c < config->num_crtc; c++)
- xf86RandR13Pan (config->crtc[c], x, y);
-}
-
-static Bool
-xf86RandR13GetPanning (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc,
- BoxPtr totalArea,
- BoxPtr trackingArea,
- INT16 *border)
-{
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
-
- if (crtc->version < 2)
- return FALSE;
- if (totalArea)
- memcpy (totalArea, &crtc->panningTotalArea, sizeof(BoxRec));
- if (trackingArea)
- memcpy (trackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
- if (border)
- memcpy (border, crtc->panningBorder, 4*sizeof(INT16));
-
- return TRUE;
-}
-
-static Bool
-xf86RandR13SetPanning (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc,
- BoxPtr totalArea,
- BoxPtr trackingArea,
- INT16 *border)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
- BoxRec oldTotalArea;
- BoxRec oldTrackingArea;
- INT16 oldBorder[4];
-
-
- if (crtc->version < 2)
- return FALSE;
-
- memcpy (&oldTotalArea, &crtc->panningTotalArea, sizeof(BoxRec));
- memcpy (&oldTrackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
- memcpy (oldBorder, crtc->panningBorder, 4*sizeof(INT16));
-
- if (totalArea)
- memcpy (&crtc->panningTotalArea, totalArea, sizeof(BoxRec));
- if (trackingArea)
- memcpy (&crtc->panningTrackingArea, trackingArea, sizeof(BoxRec));
- if (border)
- memcpy (crtc->panningBorder, border, 4*sizeof(INT16));
-
- if (xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height)) {
- xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
- return TRUE;
- } else {
- /* Restore old settings */
- memcpy (&crtc->panningTotalArea, &oldTotalArea, sizeof(BoxRec));
- memcpy (&crtc->panningTrackingArea, &oldTrackingArea, sizeof(BoxRec));
- memcpy (crtc->panningBorder, oldBorder, 4*sizeof(INT16));
- return FALSE;
- }
-}
-
-/*
- * Compatibility with XF86VidMode's gamma changer. This necessarily clobbers
- * any per-crtc setup. You asked for it...
- */
-
-static void
-gamma_to_ramp(float gamma, CARD16 *ramp, int size)
-{
- int i;
-
- for (i = 0; i < size; i++) {
- if (gamma == 1.0)
- ramp[i] = i << 8;
- else
- ramp[i] = (CARD16)(pow((double)i / (double)(size - 1), 1. / gamma)
- * (double)(size - 1) * 256);
- }
-}
-
-static int
-xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma)
-{
- CARD16 *points, *red, *green, *blue;
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
- int size;
-
- if (!crtc)
- return Success;
-
- size = max(0, crtc->gammaSize);
- if (!size)
- return Success;
-
- points = calloc(size, 3 * sizeof(CARD16));
- if (!points)
- return BadAlloc;
-
- red = points;
- green = points + size;
- blue = points + 2 * size;
-
- gamma_to_ramp(gamma.red, red, size);
- gamma_to_ramp(gamma.green, green, size);
- gamma_to_ramp(gamma.blue, blue, size);
- RRCrtcGammaSet(crtc, red, green, blue);
-
- free(points);
-
- pScrn->gamma = gamma;
-
- return Success;
-}
-
-static Bool
-xf86RandR12EnterVT (int screen_index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[screen_index];
- ScrnInfoPtr pScrn = xf86Screens[screen_index];
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- rrScrPrivPtr rp = rrGetScrPriv(pScreen);
- Bool ret;
- int i;
-
- if (randrp->orig_EnterVT) {
- pScrn->EnterVT = randrp->orig_EnterVT;
- ret = pScrn->EnterVT (screen_index, flags);
- randrp->orig_EnterVT = pScrn->EnterVT;
- pScrn->EnterVT = xf86RandR12EnterVT;
- if (!ret)
- return FALSE;
- }
-
- /* reload gamma */
- for (i = 0; i < rp->numCrtcs; i++)
- xf86RandR12CrtcSetGamma(pScreen, rp->crtcs[i]);
-
- return RRGetInfo (pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */
-}
-
-static Bool
-xf86RandR12Init12 (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- rrScrPrivPtr rp = rrGetScrPriv(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- int i;
-
- rp->rrGetInfo = xf86RandR12GetInfo12;
- rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
- rp->rrCrtcSet = xf86RandR12CrtcSet;
- rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
- rp->rrCrtcGetGamma = xf86RandR12CrtcGetGamma;
- rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
- rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
-#if RANDR_13_INTERFACE
- rp->rrOutputGetProperty = xf86RandR13OutputGetProperty;
- rp->rrGetPanning = xf86RandR13GetPanning;
- rp->rrSetPanning = xf86RandR13SetPanning;
-#endif
- rp->rrModeDestroy = xf86RandR12ModeDestroy;
- rp->rrSetConfig = NULL;
- pScrn->PointerMoved = xf86RandR12PointerMoved;
- pScrn->ChangeGamma = xf86RandR12ChangeGamma;
-
- randrp->orig_EnterVT = pScrn->EnterVT;
- pScrn->EnterVT = xf86RandR12EnterVT;
-
- if (!xf86RandR12CreateObjects12 (pScreen))
- return FALSE;
-
- /*
- * Configure output modes
- */
- if (!xf86RandR12SetInfo12 (pScreen))
- return FALSE;
- for (i = 0; i < rp->numCrtcs; i++) {
- xf86RandR12CrtcGetGamma(pScreen, rp->crtcs[i]);
- }
- return TRUE;
-}
-
-#endif
-
-Bool
-xf86RandR12PreInit (ScrnInfoPtr pScrn)
-{
- return TRUE;
-}
+/* + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#else +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#endif + +#include "xf86.h" +#include "os.h" +#include "globals.h" +#include "xf86Priv.h" +#include "xf86DDC.h" +#include "mipointer.h" +#include "windowstr.h" +#include "inputstr.h" +#include <randrstr.h> +#include <X11/extensions/render.h> + +#include "xf86Crtc.h" +#include "xf86RandR12.h" + +typedef struct _xf86RandR12Info { + int virtualX; + int virtualY; + int mmWidth; + int mmHeight; + int maxX; + int maxY; + int pointerX; + int pointerY; + Rotation rotation; /* current mode */ + Rotation supported_rotations; /* driver supported */ + + /* Used to wrap EnterVT so we can re-probe the outputs when a laptop unsuspends + * (actually, any time that we switch back into our VT). + * + * See https://bugs.freedesktop.org/show_bug.cgi?id=21554 + */ + xf86EnterVTProc *orig_EnterVT; +} XF86RandRInfoRec, *XF86RandRInfoPtr; + +#ifdef RANDR_12_INTERFACE +static Bool xf86RandR12Init12 (ScreenPtr pScreen); +static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen); +#endif + +static int xf86RandR12Generation; + +static DevPrivateKeyRec xf86RandR12KeyRec; +static DevPrivateKey xf86RandR12Key; +#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \ + dixLookupPrivate(&(p)->devPrivates, xf86RandR12Key)) + + +static int +xf86RandR12ModeRefresh (DisplayModePtr mode) +{ + if (mode->VRefresh) + return (int) (mode->VRefresh + 0.5); + else + return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5); +} + +/* Adapt panning area; return TRUE if panning area was valid without adaption */ +static int +xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight) +{ + int ret = TRUE; + + if (crtc->version < 2) + return FALSE; + + if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1) { + /* Panning in X is disabled */ + if (crtc->panningTotalArea.x1 || crtc->panningTotalArea.x2) + /* Illegal configuration -> fail/disable */ + ret = FALSE; + crtc->panningTotalArea.x1 = crtc->panningTotalArea.x2 = 0; + crtc->panningTrackingArea.x1 = crtc->panningTrackingArea.x2 = 0; + crtc->panningBorder[0] = crtc->panningBorder[2] = 0; + } else { + /* Panning in X is enabled */ + if (crtc->panningTotalArea.x1 < 0) { + /* Panning region outside screen -> move inside */ + crtc->panningTotalArea.x2 -= crtc->panningTotalArea.x1; + crtc->panningTotalArea.x1 = 0; + ret = FALSE; + } + if (crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay) { + /* Panning region smaller than displayed area -> crop to displayed area */ + crtc->panningTotalArea.x2 = crtc->panningTotalArea.x1 + crtc->mode.HDisplay; + ret = FALSE; + } + if (crtc->panningTotalArea.x2 > screenWidth) { + /* Panning region larger than screen -> move inside, then crop to screen */ + crtc->panningTotalArea.x1 -= crtc->panningTotalArea.x2 - screenWidth; + crtc->panningTotalArea.x2 = screenWidth; + ret = FALSE; + if (crtc->panningTotalArea.x1 < 0) + crtc->panningTotalArea.x1 = 0; + } + if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay) { + /* Borders too large -> set to 0 */ + crtc->panningBorder[0] = crtc->panningBorder[2] = 0; + ret = FALSE; + } + } + + if (crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) { + /* Panning in Y is disabled */ + if (crtc->panningTotalArea.y1 || crtc->panningTotalArea.y2) + /* Illegal configuration -> fail/disable */ + ret = FALSE; + crtc->panningTotalArea.y1 = crtc->panningTotalArea.y2 = 0; + crtc->panningTrackingArea.y1 = crtc->panningTrackingArea.y2 = 0; + crtc->panningBorder[1] = crtc->panningBorder[3] = 0; + } else { + /* Panning in Y is enabled */ + if (crtc->panningTotalArea.y1 < 0) { + /* Panning region outside screen -> move inside */ + crtc->panningTotalArea.y2 -= crtc->panningTotalArea.y1; + crtc->panningTotalArea.y1 = 0; + ret = FALSE; + } + if (crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay) { + /* Panning region smaller than displayed area -> crop to displayed area */ + crtc->panningTotalArea.y2 = crtc->panningTotalArea.y1 + crtc->mode.VDisplay; + ret = FALSE; + } + if (crtc->panningTotalArea.y2 > screenHeight) { + /* Panning region larger than screen -> move inside, then crop to screen */ + crtc->panningTotalArea.y1 -= crtc->panningTotalArea.y2 - screenHeight; + crtc->panningTotalArea.y2 = screenHeight; + ret = FALSE; + if (crtc->panningTotalArea.y1 < 0) + crtc->panningTotalArea.y1 = 0; + } + if (crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) { + /* Borders too large -> set to 0 */ + crtc->panningBorder[1] = crtc->panningBorder[3] = 0; + ret = FALSE; + } + } + + return ret; +} + +/* + * The heart of the panning operation: + * + * Given a frame buffer position (fb_x, fb_y), + * and a crtc position (crtc_x, crtc_y), + * and a transform matrix which maps frame buffer to crtc, + * compute a panning position (pan_x, pan_y) that + * makes the resulting transform line those two up + */ + +static void +xf86ComputeCrtcPan (Bool transform_in_use, + struct pixman_f_transform *m, + double screen_x, double screen_y, + double crtc_x, double crtc_y, + int old_pan_x, int old_pan_y, + int *new_pan_x, int *new_pan_y) +{ + if (transform_in_use) { + /* + * Given the current transform, M, the current position + * on the Screen, S, and the desired position on the CRTC, + * C, compute a translation, T, such that: + * + * M T S = C + * + * where T is of the form + * + * | 1 0 dx | + * | 0 1 dy | + * | 0 0 1 | + * + * M T S = + * | M00 Sx + M01 Sy + M00 dx + M01 dy + M02 | | Cx F | + * | M10 Sx + M11 Sy + M10 dx + M11 dy + M12 | = | Cy F | + * | M20 Sx + M21 Sy + M20 dx + M21 dy + M22 | | F | + * + * R = M S + * + * Cx F = M00 dx + M01 dy + R0 + * Cy F = M10 dx + M11 dy + R1 + * F = M20 dx + M21 dy + R2 + * + * Zero out dx, then dy + * + * F (Cx M10 - Cy M00) = + * (M10 M01 - M00 M11) dy + M10 R0 - M00 R1 + * F (M10 - Cy M20) = + * (M10 M21 - M20 M11) dy + M10 R2 - M20 R1 + * + * F (Cx M11 - Cy M01) = + * (M11 M00 - M01 M10) dx + M11 R0 - M01 R1 + * F (M11 - Cy M21) = + * (M11 M20 - M21 M10) dx + M11 R2 - M21 R1 + * + * Make some temporaries + * + * T = | Cx M10 - Cy M00 | + * | Cx M11 - Cy M01 | + * + * U = | M10 M01 - M00 M11 | + * | M11 M00 - M01 M10 | + * + * Q = | M10 R0 - M00 R1 | + * | M11 R0 - M01 R1 | + * + * P = | M10 - Cy M20 | + * | M11 - Cy M21 | + * + * W = | M10 M21 - M20 M11 | + * | M11 M20 - M21 M10 | + * + * V = | M10 R2 - M20 R1 | + * | M11 R2 - M21 R1 | + * + * Rewrite: + * + * F T0 = U0 dy + Q0 + * F P0 = W0 dy + V0 + * F T1 = U1 dx + Q1 + * F P1 = W1 dx + V1 + * + * Solve for F (two ways) + * + * F (W0 T0 - U0 P0) = W0 Q0 - U0 V0 + * + * W0 Q0 - U0 V0 + * F = ------------- + * W0 T0 - U0 P0 + * + * F (W1 T1 - U1 P1) = W1 Q1 - U1 V1 + * + * W1 Q1 - U1 V1 + * F = ------------- + * W1 T1 - U1 P1 + * + * We'll use which ever solution works (denominator != 0) + * + * Finally, solve for dx and dy: + * + * dx = (F T1 - Q1) / U1 + * dx = (F P1 - V1) / W1 + * + * dy = (F T0 - Q0) / U0 + * dy = (F P0 - V0) / W0 + */ + double r[3]; + double q[2], u[2], t[2], v[2], w[2], p[2]; + double f; + struct pict_f_vector d; + int i; + + /* Get the un-normalized crtc coordinates again */ + for (i = 0; i < 3; i++) + r[i] = m->m[i][0] * screen_x + m->m[i][1] * screen_y + m->m[i][2]; + + /* Combine values into temporaries */ + for (i = 0; i < 2; i++) { + q[i] = m->m[1][i] * r[0] - m->m[0][i] * r[1]; + u[i] = m->m[1][i] * m->m[0][1-i] - m->m[0][i] * m->m[1][1-i]; + t[i] = m->m[1][i] * crtc_x - m->m[0][i] * crtc_y; + + v[i] = m->m[1][i] * r[2] - m->m[2][i] * r[1]; + w[i] = m->m[1][i] * m->m[2][1-i] - m->m[2][i] * m->m[1][1-i]; + p[i] = m->m[1][i] - m->m[2][i] * crtc_y; + } + + /* Find a way to compute f */ + f = 0; + for (i = 0; i < 2; i++) { + double a = w[i] * q[i] - u[i] * v[i]; + double b = w[i] * t[i] - u[i] * p[i]; + if (b != 0) { + f = a/b; + break; + } + } + + /* Solve for the resulting transform vector */ + for (i = 0; i < 2; i++) { + if (u[i]) + d.v[1-i] = (t[i] * f - q[i]) / u[i]; + else if (w[1]) + d.v[1-i] = (p[i] * f - v[i]) / w[i]; + else + d.v[1-i] = 0; + } + *new_pan_x = old_pan_x - floor (d.v[0] + 0.5); + *new_pan_y = old_pan_y - floor (d.v[1] + 0.5); + } else { + *new_pan_x = screen_x - crtc_x; + *new_pan_y = screen_y - crtc_y; + } +} + +static void +xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y) +{ + int newX, newY; + int width, height; + Bool panned = FALSE; + + if (crtc->version < 2) + return; + + if (! crtc->enabled || + (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 && + crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1)) + return; + + newX = crtc->x; + newY = crtc->y; + width = crtc->mode.HDisplay; + height = crtc->mode.VDisplay; + + if ((crtc->panningTrackingArea.x2 <= crtc->panningTrackingArea.x1 || + (x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2)) && + (crtc->panningTrackingArea.y2 <= crtc->panningTrackingArea.y1 || + (y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2))) + { + struct pict_f_vector c; + + /* + * Pre-clip the mouse position to the panning area so that we don't + * push the crtc outside. This doesn't deal with changes to the + * panning values, only mouse position changes. + */ + if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) + { + if (x < crtc->panningTotalArea.x1) + x = crtc->panningTotalArea.x1; + if (x >= crtc->panningTotalArea.x2) + x = crtc->panningTotalArea.x2 - 1; + } + if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) + { + if (y < crtc->panningTotalArea.y1) + y = crtc->panningTotalArea.y1; + if (y >= crtc->panningTotalArea.y2) + y = crtc->panningTotalArea.y2 - 1; + } + + c.v[0] = x; + c.v[1] = y; + c.v[2] = 1.0; + if (crtc->transform_in_use) { + pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &c); + } else { + c.v[0] -= crtc->x; + c.v[1] -= crtc->y; + } + + if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) { + if (c.v[0] < crtc->panningBorder[0]) { + c.v[0] = crtc->panningBorder[0]; + panned = TRUE; + } + if (c.v[0] >= width - crtc->panningBorder[2]) { + c.v[0] = width - crtc->panningBorder[2] - 1; + panned = TRUE; + } + } + if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) { + if (c.v[1] < crtc->panningBorder[1]) { + c.v[1] = crtc->panningBorder[1]; + panned = TRUE; + } + if (c.v[1] >= height - crtc->panningBorder[3]) { + c.v[1] = height - crtc->panningBorder[3] - 1; + panned = TRUE; + } + } + if (panned) + xf86ComputeCrtcPan (crtc->transform_in_use, + &crtc->f_framebuffer_to_crtc, + x, y, c.v[0], c.v[1], + newX, newY, &newX, &newY); + } + + /* + * Ensure that the crtc is within the panning region. + * + * XXX This computation only works when we do not have a transform + * in use. + */ + if (!crtc->transform_in_use) + { + /* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */ + if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) { + if (newX > crtc->panningTotalArea.x2 - width) + newX = crtc->panningTotalArea.x2 - width; + if (newX < crtc->panningTotalArea.x1) + newX = crtc->panningTotalArea.x1; + } + if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) { + if (newY > crtc->panningTotalArea.y2 - height) + newY = crtc->panningTotalArea.y2 - height; + if (newY < crtc->panningTotalArea.y1) + newY = crtc->panningTotalArea.y1; + } + } + if (newX != crtc->x || newY != crtc->y) + xf86CrtcSetOrigin (crtc, newX, newY); +} + +static Bool +xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations) +{ + RRScreenSizePtr pSize; + ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + DisplayModePtr mode; + int refresh0 = 60; + int maxX = 0, maxY = 0; + + *rotations = randrp->supported_rotations; + + if (randrp->virtualX == -1 || randrp->virtualY == -1) + { + randrp->virtualX = scrp->virtualX; + randrp->virtualY = scrp->virtualY; + } + + /* Re-probe the outputs for new monitors or modes */ + if (scrp->vtSema) + { + xf86ProbeOutputModes (scrp, 0, 0); + xf86SetScrnInfoModes (scrp); + } + + for (mode = scrp->modes; ; mode = mode->next) + { + int refresh = xf86RandR12ModeRefresh (mode); + if (randrp->maxX == 0 || randrp->maxY == 0) + { + if (maxX < mode->HDisplay) + maxX = mode->HDisplay; + if (maxY < mode->VDisplay) + maxY = mode->VDisplay; + } + if (mode == scrp->modes) + refresh0 = refresh; + pSize = RRRegisterSize (pScreen, + mode->HDisplay, mode->VDisplay, + randrp->mmWidth, randrp->mmHeight); + if (!pSize) + return FALSE; + RRRegisterRate (pScreen, pSize, refresh); + + if (xf86ModesEqual(mode, scrp->currentMode)) + { + RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize); + } + if (mode->next == scrp->modes) + break; + } + + if (randrp->maxX == 0 || randrp->maxY == 0) + { + randrp->maxX = maxX; + randrp->maxY = maxY; + } + + return TRUE; +} + +static Bool +xf86RandR12SetMode (ScreenPtr pScreen, + DisplayModePtr mode, + Bool useVirtual, + int mmWidth, + int mmHeight) +{ + ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + int oldWidth = pScreen->width; + int oldHeight = pScreen->height; + int oldmmWidth = pScreen->mmWidth; + int oldmmHeight = pScreen->mmHeight; + WindowPtr pRoot = pScreen->root; + DisplayModePtr currentMode = NULL; + Bool ret = TRUE; + + if (pRoot) + (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE); + if (useVirtual) + { + scrp->virtualX = randrp->virtualX; + scrp->virtualY = randrp->virtualY; + } + else + { + scrp->virtualX = mode->HDisplay; + scrp->virtualY = mode->VDisplay; + } + + if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270)) + { + /* If the screen is rotated 90 or 270 degrees, swap the sizes. */ + pScreen->width = scrp->virtualY; + pScreen->height = scrp->virtualX; + pScreen->mmWidth = mmHeight; + pScreen->mmHeight = mmWidth; + } + else + { + pScreen->width = scrp->virtualX; + pScreen->height = scrp->virtualY; + pScreen->mmWidth = mmWidth; + pScreen->mmHeight = mmHeight; + } + if (scrp->currentMode == mode) { + /* Save current mode */ + currentMode = scrp->currentMode; + /* Reset, just so we ensure the drivers SwitchMode is called */ + scrp->currentMode = NULL; + } + /* + * We know that if the driver failed to SwitchMode to the rotated + * version, then it should revert back to it's prior mode. + */ + if (!xf86SwitchMode (pScreen, mode)) + { + ret = FALSE; + scrp->virtualX = pScreen->width = oldWidth; + scrp->virtualY = pScreen->height = oldHeight; + pScreen->mmWidth = oldmmWidth; + pScreen->mmHeight = oldmmHeight; + scrp->currentMode = currentMode; + } + + /* + * Make sure the layout is correct + */ + xf86ReconfigureLayout(); + + /* + * Make sure the whole screen is visible + */ + xf86SetViewport (pScreen, pScreen->width, pScreen->height); + xf86SetViewport (pScreen, 0, 0); + if (pRoot) + (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE); + return ret; +} + +Bool +xf86RandR12SetConfig (ScreenPtr pScreen, + Rotation rotation, + int rate, + RRScreenSizePtr pSize) +{ + ScrnInfoPtr scrp = XF86SCRNINFO(pScreen); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + DisplayModePtr mode; + int pos[MAXDEVICES][2]; + Bool useVirtual = FALSE; + int maxX = 0, maxY = 0; + Rotation oldRotation = randrp->rotation; + DeviceIntPtr dev; + Bool view_adjusted = FALSE; + + randrp->rotation = rotation; + + if (randrp->virtualX == -1 || randrp->virtualY == -1) + { + randrp->virtualX = scrp->virtualX; + randrp->virtualY = scrp->virtualY; + } + + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (!IsMaster(dev) && !IsFloating(dev)) + continue; + + miPointerGetPosition(dev, &pos[dev->id][0], &pos[dev->id][1]); + } + + for (mode = scrp->modes; ; mode = mode->next) + { + if (randrp->maxX == 0 || randrp->maxY == 0) + { + if (maxX < mode->HDisplay) + maxX = mode->HDisplay; + if (maxY < mode->VDisplay) + maxY = mode->VDisplay; + } + if (mode->HDisplay == pSize->width && + mode->VDisplay == pSize->height && + (rate == 0 || xf86RandR12ModeRefresh (mode) == rate)) + break; + if (mode->next == scrp->modes) + { + if (pSize->width == randrp->virtualX && + pSize->height == randrp->virtualY) + { + mode = scrp->modes; + useVirtual = TRUE; + break; + } + if (randrp->maxX == 0 || randrp->maxY == 0) + { + randrp->maxX = maxX; + randrp->maxY = maxY; + } + return FALSE; + } + } + + if (randrp->maxX == 0 || randrp->maxY == 0) + { + randrp->maxX = maxX; + randrp->maxY = maxY; + } + + if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth, + pSize->mmHeight)) { + randrp->rotation = oldRotation; + return FALSE; + } + + /* + * Move the cursor back where it belongs; SwitchMode repositions it + * FIXME: duplicated code, see modes/xf86RandR12.c + */ + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (!IsMaster(dev) && !IsFloating(dev)) + continue; + + if (pScreen == miPointerGetScreen(dev)) { + int px = pos[dev->id][0]; + int py = pos[dev->id][1]; + + px = (px >= pScreen->width ? (pScreen->width - 1) : px); + py = (py >= pScreen->height ? (pScreen->height - 1) : py); + + /* Setting the viewpoint makes only sense on one device */ + if (!view_adjusted && IsMaster(dev)) { + xf86SetViewport(pScreen, px, py); + view_adjusted = TRUE; + } + + (*pScreen->SetCursorPosition) (dev, pScreen, px, py, FALSE); + } + } + + return TRUE; +} + +static Bool +xf86RandR12ScreenSetSize (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight) +{ + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + WindowPtr pRoot = pScreen->root; + PixmapPtr pScrnPix; + Bool ret = FALSE; + int c; + + if (xf86RandR12Key) { + if (randrp->virtualX == -1 || randrp->virtualY == -1) + { + randrp->virtualX = pScrn->virtualX; + randrp->virtualY = pScrn->virtualY; + } + } + if (pRoot && pScrn->vtSema) + (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE); + + /* Let the driver update virtualX and virtualY */ + if (!(*config->funcs->resize)(pScrn, width, height)) + goto finish; + + ret = TRUE; + /* Update panning information */ + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 || + crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) { + if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1) + crtc->panningTotalArea.x2 += width - pScreen->width; + if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1) + crtc->panningTotalArea.y2 += height - pScreen->height; + if (crtc->panningTrackingArea.x2 > crtc->panningTrackingArea.x1) + crtc->panningTrackingArea.x2 += width - pScreen->width; + if (crtc->panningTrackingArea.y2 > crtc->panningTrackingArea.y1) + crtc->panningTrackingArea.y2 += height - pScreen->height; + xf86RandR13VerifyPanningArea (crtc, width, height); + xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY); + } + } + + pScrnPix = (*pScreen->GetScreenPixmap)(pScreen); + pScreen->width = pScrnPix->drawable.width = width; + pScreen->height = pScrnPix->drawable.height = height; + randrp->mmWidth = pScreen->mmWidth = mmWidth; + randrp->mmHeight = pScreen->mmHeight = mmHeight; + + xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1); + xf86SetViewport (pScreen, 0, 0); + +finish: + if (pRoot && pScrn->vtSema) + (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE); +#if RANDR_12_INTERFACE + if (xf86RandR12Key && pScreen->root && ret) + RRScreenSizeNotify (pScreen); +#endif + return ret; +} + +Rotation +xf86RandR12GetRotation(ScreenPtr pScreen) +{ + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + + return randrp->rotation; +} + +Bool +xf86RandR12CreateScreenResources (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config; + XF86RandRInfoPtr randrp; + int c; + int width, height; + int mmWidth, mmHeight; +#ifdef PANORAMIX + /* XXX disable RandR when using Xinerama */ + if (!noPanoramiXExtension) + return TRUE; +#endif + + config = XF86_CRTC_CONFIG_PTR(pScrn); + randrp = XF86RANDRINFO(pScreen); + /* + * Compute size of screen + */ + width = 0; height = 0; + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + int crtc_width = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation); + int crtc_height = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation); + + if (crtc->enabled) { + if (crtc_width > width) + width = crtc_width; + if (crtc_height > height) + height = crtc_height; + if (crtc->panningTotalArea.x2 > width) + width = crtc->panningTotalArea.x2; + if (crtc->panningTotalArea.y2 > height) + height = crtc->panningTotalArea.y2; + } + } + + if (width && height) + { + /* + * Compute physical size of screen + */ + if (monitorResolution) + { + mmWidth = width * 25.4 / monitorResolution; + mmHeight = height * 25.4 / monitorResolution; + } + else + { + xf86OutputPtr output = xf86CompatOutput(pScrn); + + if (output && + output->conf_monitor && + (output->conf_monitor->mon_width > 0 && + output->conf_monitor->mon_height > 0)) + { + /* + * Prefer user configured DisplaySize + */ + mmWidth = output->conf_monitor->mon_width; + mmHeight = output->conf_monitor->mon_height; + } + else + { + /* + * Otherwise, just set the screen to DEFAULT_DPI + */ + mmWidth = width * 25.4 / DEFAULT_DPI; + mmHeight = height * 25.4 / DEFAULT_DPI; + } + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Setting screen physical size to %d x %d\n", + mmWidth, mmHeight); + /* + * This is the initial setting of the screen size. + * We have to pre-set it here, otherwise panning would be adapted + * to the new screen size. + */ + pScreen->width = width; + pScreen->height = height; + xf86RandR12ScreenSetSize (pScreen, + width, + height, + mmWidth, + mmHeight); + } + + if (xf86RandR12Key == NULL) + return TRUE; + + if (randrp->virtualX == -1 || randrp->virtualY == -1) + { + randrp->virtualX = pScrn->virtualX; + randrp->virtualY = pScrn->virtualY; + } + xf86CrtcSetScreenSubpixelOrder (pScreen); +#if RANDR_12_INTERFACE + if (xf86RandR12CreateScreenResources12 (pScreen)) + return TRUE; +#endif + return TRUE; +} + + +Bool +xf86RandR12Init (ScreenPtr pScreen) +{ + rrScrPrivPtr rp; + XF86RandRInfoPtr randrp; + +#ifdef PANORAMIX + /* XXX disable RandR when using Xinerama */ + if (!noPanoramiXExtension) + { + if (xf86NumScreens == 1) + noPanoramiXExtension = TRUE; + else + return TRUE; + } +#endif + + if (xf86RandR12Generation != serverGeneration) + xf86RandR12Generation = serverGeneration; + + xf86RandR12Key = &xf86RandR12KeyRec; + if (!dixRegisterPrivateKey(&xf86RandR12KeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + + randrp = malloc(sizeof (XF86RandRInfoRec)); + if (!randrp) + return FALSE; + + if (!RRScreenInit(pScreen)) + { + free(randrp); + return FALSE; + } + rp = rrGetScrPriv(pScreen); + rp->rrGetInfo = xf86RandR12GetInfo; + rp->rrSetConfig = xf86RandR12SetConfig; + + randrp->virtualX = -1; + randrp->virtualY = -1; + randrp->mmWidth = pScreen->mmWidth; + randrp->mmHeight = pScreen->mmHeight; + + randrp->rotation = RR_Rotate_0; /* initial rotated mode */ + + randrp->supported_rotations = RR_Rotate_0; + + randrp->maxX = randrp->maxY = 0; + + dixSetPrivate(&pScreen->devPrivates, xf86RandR12Key, randrp); + +#if RANDR_12_INTERFACE + if (!xf86RandR12Init12 (pScreen)) + return FALSE; +#endif + return TRUE; +} + +void +xf86RandR12CloseScreen (ScreenPtr pScreen) +{ + XF86RandRInfoPtr randrp; + + if (xf86RandR12Key == NULL) + return; + + randrp = XF86RANDRINFO(pScreen); +#if RANDR_12_INTERFACE + xf86Screens[pScreen->myNum]->EnterVT = randrp->orig_EnterVT; +#endif + + free(randrp); +} + +void +xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations) +{ + XF86RandRInfoPtr randrp; +#if RANDR_12_INTERFACE + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + int c; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); +#endif + + if (xf86RandR12Key == NULL) + return; + + randrp = XF86RANDRINFO(pScreen); +#if RANDR_12_INTERFACE + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + + RRCrtcSetRotations (crtc->randr_crtc, rotations); + } +#endif + randrp->supported_rotations = rotations; +} + +void +xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms) +{ + XF86RandRInfoPtr randrp; +#if RANDR_13_INTERFACE + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + int c; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); +#endif + + if (xf86RandR12Key == NULL) + return; + + randrp = XF86RANDRINFO(pScreen); +#if RANDR_13_INTERFACE + for (c = 0; c < config->num_crtc; c++) { + xf86CrtcPtr crtc = config->crtc[c]; + + RRCrtcSetTransformSupport (crtc->randr_crtc, transforms); + } +#endif +} + +void +xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y) +{ + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + + if (xf86RandR12Generation != serverGeneration || + XF86RANDRINFO(pScreen)->virtualX == -1) + { + *x = pScrn->virtualX; + *y = pScrn->virtualY; + } else { + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + + *x = randrp->virtualX; + *y = randrp->virtualY; + } +} + +#if RANDR_12_INTERFACE + +#define FLAG_BITS (RR_HSyncPositive | \ + RR_HSyncNegative | \ + RR_VSyncPositive | \ + RR_VSyncNegative | \ + RR_Interlace | \ + RR_DoubleScan | \ + RR_CSync | \ + RR_CSyncPositive | \ + RR_CSyncNegative | \ + RR_HSkewPresent | \ + RR_BCast | \ + RR_PixelMultiplex | \ + RR_DoubleClock | \ + RR_ClockDivideBy2) + +static Bool +xf86RandRModeMatches (RRModePtr randr_mode, + DisplayModePtr mode) +{ +#if 0 + if (match_name) + { + /* check for same name */ + int len = strlen (mode->name); + if (randr_mode->mode.nameLength != len) return FALSE; + if (memcmp (randr_mode->name, mode->name, len) != 0) return FALSE; + } +#endif + + /* check for same timings */ + if (randr_mode->mode.dotClock / 1000 != mode->Clock) return FALSE; + if (randr_mode->mode.width != mode->HDisplay) return FALSE; + if (randr_mode->mode.hSyncStart != mode->HSyncStart) return FALSE; + if (randr_mode->mode.hSyncEnd != mode->HSyncEnd) return FALSE; + if (randr_mode->mode.hTotal != mode->HTotal) return FALSE; + if (randr_mode->mode.hSkew != mode->HSkew) return FALSE; + if (randr_mode->mode.height != mode->VDisplay) return FALSE; + if (randr_mode->mode.vSyncStart != mode->VSyncStart) return FALSE; + if (randr_mode->mode.vSyncEnd != mode->VSyncEnd) return FALSE; + if (randr_mode->mode.vTotal != mode->VTotal) return FALSE; + + /* check for same flags (using only the XF86 valid flag bits) */ + if ((randr_mode->mode.modeFlags & FLAG_BITS) != (mode->Flags & FLAG_BITS)) + return FALSE; + + /* everything matches */ + return TRUE; +} + +static Bool +xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc) +{ + ScreenPtr pScreen = randr_crtc->pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + RRModePtr randr_mode = NULL; + int x; + int y; + Rotation rotation; + int numOutputs; + RROutputPtr *randr_outputs; + RROutputPtr randr_output; + xf86CrtcPtr crtc = randr_crtc->devPrivate; + xf86OutputPtr output; + int i, j; + DisplayModePtr mode = &crtc->mode; + Bool ret; + + randr_outputs = malloc(config->num_output * sizeof (RROutputPtr)); + if (!randr_outputs) + return FALSE; + x = crtc->x; + y = crtc->y; + rotation = crtc->rotation; + numOutputs = 0; + randr_mode = NULL; + for (i = 0; i < config->num_output; i++) + { + output = config->output[i]; + if (output->crtc == crtc) + { + randr_output = output->randr_output; + randr_outputs[numOutputs++] = randr_output; + /* + * We make copies of modes, so pointer equality + * isn't sufficient + */ + for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++) + { + RRModePtr m = (j < randr_output->numModes ? + randr_output->modes[j] : + randr_output->userModes[j-randr_output->numModes]); + + if (xf86RandRModeMatches (m, mode)) + { + randr_mode = m; + break; + } + } + } + } + ret = RRCrtcNotify (randr_crtc, randr_mode, x, y, + rotation, + crtc->transformPresent ? &crtc->transform : NULL, + numOutputs, randr_outputs); + free(randr_outputs); + return ret; +} + +/* + * Convert a RandR mode to a DisplayMode + */ +static void +xf86RandRModeConvert (ScrnInfoPtr scrn, + RRModePtr randr_mode, + DisplayModePtr mode) +{ + memset(mode, 0, sizeof(DisplayModeRec)); + mode->status = MODE_OK; + + mode->Clock = randr_mode->mode.dotClock / 1000; + + mode->HDisplay = randr_mode->mode.width; + mode->HSyncStart = randr_mode->mode.hSyncStart; + mode->HSyncEnd = randr_mode->mode.hSyncEnd; + mode->HTotal = randr_mode->mode.hTotal; + mode->HSkew = randr_mode->mode.hSkew; + + mode->VDisplay = randr_mode->mode.height; + mode->VSyncStart = randr_mode->mode.vSyncStart; + mode->VSyncEnd = randr_mode->mode.vSyncEnd; + mode->VTotal = randr_mode->mode.vTotal; + mode->VScan = 0; + + mode->Flags = randr_mode->mode.modeFlags & FLAG_BITS; + + xf86SetModeCrtc (mode, scrn->adjustFlags); +} + +static Bool +xf86RandR12CrtcSet (ScreenPtr pScreen, + RRCrtcPtr randr_crtc, + RRModePtr randr_mode, + int x, + int y, + Rotation rotation, + int num_randr_outputs, + RROutputPtr *randr_outputs) +{ + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcPtr crtc = randr_crtc->devPrivate; + RRTransformPtr transform; + Bool changed = FALSE; + int o, ro; + xf86CrtcPtr *save_crtcs; + Bool save_enabled = crtc->enabled; + + if (!crtc->scrn->vtSema) + return FALSE; + + save_crtcs = malloc(config->num_output * sizeof (xf86CrtcPtr)); + if ((randr_mode != NULL) != crtc->enabled) + changed = TRUE; + else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode)) + changed = TRUE; + + if (rotation != crtc->rotation) + changed = TRUE; + + transform = RRCrtcGetTransform (randr_crtc); + if ((transform != NULL) != crtc->transformPresent) + changed = TRUE; + else if (transform && memcmp (&transform->transform, &crtc->transform.transform, + sizeof (transform->transform)) != 0) + changed = TRUE; + + if (x != crtc->x || y != crtc->y) + changed = TRUE; + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + xf86CrtcPtr new_crtc; + + save_crtcs[o] = output->crtc; + + if (output->crtc == crtc) + new_crtc = NULL; + else + new_crtc = output->crtc; + for (ro = 0; ro < num_randr_outputs; ro++) + if (output->randr_output == randr_outputs[ro]) + { + new_crtc = crtc; + break; + } + if (new_crtc != output->crtc) + { + changed = TRUE; + output->crtc = new_crtc; + } + } + for (ro = 0; ro < num_randr_outputs; ro++) + if (randr_outputs[ro]->pendingProperties) + changed = TRUE; + + /* XXX need device-independent mode setting code through an API */ + if (changed) + { + crtc->enabled = randr_mode != NULL; + + if (randr_mode) + { + DisplayModeRec mode; + RRTransformPtr transform = RRCrtcGetTransform (randr_crtc); + + xf86RandRModeConvert (pScrn, randr_mode, &mode); + if (!xf86CrtcSetModeTransform (crtc, &mode, rotation, transform, x, y)) + { + crtc->enabled = save_enabled; + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + output->crtc = save_crtcs[o]; + } + free(save_crtcs); + return FALSE; + } + xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height); + xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY); + /* + * Save the last successful setting for EnterVT + */ + crtc->desiredMode = mode; + crtc->desiredRotation = rotation; + if (transform) { + crtc->desiredTransform = *transform; + crtc->desiredTransformPresent = TRUE; + } else + crtc->desiredTransformPresent = FALSE; + + crtc->desiredX = x; + crtc->desiredY = y; + } + xf86DisableUnusedFunctions (pScrn); + } + free(save_crtcs); + return xf86RandR12CrtcNotify (randr_crtc); +} + +static Bool +xf86RandR12CrtcSetGamma (ScreenPtr pScreen, + RRCrtcPtr randr_crtc) +{ + xf86CrtcPtr crtc = randr_crtc->devPrivate; + + if (crtc->funcs->gamma_set == NULL) + return FALSE; + + if (!crtc->scrn->vtSema) + return TRUE; + + /* Realloc local gamma if needed. */ + if (randr_crtc->gammaSize != crtc->gamma_size) { + CARD16 *tmp_ptr; + tmp_ptr = realloc(crtc->gamma_red, 3 * crtc->gamma_size * sizeof (CARD16)); + if (!tmp_ptr) + return FALSE; + crtc->gamma_red = tmp_ptr; + crtc->gamma_green = crtc->gamma_red + crtc->gamma_size; + crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size; + } + + crtc->gamma_size = randr_crtc->gammaSize; + memcpy (crtc->gamma_red, randr_crtc->gammaRed, crtc->gamma_size * sizeof (CARD16)); + memcpy (crtc->gamma_green, randr_crtc->gammaGreen, crtc->gamma_size * sizeof (CARD16)); + memcpy (crtc->gamma_blue, randr_crtc->gammaBlue, crtc->gamma_size * sizeof (CARD16)); + + /* Only set it when the crtc is actually running. + * Otherwise it will be set when it's activated. + */ + if (crtc->active) + crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, + crtc->gamma_blue, crtc->gamma_size); + + return TRUE; +} + +static Bool +xf86RandR12CrtcGetGamma (ScreenPtr pScreen, + RRCrtcPtr randr_crtc) +{ + xf86CrtcPtr crtc = randr_crtc->devPrivate; + + if (!crtc->gamma_size) + return FALSE; + + if (!crtc->gamma_red || !crtc->gamma_green || !crtc->gamma_blue) + return FALSE; + + /* Realloc randr gamma if needed. */ + if (randr_crtc->gammaSize != crtc->gamma_size) { + CARD16 *tmp_ptr; + tmp_ptr = realloc(randr_crtc->gammaRed, 3 * crtc->gamma_size * sizeof (CARD16)); + if (!tmp_ptr) + return FALSE; + randr_crtc->gammaRed = tmp_ptr; + randr_crtc->gammaGreen = randr_crtc->gammaRed + crtc->gamma_size; + randr_crtc->gammaBlue = randr_crtc->gammaGreen + crtc->gamma_size; + } + randr_crtc->gammaSize = crtc->gamma_size; + memcpy (randr_crtc->gammaRed, crtc->gamma_red, crtc->gamma_size * sizeof (CARD16)); + memcpy (randr_crtc->gammaGreen, crtc->gamma_green, crtc->gamma_size * sizeof (CARD16)); + memcpy (randr_crtc->gammaBlue, crtc->gamma_blue, crtc->gamma_size * sizeof (CARD16)); + + return TRUE; +} + +static Bool +xf86RandR12OutputSetProperty (ScreenPtr pScreen, + RROutputPtr randr_output, + Atom property, + RRPropertyValuePtr value) +{ + xf86OutputPtr output = randr_output->devPrivate; + + /* If we don't have any property handler, then we don't care what the + * user is setting properties to. + */ + if (output->funcs->set_property == NULL) + return TRUE; + + /* + * This function gets called even when vtSema is FALSE, as + * drivers will need to remember the correct value to apply + * when the VT switch occurs + */ + return output->funcs->set_property(output, property, value); +} + +static Bool +xf86RandR13OutputGetProperty (ScreenPtr pScreen, + RROutputPtr randr_output, + Atom property) +{ + xf86OutputPtr output = randr_output->devPrivate; + + if (output->funcs->get_property == NULL) + return TRUE; + + /* Should be safe even w/o vtSema */ + return output->funcs->get_property(output, property); +} + +static Bool +xf86RandR12OutputValidateMode (ScreenPtr pScreen, + RROutputPtr randr_output, + RRModePtr randr_mode) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86OutputPtr output = randr_output->devPrivate; + DisplayModeRec mode; + + xf86RandRModeConvert (pScrn, randr_mode, &mode); + /* + * This function may be called when vtSema is FALSE, so + * the underlying function must either avoid touching the hardware + * or return FALSE when vtSema is FALSE + */ + if (output->funcs->mode_valid (output, &mode) != MODE_OK) + return FALSE; + return TRUE; +} + +static void +xf86RandR12ModeDestroy (ScreenPtr pScreen, RRModePtr randr_mode) +{ +} + +/** + * Given a list of xf86 modes and a RandR Output object, construct + * RandR modes and assign them to the output + */ +static Bool +xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes) +{ + DisplayModePtr mode; + RRModePtr *rrmodes = NULL; + int nmode = 0; + int npreferred = 0; + Bool ret = TRUE; + int pref; + + for (mode = modes; mode; mode = mode->next) + nmode++; + + if (nmode) { + rrmodes = malloc(nmode * sizeof (RRModePtr)); + + if (!rrmodes) + return FALSE; + nmode = 0; + + for (pref = 1; pref >= 0; pref--) { + for (mode = modes; mode; mode = mode->next) { + if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) { + xRRModeInfo modeInfo; + RRModePtr rrmode; + + modeInfo.nameLength = strlen (mode->name); + modeInfo.width = mode->HDisplay; + modeInfo.dotClock = mode->Clock * 1000; + modeInfo.hSyncStart = mode->HSyncStart; + modeInfo.hSyncEnd = mode->HSyncEnd; + modeInfo.hTotal = mode->HTotal; + modeInfo.hSkew = mode->HSkew; + + modeInfo.height = mode->VDisplay; + modeInfo.vSyncStart = mode->VSyncStart; + modeInfo.vSyncEnd = mode->VSyncEnd; + modeInfo.vTotal = mode->VTotal; + modeInfo.modeFlags = mode->Flags; + + rrmode = RRModeGet (&modeInfo, mode->name); + if (rrmode) { + rrmodes[nmode++] = rrmode; + npreferred += pref; + } + } + } + } + } + + ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred); + free(rrmodes); + return ret; +} + +/* + * Mirror the current mode configuration to RandR + */ +static Bool +xf86RandR12SetInfo12 (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + RROutputPtr *clones; + RRCrtcPtr *crtcs; + int ncrtc; + int o, c, l; + RRCrtcPtr randr_crtc; + int nclone; + + clones = malloc(config->num_output * sizeof (RROutputPtr)); + crtcs = malloc(config->num_crtc * sizeof (RRCrtcPtr)); + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + ncrtc = 0; + for (c = 0; c < config->num_crtc; c++) + if (output->possible_crtcs & (1 << c)) + crtcs[ncrtc++] = config->crtc[c]->randr_crtc; + + if (output->crtc) + randr_crtc = output->crtc->randr_crtc; + else + randr_crtc = NULL; + + if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc)) + { + free(crtcs); + free(clones); + return FALSE; + } + + RROutputSetPhysicalSize(output->randr_output, + output->mm_width, + output->mm_height); + xf86RROutputSetModes (output->randr_output, output->probed_modes); + + switch (output->status) { + case XF86OutputStatusConnected: + RROutputSetConnection (output->randr_output, RR_Connected); + break; + case XF86OutputStatusDisconnected: + RROutputSetConnection (output->randr_output, RR_Disconnected); + break; + case XF86OutputStatusUnknown: + RROutputSetConnection (output->randr_output, RR_UnknownConnection); + break; + } + + RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order); + + /* + * Valid clones + */ + nclone = 0; + for (l = 0; l < config->num_output; l++) + { + xf86OutputPtr clone = config->output[l]; + + if (l != o && (output->possible_clones & (1 << l))) + clones[nclone++] = clone->randr_output; + } + if (!RROutputSetClones (output->randr_output, clones, nclone)) + { + free(crtcs); + free(clones); + return FALSE; + } + } + free(crtcs); + free(clones); + return TRUE; +} + + + +/* + * Query the hardware for the current state, then mirror + * that to RandR + */ +static Bool +xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + if (!pScrn->vtSema) + return TRUE; + xf86ProbeOutputModes (pScrn, 0, 0); + xf86SetScrnInfoModes (pScrn); + return xf86RandR12SetInfo12 (pScreen); +} + +static Bool +xf86RandR12CreateObjects12 (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; + int o; + + if (!RRInit ()) + return FALSE; + + /* + * Configure crtcs + */ + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + + crtc->randr_crtc = RRCrtcCreate (pScreen, crtc); + RRCrtcGammaSetSize (crtc->randr_crtc, 256); + } + /* + * Configure outputs + */ + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + output->randr_output = RROutputCreate (pScreen, output->name, + strlen (output->name), + output); + + if (output->funcs->create_resources != NULL) + output->funcs->create_resources(output); + RRPostPendingProperties (output->randr_output); + } + return TRUE; +} + +static Bool +xf86RandR12CreateScreenResources12 (ScreenPtr pScreen) +{ + int c; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + + if (xf86RandR12Key == NULL) + return TRUE; + + for (c = 0; c < config->num_crtc; c++) + xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc); + + RRScreenSetSizeRange (pScreen, config->minWidth, config->minHeight, + config->maxWidth, config->maxHeight); + return TRUE; +} + +/* + * Something happened within the screen configuration due + * to DGA, VidMode or hot key. Tell RandR + */ + +void +xf86RandR12TellChanged (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; + + if (xf86RandR12Key == NULL) + return; + + xf86RandR12SetInfo12 (pScreen); + for (c = 0; c < config->num_crtc; c++) + xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc); + + RRTellChanged (pScreen); +} + +static void +xf86RandR12PointerMoved (int scrnIndex, int x, int y) +{ + ScreenPtr pScreen = screenInfo.screens[scrnIndex]; + ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + int c; + + randrp->pointerX = x; + randrp->pointerY = y; + for (c = 0; c < config->num_crtc; c++) + xf86RandR13Pan (config->crtc[c], x, y); +} + +static Bool +xf86RandR13GetPanning (ScreenPtr pScreen, + RRCrtcPtr randr_crtc, + BoxPtr totalArea, + BoxPtr trackingArea, + INT16 *border) +{ + xf86CrtcPtr crtc = randr_crtc->devPrivate; + + if (crtc->version < 2) + return FALSE; + if (totalArea) + memcpy (totalArea, &crtc->panningTotalArea, sizeof(BoxRec)); + if (trackingArea) + memcpy (trackingArea, &crtc->panningTrackingArea, sizeof(BoxRec)); + if (border) + memcpy (border, crtc->panningBorder, 4*sizeof(INT16)); + + return TRUE; +} + +static Bool +xf86RandR13SetPanning (ScreenPtr pScreen, + RRCrtcPtr randr_crtc, + BoxPtr totalArea, + BoxPtr trackingArea, + INT16 *border) +{ + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + xf86CrtcPtr crtc = randr_crtc->devPrivate; + BoxRec oldTotalArea; + BoxRec oldTrackingArea; + INT16 oldBorder[4]; + + + if (crtc->version < 2) + return FALSE; + + memcpy (&oldTotalArea, &crtc->panningTotalArea, sizeof(BoxRec)); + memcpy (&oldTrackingArea, &crtc->panningTrackingArea, sizeof(BoxRec)); + memcpy (oldBorder, crtc->panningBorder, 4*sizeof(INT16)); + + if (totalArea) + memcpy (&crtc->panningTotalArea, totalArea, sizeof(BoxRec)); + if (trackingArea) + memcpy (&crtc->panningTrackingArea, trackingArea, sizeof(BoxRec)); + if (border) + memcpy (crtc->panningBorder, border, 4*sizeof(INT16)); + + if (xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height)) { + xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY); + return TRUE; + } else { + /* Restore old settings */ + memcpy (&crtc->panningTotalArea, &oldTotalArea, sizeof(BoxRec)); + memcpy (&crtc->panningTrackingArea, &oldTrackingArea, sizeof(BoxRec)); + memcpy (crtc->panningBorder, oldBorder, 4*sizeof(INT16)); + return FALSE; + } +} + +/* + * Compatibility with XF86VidMode's gamma changer. This necessarily clobbers + * any per-crtc setup. You asked for it... + */ + +static void +gamma_to_ramp(float gamma, CARD16 *ramp, int size) +{ + int i; + + for (i = 0; i < size; i++) { + if (gamma == 1.0) + ramp[i] = i << 8; + else + ramp[i] = (CARD16)(pow((double)i / (double)(size - 1), 1. / gamma) + * (double)(size - 1) * 256); + } +} + +static int +xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma) +{ + CARD16 *points, *red, *green, *blue; + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn); + int size; + + if (!crtc) + return Success; + + size = max(0, crtc->gammaSize); + if (!size) + return Success; + + points = calloc(size, 3 * sizeof(CARD16)); + if (!points) + return BadAlloc; + + red = points; + green = points + size; + blue = points + 2 * size; + + gamma_to_ramp(gamma.red, red, size); + gamma_to_ramp(gamma.green, green, size); + gamma_to_ramp(gamma.blue, blue, size); + RRCrtcGammaSet(crtc, red, green, blue); + + free(points); + + pScrn->gamma = gamma; + + return Success; +} + +static Bool +xf86RandR12EnterVT (int screen_index, int flags) +{ + ScreenPtr pScreen = screenInfo.screens[screen_index]; + ScrnInfoPtr pScrn = xf86Screens[screen_index]; + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + rrScrPrivPtr rp = rrGetScrPriv(pScreen); + Bool ret; + int i; + + if (randrp->orig_EnterVT) { + pScrn->EnterVT = randrp->orig_EnterVT; + ret = pScrn->EnterVT (screen_index, flags); + randrp->orig_EnterVT = pScrn->EnterVT; + pScrn->EnterVT = xf86RandR12EnterVT; + if (!ret) + return FALSE; + } + + /* reload gamma */ + for (i = 0; i < rp->numCrtcs; i++) + xf86RandR12CrtcSetGamma(pScreen, rp->crtcs[i]); + + return RRGetInfo (pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */ +} + +static Bool +xf86RandR12Init12 (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + rrScrPrivPtr rp = rrGetScrPriv(pScreen); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + int i; + + rp->rrGetInfo = xf86RandR12GetInfo12; + rp->rrScreenSetSize = xf86RandR12ScreenSetSize; + rp->rrCrtcSet = xf86RandR12CrtcSet; + rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma; + rp->rrCrtcGetGamma = xf86RandR12CrtcGetGamma; + rp->rrOutputSetProperty = xf86RandR12OutputSetProperty; + rp->rrOutputValidateMode = xf86RandR12OutputValidateMode; +#if RANDR_13_INTERFACE + rp->rrOutputGetProperty = xf86RandR13OutputGetProperty; + rp->rrGetPanning = xf86RandR13GetPanning; + rp->rrSetPanning = xf86RandR13SetPanning; +#endif + rp->rrModeDestroy = xf86RandR12ModeDestroy; + rp->rrSetConfig = NULL; + pScrn->PointerMoved = xf86RandR12PointerMoved; + pScrn->ChangeGamma = xf86RandR12ChangeGamma; + + randrp->orig_EnterVT = pScrn->EnterVT; + pScrn->EnterVT = xf86RandR12EnterVT; + + if (!xf86RandR12CreateObjects12 (pScreen)) + return FALSE; + + /* + * Configure output modes + */ + if (!xf86RandR12SetInfo12 (pScreen)) + return FALSE; + for (i = 0; i < rp->numCrtcs; i++) { + xf86RandR12CrtcGetGamma(pScreen, rp->crtcs[i]); + } + return TRUE; +} + +#endif + +Bool +xf86RandR12PreInit (ScrnInfoPtr pScrn) +{ + return TRUE; +} diff --git a/xorg-server/hw/xnest/Pixmap.c b/xorg-server/hw/xnest/Pixmap.c index da81a1d06..eccf56986 100644 --- a/xorg-server/hw/xnest/Pixmap.c +++ b/xorg-server/hw/xnest/Pixmap.c @@ -1,137 +1,136 @@ -/*
-
-Copyright 1993 by Davor Matic
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation. Davor Matic makes no representations about
-the suitability of this software for any purpose. It is provided "as
-is" without express or implied warranty.
-
-*/
-
-#ifdef HAVE_XNEST_CONFIG_H
-#include <xnest-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "regionstr.h"
-#include "pixmapstr.h"
-#include "scrnintstr.h"
-#include "regionstr.h"
-#include "gc.h"
-#include "servermd.h"
-#include "privates.h"
-#include "mi.h"
-
-#include "Xnest.h"
-
-#include "Display.h"
-#include "Screen.h"
-#include "XNPixmap.h"
-
-DevPrivateKeyRec xnestPixmapPrivateKeyRec;
-
-PixmapPtr
-xnestCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
- unsigned usage_hint)
-{
- PixmapPtr pPixmap;
-
- pPixmap = AllocatePixmap(pScreen, 0);
- if (!pPixmap)
- return NullPixmap;
- pPixmap->drawable.type = DRAWABLE_PIXMAP;
- pPixmap->drawable.class = 0;
- pPixmap->drawable.depth = depth;
- pPixmap->drawable.bitsPerPixel = depth;
- pPixmap->drawable.id = 0;
- pPixmap->drawable.x = 0;
- pPixmap->drawable.y = 0;
- pPixmap->drawable.width = width;
- pPixmap->drawable.height = height;
- pPixmap->drawable.pScreen = pScreen;
- pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- pPixmap->refcnt = 1;
- pPixmap->devKind = PixmapBytePad(width, depth);
- pPixmap->usage_hint = usage_hint;
- if (width && height)
- xnestPixmapPriv(pPixmap)->pixmap =
- XCreatePixmap(xnestDisplay,
- xnestDefaultWindows[pScreen->myNum],
- width, height, depth);
- else
- xnestPixmapPriv(pPixmap)->pixmap = 0;
-
- return pPixmap;
-}
-
-Bool
-xnestDestroyPixmap(PixmapPtr pPixmap)
-{
- if(--pPixmap->refcnt)
- return TRUE;
- XFreePixmap(xnestDisplay, xnestPixmap(pPixmap));
- FreePixmap(pPixmap);
- return TRUE;
-}
-
-RegionPtr
-xnestPixmapToRegion(PixmapPtr pPixmap)
-{
- XImage *ximage;
- register RegionPtr pReg, pTmpReg;
- register int x, y;
- unsigned long previousPixel, currentPixel;
- BoxRec Box = { 0, 0, 0, 0 };
- Bool overlap;
-
- ximage = XGetImage(xnestDisplay, xnestPixmap(pPixmap), 0, 0,
- pPixmap->drawable.width, pPixmap->drawable.height,
- 1, XYPixmap);
-
- pReg = RegionCreate(NULL, 1);
- pTmpReg = RegionCreate(NULL, 1);
- if(!pReg || !pTmpReg) {
- XDestroyImage(ximage);
- return NullRegion;
- }
-
- for (y = 0; y < pPixmap->drawable.height; y++) {
- Box.y1 = y;
- Box.y2 = y + 1;
- previousPixel = 0L;
- for (x = 0; x < pPixmap->drawable.width; x++) {
- currentPixel = XGetPixel(ximage, x, y);
- if (previousPixel != currentPixel) {
- if (previousPixel == 0L) {
- /* left edge */
- Box.x1 = x;
- }
- else if (currentPixel == 0L) {
- /* right edge */
- Box.x2 = x;
- RegionReset(pTmpReg, &Box);
- RegionAppend(pReg, pTmpReg);
- }
- previousPixel = currentPixel;
- }
- }
- if (previousPixel != 0L) {
- /* right edge because of the end of pixmap */
- Box.x2 = pPixmap->drawable.width;
- RegionReset(pTmpReg, &Box);
- RegionAppend(pReg, pTmpReg);
- }
- }
-
- RegionDestroy(pTmpReg);
- XDestroyImage(ximage);
-
- RegionValidate(pReg, &overlap);
-
- return pReg;
-}
+/* + +Copyright 1993 by Davor Matic + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation. Davor Matic makes no representations about +the suitability of this software for any purpose. It is provided "as +is" without express or implied warranty. + +*/ + +#ifdef HAVE_XNEST_CONFIG_H +#include <xnest-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "regionstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "gc.h" +#include "servermd.h" +#include "privates.h" +#include "mi.h" + +#include "Xnest.h" + +#include "Display.h" +#include "Screen.h" +#include "XNPixmap.h" + +DevPrivateKeyRec xnestPixmapPrivateKeyRec; + +PixmapPtr +xnestCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, + unsigned usage_hint) +{ + PixmapPtr pPixmap; + + pPixmap = AllocatePixmap(pScreen, 0); + if (!pPixmap) + return NullPixmap; + pPixmap->drawable.type = DRAWABLE_PIXMAP; + pPixmap->drawable.class = 0; + pPixmap->drawable.depth = depth; + pPixmap->drawable.bitsPerPixel = depth; + pPixmap->drawable.id = 0; + pPixmap->drawable.x = 0; + pPixmap->drawable.y = 0; + pPixmap->drawable.width = width; + pPixmap->drawable.height = height; + pPixmap->drawable.pScreen = pScreen; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pPixmap->refcnt = 1; + pPixmap->devKind = PixmapBytePad(width, depth); + pPixmap->usage_hint = usage_hint; + if (width && height) + xnestPixmapPriv(pPixmap)->pixmap = + XCreatePixmap(xnestDisplay, + xnestDefaultWindows[pScreen->myNum], + width, height, depth); + else + xnestPixmapPriv(pPixmap)->pixmap = 0; + + return pPixmap; +} + +Bool +xnestDestroyPixmap(PixmapPtr pPixmap) +{ + if(--pPixmap->refcnt) + return TRUE; + XFreePixmap(xnestDisplay, xnestPixmap(pPixmap)); + FreePixmap(pPixmap); + return TRUE; +} + +RegionPtr +xnestPixmapToRegion(PixmapPtr pPixmap) +{ + XImage *ximage; + register RegionPtr pReg, pTmpReg; + register int x, y; + unsigned long previousPixel, currentPixel; + BoxRec Box = { 0, 0, 0, 0 }; + Bool overlap; + + ximage = XGetImage(xnestDisplay, xnestPixmap(pPixmap), 0, 0, + pPixmap->drawable.width, pPixmap->drawable.height, + 1, XYPixmap); + + pReg = RegionCreate(NULL, 1); + pTmpReg = RegionCreate(NULL, 1); + if(!pReg || !pTmpReg) { + XDestroyImage(ximage); + return NullRegion; + } + + for (y = 0; y < pPixmap->drawable.height; y++) { + Box.y1 = y; + Box.y2 = y + 1; + previousPixel = 0L; + for (x = 0; x < pPixmap->drawable.width; x++) { + currentPixel = XGetPixel(ximage, x, y); + if (previousPixel != currentPixel) { + if (previousPixel == 0L) { + /* left edge */ + Box.x1 = x; + } + else if (currentPixel == 0L) { + /* right edge */ + Box.x2 = x; + RegionReset(pTmpReg, &Box); + RegionAppend(pReg, pTmpReg); + } + previousPixel = currentPixel; + } + } + if (previousPixel != 0L) { + /* right edge because of the end of pixmap */ + Box.x2 = pPixmap->drawable.width; + RegionReset(pTmpReg, &Box); + RegionAppend(pReg, pTmpReg); + } + } + + RegionDestroy(pTmpReg); + XDestroyImage(ximage); + + RegionValidate(pReg, &overlap); + + return pReg; +} diff --git a/xorg-server/hw/xquartz/GL/capabilities.c b/xorg-server/hw/xquartz/GL/capabilities.c index fc7dd57dd..dd3f855f4 100644 --- a/xorg-server/hw/xquartz/GL/capabilities.c +++ b/xorg-server/hw/xquartz/GL/capabilities.c @@ -507,7 +507,7 @@ bool getGlCapabilities(struct glCapabilities *cap) { err = CGLQueryRendererInfo((GLuint)-1, &info, &numRenderers); if(err) { - fprintf(stderr, "CGLQueryRendererInfo error: %s\n", CGLErrorString(err)); + ErrorF("CGLQueryRendererInfo error: %s\n", CGLErrorString(err)); return err; } @@ -518,8 +518,8 @@ bool getGlCapabilities(struct glCapabilities *cap) { err = handleRendererDescriptions(info, r, &tmpconf); if(err) { - fprintf(stderr, "handleRendererDescriptions returned error: %s\n", CGLErrorString(err)); - fprintf(stderr, "trying to continue...\n"); + ErrorF("handleRendererDescriptions returned error: %s\n", CGLErrorString(err)); + ErrorF("trying to continue...\n"); continue; } diff --git a/xorg-server/hw/xquartz/GL/indirect.c b/xorg-server/hw/xquartz/GL/indirect.c index b7ee109ed..6da27c78a 100644 --- a/xorg-server/hw/xquartz/GL/indirect.c +++ b/xorg-server/hw/xquartz/GL/indirect.c @@ -1,1614 +1,1613 @@ -/*
- * GLX implementation that uses Apple's OpenGL.framework
- * (Indirect rendering path -- it's also used for some direct mode code too)
- *
- * Copyright (c) 2007, 2008, 2009 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 <dix-config.h>
-#endif
-
-#include "dri.h"
-
-#include <AvailabilityMacros.h>
-
-#define GL_GLEXT_WUNDEF_SUPPORT
-
-#include <OpenGL/OpenGL.h>
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-#include <OpenGL/CGLContext.h>
-
-/* These next few GL_EXT pre-processing blocks are to explicitly define
- * these symbols to 0 if they are not set by OpenGL.framework. This
- * prevents the X11 glext.h from setting them to 1.
- */
-
-#ifndef GL_EXT_fragment_shader
-#define GL_EXT_fragment_shader 0
-#endif
-
-#ifndef GL_EXT_blend_equation_separate
-#define GL_EXT_blend_equation_separate 0
-#endif
-
-#ifndef GL_EXT_blend_func_separate
-#define GL_EXT_blend_func_separate 0
-#endif
-
-#ifndef GL_EXT_depth_bounds_test
-#define GL_EXT_depth_bounds_test 0
-#endif
-
-#ifndef GL_EXT_compiled_vertex_array
-#define GL_EXT_compiled_vertex_array 0
-#endif
-
-#ifndef GL_EXT_cull_vertex
-#define GL_EXT_cull_vertex 0
-#endif
-
-#ifndef GL_EXT_fog_coord
-#define GL_EXT_fog_coord 0
-#endif
-
-#ifndef GL_EXT_framebuffer_blit
-#define GL_EXT_framebuffer_blit 0
-#endif
-
-#ifndef GL_EXT_framebuffer_object
-#define GL_EXT_framebuffer_object 0
-#endif
-
-#ifndef GL_EXT_gpu_program_parameters
-#define GL_EXT_gpu_program_parameters 0
-#endif
-
-#ifndef GL_EXT_multi_draw_arrays
-#define GL_EXT_multi_draw_arrays 0
-#endif
-
-#ifndef GL_EXT_point_parameters
-#define GL_EXT_point_parameters 0
-#endif
-
-#ifndef GL_EXT_polygon_offset
-#define GL_EXT_polygon_offset 0
-#endif
-
-#ifndef GL_EXT_secondary_color
-#define GL_EXT_secondary_color 0
-#endif
-
-#ifndef GL_EXT_stencil_two_side
-#define GL_EXT_stencil_two_side 0
-#endif
-
-#ifndef GL_EXT_timer_query
-#define GL_EXT_timer_query 0
-#endif
-
-#ifndef GL_EXT_vertex_array
-#define GL_EXT_vertex_array 0
-#endif
-
-/* Tiger PPC doesn't have the associated symbols, but glext.h says it does. Liars!
- * http://trac.macports.org/ticket/20638
- */
-#if defined(__ppc__) && MAC_OS_X_VERSION_MIN_REQUIRED < 1050
-#undef GL_EXT_gpu_program_parameters
-#define GL_EXT_gpu_program_parameters 0
-#endif
-
-#include <GL/glxproto.h>
-#include <windowstr.h>
-#include <resource.h>
-#include <GL/glxint.h>
-#include <GL/glxtokens.h>
-#include <scrnintstr.h>
-#include <glxserver.h>
-#include <glxscreens.h>
-#include <glxdrawable.h>
-#include <glxcontext.h>
-#include <glxext.h>
-#include <glxutil.h>
-#include <glxscreens.h>
-#include <GL/internal/glcore.h>
-#include "x-hash.h"
-#include "x-list.h"
-
-//#include "capabilities.h"
-#include "visualConfigs.h"
-
-typedef unsigned long long GLuint64EXT;
-typedef long long GLint64EXT;
-#include <dispatch.h>
-#include <Xplugin.h>
-#include <glapi.h>
-#include <glapitable.h>
-
-__GLXprovider * GlxGetDRISWrastProvider (void);
-
-// Write debugging output, or not
-#ifdef GLAQUA_DEBUG
-#define GLAQUA_DEBUG_MSG ErrorF
-#else
-#define GLAQUA_DEBUG_MSG(a, ...)
-#endif
-
-static void setup_dispatch_table(void);
-GLuint __glFloorLog2(GLuint val);
-void warn_func(void * p1, char *format, ...);
-
-// some prototypes
-static __GLXscreen * __glXAquaScreenProbe(ScreenPtr pScreen);
-static __GLXdrawable * __glXAquaScreenCreateDrawable(ClientPtr client, __GLXscreen *screen, DrawablePtr pDraw, XID drawId, int type, XID glxDrawId, __GLXconfig *conf);
-
-static void __glXAquaContextDestroy(__GLXcontext *baseContext);
-static int __glXAquaContextMakeCurrent(__GLXcontext *baseContext);
-static int __glXAquaContextLoseCurrent(__GLXcontext *baseContext);
-static int __glXAquaContextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc, unsigned long mask);
-
-static CGLPixelFormatObj makeFormat(__GLXconfig *conf);
-
-__GLXprovider __glXDRISWRastProvider = {
- __glXAquaScreenProbe,
- "Core OpenGL",
- NULL
-};
-
-typedef struct __GLXAquaScreen __GLXAquaScreen;
-typedef struct __GLXAquaContext __GLXAquaContext;
-typedef struct __GLXAquaDrawable __GLXAquaDrawable;
-
-struct __GLXAquaScreen {
- __GLXscreen base;
- int index;
- int num_vis;
-};
-
-struct __GLXAquaContext {
- __GLXcontext base;
- CGLContextObj ctx;
- CGLPixelFormatObj pixelFormat;
- xp_surface_id sid;
- unsigned isAttached :1;
-};
-
-struct __GLXAquaDrawable {
- __GLXdrawable base;
- DrawablePtr pDraw;
- xp_surface_id sid;
- __GLXAquaContext *context;
-};
-
-
-static __GLXcontext *
-__glXAquaScreenCreateContext(__GLXscreen *screen,
- __GLXconfig *conf,
- __GLXcontext *baseShareContext)
-{
- __GLXAquaContext *context;
- __GLXAquaContext *shareContext = (__GLXAquaContext *) baseShareContext;
- CGLError gl_err;
-
- GLAQUA_DEBUG_MSG("glXAquaScreenCreateContext\n");
-
- context = calloc(1, sizeof (__GLXAquaContext));
-
- if (context == NULL)
- return NULL;
-
- memset(context, 0, sizeof *context);
-
- context->base.pGlxScreen = screen;
-
- context->base.destroy = __glXAquaContextDestroy;
- context->base.makeCurrent = __glXAquaContextMakeCurrent;
- context->base.loseCurrent = __glXAquaContextLoseCurrent;
- context->base.copy = __glXAquaContextCopy;
- /*FIXME verify that the context->base is fully initialized. */
-
- context->pixelFormat = makeFormat(conf);
-
- if (!context->pixelFormat) {
- free(context);
- return NULL;
- }
-
- context->ctx = NULL;
- gl_err = CGLCreateContext(context->pixelFormat,
- shareContext ? shareContext->ctx : NULL,
- &context->ctx);
-
- if (gl_err != 0) {
- ErrorF("CGLCreateContext error: %s\n", CGLErrorString(gl_err));
- CGLDestroyPixelFormat(context->pixelFormat);
- free(context);
- return NULL;
- }
-
- setup_dispatch_table();
- GLAQUA_DEBUG_MSG("glAquaCreateContext done\n");
-
- return &context->base;
-}
-
-/* maps from surface id -> list of __GLcontext */
-static x_hash_table *surface_hash;
-
-static void __glXAquaContextDestroy(__GLXcontext *baseContext) {
- x_list *lst;
-
- __GLXAquaContext *context = (__GLXAquaContext *) baseContext;
-
- GLAQUA_DEBUG_MSG("glAquaContextDestroy (ctx %p)\n", baseContext);
- if (context != NULL) {
- if (context->sid != 0 && surface_hash != NULL) {
- lst = x_hash_table_lookup(surface_hash, x_cvt_uint_to_vptr(context->sid), NULL);
- lst = x_list_remove(lst, context);
- x_hash_table_insert(surface_hash, x_cvt_uint_to_vptr(context->sid), lst);
- }
-
- if (context->ctx != NULL)
- CGLDestroyContext(context->ctx);
-
- if (context->pixelFormat != NULL)
- CGLDestroyPixelFormat(context->pixelFormat);
-
- free(context);
- }
-}
-
-static int __glXAquaContextLoseCurrent(__GLXcontext *baseContext) {
- CGLError gl_err;
-
- GLAQUA_DEBUG_MSG("glAquaLoseCurrent (ctx 0x%p)\n", baseContext);
-
- gl_err = CGLSetCurrentContext(NULL);
- if (gl_err != 0)
- ErrorF("CGLSetCurrentContext error: %s\n", CGLErrorString(gl_err));
-
- __glXLastContext = NULL; // Mesa does this; why?
-
- return GL_TRUE;
-}
-
-/* Called when a surface is destroyed as a side effect of destroying
- the window it's attached to. */
-static void surface_notify(void *_arg, void *data) {
- DRISurfaceNotifyArg *arg = (DRISurfaceNotifyArg *)_arg;
- __GLXAquaDrawable *draw = (__GLXAquaDrawable *)data;
- __GLXAquaContext *context;
- x_list *lst;
- if(_arg == NULL || data == NULL) {
- ErrorF("surface_notify called with bad params");
- return;
- }
-
- GLAQUA_DEBUG_MSG("surface_notify(%p, %p)\n", _arg, data);
- switch (arg->kind) {
- case AppleDRISurfaceNotifyDestroyed:
- if (surface_hash != NULL)
- x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(arg->id));
- draw->pDraw = NULL;
- draw->sid = 0;
- break;
-
- case AppleDRISurfaceNotifyChanged:
- if (surface_hash != NULL) {
- lst = x_hash_table_lookup(surface_hash, x_cvt_uint_to_vptr(arg->id), NULL);
- for (; lst != NULL; lst = lst->next)
- {
- context = lst->data;
- xp_update_gl_context(context->ctx);
- }
- }
- break;
- default:
- ErrorF("surface_notify: unknown kind %d\n", arg->kind);
- break;
- }
-}
-
-static BOOL attach(__GLXAquaContext *context, __GLXAquaDrawable *draw) {
- DrawablePtr pDraw;
-
- GLAQUA_DEBUG_MSG("attach(%p, %p)\n", context, draw);
-
- if(NULL == context || NULL == draw)
- return TRUE;
-
- pDraw = draw->base.pDraw;
-
- if(NULL == pDraw) {
- ErrorF("%s:%s() pDraw is NULL!\n", __FILE__, __func__);
- return TRUE;
- }
-
- if (draw->sid == 0) {
- //if (!quartzProcs->CreateSurface(pDraw->pScreen, pDraw->id, pDraw,
- if (!DRICreateSurface(pDraw->pScreen, pDraw->id, pDraw,
- 0, &draw->sid, NULL,
- surface_notify, draw))
- return TRUE;
- draw->pDraw = pDraw;
- }
-
- if (!context->isAttached || context->sid != draw->sid) {
- x_list *lst;
-
- if (xp_attach_gl_context(context->ctx, draw->sid) != Success) {
- //quartzProcs->DestroySurface(pDraw->pScreen, pDraw->id, pDraw,
- DRIDestroySurface(pDraw->pScreen, pDraw->id, pDraw,
- surface_notify, draw);
- if (surface_hash != NULL)
- x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(draw->sid));
-
- draw->sid = 0;
- return TRUE;
- }
-
- context->isAttached = TRUE;
- context->sid = draw->sid;
-
- if (surface_hash == NULL)
- surface_hash = x_hash_table_new(NULL, NULL, NULL, NULL);
-
- lst = x_hash_table_lookup(surface_hash, x_cvt_uint_to_vptr(context->sid), NULL);
- if (x_list_find(lst, context) == NULL) {
- lst = x_list_prepend(lst, context);
- x_hash_table_insert(surface_hash, x_cvt_uint_to_vptr(context->sid), lst);
- }
-
-
-
- GLAQUA_DEBUG_MSG("attached 0x%x to 0x%x\n", (unsigned int) pDraw->id,
- (unsigned int) draw->sid);
- }
-
- draw->context = context;
-
- return FALSE;
-}
-
-#if 0 // unused
-static void unattach(__GLXAquaContext *context) {
- x_list *lst;
- GLAQUA_DEBUG_MSG("unattach\n");
- if (context == NULL) {
- ErrorF("Tried to unattach a null context\n");
- return;
- }
- if (context->isAttached) {
- GLAQUA_DEBUG_MSG("unattaching\n");
-
- if (surface_hash != NULL) {
- lst = x_hash_table_lookup(surface_hash, (void *) context->sid, NULL);
- lst = x_list_remove(lst, context);
- x_hash_table_insert(surface_hash, (void *) context->sid, lst);
- }
-
- CGLClearDrawable(context->ctx);
- context->isAttached = FALSE;
- context->sid = 0;
- }
-}
-#endif
-
-static int __glXAquaContextMakeCurrent(__GLXcontext *baseContext) {
- CGLError gl_err;
- __GLXAquaContext *context = (__GLXAquaContext *) baseContext;
- __GLXAquaDrawable *drawPriv = (__GLXAquaDrawable *) context->base.drawPriv;
-
- GLAQUA_DEBUG_MSG("glAquaMakeCurrent (ctx 0x%p)\n", baseContext);
-
- if(attach(context, drawPriv))
- return /*error*/ 0;
-
- gl_err = CGLSetCurrentContext(context->ctx);
- if (gl_err != 0)
- ErrorF("CGLSetCurrentContext error: %s\n", CGLErrorString(gl_err));
-
- return gl_err == 0;
-}
-
-static int __glXAquaContextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc, unsigned long mask)
-{
- CGLError gl_err;
-
- __GLXAquaContext *dst = (__GLXAquaContext *) baseDst;
- __GLXAquaContext *src = (__GLXAquaContext *) baseSrc;
-
- GLAQUA_DEBUG_MSG("GLXAquaContextCopy\n");
-
- gl_err = CGLCopyContext(src->ctx, dst->ctx, mask);
- if (gl_err != 0)
- ErrorF("CGLCopyContext error: %s\n", CGLErrorString(gl_err));
-
- return gl_err == 0;
-}
-
-/* Drawing surface notification callbacks */
-static GLboolean __glXAquaDrawableSwapBuffers(ClientPtr client, __GLXdrawable *base) {
- CGLError err;
- __GLXAquaDrawable *drawable;
-
- // GLAQUA_DEBUG_MSG("glAquaDrawableSwapBuffers(%p)\n",base);
-
- if(!base) {
- ErrorF("%s passed NULL\n", __func__);
- return GL_FALSE;
- }
-
- drawable = (__GLXAquaDrawable *)base;
-
- if(NULL == drawable->context) {
- ErrorF("%s called with a NULL->context for drawable %p!\n",
- __func__, (void *)drawable);
- return GL_FALSE;
- }
-
- err = CGLFlushDrawable(drawable->context->ctx);
-
- if(kCGLNoError != err) {
- ErrorF("CGLFlushDrawable error: %s in %s\n", CGLErrorString(err),
- __func__);
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
-
-
-static CGLPixelFormatObj makeFormat(__GLXconfig *conf) {
- CGLPixelFormatAttribute attr[64];
- CGLPixelFormatObj fobj;
- GLint formats;
- CGLError error;
- int i = 0;
-
- if(conf->doubleBufferMode)
- attr[i++] = kCGLPFADoubleBuffer;
-
- if(conf->stereoMode)
- attr[i++] = kCGLPFAStereo;
-
- attr[i++] = kCGLPFAColorSize;
- attr[i++] = conf->redBits + conf->greenBits + conf->blueBits;
- attr[i++] = kCGLPFAAlphaSize;
- attr[i++] = conf->alphaBits;
-
- if((conf->accumRedBits + conf->accumGreenBits + conf->accumBlueBits +
- conf->accumAlphaBits) > 0) {
-
- attr[i++] = kCGLPFAAccumSize;
- attr[i++] = conf->accumRedBits + conf->accumGreenBits
- + conf->accumBlueBits + conf->accumAlphaBits;
- }
-
- attr[i++] = kCGLPFADepthSize;
- attr[i++] = conf->depthBits;
-
- if(conf->stencilBits) {
- attr[i++] = kCGLPFAStencilSize;
- attr[i++] = conf->stencilBits;
- }
-
- if(conf->numAuxBuffers > 0) {
- attr[i++] = kCGLPFAAuxBuffers;
- attr[i++] = conf->numAuxBuffers;
- }
-
- if(conf->sampleBuffers > 0) {
- attr[i++] = kCGLPFASampleBuffers;
- attr[i++] = conf->sampleBuffers;
- attr[i++] = kCGLPFASamples;
- attr[i++] = conf->samples;
- }
-
- attr[i] = 0;
-
- error = CGLChoosePixelFormat(attr, &fobj, &formats);
- if(error) {
- ErrorF("error: creating pixel format %s\n", CGLErrorString(error));
- return NULL;
- }
-
- return fobj;
-}
-
-static void __glXAquaScreenDestroy(__GLXscreen *screen) {
-
- GLAQUA_DEBUG_MSG("glXAquaScreenDestroy(%p)\n", screen);
- __glXScreenDestroy(screen);
-
- free(screen);
-}
-
-/* This is called by __glXInitScreens(). */
-static __GLXscreen * __glXAquaScreenProbe(ScreenPtr pScreen) {
- __GLXAquaScreen *screen;
-
- GLAQUA_DEBUG_MSG("glXAquaScreenProbe\n");
-
- if (pScreen == NULL)
- return NULL;
-
- screen = calloc(1, sizeof *screen);
-
- if(NULL == screen)
- return NULL;
-
- screen->base.destroy = __glXAquaScreenDestroy;
- screen->base.createContext = __glXAquaScreenCreateContext;
- screen->base.createDrawable = __glXAquaScreenCreateDrawable;
- screen->base.swapInterval = /*FIXME*/ NULL;
- screen->base.pScreen = pScreen;
-
- screen->base.fbconfigs = __glXAquaCreateVisualConfigs(&screen->base.numFBConfigs, pScreen->myNum);
-
- __glXScreenInit(&screen->base, pScreen);
-
- screen->base.GLXversion = strdup("1.4");
- screen->base.GLXextensions = strdup("GLX_SGIX_fbconfig "
- "GLX_SGIS_multisample "
- "GLX_ARB_multisample "
- "GLX_EXT_visual_info "
- "GLX_EXT_import_context ");
-
- /*We may be able to add more GLXextensions at a later time. */
-
- return &screen->base;
-}
-
-#if 0 // unused
-static void __glXAquaDrawableCopySubBuffer (__GLXdrawable *drawable,
- int x, int y, int w, int h) {
- /*TODO finish me*/
-}
-#endif
-
-static void __glXAquaDrawableDestroy(__GLXdrawable *base) {
- /* gstaplin: base is the head of the structure, so it's at the same
- * offset in memory.
- * Is this safe with strict aliasing? I noticed that the other dri code
- * does this too...
- */
- __GLXAquaDrawable *glxPriv = (__GLXAquaDrawable *)base;
-
- GLAQUA_DEBUG_MSG(__func__);
-
- /* It doesn't work to call DRIDestroySurface here, the drawable's
- already gone.. But dri.c notices the window destruction and
- frees the surface itself. */
-
- /*gstaplin: verify the statement above. The surface destroy
- *messages weren't making it through, and may still not be.
- *We need a good test case for surface creation and destruction.
- *We also need a good way to enable introspection on the server
- *to validate the test, beyond using gdb with print.
- */
-
- free(glxPriv);
-}
-
-static __GLXdrawable *
-__glXAquaScreenCreateDrawable(ClientPtr client,
- __GLXscreen *screen,
- DrawablePtr pDraw,
- XID drawId,
- int type,
- XID glxDrawId,
- __GLXconfig *conf) {
- __GLXAquaDrawable *glxPriv;
-
- glxPriv = malloc(sizeof *glxPriv);
-
- if(glxPriv == NULL)
- return NULL;
-
- memset(glxPriv, 0, sizeof *glxPriv);
-
- if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, glxDrawId, conf)) {
- free(glxPriv);
- return NULL;
- }
-
- glxPriv->base.destroy = __glXAquaDrawableDestroy;
- glxPriv->base.swapBuffers = __glXAquaDrawableSwapBuffers;
- glxPriv->base.copySubBuffer = NULL; /* __glXAquaDrawableCopySubBuffer; */
-
- glxPriv->pDraw = pDraw;
- glxPriv->sid = 0;
- glxPriv->context = NULL;
-
- return &glxPriv->base;
-}
-
-// Extra goodies for glx
-
-GLuint __glFloorLog2(GLuint val)
-{
- int c = 0;
-
- while (val > 1) {
- c++;
- val >>= 1;
- }
- return c;
-}
-
-static void setup_dispatch_table(void) {
- struct _glapi_table *disp=_glapi_get_dispatch();
-
- /* to update:
- * for f in $(grep 'define SET_' ../../../glx/dispatch.h | cut -f2 -d' ' | cut -f1 -d\( | sort -u); do grep -q $f indirect.c || echo $f ; done | grep -v by_offset | sed 's:SET_\(.*\)$:SET_\1(disp, gl\1)\;:' | pbcopy
- */
-
- SET_Accum(disp, glAccum);
- SET_AlphaFunc(disp, glAlphaFunc);
- SET_AreTexturesResident(disp, glAreTexturesResident);
- SET_ArrayElement(disp, glArrayElement);
- SET_Begin(disp, glBegin);
- SET_BindTexture(disp, glBindTexture);
- SET_Bitmap(disp, glBitmap);
- SET_BlendColor(disp, glBlendColor);
- SET_BlendEquation(disp, glBlendEquation);
- SET_BlendFunc(disp, glBlendFunc);
- SET_CallList(disp, glCallList);
- SET_CallLists(disp, glCallLists);
- SET_Clear(disp, glClear);
- SET_ClearAccum(disp, glClearAccum);
- SET_ClearColor(disp, glClearColor);
- SET_ClearDepth(disp, glClearDepth);
- SET_ClearIndex(disp, glClearIndex);
- SET_ClearStencil(disp, glClearStencil);
- SET_ClipPlane(disp, glClipPlane);
- SET_Color3b(disp, glColor3b);
- SET_Color3bv(disp, glColor3bv);
- SET_Color3d(disp, glColor3d);
- SET_Color3dv(disp, glColor3dv);
- SET_Color3f(disp, glColor3f);
- SET_Color3fv(disp, glColor3fv);
- SET_Color3i(disp, glColor3i);
- SET_Color3iv(disp, glColor3iv);
- SET_Color3s(disp, glColor3s);
- SET_Color3sv(disp, glColor3sv);
- SET_Color3ub(disp, glColor3ub);
- SET_Color3ubv(disp, glColor3ubv);
- SET_Color3ui(disp, glColor3ui);
- SET_Color3uiv(disp, glColor3uiv);
- SET_Color3us(disp, glColor3us);
- SET_Color3usv(disp, glColor3usv);
- SET_Color4b(disp, glColor4b);
- SET_Color4bv(disp, glColor4bv);
- SET_Color4d(disp, glColor4d);
- SET_Color4dv(disp, glColor4dv);
- SET_Color4f(disp, glColor4f);
- SET_Color4fv(disp, glColor4fv);
- SET_Color4i(disp, glColor4i);
- SET_Color4iv(disp, glColor4iv);
- SET_Color4s(disp, glColor4s);
- SET_Color4sv(disp, glColor4sv);
- SET_Color4ub(disp, glColor4ub);
- SET_Color4ubv(disp, glColor4ubv);
- SET_Color4ui(disp, glColor4ui);
- SET_Color4uiv(disp, glColor4uiv);
- SET_Color4us(disp, glColor4us);
- SET_Color4usv(disp, glColor4usv);
- SET_ColorMask(disp, glColorMask);
- SET_ColorMaterial(disp, glColorMaterial);
- SET_ColorPointer(disp, glColorPointer);
- SET_ColorSubTable(disp, glColorSubTable);
- SET_ColorTable(disp, glColorTable);
- SET_ColorTableParameterfv(disp, glColorTableParameterfv);
- SET_ColorTableParameteriv(disp, glColorTableParameteriv);
- SET_ConvolutionFilter1D(disp, glConvolutionFilter1D);
- SET_ConvolutionFilter2D(disp, glConvolutionFilter2D);
- SET_ConvolutionParameterf(disp, glConvolutionParameterf);
- SET_ConvolutionParameterfv(disp, glConvolutionParameterfv);
- SET_ConvolutionParameteri(disp, glConvolutionParameteri);
- SET_ConvolutionParameteriv(disp, glConvolutionParameteriv);
- SET_CopyColorSubTable(disp, glCopyColorSubTable);
- SET_CopyColorTable(disp, glCopyColorTable);
- SET_CopyConvolutionFilter1D(disp, glCopyConvolutionFilter1D);
- SET_CopyConvolutionFilter2D(disp, glCopyConvolutionFilter2D);
- SET_CopyPixels(disp, glCopyPixels);
- SET_CopyTexImage1D(disp, glCopyTexImage1D);
- SET_CopyTexImage2D(disp, glCopyTexImage2D);
- SET_CopyTexSubImage1D(disp, glCopyTexSubImage1D);
- SET_CopyTexSubImage2D(disp, glCopyTexSubImage2D);
- SET_CopyTexSubImage3D(disp, glCopyTexSubImage3D);
- SET_CullFace(disp, glCullFace);
- SET_DeleteLists(disp, glDeleteLists);
- SET_DeleteTextures(disp, glDeleteTextures);
- SET_DepthFunc(disp, glDepthFunc);
- SET_DepthMask(disp, glDepthMask);
- SET_DepthRange(disp, glDepthRange);
- SET_Disable(disp, glDisable);
- SET_DisableClientState(disp, glDisableClientState);
- SET_DrawArrays(disp, glDrawArrays);
- SET_DrawBuffer(disp, glDrawBuffer);
- SET_DrawElements(disp, glDrawElements);
- SET_DrawPixels(disp, glDrawPixels);
- SET_DrawRangeElements(disp, glDrawRangeElements);
- SET_EdgeFlag(disp, glEdgeFlag);
- SET_EdgeFlagPointer(disp, glEdgeFlagPointer);
- SET_EdgeFlagv(disp, glEdgeFlagv);
- SET_Enable(disp, glEnable);
- SET_EnableClientState(disp, glEnableClientState);
- SET_End(disp, glEnd);
- SET_EndList(disp, glEndList);
- SET_EvalCoord1d(disp, glEvalCoord1d);
- SET_EvalCoord1dv(disp, glEvalCoord1dv);
- SET_EvalCoord1f(disp, glEvalCoord1f);
- SET_EvalCoord1fv(disp, glEvalCoord1fv);
- SET_EvalCoord2d(disp, glEvalCoord2d);
- SET_EvalCoord2dv(disp, glEvalCoord2dv);
- SET_EvalCoord2f(disp, glEvalCoord2f);
- SET_EvalCoord2fv(disp, glEvalCoord2fv);
- SET_EvalMesh1(disp, glEvalMesh1);
- SET_EvalMesh2(disp, glEvalMesh2);
- SET_EvalPoint1(disp, glEvalPoint1);
- SET_EvalPoint2(disp, glEvalPoint2);
- SET_FeedbackBuffer(disp, glFeedbackBuffer);
- SET_Finish(disp, glFinish);
- SET_Flush(disp, glFlush);
- SET_Fogf(disp, glFogf);
- SET_Fogfv(disp, glFogfv);
- SET_Fogi(disp, glFogi);
- SET_Fogiv(disp, glFogiv);
- SET_FrontFace(disp, glFrontFace);
- SET_Frustum(disp, glFrustum);
- SET_GenLists(disp, glGenLists);
- SET_GenTextures(disp, glGenTextures);
- SET_GetBooleanv(disp, glGetBooleanv);
- SET_GetClipPlane(disp, glGetClipPlane);
- SET_GetColorTable(disp, glGetColorTable);
- SET_GetColorTableParameterfv(disp, glGetColorTableParameterfv);
- SET_GetColorTableParameteriv(disp, glGetColorTableParameteriv);
- SET_GetConvolutionFilter(disp, glGetConvolutionFilter);
- SET_GetConvolutionParameterfv(disp, glGetConvolutionParameterfv);
- SET_GetConvolutionParameteriv(disp, glGetConvolutionParameteriv);
- SET_GetDoublev(disp, glGetDoublev);
- SET_GetError(disp, glGetError);
- SET_GetFloatv(disp, glGetFloatv);
- SET_GetHistogram(disp, glGetHistogram);
- SET_GetHistogramParameterfv(disp, glGetHistogramParameterfv);
- SET_GetHistogramParameteriv(disp, glGetHistogramParameteriv);
- SET_GetIntegerv(disp, glGetIntegerv);
- SET_GetLightfv(disp, glGetLightfv);
- SET_GetLightiv(disp, glGetLightiv);
- SET_GetMapdv(disp, glGetMapdv);
- SET_GetMapfv(disp, glGetMapfv);
- SET_GetMapiv(disp, glGetMapiv);
- SET_GetMaterialfv(disp, glGetMaterialfv);
- SET_GetMaterialiv(disp, glGetMaterialiv);
- SET_GetMinmax(disp, glGetMinmax);
- SET_GetMinmaxParameterfv(disp, glGetMinmaxParameterfv);
- SET_GetMinmaxParameteriv(disp, glGetMinmaxParameteriv);
- SET_GetPixelMapfv(disp, glGetPixelMapfv);
- SET_GetPixelMapuiv(disp, glGetPixelMapuiv);
- SET_GetPixelMapusv(disp, glGetPixelMapusv);
- SET_GetPointerv(disp, glGetPointerv);
- SET_GetPolygonStipple(disp, glGetPolygonStipple);
- SET_GetSeparableFilter(disp, glGetSeparableFilter);
- SET_GetString(disp, glGetString);
- SET_GetTexEnvfv(disp, glGetTexEnvfv);
- SET_GetTexEnviv(disp, glGetTexEnviv);
- SET_GetTexGendv(disp, glGetTexGendv);
- SET_GetTexGenfv(disp, glGetTexGenfv);
- SET_GetTexGeniv(disp, glGetTexGeniv);
- SET_GetTexImage(disp, glGetTexImage);
- SET_GetTexLevelParameterfv(disp, glGetTexLevelParameterfv);
- SET_GetTexLevelParameteriv(disp, glGetTexLevelParameteriv);
- SET_GetTexParameterfv(disp, glGetTexParameterfv);
- SET_GetTexParameteriv(disp, glGetTexParameteriv);
- SET_Hint(disp, glHint);
- SET_Histogram(disp, glHistogram);
- SET_IndexMask(disp, glIndexMask);
- SET_IndexPointer(disp, glIndexPointer);
- SET_Indexd(disp, glIndexd);
- SET_Indexdv(disp, glIndexdv);
- SET_Indexf(disp, glIndexf);
- SET_Indexfv(disp, glIndexfv);
- SET_Indexi(disp, glIndexi);
- SET_Indexiv(disp, glIndexiv);
- SET_Indexs(disp, glIndexs);
- SET_Indexsv(disp, glIndexsv);
- SET_Indexub(disp, glIndexub);
- SET_Indexubv(disp, glIndexubv);
- SET_InitNames(disp, glInitNames);
- SET_InterleavedArrays(disp, glInterleavedArrays);
- SET_IsEnabled(disp, glIsEnabled);
- SET_IsList(disp, glIsList);
- SET_IsTexture(disp, glIsTexture);
- SET_LightModelf(disp, glLightModelf);
- SET_LightModelfv(disp, glLightModelfv);
- SET_LightModeli(disp, glLightModeli);
- SET_LightModeliv(disp, glLightModeliv);
- SET_Lightf(disp, glLightf);
- SET_Lightfv(disp, glLightfv);
- SET_Lighti(disp, glLighti);
- SET_Lightiv(disp, glLightiv);
- SET_LineStipple(disp, glLineStipple);
- SET_LineWidth(disp, glLineWidth);
- SET_ListBase(disp, glListBase);
- SET_LoadIdentity(disp, glLoadIdentity);
- SET_LoadMatrixd(disp, glLoadMatrixd);
- SET_LoadMatrixf(disp, glLoadMatrixf);
- SET_LoadName(disp, glLoadName);
- SET_LogicOp(disp, glLogicOp);
- SET_Map1d(disp, glMap1d);
- SET_Map1f(disp, glMap1f);
- SET_Map2d(disp, glMap2d);
- SET_Map2f(disp, glMap2f);
- SET_MapGrid1d(disp, glMapGrid1d);
- SET_MapGrid1f(disp, glMapGrid1f);
- SET_MapGrid2d(disp, glMapGrid2d);
- SET_MapGrid2f(disp, glMapGrid2f);
- SET_Materialf(disp, glMaterialf);
- SET_Materialfv(disp, glMaterialfv);
- SET_Materiali(disp, glMateriali);
- SET_Materialiv(disp, glMaterialiv);
- SET_MatrixMode(disp, glMatrixMode);
- SET_Minmax(disp, glMinmax);
- SET_MultMatrixd(disp, glMultMatrixd);
- SET_MultMatrixf(disp, glMultMatrixf);
- SET_NewList(disp, glNewList);
- SET_Normal3b(disp, glNormal3b);
- SET_Normal3bv(disp, glNormal3bv);
- SET_Normal3d(disp, glNormal3d);
- SET_Normal3dv(disp, glNormal3dv);
- SET_Normal3f(disp, glNormal3f);
- SET_Normal3fv(disp, glNormal3fv);
- SET_Normal3i(disp, glNormal3i);
- SET_Normal3iv(disp, glNormal3iv);
- SET_Normal3s(disp, glNormal3s);
- SET_Normal3sv(disp, glNormal3sv);
- SET_NormalPointer(disp, glNormalPointer);
- SET_Ortho(disp, glOrtho);
- SET_PassThrough(disp, glPassThrough);
- SET_PixelMapfv(disp, glPixelMapfv);
- SET_PixelMapuiv(disp, glPixelMapuiv);
- SET_PixelMapusv(disp, glPixelMapusv);
- SET_PixelStoref(disp, glPixelStoref);
- SET_PixelStorei(disp, glPixelStorei);
- SET_PixelTransferf(disp, glPixelTransferf);
- SET_PixelTransferi(disp, glPixelTransferi);
- SET_PixelZoom(disp, glPixelZoom);
- SET_PointSize(disp, glPointSize);
- SET_PolygonMode(disp, glPolygonMode);
- SET_PolygonOffset(disp, glPolygonOffset);
- SET_PolygonStipple(disp, glPolygonStipple);
- SET_PopAttrib(disp, glPopAttrib);
- SET_PopClientAttrib(disp, glPopClientAttrib);
- SET_PopMatrix(disp, glPopMatrix);
- SET_PopName(disp, glPopName);
- SET_PrioritizeTextures(disp, glPrioritizeTextures);
- SET_PushAttrib(disp, glPushAttrib);
- SET_PushClientAttrib(disp, glPushClientAttrib);
- SET_PushMatrix(disp, glPushMatrix);
- SET_PushName(disp, glPushName);
- SET_RasterPos2d(disp, glRasterPos2d);
- SET_RasterPos2dv(disp, glRasterPos2dv);
- SET_RasterPos2f(disp, glRasterPos2f);
- SET_RasterPos2fv(disp, glRasterPos2fv);
- SET_RasterPos2i(disp, glRasterPos2i);
- SET_RasterPos2iv(disp, glRasterPos2iv);
- SET_RasterPos2s(disp, glRasterPos2s);
- SET_RasterPos2sv(disp, glRasterPos2sv);
- SET_RasterPos3d(disp, glRasterPos3d);
- SET_RasterPos3dv(disp, glRasterPos3dv);
- SET_RasterPos3f(disp, glRasterPos3f);
- SET_RasterPos3fv(disp, glRasterPos3fv);
- SET_RasterPos3i(disp, glRasterPos3i);
- SET_RasterPos3iv(disp, glRasterPos3iv);
- SET_RasterPos3s(disp, glRasterPos3s);
- SET_RasterPos3sv(disp, glRasterPos3sv);
- SET_RasterPos4d(disp, glRasterPos4d);
- SET_RasterPos4dv(disp, glRasterPos4dv);
- SET_RasterPos4f(disp, glRasterPos4f);
- SET_RasterPos4fv(disp, glRasterPos4fv);
- SET_RasterPos4i(disp, glRasterPos4i);
- SET_RasterPos4iv(disp, glRasterPos4iv);
- SET_RasterPos4s(disp, glRasterPos4s);
- SET_RasterPos4sv(disp, glRasterPos4sv);
- SET_ReadBuffer(disp, glReadBuffer);
- SET_ReadPixels(disp, glReadPixels);
- SET_Rectd(disp, glRectd);
- SET_Rectdv(disp, glRectdv);
- SET_Rectf(disp, glRectf);
- SET_Rectfv(disp, glRectfv);
- SET_Recti(disp, glRecti);
- SET_Rectiv(disp, glRectiv);
- SET_Rects(disp, glRects);
- SET_Rectsv(disp, glRectsv);
- SET_RenderMode(disp, glRenderMode);
- SET_ResetHistogram(disp, glResetHistogram);
- SET_ResetMinmax(disp, glResetMinmax);
- SET_Rotated(disp, glRotated);
- SET_Rotatef(disp, glRotatef);
- SET_Scaled(disp, glScaled);
- SET_Scalef(disp, glScalef);
- SET_Scissor(disp, glScissor);
- SET_SelectBuffer(disp, glSelectBuffer);
- SET_SeparableFilter2D(disp, glSeparableFilter2D);
- SET_ShadeModel(disp, glShadeModel);
- SET_StencilFunc(disp, glStencilFunc);
- SET_StencilMask(disp, glStencilMask);
- SET_StencilOp(disp, glStencilOp);
- SET_TexCoord1d(disp, glTexCoord1d);
- SET_TexCoord1dv(disp, glTexCoord1dv);
- SET_TexCoord1f(disp, glTexCoord1f);
- SET_TexCoord1fv(disp, glTexCoord1fv);
- SET_TexCoord1i(disp, glTexCoord1i);
- SET_TexCoord1iv(disp, glTexCoord1iv);
- SET_TexCoord1s(disp, glTexCoord1s);
- SET_TexCoord1sv(disp, glTexCoord1sv);
- SET_TexCoord2d(disp, glTexCoord2d);
- SET_TexCoord2dv(disp, glTexCoord2dv);
- SET_TexCoord2f(disp, glTexCoord2f);
- SET_TexCoord2fv(disp, glTexCoord2fv);
- SET_TexCoord2i(disp, glTexCoord2i);
- SET_TexCoord2iv(disp, glTexCoord2iv);
- SET_TexCoord2s(disp, glTexCoord2s);
- SET_TexCoord2sv(disp, glTexCoord2sv);
- SET_TexCoord3d(disp, glTexCoord3d);
- SET_TexCoord3dv(disp, glTexCoord3dv);
- SET_TexCoord3f(disp, glTexCoord3f);
- SET_TexCoord3fv(disp, glTexCoord3fv);
- SET_TexCoord3i(disp, glTexCoord3i);
- SET_TexCoord3iv(disp, glTexCoord3iv);
- SET_TexCoord3s(disp, glTexCoord3s);
- SET_TexCoord3sv(disp, glTexCoord3sv);
- SET_TexCoord4d(disp, glTexCoord4d);
- SET_TexCoord4dv(disp, glTexCoord4dv);
- SET_TexCoord4f(disp, glTexCoord4f);
- SET_TexCoord4fv(disp, glTexCoord4fv);
- SET_TexCoord4i(disp, glTexCoord4i);
- SET_TexCoord4iv(disp, glTexCoord4iv);
- SET_TexCoord4s(disp, glTexCoord4s);
- SET_TexCoord4sv(disp, glTexCoord4sv);
- SET_TexCoordPointer(disp, glTexCoordPointer);
- SET_TexEnvf(disp, glTexEnvf);
- SET_TexEnvfv(disp, glTexEnvfv);
- SET_TexEnvi(disp, glTexEnvi);
- SET_TexEnviv(disp, glTexEnviv);
- SET_TexGend(disp, glTexGend);
- SET_TexGendv(disp, glTexGendv);
- SET_TexGenf(disp, glTexGenf);
- SET_TexGenfv(disp, glTexGenfv);
- SET_TexGeni(disp, glTexGeni);
- SET_TexGeniv(disp, glTexGeniv);
-
- /* Pointer Incompatability:
- * internalformat is a GLenum according to /System/Library/Frameworks/OpenGL.framework/Headers/gl.h
- * extern void glTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- * extern void glTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- * extern void glTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- *
- * and it's a GLint in glx/glapitable.h and according to the man page
- * void ( * TexImage1D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid * pixels);
- * void ( * TexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels);
- * void ( * TexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels);
- *
- * <rdar://problem/6953344> gl.h contains incorrect prototypes for glTexImage[123]D
- */
-
- SET_TexImage1D(disp, (void *)glTexImage1D);
- SET_TexImage2D(disp, (void *)glTexImage2D);
- SET_TexImage3D(disp, (void *)glTexImage3D);
- SET_TexParameterf(disp, glTexParameterf);
- SET_TexParameterfv(disp, glTexParameterfv);
- SET_TexParameteri(disp, glTexParameteri);
- SET_TexParameteriv(disp, glTexParameteriv);
- SET_TexSubImage1D(disp, glTexSubImage1D);
- SET_TexSubImage2D(disp, glTexSubImage2D);
- SET_TexSubImage3D(disp, glTexSubImage3D);
- SET_Translated(disp, glTranslated);
- SET_Translatef(disp, glTranslatef);
- SET_Vertex2d(disp, glVertex2d);
- SET_Vertex2dv(disp, glVertex2dv);
- SET_Vertex2f(disp, glVertex2f);
- SET_Vertex2fv(disp, glVertex2fv);
- SET_Vertex2i(disp, glVertex2i);
- SET_Vertex2iv(disp, glVertex2iv);
- SET_Vertex2s(disp, glVertex2s);
- SET_Vertex2sv(disp, glVertex2sv);
- SET_Vertex3d(disp, glVertex3d);
- SET_Vertex3dv(disp, glVertex3dv);
- SET_Vertex3f(disp, glVertex3f);
- SET_Vertex3fv(disp, glVertex3fv);
- SET_Vertex3i(disp, glVertex3i);
- SET_Vertex3iv(disp, glVertex3iv);
- SET_Vertex3s(disp, glVertex3s);
- SET_Vertex3sv(disp, glVertex3sv);
- SET_Vertex4d(disp, glVertex4d);
- SET_Vertex4dv(disp, glVertex4dv);
- SET_Vertex4f(disp, glVertex4f);
- SET_Vertex4fv(disp, glVertex4fv);
- SET_Vertex4i(disp, glVertex4i);
- SET_Vertex4iv(disp, glVertex4iv);
- SET_Vertex4s(disp, glVertex4s);
- SET_Vertex4sv(disp, glVertex4sv);
- SET_VertexPointer(disp, glVertexPointer);
- SET_Viewport(disp, glViewport);
-
-#if GL_VERSION_2_0
- SET_AttachShader(disp, glAttachShader);
- SET_DeleteShader(disp, glDeleteShader);
- SET_DetachShader(disp, glDetachShader);
- SET_GetAttachedShaders(disp, glGetAttachedShaders);
- SET_GetProgramInfoLog(disp, glGetProgramInfoLog);
- SET_GetShaderInfoLog(disp, glGetShaderInfoLog);
- SET_GetShaderiv(disp, glGetShaderiv);
- SET_IsShader(disp, glIsShader);
- SET_StencilFuncSeparate(disp, glStencilFuncSeparate);
- SET_StencilMaskSeparate(disp, glStencilMaskSeparate);
- SET_StencilOpSeparate(disp, glStencilOpSeparate);
-#endif
-
-#if GL_VERSION_2_1
- SET_UniformMatrix2x3fv(disp, glUniformMatrix2x3fv);
- SET_UniformMatrix2x4fv(disp, glUniformMatrix2x4fv);
- SET_UniformMatrix3x2fv(disp, glUniformMatrix3x2fv);
- SET_UniformMatrix3x4fv(disp, glUniformMatrix3x4fv);
- SET_UniformMatrix4x2fv(disp, glUniformMatrix4x2fv);
- SET_UniformMatrix4x3fv(disp, glUniformMatrix4x3fv);
-#endif
-
-#if GL_APPLE_vertex_array_object
- SET_BindVertexArrayAPPLE(disp, glBindVertexArrayAPPLE);
- SET_DeleteVertexArraysAPPLE(disp, glDeleteVertexArraysAPPLE);
- SET_GenVertexArraysAPPLE(disp, glGenVertexArraysAPPLE);
- SET_IsVertexArrayAPPLE(disp, glIsVertexArrayAPPLE);
-#endif
-
-#if GL_ARB_draw_buffers
- SET_DrawBuffersARB(disp, glDrawBuffersARB);
-#endif
-
-#if GL_ARB_multisample
- SET_SampleCoverageARB(disp, glSampleCoverageARB);
-#endif
-
-#if GL_ARB_multitexture
- SET_ActiveTextureARB(disp, glActiveTextureARB);
- SET_ClientActiveTextureARB(disp, glClientActiveTextureARB);
- SET_MultiTexCoord1dARB(disp, glMultiTexCoord1dARB);
- SET_MultiTexCoord1dvARB(disp, glMultiTexCoord1dvARB);
- SET_MultiTexCoord1fARB(disp, glMultiTexCoord1fARB);
- SET_MultiTexCoord1fvARB(disp, glMultiTexCoord1fvARB);
- SET_MultiTexCoord1iARB(disp, glMultiTexCoord1iARB);
- SET_MultiTexCoord1ivARB(disp, glMultiTexCoord1ivARB);
- SET_MultiTexCoord1sARB(disp, glMultiTexCoord1sARB);
- SET_MultiTexCoord1svARB(disp, glMultiTexCoord1svARB);
- SET_MultiTexCoord2dARB(disp, glMultiTexCoord2dARB);
- SET_MultiTexCoord2dvARB(disp, glMultiTexCoord2dvARB);
- SET_MultiTexCoord2fARB(disp, glMultiTexCoord2fARB);
- SET_MultiTexCoord2fvARB(disp, glMultiTexCoord2fvARB);
- SET_MultiTexCoord2iARB(disp, glMultiTexCoord2iARB);
- SET_MultiTexCoord2ivARB(disp, glMultiTexCoord2ivARB);
- SET_MultiTexCoord2sARB(disp, glMultiTexCoord2sARB);
- SET_MultiTexCoord2svARB(disp, glMultiTexCoord2svARB);
- SET_MultiTexCoord3dARB(disp, glMultiTexCoord3dARB);
- SET_MultiTexCoord3dvARB(disp, glMultiTexCoord3dvARB);
- SET_MultiTexCoord3fARB(disp, glMultiTexCoord3fARB);
- SET_MultiTexCoord3fvARB(disp, glMultiTexCoord3fvARB);
- SET_MultiTexCoord3iARB(disp, glMultiTexCoord3iARB);
- SET_MultiTexCoord3ivARB(disp, glMultiTexCoord3ivARB);
- SET_MultiTexCoord3sARB(disp, glMultiTexCoord3sARB);
- SET_MultiTexCoord3svARB(disp, glMultiTexCoord3svARB);
- SET_MultiTexCoord4dARB(disp, glMultiTexCoord4dARB);
- SET_MultiTexCoord4dvARB(disp, glMultiTexCoord4dvARB);
- SET_MultiTexCoord4fARB(disp, glMultiTexCoord4fARB);
- SET_MultiTexCoord4fvARB(disp, glMultiTexCoord4fvARB);
- SET_MultiTexCoord4iARB(disp, glMultiTexCoord4iARB);
- SET_MultiTexCoord4ivARB(disp, glMultiTexCoord4ivARB);
- SET_MultiTexCoord4sARB(disp, glMultiTexCoord4sARB);
- SET_MultiTexCoord4svARB(disp, glMultiTexCoord4svARB);
-#endif
-
-#if GL_ARB_occlusion_query
- SET_BeginQueryARB(disp, glBeginQueryARB);
- SET_DeleteQueriesARB(disp, glDeleteQueriesARB);
- SET_EndQueryARB(disp, glEndQueryARB);
- SET_GenQueriesARB(disp, glGenQueriesARB);
- SET_GetQueryObjectivARB(disp, glGetQueryObjectivARB);
- SET_GetQueryObjectuivARB(disp, glGetQueryObjectuivARB);
- SET_GetQueryivARB(disp, glGetQueryivARB);
- SET_IsQueryARB(disp, glIsQueryARB);
-#endif
-
-#if GL_ARB_shader_objects
- SET_AttachObjectARB(disp, glAttachObjectARB);
- SET_CompileShaderARB(disp, glCompileShaderARB);
- SET_DeleteObjectARB(disp, glDeleteObjectARB);
- SET_GetHandleARB(disp, glGetHandleARB);
- SET_DetachObjectARB(disp, glDetachObjectARB);
- SET_CreateProgramObjectARB(disp, glCreateProgramObjectARB);
- SET_CreateShaderObjectARB(disp, glCreateShaderObjectARB);
- SET_GetInfoLogARB(disp, glGetInfoLogARB);
- SET_GetActiveUniformARB(disp, glGetActiveUniformARB);
- SET_GetAttachedObjectsARB(disp, glGetAttachedObjectsARB);
- SET_GetObjectParameterfvARB(disp, glGetObjectParameterfvARB);
- SET_GetObjectParameterivARB(disp, glGetObjectParameterivARB);
- SET_GetShaderSourceARB(disp, glGetShaderSourceARB);
- SET_GetUniformLocationARB(disp, glGetUniformLocationARB);
- SET_GetUniformfvARB(disp, glGetUniformfvARB);
- SET_GetUniformivARB(disp, glGetUniformivARB);
- SET_LinkProgramARB(disp, glLinkProgramARB);
- SET_ShaderSourceARB(disp, glShaderSourceARB);
- SET_Uniform1fARB(disp, glUniform1fARB);
- SET_Uniform1fvARB(disp, glUniform1fvARB);
- SET_Uniform1iARB(disp, glUniform1iARB);
- SET_Uniform1ivARB(disp, glUniform1ivARB);
- SET_Uniform2fARB(disp, glUniform2fARB);
- SET_Uniform2fvARB(disp, glUniform2fvARB);
- SET_Uniform2iARB(disp, glUniform2iARB);
- SET_Uniform2ivARB(disp, glUniform2ivARB);
- SET_Uniform3fARB(disp, glUniform3fARB);
- SET_Uniform3fvARB(disp, glUniform3fvARB);
- SET_Uniform3iARB(disp, glUniform3iARB);
- SET_Uniform3ivARB(disp, glUniform3ivARB);
- SET_Uniform4fARB(disp, glUniform4fARB);
- SET_Uniform4fvARB(disp, glUniform4fvARB);
- SET_Uniform4iARB(disp, glUniform4iARB);
- SET_Uniform4ivARB(disp, glUniform4ivARB);
- SET_UniformMatrix2fvARB(disp, glUniformMatrix2fvARB);
- SET_UniformMatrix3fvARB(disp, glUniformMatrix3fvARB);
- SET_UniformMatrix4fvARB(disp, glUniformMatrix4fvARB);
- SET_UseProgramObjectARB(disp, glUseProgramObjectARB);
- SET_ValidateProgramARB(disp, glValidateProgramARB);
-#endif
-
-#if GL_ARB_texture_compression
- SET_CompressedTexImage1DARB(disp, glCompressedTexImage1DARB);
- SET_CompressedTexImage2DARB(disp, glCompressedTexImage2DARB);
- SET_CompressedTexImage3DARB(disp, glCompressedTexImage3DARB);
- SET_CompressedTexSubImage1DARB(disp, glCompressedTexSubImage1DARB);
- SET_CompressedTexSubImage2DARB(disp, glCompressedTexSubImage2DARB);
- SET_CompressedTexSubImage3DARB(disp, glCompressedTexSubImage3DARB);
- SET_GetCompressedTexImageARB(disp, glGetCompressedTexImageARB);
-#endif
-
-#if GL_ARB_transpose_matrix
- SET_LoadTransposeMatrixdARB(disp, glLoadTransposeMatrixdARB);
- SET_LoadTransposeMatrixfARB(disp, glLoadTransposeMatrixfARB);
- SET_MultTransposeMatrixdARB(disp, glMultTransposeMatrixdARB);
- SET_MultTransposeMatrixfARB(disp, glMultTransposeMatrixfARB);
-#endif
-
-#if GL_ARB_vertex_buffer_object
- SET_BindBufferARB(disp, glBindBufferARB);
- SET_BufferDataARB(disp, glBufferDataARB);
- SET_BufferSubDataARB(disp, glBufferSubDataARB);
- SET_DeleteBuffersARB(disp, glDeleteBuffersARB);
- SET_GenBuffersARB(disp, glGenBuffersARB);
- SET_GetBufferParameterivARB(disp, glGetBufferParameterivARB);
- SET_GetBufferPointervARB(disp, glGetBufferPointervARB);
- SET_GetBufferSubDataARB(disp, glGetBufferSubDataARB);
- SET_IsBufferARB(disp, glIsBufferARB);
- SET_MapBufferARB(disp, glMapBufferARB);
- SET_UnmapBufferARB(disp, glUnmapBufferARB);
-#endif
-
-#if GL_ARB_vertex_program
- SET_DisableVertexAttribArrayARB(disp, glDisableVertexAttribArrayARB);
- SET_EnableVertexAttribArrayARB(disp, glEnableVertexAttribArrayARB);
- SET_GetProgramEnvParameterdvARB(disp, glGetProgramEnvParameterdvARB);
- SET_GetProgramEnvParameterfvARB(disp, glGetProgramEnvParameterfvARB);
- SET_GetProgramLocalParameterdvARB(disp, glGetProgramLocalParameterdvARB);
- SET_GetProgramLocalParameterfvARB(disp, glGetProgramLocalParameterfvARB);
- SET_GetProgramStringARB(disp, glGetProgramStringARB);
- SET_GetProgramivARB(disp, glGetProgramivARB);
- SET_GetVertexAttribdvARB(disp, glGetVertexAttribdvARB);
- SET_GetVertexAttribfvARB(disp, glGetVertexAttribfvARB);
- SET_GetVertexAttribivARB(disp, glGetVertexAttribivARB);
- SET_ProgramEnvParameter4dARB(disp, glProgramEnvParameter4dARB);
- SET_ProgramEnvParameter4dvARB(disp, glProgramEnvParameter4dvARB);
- SET_ProgramEnvParameter4fARB(disp, glProgramEnvParameter4fARB);
- SET_ProgramEnvParameter4fvARB(disp, glProgramEnvParameter4fvARB);
- SET_ProgramLocalParameter4dARB(disp, glProgramLocalParameter4dARB);
- SET_ProgramLocalParameter4dvARB(disp, glProgramLocalParameter4dvARB);
- SET_ProgramLocalParameter4fARB(disp, glProgramLocalParameter4fARB);
- SET_ProgramLocalParameter4fvARB(disp, glProgramLocalParameter4fvARB);
- SET_ProgramStringARB(disp, glProgramStringARB);
- SET_VertexAttrib1dARB(disp, glVertexAttrib1dARB);
- SET_VertexAttrib1dvARB(disp, glVertexAttrib1dvARB);
- SET_VertexAttrib1fARB(disp, glVertexAttrib1fARB);
- SET_VertexAttrib1fvARB(disp, glVertexAttrib1fvARB);
- SET_VertexAttrib1sARB(disp, glVertexAttrib1sARB);
- SET_VertexAttrib1svARB(disp, glVertexAttrib1svARB);
- SET_VertexAttrib2dARB(disp, glVertexAttrib2dARB);
- SET_VertexAttrib2dvARB(disp, glVertexAttrib2dvARB);
- SET_VertexAttrib2fARB(disp, glVertexAttrib2fARB);
- SET_VertexAttrib2fvARB(disp, glVertexAttrib2fvARB);
- SET_VertexAttrib2sARB(disp, glVertexAttrib2sARB);
- SET_VertexAttrib2svARB(disp, glVertexAttrib2svARB);
- SET_VertexAttrib3dARB(disp, glVertexAttrib3dARB);
- SET_VertexAttrib3dvARB(disp, glVertexAttrib3dvARB);
- SET_VertexAttrib3fARB(disp, glVertexAttrib3fARB);
- SET_VertexAttrib3fvARB(disp, glVertexAttrib3fvARB);
- SET_VertexAttrib3sARB(disp, glVertexAttrib3sARB);
- SET_VertexAttrib3svARB(disp, glVertexAttrib3svARB);
- SET_VertexAttrib4NbvARB(disp, glVertexAttrib4NbvARB);
- SET_VertexAttrib4NivARB(disp, glVertexAttrib4NivARB);
- SET_VertexAttrib4NsvARB(disp, glVertexAttrib4NsvARB);
- SET_VertexAttrib4NubARB(disp, glVertexAttrib4NubARB);
- SET_VertexAttrib4NubvARB(disp, glVertexAttrib4NubvARB);
- SET_VertexAttrib4NuivARB(disp, glVertexAttrib4NuivARB);
- SET_VertexAttrib4NusvARB(disp, glVertexAttrib4NusvARB);
- SET_VertexAttrib4bvARB(disp, glVertexAttrib4bvARB);
- SET_VertexAttrib4dARB(disp, glVertexAttrib4dARB);
- SET_VertexAttrib4dvARB(disp, glVertexAttrib4dvARB);
- SET_VertexAttrib4fARB(disp, glVertexAttrib4fARB);
- SET_VertexAttrib4fvARB(disp, glVertexAttrib4fvARB);
- SET_VertexAttrib4ivARB(disp, glVertexAttrib4ivARB);
- SET_VertexAttrib4sARB(disp, glVertexAttrib4sARB);
- SET_VertexAttrib4svARB(disp, glVertexAttrib4svARB);
- SET_VertexAttrib4ubvARB(disp, glVertexAttrib4ubvARB);
- SET_VertexAttrib4uivARB(disp, glVertexAttrib4uivARB);
- SET_VertexAttrib4usvARB(disp, glVertexAttrib4usvARB);
- SET_VertexAttribPointerARB(disp, glVertexAttribPointerARB);
-#endif
-
-#if GL_ARB_vertex_shader
- SET_BindAttribLocationARB(disp, glBindAttribLocationARB);
- SET_GetActiveAttribARB(disp, glGetActiveAttribARB);
- SET_GetAttribLocationARB(disp, glGetAttribLocationARB);
-#endif
-
-#if GL_ARB_window_pos
- SET_WindowPos2dMESA(disp, glWindowPos2dARB);
- SET_WindowPos2dvMESA(disp, glWindowPos2dvARB);
- SET_WindowPos2fMESA(disp, glWindowPos2fARB);
- SET_WindowPos2fvMESA(disp, glWindowPos2fvARB);
- SET_WindowPos2iMESA(disp, glWindowPos2iARB);
- SET_WindowPos2ivMESA(disp, glWindowPos2ivARB);
- SET_WindowPos2sMESA(disp, glWindowPos2sARB);
- SET_WindowPos2svMESA(disp, glWindowPos2svARB);
- SET_WindowPos3dMESA(disp, glWindowPos3dARB);
- SET_WindowPos3dvMESA(disp, glWindowPos3dvARB);
- SET_WindowPos3fMESA(disp, glWindowPos3fARB);
- SET_WindowPos3fvMESA(disp, glWindowPos3fvARB);
- SET_WindowPos3iMESA(disp, glWindowPos3iARB);
- SET_WindowPos3ivMESA(disp, glWindowPos3ivARB);
- SET_WindowPos3sMESA(disp, glWindowPos3sARB);
- SET_WindowPos3svMESA(disp, glWindowPos3svARB);
-#endif
-
-#if GL_ATI_fragment_shader
- SET_AlphaFragmentOp1ATI(disp, glAlphaFragmentOp1ATI);
- SET_AlphaFragmentOp2ATI(disp, glAlphaFragmentOp2ATI);
- SET_AlphaFragmentOp3ATI(disp, glAlphaFragmentOp3ATI);
- SET_BeginFragmentShaderATI(disp, glBeginFragmentShaderATI);
- SET_BindFragmentShaderATI(disp, glBindFragmentShaderATI);
- SET_ColorFragmentOp1ATI(disp, glColorFragmentOp1ATI);
- SET_ColorFragmentOp2ATI(disp, glColorFragmentOp2ATI);
- SET_ColorFragmentOp3ATI(disp, glColorFragmentOp3ATI);
- SET_DeleteFragmentShaderATI(disp, glDeleteFragmentShaderATI);
- SET_EndFragmentShaderATI(disp, glEndFragmentShaderATI);
- SET_GenFragmentShadersATI(disp, glGenFragmentShadersATI);
- SET_PassTexCoordATI(disp, glPassTexCoordATI);
- SET_SampleMapATI(disp, glSampleMapATI);
- SET_SetFragmentShaderConstantATI(disp, glSetFragmentShaderConstantATI);
-#elif GL_EXT_fragment_shader
- SET_AlphaFragmentOp1ATI(disp, glAlphaFragmentOp1EXT);
- SET_AlphaFragmentOp2ATI(disp, glAlphaFragmentOp2EXT);
- SET_AlphaFragmentOp3ATI(disp, glAlphaFragmentOp3EXT);
- SET_BeginFragmentShaderATI(disp, glBeginFragmentShaderEXT);
- SET_BindFragmentShaderATI(disp, glBindFragmentShaderEXT);
- SET_ColorFragmentOp1ATI(disp, glColorFragmentOp1EXT);
- SET_ColorFragmentOp2ATI(disp, glColorFragmentOp2EXT);
- SET_ColorFragmentOp3ATI(disp, glColorFragmentOp3EXT);
- SET_DeleteFragmentShaderATI(disp, glDeleteFragmentShaderEXT);
- SET_EndFragmentShaderATI(disp, glEndFragmentShaderEXT);
- SET_GenFragmentShadersATI(disp, glGenFragmentShadersEXT);
- SET_PassTexCoordATI(disp, glPassTexCoordEXT);
- SET_SampleMapATI(disp, glSampleMapEXT);
- SET_SetFragmentShaderConstantATI(disp, glSetFragmentShaderConstantEXT);
-#endif
-
-#if GL_ATI_separate_stencil
- SET_StencilFuncSeparateATI(disp, glStencilFuncSeparateATI);
-#endif
-
-#if GL_EXT_blend_equation_separate
- SET_BlendEquationSeparateEXT(disp, glBlendEquationSeparateEXT);
-#endif
-
-#if GL_EXT_blend_func_separate
- SET_BlendFuncSeparateEXT(disp, glBlendFuncSeparateEXT);
-#endif
-
-#if GL_EXT_depth_bounds_test
- SET_DepthBoundsEXT(disp, glDepthBoundsEXT);
-#endif
-
-#if GL_EXT_compiled_vertex_array
- SET_LockArraysEXT(disp, glLockArraysEXT);
- SET_UnlockArraysEXT(disp, glUnlockArraysEXT);
-#endif
-
-#if GL_EXT_cull_vertex
- SET_CullParameterdvEXT(disp, glCullParameterdvEXT);
- SET_CullParameterfvEXT(disp, glCullParameterfvEXT);
-#endif
-
-#if GL_EXT_fog_coord
- SET_FogCoordPointerEXT(disp, glFogCoordPointerEXT);
- SET_FogCoorddEXT(disp, glFogCoorddEXT);
- SET_FogCoorddvEXT(disp, glFogCoorddvEXT);
- SET_FogCoordfEXT(disp, glFogCoordfEXT);
- SET_FogCoordfvEXT(disp, glFogCoordfvEXT);
-#endif
-
-#if GL_EXT_framebuffer_blit
- SET_BlitFramebufferEXT(disp, glBlitFramebufferEXT);
-#endif
-
-#if GL_EXT_framebuffer_object
- SET_BindFramebufferEXT(disp, glBindFramebufferEXT);
- SET_BindRenderbufferEXT(disp, glBindRenderbufferEXT);
- SET_CheckFramebufferStatusEXT(disp, glCheckFramebufferStatusEXT);
- SET_DeleteFramebuffersEXT(disp, glDeleteFramebuffersEXT);
- SET_DeleteRenderbuffersEXT(disp, glDeleteRenderbuffersEXT);
- SET_FramebufferRenderbufferEXT(disp, glFramebufferRenderbufferEXT);
- SET_FramebufferTexture1DEXT(disp, glFramebufferTexture1DEXT);
- SET_FramebufferTexture2DEXT(disp, glFramebufferTexture2DEXT);
- SET_FramebufferTexture3DEXT(disp, glFramebufferTexture3DEXT);
- SET_GenerateMipmapEXT(disp, glGenerateMipmapEXT);
- SET_GenFramebuffersEXT(disp, glGenFramebuffersEXT);
- SET_GenRenderbuffersEXT(disp, glGenRenderbuffersEXT);
- SET_GetFramebufferAttachmentParameterivEXT(disp, glGetFramebufferAttachmentParameterivEXT);
- SET_GetRenderbufferParameterivEXT(disp, glGetRenderbufferParameterivEXT);
- SET_IsFramebufferEXT(disp, glIsFramebufferEXT);
- SET_IsRenderbufferEXT(disp, glIsRenderbufferEXT);
- SET_RenderbufferStorageEXT(disp, glRenderbufferStorageEXT);
-#endif
-
-#if GL_EXT_gpu_program_parameters
- SET_ProgramEnvParameters4fvEXT(disp, glProgramEnvParameters4fvEXT);
- SET_ProgramLocalParameters4fvEXT(disp, glProgramLocalParameters4fvEXT);
-#endif
-
-#if GL_EXT_multi_draw_arrays
- /* Pointer Incompatability:
- * This warning can be safely ignored. OpenGL.framework adds const to the
- * two pointers.
- *
- * extern void glMultiDrawArraysEXT (GLenum, const GLint *, const GLsizei *, GLsizei);
- *
- * void ( * MultiDrawArraysEXT)(GLenum mode, GLint * first, GLsizei * count, GLsizei primcount);
- */
- SET_MultiDrawArraysEXT(disp, (void *)glMultiDrawArraysEXT);
- SET_MultiDrawElementsEXT(disp, glMultiDrawElementsEXT);
-#endif
-
-#if GL_EXT_point_parameters
- SET_PointParameterfEXT(disp, glPointParameterfEXT);
- SET_PointParameterfvEXT(disp, glPointParameterfvEXT);
-#elif GL_ARB_point_parameters
- SET_PointParameterfEXT(disp, glPointParameterfARB);
- SET_PointParameterfvEXT(disp, glPointParameterfvARB);
-#endif
-
-#if GL_EXT_polygon_offset
- SET_PolygonOffsetEXT(disp, glPolygonOffsetEXT);
-#endif
-
-#if GL_EXT_secondary_color
- SET_SecondaryColor3bEXT(disp, glSecondaryColor3bEXT);
- SET_SecondaryColor3bvEXT(disp, glSecondaryColor3bvEXT);
- SET_SecondaryColor3dEXT(disp, glSecondaryColor3dEXT);
- SET_SecondaryColor3dvEXT(disp, glSecondaryColor3dvEXT);
- SET_SecondaryColor3fEXT(disp, glSecondaryColor3fEXT);
- SET_SecondaryColor3fvEXT(disp, glSecondaryColor3fvEXT);
- SET_SecondaryColor3iEXT(disp, glSecondaryColor3iEXT);
- SET_SecondaryColor3ivEXT(disp, glSecondaryColor3ivEXT);
- SET_SecondaryColor3sEXT(disp, glSecondaryColor3sEXT);
- SET_SecondaryColor3svEXT(disp, glSecondaryColor3svEXT);
- SET_SecondaryColor3ubEXT(disp, glSecondaryColor3ubEXT);
- SET_SecondaryColor3ubvEXT(disp, glSecondaryColor3ubvEXT);
- SET_SecondaryColor3uiEXT(disp, glSecondaryColor3uiEXT);
- SET_SecondaryColor3uivEXT(disp, glSecondaryColor3uivEXT);
- SET_SecondaryColor3usEXT(disp, glSecondaryColor3usEXT);
- SET_SecondaryColor3usvEXT(disp, glSecondaryColor3usvEXT);
- SET_SecondaryColorPointerEXT(disp, glSecondaryColorPointerEXT);
-#endif
-
-#if GL_EXT_stencil_two_side
- SET_ActiveStencilFaceEXT(disp, glActiveStencilFaceEXT);
-#endif
-
-#if GL_EXT_timer_query
- SET_GetQueryObjecti64vEXT(disp, glGetQueryObjecti64vEXT);
- SET_GetQueryObjectui64vEXT(disp, glGetQueryObjectui64vEXT);
-#endif
-
-#if GL_EXT_vertex_array
- SET_ColorPointerEXT(disp, glColorPointerEXT);
- SET_EdgeFlagPointerEXT(disp, glEdgeFlagPointerEXT);
- SET_IndexPointerEXT(disp, glIndexPointerEXT);
- SET_NormalPointerEXT(disp, glNormalPointerEXT);
- SET_TexCoordPointerEXT(disp, glTexCoordPointerEXT);
- SET_VertexPointerEXT(disp, glVertexPointerEXT);
-#endif
-
-#if GL_IBM_multimode_draw_arrays
- SET_MultiModeDrawArraysIBM(disp, glMultiModeDrawArraysIBM);
- SET_MultiModeDrawElementsIBM(disp, glMultiModeDrawElementsIBM);
-#endif
-
-#if GL_MESA_resize_buffers
- SET_ResizeBuffersMESA(disp, glResizeBuffersMESA);
-#endif
-
-#if GL_MESA_window_pos
- SET_WindowPos4dMESA(disp, glWindowPos4dMESA);
- SET_WindowPos4dvMESA(disp, glWindowPos4dvMESA);
- SET_WindowPos4fMESA(disp, glWindowPos4fMESA);
- SET_WindowPos4fvMESA(disp, glWindowPos4fvMESA);
- SET_WindowPos4iMESA(disp, glWindowPos4iMESA);
- SET_WindowPos4ivMESA(disp, glWindowPos4ivMESA);
- SET_WindowPos4sMESA(disp, glWindowPos4sMESA);
- SET_WindowPos4svMESA(disp, glWindowPos4svMESA);
-#endif
-
-#if GL_NV_fence
- SET_DeleteFencesNV(disp, glDeleteFencesNV);
- SET_FinishFenceNV(disp, glFinishFenceNV);
- SET_GenFencesNV(disp, glGenFencesNV);
- SET_GetFenceivNV(disp, glGetFenceivNV);
- SET_IsFenceNV(disp, glIsFenceNV);
- SET_SetFenceNV(disp, glSetFenceNV);
- SET_TestFenceNV(disp, glTestFenceNV);
-#endif
-
-#if GL_NV_fragment_program
- SET_GetProgramNamedParameterdvNV(disp, glGetProgramNamedParameterdvNV);
- SET_GetProgramNamedParameterfvNV(disp, glGetProgramNamedParameterfvNV);
- SET_ProgramNamedParameter4dNV(disp, glProgramNamedParameter4dNV);
- SET_ProgramNamedParameter4dvNV(disp, glProgramNamedParameter4dvNV);
- SET_ProgramNamedParameter4fNV(disp, glProgramNamedParameter4fNV);
- SET_ProgramNamedParameter4fvNV(disp, glProgramNamedParameter4fvNV);
-#endif
-
-#if GL_NV_geometry_program4
- SET_FramebufferTextureLayerEXT(disp, glFramebufferTextureLayerEXT);
-#endif
-
-#if GL_NV_point_sprite
- SET_PointParameteriNV(disp, glPointParameteriNV);
- SET_PointParameterivNV(disp, glPointParameterivNV);
-#endif
-
-#if GL_NV_register_combiners
- SET_CombinerInputNV(disp, glCombinerInputNV);
- SET_CombinerOutputNV(disp, glCombinerOutputNV);
- SET_CombinerParameterfNV(disp, glCombinerParameterfNV);
- SET_CombinerParameterfvNV(disp, glCombinerParameterfvNV);
- SET_CombinerParameteriNV(disp, glCombinerParameteriNV);
- SET_CombinerParameterivNV(disp, glCombinerParameterivNV);
- SET_FinalCombinerInputNV(disp, glFinalCombinerInputNV);
- SET_GetCombinerInputParameterfvNV(disp, glGetCombinerInputParameterfvNV);
- SET_GetCombinerInputParameterivNV(disp, glGetCombinerInputParameterivNV);
- SET_GetCombinerOutputParameterfvNV(disp, glGetCombinerOutputParameterfvNV);
- SET_GetCombinerOutputParameterivNV(disp, glGetCombinerOutputParameterivNV);
- SET_GetFinalCombinerInputParameterfvNV(disp, glGetFinalCombinerInputParameterfvNV);
- SET_GetFinalCombinerInputParameterivNV(disp, glGetFinalCombinerInputParameterivNV);
-#endif
-
-#if GL_NV_vertex_array_range
- SET_FlushVertexArrayRangeNV(disp, glFlushVertexArrayRangeNV);
- SET_VertexArrayRangeNV(disp, glVertexArrayRangeNV);
-#endif
-
-#if GL_NV_vertex_program
- SET_AreProgramsResidentNV(disp, glAreProgramsResidentNV);
- SET_BindProgramNV(disp, glBindProgramNV);
- SET_DeleteProgramsNV(disp, glDeleteProgramsNV);
- SET_ExecuteProgramNV(disp, glExecuteProgramNV);
- SET_GenProgramsNV(disp, glGenProgramsNV);
- SET_GetProgramParameterdvNV(disp, glGetProgramParameterdvNV);
- SET_GetProgramParameterfvNV(disp, glGetProgramParameterfvNV);
- SET_GetProgramStringNV(disp, glGetProgramStringNV);
- SET_GetProgramivNV(disp, glGetProgramivNV);
- SET_GetTrackMatrixivNV(disp, glGetTrackMatrixivNV);
- SET_GetVertexAttribPointervNV(disp, glGetVertexAttribPointervNV);
- SET_GetVertexAttribdvNV(disp, glGetVertexAttribdvNV);
- SET_GetVertexAttribfvNV(disp, glGetVertexAttribfvNV);
- SET_GetVertexAttribivNV(disp, glGetVertexAttribivNV);
- SET_IsProgramNV(disp, glIsProgramNV);
- SET_LoadProgramNV(disp, glLoadProgramNV);
- SET_ProgramParameters4dvNV(disp, glProgramParameters4dvNV);
- SET_ProgramParameters4fvNV(disp, glProgramParameters4fvNV);
- SET_RequestResidentProgramsNV(disp, glRequestResidentProgramsNV);
- SET_TrackMatrixNV(disp, glTrackMatrixNV);
- SET_VertexAttrib1dNV(disp, glVertexAttrib1dNV)
- SET_VertexAttrib1dvNV(disp, glVertexAttrib1dvNV)
- SET_VertexAttrib1fNV(disp, glVertexAttrib1fNV)
- SET_VertexAttrib1fvNV(disp, glVertexAttrib1fvNV)
- SET_VertexAttrib1sNV(disp, glVertexAttrib1sNV)
- SET_VertexAttrib1svNV(disp, glVertexAttrib1svNV)
- SET_VertexAttrib2dNV(disp, glVertexAttrib2dNV)
- SET_VertexAttrib2dvNV(disp, glVertexAttrib2dvNV)
- SET_VertexAttrib2fNV(disp, glVertexAttrib2fNV)
- SET_VertexAttrib2fvNV(disp, glVertexAttrib2fvNV)
- SET_VertexAttrib2sNV(disp, glVertexAttrib2sNV)
- SET_VertexAttrib2svNV(disp, glVertexAttrib2svNV)
- SET_VertexAttrib3dNV(disp, glVertexAttrib3dNV)
- SET_VertexAttrib3dvNV(disp, glVertexAttrib3dvNV)
- SET_VertexAttrib3fNV(disp, glVertexAttrib3fNV)
- SET_VertexAttrib3fvNV(disp, glVertexAttrib3fvNV)
- SET_VertexAttrib3sNV(disp, glVertexAttrib3sNV)
- SET_VertexAttrib3svNV(disp, glVertexAttrib3svNV)
- SET_VertexAttrib4dNV(disp, glVertexAttrib4dNV)
- SET_VertexAttrib4dvNV(disp, glVertexAttrib4dvNV)
- SET_VertexAttrib4fNV(disp, glVertexAttrib4fNV)
- SET_VertexAttrib4fvNV(disp, glVertexAttrib4fvNV)
- SET_VertexAttrib4sNV(disp, glVertexAttrib4sNV)
- SET_VertexAttrib4svNV(disp, glVertexAttrib4svNV)
- SET_VertexAttrib4ubNV(disp, glVertexAttrib4ubNV)
- SET_VertexAttrib4ubvNV(disp, glVertexAttrib4ubvNV)
- SET_VertexAttribPointerNV(disp, glVertexAttribPointerNV)
- SET_VertexAttribs1dvNV(disp, glVertexAttribs1dvNV)
- SET_VertexAttribs1fvNV(disp, glVertexAttribs1fvNV)
- SET_VertexAttribs1svNV(disp, glVertexAttribs1svNV)
- SET_VertexAttribs2dvNV(disp, glVertexAttribs2dvNV)
- SET_VertexAttribs2fvNV(disp, glVertexAttribs2fvNV)
- SET_VertexAttribs2svNV(disp, glVertexAttribs2svNV)
- SET_VertexAttribs3dvNV(disp, glVertexAttribs3dvNV)
- SET_VertexAttribs3fvNV(disp, glVertexAttribs3fvNV)
- SET_VertexAttribs3svNV(disp, glVertexAttribs3svNV)
- SET_VertexAttribs4dvNV(disp, glVertexAttribs4dvNV)
- SET_VertexAttribs4fvNV(disp, glVertexAttribs4fvNV)
- SET_VertexAttribs4svNV(disp, glVertexAttribs4svNV)
- SET_VertexAttribs4ubvNV(disp, glVertexAttribs4ubvNV)
-#endif
-
-#if GL_SGIS_multisample
- SET_SampleMaskSGIS(disp, glSampleMaskSGIS);
- SET_SamplePatternSGIS(disp, glSamplePatternSGIS);
-#endif
-
-#if GL_SGIS_pixel_texture
- SET_GetPixelTexGenParameterfvSGIS(disp, glGetPixelTexGenParameterfvSGIS);
- SET_GetPixelTexGenParameterivSGIS(disp, glGetPixelTexGenParameterivSGIS);
- SET_PixelTexGenParameterfSGIS(disp, glPixelTexGenParameterfSGIS);
- SET_PixelTexGenParameterfvSGIS(disp, glPixelTexGenParameterfvSGIS);
- SET_PixelTexGenParameteriSGIS(disp, glPixelTexGenParameteriSGIS);
- SET_PixelTexGenParameterivSGIS(disp, glPixelTexGenParameterivSGIS);
- SET_PixelTexGenSGIX(disp, glPixelTexGenSGIX);
-#endif
-}
+/* + * GLX implementation that uses Apple's OpenGL.framework + * (Indirect rendering path -- it's also used for some direct mode code too) + * + * Copyright (c) 2007, 2008, 2009 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 <dix-config.h> +#endif + +#include "dri.h" + +#include <AvailabilityMacros.h> + +#define GL_GLEXT_WUNDEF_SUPPORT + +#include <OpenGL/OpenGL.h> +#include <OpenGL/gl.h> +#include <OpenGL/glext.h> +#include <OpenGL/CGLContext.h> + +/* These next few GL_EXT pre-processing blocks are to explicitly define + * these symbols to 0 if they are not set by OpenGL.framework. This + * prevents the X11 glext.h from setting them to 1. + */ + +#ifndef GL_EXT_fragment_shader +#define GL_EXT_fragment_shader 0 +#endif + +#ifndef GL_EXT_blend_equation_separate +#define GL_EXT_blend_equation_separate 0 +#endif + +#ifndef GL_EXT_blend_func_separate +#define GL_EXT_blend_func_separate 0 +#endif + +#ifndef GL_EXT_depth_bounds_test +#define GL_EXT_depth_bounds_test 0 +#endif + +#ifndef GL_EXT_compiled_vertex_array +#define GL_EXT_compiled_vertex_array 0 +#endif + +#ifndef GL_EXT_cull_vertex +#define GL_EXT_cull_vertex 0 +#endif + +#ifndef GL_EXT_fog_coord +#define GL_EXT_fog_coord 0 +#endif + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 0 +#endif + +#ifndef GL_EXT_framebuffer_object +#define GL_EXT_framebuffer_object 0 +#endif + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters 0 +#endif + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 0 +#endif + +#ifndef GL_EXT_point_parameters +#define GL_EXT_point_parameters 0 +#endif + +#ifndef GL_EXT_polygon_offset +#define GL_EXT_polygon_offset 0 +#endif + +#ifndef GL_EXT_secondary_color +#define GL_EXT_secondary_color 0 +#endif + +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 0 +#endif + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query 0 +#endif + +#ifndef GL_EXT_vertex_array +#define GL_EXT_vertex_array 0 +#endif + +/* Tiger PPC doesn't have the associated symbols, but glext.h says it does. Liars! + * http://trac.macports.org/ticket/20638 + */ +#if defined(__ppc__) && MAC_OS_X_VERSION_MIN_REQUIRED < 1050 +#undef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters 0 +#endif + +#include <GL/glxproto.h> +#include <windowstr.h> +#include <resource.h> +#include <GL/glxint.h> +#include <GL/glxtokens.h> +#include <scrnintstr.h> +#include <glxserver.h> +#include <glxscreens.h> +#include <glxdrawable.h> +#include <glxcontext.h> +#include <glxext.h> +#include <glxutil.h> +#include <GL/internal/glcore.h> +#include "x-hash.h" +#include "x-list.h" + +//#include "capabilities.h" +#include "visualConfigs.h" + +typedef unsigned long long GLuint64EXT; +typedef long long GLint64EXT; +#include <dispatch.h> +#include <Xplugin.h> +#include <glapi.h> +#include <glapitable.h> + +__GLXprovider * GlxGetDRISWrastProvider (void); + +// Write debugging output, or not +#ifdef GLAQUA_DEBUG +#define GLAQUA_DEBUG_MSG ErrorF +#else +#define GLAQUA_DEBUG_MSG(a, ...) +#endif + +static void setup_dispatch_table(void); +GLuint __glFloorLog2(GLuint val); +void warn_func(void * p1, char *format, ...); + +// some prototypes +static __GLXscreen * __glXAquaScreenProbe(ScreenPtr pScreen); +static __GLXdrawable * __glXAquaScreenCreateDrawable(ClientPtr client, __GLXscreen *screen, DrawablePtr pDraw, XID drawId, int type, XID glxDrawId, __GLXconfig *conf); + +static void __glXAquaContextDestroy(__GLXcontext *baseContext); +static int __glXAquaContextMakeCurrent(__GLXcontext *baseContext); +static int __glXAquaContextLoseCurrent(__GLXcontext *baseContext); +static int __glXAquaContextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc, unsigned long mask); + +static CGLPixelFormatObj makeFormat(__GLXconfig *conf); + +__GLXprovider __glXDRISWRastProvider = { + __glXAquaScreenProbe, + "Core OpenGL", + NULL +}; + +typedef struct __GLXAquaScreen __GLXAquaScreen; +typedef struct __GLXAquaContext __GLXAquaContext; +typedef struct __GLXAquaDrawable __GLXAquaDrawable; + +struct __GLXAquaScreen { + __GLXscreen base; + int index; + int num_vis; +}; + +struct __GLXAquaContext { + __GLXcontext base; + CGLContextObj ctx; + CGLPixelFormatObj pixelFormat; + xp_surface_id sid; + unsigned isAttached :1; +}; + +struct __GLXAquaDrawable { + __GLXdrawable base; + DrawablePtr pDraw; + xp_surface_id sid; + __GLXAquaContext *context; +}; + + +static __GLXcontext * +__glXAquaScreenCreateContext(__GLXscreen *screen, + __GLXconfig *conf, + __GLXcontext *baseShareContext) +{ + __GLXAquaContext *context; + __GLXAquaContext *shareContext = (__GLXAquaContext *) baseShareContext; + CGLError gl_err; + + GLAQUA_DEBUG_MSG("glXAquaScreenCreateContext\n"); + + context = calloc(1, sizeof (__GLXAquaContext)); + + if (context == NULL) + return NULL; + + memset(context, 0, sizeof *context); + + context->base.pGlxScreen = screen; + + context->base.destroy = __glXAquaContextDestroy; + context->base.makeCurrent = __glXAquaContextMakeCurrent; + context->base.loseCurrent = __glXAquaContextLoseCurrent; + context->base.copy = __glXAquaContextCopy; + /*FIXME verify that the context->base is fully initialized. */ + + context->pixelFormat = makeFormat(conf); + + if (!context->pixelFormat) { + free(context); + return NULL; + } + + context->ctx = NULL; + gl_err = CGLCreateContext(context->pixelFormat, + shareContext ? shareContext->ctx : NULL, + &context->ctx); + + if (gl_err != 0) { + ErrorF("CGLCreateContext error: %s\n", CGLErrorString(gl_err)); + CGLDestroyPixelFormat(context->pixelFormat); + free(context); + return NULL; + } + + setup_dispatch_table(); + GLAQUA_DEBUG_MSG("glAquaCreateContext done\n"); + + return &context->base; +} + +/* maps from surface id -> list of __GLcontext */ +static x_hash_table *surface_hash; + +static void __glXAquaContextDestroy(__GLXcontext *baseContext) { + x_list *lst; + + __GLXAquaContext *context = (__GLXAquaContext *) baseContext; + + GLAQUA_DEBUG_MSG("glAquaContextDestroy (ctx %p)\n", baseContext); + if (context != NULL) { + if (context->sid != 0 && surface_hash != NULL) { + lst = x_hash_table_lookup(surface_hash, x_cvt_uint_to_vptr(context->sid), NULL); + lst = x_list_remove(lst, context); + x_hash_table_insert(surface_hash, x_cvt_uint_to_vptr(context->sid), lst); + } + + if (context->ctx != NULL) + CGLDestroyContext(context->ctx); + + if (context->pixelFormat != NULL) + CGLDestroyPixelFormat(context->pixelFormat); + + free(context); + } +} + +static int __glXAquaContextLoseCurrent(__GLXcontext *baseContext) { + CGLError gl_err; + + GLAQUA_DEBUG_MSG("glAquaLoseCurrent (ctx 0x%p)\n", baseContext); + + gl_err = CGLSetCurrentContext(NULL); + if (gl_err != 0) + ErrorF("CGLSetCurrentContext error: %s\n", CGLErrorString(gl_err)); + + __glXLastContext = NULL; // Mesa does this; why? + + return GL_TRUE; +} + +/* Called when a surface is destroyed as a side effect of destroying + the window it's attached to. */ +static void surface_notify(void *_arg, void *data) { + DRISurfaceNotifyArg *arg = (DRISurfaceNotifyArg *)_arg; + __GLXAquaDrawable *draw = (__GLXAquaDrawable *)data; + __GLXAquaContext *context; + x_list *lst; + if(_arg == NULL || data == NULL) { + ErrorF("surface_notify called with bad params"); + return; + } + + GLAQUA_DEBUG_MSG("surface_notify(%p, %p)\n", _arg, data); + switch (arg->kind) { + case AppleDRISurfaceNotifyDestroyed: + if (surface_hash != NULL) + x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(arg->id)); + draw->pDraw = NULL; + draw->sid = 0; + break; + + case AppleDRISurfaceNotifyChanged: + if (surface_hash != NULL) { + lst = x_hash_table_lookup(surface_hash, x_cvt_uint_to_vptr(arg->id), NULL); + for (; lst != NULL; lst = lst->next) + { + context = lst->data; + xp_update_gl_context(context->ctx); + } + } + break; + default: + ErrorF("surface_notify: unknown kind %d\n", arg->kind); + break; + } +} + +static BOOL attach(__GLXAquaContext *context, __GLXAquaDrawable *draw) { + DrawablePtr pDraw; + + GLAQUA_DEBUG_MSG("attach(%p, %p)\n", context, draw); + + if(NULL == context || NULL == draw) + return TRUE; + + pDraw = draw->base.pDraw; + + if(NULL == pDraw) { + ErrorF("%s:%s() pDraw is NULL!\n", __FILE__, __func__); + return TRUE; + } + + if (draw->sid == 0) { + //if (!quartzProcs->CreateSurface(pDraw->pScreen, pDraw->id, pDraw, + if (!DRICreateSurface(pDraw->pScreen, pDraw->id, pDraw, + 0, &draw->sid, NULL, + surface_notify, draw)) + return TRUE; + draw->pDraw = pDraw; + } + + if (!context->isAttached || context->sid != draw->sid) { + x_list *lst; + + if (xp_attach_gl_context(context->ctx, draw->sid) != Success) { + //quartzProcs->DestroySurface(pDraw->pScreen, pDraw->id, pDraw, + DRIDestroySurface(pDraw->pScreen, pDraw->id, pDraw, + surface_notify, draw); + if (surface_hash != NULL) + x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(draw->sid)); + + draw->sid = 0; + return TRUE; + } + + context->isAttached = TRUE; + context->sid = draw->sid; + + if (surface_hash == NULL) + surface_hash = x_hash_table_new(NULL, NULL, NULL, NULL); + + lst = x_hash_table_lookup(surface_hash, x_cvt_uint_to_vptr(context->sid), NULL); + if (x_list_find(lst, context) == NULL) { + lst = x_list_prepend(lst, context); + x_hash_table_insert(surface_hash, x_cvt_uint_to_vptr(context->sid), lst); + } + + + + GLAQUA_DEBUG_MSG("attached 0x%x to 0x%x\n", (unsigned int) pDraw->id, + (unsigned int) draw->sid); + } + + draw->context = context; + + return FALSE; +} + +#if 0 // unused +static void unattach(__GLXAquaContext *context) { + x_list *lst; + GLAQUA_DEBUG_MSG("unattach\n"); + if (context == NULL) { + ErrorF("Tried to unattach a null context\n"); + return; + } + if (context->isAttached) { + GLAQUA_DEBUG_MSG("unattaching\n"); + + if (surface_hash != NULL) { + lst = x_hash_table_lookup(surface_hash, (void *) context->sid, NULL); + lst = x_list_remove(lst, context); + x_hash_table_insert(surface_hash, (void *) context->sid, lst); + } + + CGLClearDrawable(context->ctx); + context->isAttached = FALSE; + context->sid = 0; + } +} +#endif + +static int __glXAquaContextMakeCurrent(__GLXcontext *baseContext) { + CGLError gl_err; + __GLXAquaContext *context = (__GLXAquaContext *) baseContext; + __GLXAquaDrawable *drawPriv = (__GLXAquaDrawable *) context->base.drawPriv; + + GLAQUA_DEBUG_MSG("glAquaMakeCurrent (ctx 0x%p)\n", baseContext); + + if(attach(context, drawPriv)) + return /*error*/ 0; + + gl_err = CGLSetCurrentContext(context->ctx); + if (gl_err != 0) + ErrorF("CGLSetCurrentContext error: %s\n", CGLErrorString(gl_err)); + + return gl_err == 0; +} + +static int __glXAquaContextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc, unsigned long mask) +{ + CGLError gl_err; + + __GLXAquaContext *dst = (__GLXAquaContext *) baseDst; + __GLXAquaContext *src = (__GLXAquaContext *) baseSrc; + + GLAQUA_DEBUG_MSG("GLXAquaContextCopy\n"); + + gl_err = CGLCopyContext(src->ctx, dst->ctx, mask); + if (gl_err != 0) + ErrorF("CGLCopyContext error: %s\n", CGLErrorString(gl_err)); + + return gl_err == 0; +} + +/* Drawing surface notification callbacks */ +static GLboolean __glXAquaDrawableSwapBuffers(ClientPtr client, __GLXdrawable *base) { + CGLError err; + __GLXAquaDrawable *drawable; + + // GLAQUA_DEBUG_MSG("glAquaDrawableSwapBuffers(%p)\n",base); + + if(!base) { + ErrorF("%s passed NULL\n", __func__); + return GL_FALSE; + } + + drawable = (__GLXAquaDrawable *)base; + + if(NULL == drawable->context) { + ErrorF("%s called with a NULL->context for drawable %p!\n", + __func__, (void *)drawable); + return GL_FALSE; + } + + err = CGLFlushDrawable(drawable->context->ctx); + + if(kCGLNoError != err) { + ErrorF("CGLFlushDrawable error: %s in %s\n", CGLErrorString(err), + __func__); + return GL_FALSE; + } + + return GL_TRUE; +} + + +static CGLPixelFormatObj makeFormat(__GLXconfig *conf) { + CGLPixelFormatAttribute attr[64]; + CGLPixelFormatObj fobj; + GLint formats; + CGLError error; + int i = 0; + + if(conf->doubleBufferMode) + attr[i++] = kCGLPFADoubleBuffer; + + if(conf->stereoMode) + attr[i++] = kCGLPFAStereo; + + attr[i++] = kCGLPFAColorSize; + attr[i++] = conf->redBits + conf->greenBits + conf->blueBits; + attr[i++] = kCGLPFAAlphaSize; + attr[i++] = conf->alphaBits; + + if((conf->accumRedBits + conf->accumGreenBits + conf->accumBlueBits + + conf->accumAlphaBits) > 0) { + + attr[i++] = kCGLPFAAccumSize; + attr[i++] = conf->accumRedBits + conf->accumGreenBits + + conf->accumBlueBits + conf->accumAlphaBits; + } + + attr[i++] = kCGLPFADepthSize; + attr[i++] = conf->depthBits; + + if(conf->stencilBits) { + attr[i++] = kCGLPFAStencilSize; + attr[i++] = conf->stencilBits; + } + + if(conf->numAuxBuffers > 0) { + attr[i++] = kCGLPFAAuxBuffers; + attr[i++] = conf->numAuxBuffers; + } + + if(conf->sampleBuffers > 0) { + attr[i++] = kCGLPFASampleBuffers; + attr[i++] = conf->sampleBuffers; + attr[i++] = kCGLPFASamples; + attr[i++] = conf->samples; + } + + attr[i] = 0; + + error = CGLChoosePixelFormat(attr, &fobj, &formats); + if(error) { + ErrorF("error: creating pixel format %s\n", CGLErrorString(error)); + return NULL; + } + + return fobj; +} + +static void __glXAquaScreenDestroy(__GLXscreen *screen) { + + GLAQUA_DEBUG_MSG("glXAquaScreenDestroy(%p)\n", screen); + __glXScreenDestroy(screen); + + free(screen); +} + +/* This is called by __glXInitScreens(). */ +static __GLXscreen * __glXAquaScreenProbe(ScreenPtr pScreen) { + __GLXAquaScreen *screen; + + GLAQUA_DEBUG_MSG("glXAquaScreenProbe\n"); + + if (pScreen == NULL) + return NULL; + + screen = calloc(1, sizeof *screen); + + if(NULL == screen) + return NULL; + + screen->base.destroy = __glXAquaScreenDestroy; + screen->base.createContext = __glXAquaScreenCreateContext; + screen->base.createDrawable = __glXAquaScreenCreateDrawable; + screen->base.swapInterval = /*FIXME*/ NULL; + screen->base.pScreen = pScreen; + + screen->base.fbconfigs = __glXAquaCreateVisualConfigs(&screen->base.numFBConfigs, pScreen->myNum); + + __glXScreenInit(&screen->base, pScreen); + + screen->base.GLXversion = strdup("1.4"); + screen->base.GLXextensions = strdup("GLX_SGIX_fbconfig " + "GLX_SGIS_multisample " + "GLX_ARB_multisample " + "GLX_EXT_visual_info " + "GLX_EXT_import_context "); + + /*We may be able to add more GLXextensions at a later time. */ + + return &screen->base; +} + +#if 0 // unused +static void __glXAquaDrawableCopySubBuffer (__GLXdrawable *drawable, + int x, int y, int w, int h) { + /*TODO finish me*/ +} +#endif + +static void __glXAquaDrawableDestroy(__GLXdrawable *base) { + /* gstaplin: base is the head of the structure, so it's at the same + * offset in memory. + * Is this safe with strict aliasing? I noticed that the other dri code + * does this too... + */ + __GLXAquaDrawable *glxPriv = (__GLXAquaDrawable *)base; + + GLAQUA_DEBUG_MSG(__func__); + + /* It doesn't work to call DRIDestroySurface here, the drawable's + already gone.. But dri.c notices the window destruction and + frees the surface itself. */ + + /*gstaplin: verify the statement above. The surface destroy + *messages weren't making it through, and may still not be. + *We need a good test case for surface creation and destruction. + *We also need a good way to enable introspection on the server + *to validate the test, beyond using gdb with print. + */ + + free(glxPriv); +} + +static __GLXdrawable * +__glXAquaScreenCreateDrawable(ClientPtr client, + __GLXscreen *screen, + DrawablePtr pDraw, + XID drawId, + int type, + XID glxDrawId, + __GLXconfig *conf) { + __GLXAquaDrawable *glxPriv; + + glxPriv = malloc(sizeof *glxPriv); + + if(glxPriv == NULL) + return NULL; + + memset(glxPriv, 0, sizeof *glxPriv); + + if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, glxDrawId, conf)) { + free(glxPriv); + return NULL; + } + + glxPriv->base.destroy = __glXAquaDrawableDestroy; + glxPriv->base.swapBuffers = __glXAquaDrawableSwapBuffers; + glxPriv->base.copySubBuffer = NULL; /* __glXAquaDrawableCopySubBuffer; */ + + glxPriv->pDraw = pDraw; + glxPriv->sid = 0; + glxPriv->context = NULL; + + return &glxPriv->base; +} + +// Extra goodies for glx + +GLuint __glFloorLog2(GLuint val) +{ + int c = 0; + + while (val > 1) { + c++; + val >>= 1; + } + return c; +} + +static void setup_dispatch_table(void) { + struct _glapi_table *disp=_glapi_get_dispatch(); + + /* to update: + * for f in $(grep 'define SET_' ../../../glx/dispatch.h | cut -f2 -d' ' | cut -f1 -d\( | sort -u); do grep -q $f indirect.c || echo $f ; done | grep -v by_offset | sed 's:SET_\(.*\)$:SET_\1(disp, gl\1)\;:' | pbcopy + */ + + SET_Accum(disp, glAccum); + SET_AlphaFunc(disp, glAlphaFunc); + SET_AreTexturesResident(disp, glAreTexturesResident); + SET_ArrayElement(disp, glArrayElement); + SET_Begin(disp, glBegin); + SET_BindTexture(disp, glBindTexture); + SET_Bitmap(disp, glBitmap); + SET_BlendColor(disp, glBlendColor); + SET_BlendEquation(disp, glBlendEquation); + SET_BlendFunc(disp, glBlendFunc); + SET_CallList(disp, glCallList); + SET_CallLists(disp, glCallLists); + SET_Clear(disp, glClear); + SET_ClearAccum(disp, glClearAccum); + SET_ClearColor(disp, glClearColor); + SET_ClearDepth(disp, glClearDepth); + SET_ClearIndex(disp, glClearIndex); + SET_ClearStencil(disp, glClearStencil); + SET_ClipPlane(disp, glClipPlane); + SET_Color3b(disp, glColor3b); + SET_Color3bv(disp, glColor3bv); + SET_Color3d(disp, glColor3d); + SET_Color3dv(disp, glColor3dv); + SET_Color3f(disp, glColor3f); + SET_Color3fv(disp, glColor3fv); + SET_Color3i(disp, glColor3i); + SET_Color3iv(disp, glColor3iv); + SET_Color3s(disp, glColor3s); + SET_Color3sv(disp, glColor3sv); + SET_Color3ub(disp, glColor3ub); + SET_Color3ubv(disp, glColor3ubv); + SET_Color3ui(disp, glColor3ui); + SET_Color3uiv(disp, glColor3uiv); + SET_Color3us(disp, glColor3us); + SET_Color3usv(disp, glColor3usv); + SET_Color4b(disp, glColor4b); + SET_Color4bv(disp, glColor4bv); + SET_Color4d(disp, glColor4d); + SET_Color4dv(disp, glColor4dv); + SET_Color4f(disp, glColor4f); + SET_Color4fv(disp, glColor4fv); + SET_Color4i(disp, glColor4i); + SET_Color4iv(disp, glColor4iv); + SET_Color4s(disp, glColor4s); + SET_Color4sv(disp, glColor4sv); + SET_Color4ub(disp, glColor4ub); + SET_Color4ubv(disp, glColor4ubv); + SET_Color4ui(disp, glColor4ui); + SET_Color4uiv(disp, glColor4uiv); + SET_Color4us(disp, glColor4us); + SET_Color4usv(disp, glColor4usv); + SET_ColorMask(disp, glColorMask); + SET_ColorMaterial(disp, glColorMaterial); + SET_ColorPointer(disp, glColorPointer); + SET_ColorSubTable(disp, glColorSubTable); + SET_ColorTable(disp, glColorTable); + SET_ColorTableParameterfv(disp, glColorTableParameterfv); + SET_ColorTableParameteriv(disp, glColorTableParameteriv); + SET_ConvolutionFilter1D(disp, glConvolutionFilter1D); + SET_ConvolutionFilter2D(disp, glConvolutionFilter2D); + SET_ConvolutionParameterf(disp, glConvolutionParameterf); + SET_ConvolutionParameterfv(disp, glConvolutionParameterfv); + SET_ConvolutionParameteri(disp, glConvolutionParameteri); + SET_ConvolutionParameteriv(disp, glConvolutionParameteriv); + SET_CopyColorSubTable(disp, glCopyColorSubTable); + SET_CopyColorTable(disp, glCopyColorTable); + SET_CopyConvolutionFilter1D(disp, glCopyConvolutionFilter1D); + SET_CopyConvolutionFilter2D(disp, glCopyConvolutionFilter2D); + SET_CopyPixels(disp, glCopyPixels); + SET_CopyTexImage1D(disp, glCopyTexImage1D); + SET_CopyTexImage2D(disp, glCopyTexImage2D); + SET_CopyTexSubImage1D(disp, glCopyTexSubImage1D); + SET_CopyTexSubImage2D(disp, glCopyTexSubImage2D); + SET_CopyTexSubImage3D(disp, glCopyTexSubImage3D); + SET_CullFace(disp, glCullFace); + SET_DeleteLists(disp, glDeleteLists); + SET_DeleteTextures(disp, glDeleteTextures); + SET_DepthFunc(disp, glDepthFunc); + SET_DepthMask(disp, glDepthMask); + SET_DepthRange(disp, glDepthRange); + SET_Disable(disp, glDisable); + SET_DisableClientState(disp, glDisableClientState); + SET_DrawArrays(disp, glDrawArrays); + SET_DrawBuffer(disp, glDrawBuffer); + SET_DrawElements(disp, glDrawElements); + SET_DrawPixels(disp, glDrawPixels); + SET_DrawRangeElements(disp, glDrawRangeElements); + SET_EdgeFlag(disp, glEdgeFlag); + SET_EdgeFlagPointer(disp, glEdgeFlagPointer); + SET_EdgeFlagv(disp, glEdgeFlagv); + SET_Enable(disp, glEnable); + SET_EnableClientState(disp, glEnableClientState); + SET_End(disp, glEnd); + SET_EndList(disp, glEndList); + SET_EvalCoord1d(disp, glEvalCoord1d); + SET_EvalCoord1dv(disp, glEvalCoord1dv); + SET_EvalCoord1f(disp, glEvalCoord1f); + SET_EvalCoord1fv(disp, glEvalCoord1fv); + SET_EvalCoord2d(disp, glEvalCoord2d); + SET_EvalCoord2dv(disp, glEvalCoord2dv); + SET_EvalCoord2f(disp, glEvalCoord2f); + SET_EvalCoord2fv(disp, glEvalCoord2fv); + SET_EvalMesh1(disp, glEvalMesh1); + SET_EvalMesh2(disp, glEvalMesh2); + SET_EvalPoint1(disp, glEvalPoint1); + SET_EvalPoint2(disp, glEvalPoint2); + SET_FeedbackBuffer(disp, glFeedbackBuffer); + SET_Finish(disp, glFinish); + SET_Flush(disp, glFlush); + SET_Fogf(disp, glFogf); + SET_Fogfv(disp, glFogfv); + SET_Fogi(disp, glFogi); + SET_Fogiv(disp, glFogiv); + SET_FrontFace(disp, glFrontFace); + SET_Frustum(disp, glFrustum); + SET_GenLists(disp, glGenLists); + SET_GenTextures(disp, glGenTextures); + SET_GetBooleanv(disp, glGetBooleanv); + SET_GetClipPlane(disp, glGetClipPlane); + SET_GetColorTable(disp, glGetColorTable); + SET_GetColorTableParameterfv(disp, glGetColorTableParameterfv); + SET_GetColorTableParameteriv(disp, glGetColorTableParameteriv); + SET_GetConvolutionFilter(disp, glGetConvolutionFilter); + SET_GetConvolutionParameterfv(disp, glGetConvolutionParameterfv); + SET_GetConvolutionParameteriv(disp, glGetConvolutionParameteriv); + SET_GetDoublev(disp, glGetDoublev); + SET_GetError(disp, glGetError); + SET_GetFloatv(disp, glGetFloatv); + SET_GetHistogram(disp, glGetHistogram); + SET_GetHistogramParameterfv(disp, glGetHistogramParameterfv); + SET_GetHistogramParameteriv(disp, glGetHistogramParameteriv); + SET_GetIntegerv(disp, glGetIntegerv); + SET_GetLightfv(disp, glGetLightfv); + SET_GetLightiv(disp, glGetLightiv); + SET_GetMapdv(disp, glGetMapdv); + SET_GetMapfv(disp, glGetMapfv); + SET_GetMapiv(disp, glGetMapiv); + SET_GetMaterialfv(disp, glGetMaterialfv); + SET_GetMaterialiv(disp, glGetMaterialiv); + SET_GetMinmax(disp, glGetMinmax); + SET_GetMinmaxParameterfv(disp, glGetMinmaxParameterfv); + SET_GetMinmaxParameteriv(disp, glGetMinmaxParameteriv); + SET_GetPixelMapfv(disp, glGetPixelMapfv); + SET_GetPixelMapuiv(disp, glGetPixelMapuiv); + SET_GetPixelMapusv(disp, glGetPixelMapusv); + SET_GetPointerv(disp, glGetPointerv); + SET_GetPolygonStipple(disp, glGetPolygonStipple); + SET_GetSeparableFilter(disp, glGetSeparableFilter); + SET_GetString(disp, glGetString); + SET_GetTexEnvfv(disp, glGetTexEnvfv); + SET_GetTexEnviv(disp, glGetTexEnviv); + SET_GetTexGendv(disp, glGetTexGendv); + SET_GetTexGenfv(disp, glGetTexGenfv); + SET_GetTexGeniv(disp, glGetTexGeniv); + SET_GetTexImage(disp, glGetTexImage); + SET_GetTexLevelParameterfv(disp, glGetTexLevelParameterfv); + SET_GetTexLevelParameteriv(disp, glGetTexLevelParameteriv); + SET_GetTexParameterfv(disp, glGetTexParameterfv); + SET_GetTexParameteriv(disp, glGetTexParameteriv); + SET_Hint(disp, glHint); + SET_Histogram(disp, glHistogram); + SET_IndexMask(disp, glIndexMask); + SET_IndexPointer(disp, glIndexPointer); + SET_Indexd(disp, glIndexd); + SET_Indexdv(disp, glIndexdv); + SET_Indexf(disp, glIndexf); + SET_Indexfv(disp, glIndexfv); + SET_Indexi(disp, glIndexi); + SET_Indexiv(disp, glIndexiv); + SET_Indexs(disp, glIndexs); + SET_Indexsv(disp, glIndexsv); + SET_Indexub(disp, glIndexub); + SET_Indexubv(disp, glIndexubv); + SET_InitNames(disp, glInitNames); + SET_InterleavedArrays(disp, glInterleavedArrays); + SET_IsEnabled(disp, glIsEnabled); + SET_IsList(disp, glIsList); + SET_IsTexture(disp, glIsTexture); + SET_LightModelf(disp, glLightModelf); + SET_LightModelfv(disp, glLightModelfv); + SET_LightModeli(disp, glLightModeli); + SET_LightModeliv(disp, glLightModeliv); + SET_Lightf(disp, glLightf); + SET_Lightfv(disp, glLightfv); + SET_Lighti(disp, glLighti); + SET_Lightiv(disp, glLightiv); + SET_LineStipple(disp, glLineStipple); + SET_LineWidth(disp, glLineWidth); + SET_ListBase(disp, glListBase); + SET_LoadIdentity(disp, glLoadIdentity); + SET_LoadMatrixd(disp, glLoadMatrixd); + SET_LoadMatrixf(disp, glLoadMatrixf); + SET_LoadName(disp, glLoadName); + SET_LogicOp(disp, glLogicOp); + SET_Map1d(disp, glMap1d); + SET_Map1f(disp, glMap1f); + SET_Map2d(disp, glMap2d); + SET_Map2f(disp, glMap2f); + SET_MapGrid1d(disp, glMapGrid1d); + SET_MapGrid1f(disp, glMapGrid1f); + SET_MapGrid2d(disp, glMapGrid2d); + SET_MapGrid2f(disp, glMapGrid2f); + SET_Materialf(disp, glMaterialf); + SET_Materialfv(disp, glMaterialfv); + SET_Materiali(disp, glMateriali); + SET_Materialiv(disp, glMaterialiv); + SET_MatrixMode(disp, glMatrixMode); + SET_Minmax(disp, glMinmax); + SET_MultMatrixd(disp, glMultMatrixd); + SET_MultMatrixf(disp, glMultMatrixf); + SET_NewList(disp, glNewList); + SET_Normal3b(disp, glNormal3b); + SET_Normal3bv(disp, glNormal3bv); + SET_Normal3d(disp, glNormal3d); + SET_Normal3dv(disp, glNormal3dv); + SET_Normal3f(disp, glNormal3f); + SET_Normal3fv(disp, glNormal3fv); + SET_Normal3i(disp, glNormal3i); + SET_Normal3iv(disp, glNormal3iv); + SET_Normal3s(disp, glNormal3s); + SET_Normal3sv(disp, glNormal3sv); + SET_NormalPointer(disp, glNormalPointer); + SET_Ortho(disp, glOrtho); + SET_PassThrough(disp, glPassThrough); + SET_PixelMapfv(disp, glPixelMapfv); + SET_PixelMapuiv(disp, glPixelMapuiv); + SET_PixelMapusv(disp, glPixelMapusv); + SET_PixelStoref(disp, glPixelStoref); + SET_PixelStorei(disp, glPixelStorei); + SET_PixelTransferf(disp, glPixelTransferf); + SET_PixelTransferi(disp, glPixelTransferi); + SET_PixelZoom(disp, glPixelZoom); + SET_PointSize(disp, glPointSize); + SET_PolygonMode(disp, glPolygonMode); + SET_PolygonOffset(disp, glPolygonOffset); + SET_PolygonStipple(disp, glPolygonStipple); + SET_PopAttrib(disp, glPopAttrib); + SET_PopClientAttrib(disp, glPopClientAttrib); + SET_PopMatrix(disp, glPopMatrix); + SET_PopName(disp, glPopName); + SET_PrioritizeTextures(disp, glPrioritizeTextures); + SET_PushAttrib(disp, glPushAttrib); + SET_PushClientAttrib(disp, glPushClientAttrib); + SET_PushMatrix(disp, glPushMatrix); + SET_PushName(disp, glPushName); + SET_RasterPos2d(disp, glRasterPos2d); + SET_RasterPos2dv(disp, glRasterPos2dv); + SET_RasterPos2f(disp, glRasterPos2f); + SET_RasterPos2fv(disp, glRasterPos2fv); + SET_RasterPos2i(disp, glRasterPos2i); + SET_RasterPos2iv(disp, glRasterPos2iv); + SET_RasterPos2s(disp, glRasterPos2s); + SET_RasterPos2sv(disp, glRasterPos2sv); + SET_RasterPos3d(disp, glRasterPos3d); + SET_RasterPos3dv(disp, glRasterPos3dv); + SET_RasterPos3f(disp, glRasterPos3f); + SET_RasterPos3fv(disp, glRasterPos3fv); + SET_RasterPos3i(disp, glRasterPos3i); + SET_RasterPos3iv(disp, glRasterPos3iv); + SET_RasterPos3s(disp, glRasterPos3s); + SET_RasterPos3sv(disp, glRasterPos3sv); + SET_RasterPos4d(disp, glRasterPos4d); + SET_RasterPos4dv(disp, glRasterPos4dv); + SET_RasterPos4f(disp, glRasterPos4f); + SET_RasterPos4fv(disp, glRasterPos4fv); + SET_RasterPos4i(disp, glRasterPos4i); + SET_RasterPos4iv(disp, glRasterPos4iv); + SET_RasterPos4s(disp, glRasterPos4s); + SET_RasterPos4sv(disp, glRasterPos4sv); + SET_ReadBuffer(disp, glReadBuffer); + SET_ReadPixels(disp, glReadPixels); + SET_Rectd(disp, glRectd); + SET_Rectdv(disp, glRectdv); + SET_Rectf(disp, glRectf); + SET_Rectfv(disp, glRectfv); + SET_Recti(disp, glRecti); + SET_Rectiv(disp, glRectiv); + SET_Rects(disp, glRects); + SET_Rectsv(disp, glRectsv); + SET_RenderMode(disp, glRenderMode); + SET_ResetHistogram(disp, glResetHistogram); + SET_ResetMinmax(disp, glResetMinmax); + SET_Rotated(disp, glRotated); + SET_Rotatef(disp, glRotatef); + SET_Scaled(disp, glScaled); + SET_Scalef(disp, glScalef); + SET_Scissor(disp, glScissor); + SET_SelectBuffer(disp, glSelectBuffer); + SET_SeparableFilter2D(disp, glSeparableFilter2D); + SET_ShadeModel(disp, glShadeModel); + SET_StencilFunc(disp, glStencilFunc); + SET_StencilMask(disp, glStencilMask); + SET_StencilOp(disp, glStencilOp); + SET_TexCoord1d(disp, glTexCoord1d); + SET_TexCoord1dv(disp, glTexCoord1dv); + SET_TexCoord1f(disp, glTexCoord1f); + SET_TexCoord1fv(disp, glTexCoord1fv); + SET_TexCoord1i(disp, glTexCoord1i); + SET_TexCoord1iv(disp, glTexCoord1iv); + SET_TexCoord1s(disp, glTexCoord1s); + SET_TexCoord1sv(disp, glTexCoord1sv); + SET_TexCoord2d(disp, glTexCoord2d); + SET_TexCoord2dv(disp, glTexCoord2dv); + SET_TexCoord2f(disp, glTexCoord2f); + SET_TexCoord2fv(disp, glTexCoord2fv); + SET_TexCoord2i(disp, glTexCoord2i); + SET_TexCoord2iv(disp, glTexCoord2iv); + SET_TexCoord2s(disp, glTexCoord2s); + SET_TexCoord2sv(disp, glTexCoord2sv); + SET_TexCoord3d(disp, glTexCoord3d); + SET_TexCoord3dv(disp, glTexCoord3dv); + SET_TexCoord3f(disp, glTexCoord3f); + SET_TexCoord3fv(disp, glTexCoord3fv); + SET_TexCoord3i(disp, glTexCoord3i); + SET_TexCoord3iv(disp, glTexCoord3iv); + SET_TexCoord3s(disp, glTexCoord3s); + SET_TexCoord3sv(disp, glTexCoord3sv); + SET_TexCoord4d(disp, glTexCoord4d); + SET_TexCoord4dv(disp, glTexCoord4dv); + SET_TexCoord4f(disp, glTexCoord4f); + SET_TexCoord4fv(disp, glTexCoord4fv); + SET_TexCoord4i(disp, glTexCoord4i); + SET_TexCoord4iv(disp, glTexCoord4iv); + SET_TexCoord4s(disp, glTexCoord4s); + SET_TexCoord4sv(disp, glTexCoord4sv); + SET_TexCoordPointer(disp, glTexCoordPointer); + SET_TexEnvf(disp, glTexEnvf); + SET_TexEnvfv(disp, glTexEnvfv); + SET_TexEnvi(disp, glTexEnvi); + SET_TexEnviv(disp, glTexEnviv); + SET_TexGend(disp, glTexGend); + SET_TexGendv(disp, glTexGendv); + SET_TexGenf(disp, glTexGenf); + SET_TexGenfv(disp, glTexGenfv); + SET_TexGeni(disp, glTexGeni); + SET_TexGeniv(disp, glTexGeniv); + + /* Pointer Incompatability: + * internalformat is a GLenum according to /System/Library/Frameworks/OpenGL.framework/Headers/gl.h + * extern void glTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); + * extern void glTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); + * extern void glTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); + * + * and it's a GLint in glx/glapitable.h and according to the man page + * void ( * TexImage1D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid * pixels); + * void ( * TexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels); + * void ( * TexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels); + * + * <rdar://problem/6953344> gl.h contains incorrect prototypes for glTexImage[123]D + */ + + SET_TexImage1D(disp, (void *)glTexImage1D); + SET_TexImage2D(disp, (void *)glTexImage2D); + SET_TexImage3D(disp, (void *)glTexImage3D); + SET_TexParameterf(disp, glTexParameterf); + SET_TexParameterfv(disp, glTexParameterfv); + SET_TexParameteri(disp, glTexParameteri); + SET_TexParameteriv(disp, glTexParameteriv); + SET_TexSubImage1D(disp, glTexSubImage1D); + SET_TexSubImage2D(disp, glTexSubImage2D); + SET_TexSubImage3D(disp, glTexSubImage3D); + SET_Translated(disp, glTranslated); + SET_Translatef(disp, glTranslatef); + SET_Vertex2d(disp, glVertex2d); + SET_Vertex2dv(disp, glVertex2dv); + SET_Vertex2f(disp, glVertex2f); + SET_Vertex2fv(disp, glVertex2fv); + SET_Vertex2i(disp, glVertex2i); + SET_Vertex2iv(disp, glVertex2iv); + SET_Vertex2s(disp, glVertex2s); + SET_Vertex2sv(disp, glVertex2sv); + SET_Vertex3d(disp, glVertex3d); + SET_Vertex3dv(disp, glVertex3dv); + SET_Vertex3f(disp, glVertex3f); + SET_Vertex3fv(disp, glVertex3fv); + SET_Vertex3i(disp, glVertex3i); + SET_Vertex3iv(disp, glVertex3iv); + SET_Vertex3s(disp, glVertex3s); + SET_Vertex3sv(disp, glVertex3sv); + SET_Vertex4d(disp, glVertex4d); + SET_Vertex4dv(disp, glVertex4dv); + SET_Vertex4f(disp, glVertex4f); + SET_Vertex4fv(disp, glVertex4fv); + SET_Vertex4i(disp, glVertex4i); + SET_Vertex4iv(disp, glVertex4iv); + SET_Vertex4s(disp, glVertex4s); + SET_Vertex4sv(disp, glVertex4sv); + SET_VertexPointer(disp, glVertexPointer); + SET_Viewport(disp, glViewport); + +#if GL_VERSION_2_0 + SET_AttachShader(disp, glAttachShader); + SET_DeleteShader(disp, glDeleteShader); + SET_DetachShader(disp, glDetachShader); + SET_GetAttachedShaders(disp, glGetAttachedShaders); + SET_GetProgramInfoLog(disp, glGetProgramInfoLog); + SET_GetShaderInfoLog(disp, glGetShaderInfoLog); + SET_GetShaderiv(disp, glGetShaderiv); + SET_IsShader(disp, glIsShader); + SET_StencilFuncSeparate(disp, glStencilFuncSeparate); + SET_StencilMaskSeparate(disp, glStencilMaskSeparate); + SET_StencilOpSeparate(disp, glStencilOpSeparate); +#endif + +#if GL_VERSION_2_1 + SET_UniformMatrix2x3fv(disp, glUniformMatrix2x3fv); + SET_UniformMatrix2x4fv(disp, glUniformMatrix2x4fv); + SET_UniformMatrix3x2fv(disp, glUniformMatrix3x2fv); + SET_UniformMatrix3x4fv(disp, glUniformMatrix3x4fv); + SET_UniformMatrix4x2fv(disp, glUniformMatrix4x2fv); + SET_UniformMatrix4x3fv(disp, glUniformMatrix4x3fv); +#endif + +#if GL_APPLE_vertex_array_object + SET_BindVertexArrayAPPLE(disp, glBindVertexArrayAPPLE); + SET_DeleteVertexArraysAPPLE(disp, glDeleteVertexArraysAPPLE); + SET_GenVertexArraysAPPLE(disp, glGenVertexArraysAPPLE); + SET_IsVertexArrayAPPLE(disp, glIsVertexArrayAPPLE); +#endif + +#if GL_ARB_draw_buffers + SET_DrawBuffersARB(disp, glDrawBuffersARB); +#endif + +#if GL_ARB_multisample + SET_SampleCoverageARB(disp, glSampleCoverageARB); +#endif + +#if GL_ARB_multitexture + SET_ActiveTextureARB(disp, glActiveTextureARB); + SET_ClientActiveTextureARB(disp, glClientActiveTextureARB); + SET_MultiTexCoord1dARB(disp, glMultiTexCoord1dARB); + SET_MultiTexCoord1dvARB(disp, glMultiTexCoord1dvARB); + SET_MultiTexCoord1fARB(disp, glMultiTexCoord1fARB); + SET_MultiTexCoord1fvARB(disp, glMultiTexCoord1fvARB); + SET_MultiTexCoord1iARB(disp, glMultiTexCoord1iARB); + SET_MultiTexCoord1ivARB(disp, glMultiTexCoord1ivARB); + SET_MultiTexCoord1sARB(disp, glMultiTexCoord1sARB); + SET_MultiTexCoord1svARB(disp, glMultiTexCoord1svARB); + SET_MultiTexCoord2dARB(disp, glMultiTexCoord2dARB); + SET_MultiTexCoord2dvARB(disp, glMultiTexCoord2dvARB); + SET_MultiTexCoord2fARB(disp, glMultiTexCoord2fARB); + SET_MultiTexCoord2fvARB(disp, glMultiTexCoord2fvARB); + SET_MultiTexCoord2iARB(disp, glMultiTexCoord2iARB); + SET_MultiTexCoord2ivARB(disp, glMultiTexCoord2ivARB); + SET_MultiTexCoord2sARB(disp, glMultiTexCoord2sARB); + SET_MultiTexCoord2svARB(disp, glMultiTexCoord2svARB); + SET_MultiTexCoord3dARB(disp, glMultiTexCoord3dARB); + SET_MultiTexCoord3dvARB(disp, glMultiTexCoord3dvARB); + SET_MultiTexCoord3fARB(disp, glMultiTexCoord3fARB); + SET_MultiTexCoord3fvARB(disp, glMultiTexCoord3fvARB); + SET_MultiTexCoord3iARB(disp, glMultiTexCoord3iARB); + SET_MultiTexCoord3ivARB(disp, glMultiTexCoord3ivARB); + SET_MultiTexCoord3sARB(disp, glMultiTexCoord3sARB); + SET_MultiTexCoord3svARB(disp, glMultiTexCoord3svARB); + SET_MultiTexCoord4dARB(disp, glMultiTexCoord4dARB); + SET_MultiTexCoord4dvARB(disp, glMultiTexCoord4dvARB); + SET_MultiTexCoord4fARB(disp, glMultiTexCoord4fARB); + SET_MultiTexCoord4fvARB(disp, glMultiTexCoord4fvARB); + SET_MultiTexCoord4iARB(disp, glMultiTexCoord4iARB); + SET_MultiTexCoord4ivARB(disp, glMultiTexCoord4ivARB); + SET_MultiTexCoord4sARB(disp, glMultiTexCoord4sARB); + SET_MultiTexCoord4svARB(disp, glMultiTexCoord4svARB); +#endif + +#if GL_ARB_occlusion_query + SET_BeginQueryARB(disp, glBeginQueryARB); + SET_DeleteQueriesARB(disp, glDeleteQueriesARB); + SET_EndQueryARB(disp, glEndQueryARB); + SET_GenQueriesARB(disp, glGenQueriesARB); + SET_GetQueryObjectivARB(disp, glGetQueryObjectivARB); + SET_GetQueryObjectuivARB(disp, glGetQueryObjectuivARB); + SET_GetQueryivARB(disp, glGetQueryivARB); + SET_IsQueryARB(disp, glIsQueryARB); +#endif + +#if GL_ARB_shader_objects + SET_AttachObjectARB(disp, glAttachObjectARB); + SET_CompileShaderARB(disp, glCompileShaderARB); + SET_DeleteObjectARB(disp, glDeleteObjectARB); + SET_GetHandleARB(disp, glGetHandleARB); + SET_DetachObjectARB(disp, glDetachObjectARB); + SET_CreateProgramObjectARB(disp, glCreateProgramObjectARB); + SET_CreateShaderObjectARB(disp, glCreateShaderObjectARB); + SET_GetInfoLogARB(disp, glGetInfoLogARB); + SET_GetActiveUniformARB(disp, glGetActiveUniformARB); + SET_GetAttachedObjectsARB(disp, glGetAttachedObjectsARB); + SET_GetObjectParameterfvARB(disp, glGetObjectParameterfvARB); + SET_GetObjectParameterivARB(disp, glGetObjectParameterivARB); + SET_GetShaderSourceARB(disp, glGetShaderSourceARB); + SET_GetUniformLocationARB(disp, glGetUniformLocationARB); + SET_GetUniformfvARB(disp, glGetUniformfvARB); + SET_GetUniformivARB(disp, glGetUniformivARB); + SET_LinkProgramARB(disp, glLinkProgramARB); + SET_ShaderSourceARB(disp, glShaderSourceARB); + SET_Uniform1fARB(disp, glUniform1fARB); + SET_Uniform1fvARB(disp, glUniform1fvARB); + SET_Uniform1iARB(disp, glUniform1iARB); + SET_Uniform1ivARB(disp, glUniform1ivARB); + SET_Uniform2fARB(disp, glUniform2fARB); + SET_Uniform2fvARB(disp, glUniform2fvARB); + SET_Uniform2iARB(disp, glUniform2iARB); + SET_Uniform2ivARB(disp, glUniform2ivARB); + SET_Uniform3fARB(disp, glUniform3fARB); + SET_Uniform3fvARB(disp, glUniform3fvARB); + SET_Uniform3iARB(disp, glUniform3iARB); + SET_Uniform3ivARB(disp, glUniform3ivARB); + SET_Uniform4fARB(disp, glUniform4fARB); + SET_Uniform4fvARB(disp, glUniform4fvARB); + SET_Uniform4iARB(disp, glUniform4iARB); + SET_Uniform4ivARB(disp, glUniform4ivARB); + SET_UniformMatrix2fvARB(disp, glUniformMatrix2fvARB); + SET_UniformMatrix3fvARB(disp, glUniformMatrix3fvARB); + SET_UniformMatrix4fvARB(disp, glUniformMatrix4fvARB); + SET_UseProgramObjectARB(disp, glUseProgramObjectARB); + SET_ValidateProgramARB(disp, glValidateProgramARB); +#endif + +#if GL_ARB_texture_compression + SET_CompressedTexImage1DARB(disp, glCompressedTexImage1DARB); + SET_CompressedTexImage2DARB(disp, glCompressedTexImage2DARB); + SET_CompressedTexImage3DARB(disp, glCompressedTexImage3DARB); + SET_CompressedTexSubImage1DARB(disp, glCompressedTexSubImage1DARB); + SET_CompressedTexSubImage2DARB(disp, glCompressedTexSubImage2DARB); + SET_CompressedTexSubImage3DARB(disp, glCompressedTexSubImage3DARB); + SET_GetCompressedTexImageARB(disp, glGetCompressedTexImageARB); +#endif + +#if GL_ARB_transpose_matrix + SET_LoadTransposeMatrixdARB(disp, glLoadTransposeMatrixdARB); + SET_LoadTransposeMatrixfARB(disp, glLoadTransposeMatrixfARB); + SET_MultTransposeMatrixdARB(disp, glMultTransposeMatrixdARB); + SET_MultTransposeMatrixfARB(disp, glMultTransposeMatrixfARB); +#endif + +#if GL_ARB_vertex_buffer_object + SET_BindBufferARB(disp, glBindBufferARB); + SET_BufferDataARB(disp, glBufferDataARB); + SET_BufferSubDataARB(disp, glBufferSubDataARB); + SET_DeleteBuffersARB(disp, glDeleteBuffersARB); + SET_GenBuffersARB(disp, glGenBuffersARB); + SET_GetBufferParameterivARB(disp, glGetBufferParameterivARB); + SET_GetBufferPointervARB(disp, glGetBufferPointervARB); + SET_GetBufferSubDataARB(disp, glGetBufferSubDataARB); + SET_IsBufferARB(disp, glIsBufferARB); + SET_MapBufferARB(disp, glMapBufferARB); + SET_UnmapBufferARB(disp, glUnmapBufferARB); +#endif + +#if GL_ARB_vertex_program + SET_DisableVertexAttribArrayARB(disp, glDisableVertexAttribArrayARB); + SET_EnableVertexAttribArrayARB(disp, glEnableVertexAttribArrayARB); + SET_GetProgramEnvParameterdvARB(disp, glGetProgramEnvParameterdvARB); + SET_GetProgramEnvParameterfvARB(disp, glGetProgramEnvParameterfvARB); + SET_GetProgramLocalParameterdvARB(disp, glGetProgramLocalParameterdvARB); + SET_GetProgramLocalParameterfvARB(disp, glGetProgramLocalParameterfvARB); + SET_GetProgramStringARB(disp, glGetProgramStringARB); + SET_GetProgramivARB(disp, glGetProgramivARB); + SET_GetVertexAttribdvARB(disp, glGetVertexAttribdvARB); + SET_GetVertexAttribfvARB(disp, glGetVertexAttribfvARB); + SET_GetVertexAttribivARB(disp, glGetVertexAttribivARB); + SET_ProgramEnvParameter4dARB(disp, glProgramEnvParameter4dARB); + SET_ProgramEnvParameter4dvARB(disp, glProgramEnvParameter4dvARB); + SET_ProgramEnvParameter4fARB(disp, glProgramEnvParameter4fARB); + SET_ProgramEnvParameter4fvARB(disp, glProgramEnvParameter4fvARB); + SET_ProgramLocalParameter4dARB(disp, glProgramLocalParameter4dARB); + SET_ProgramLocalParameter4dvARB(disp, glProgramLocalParameter4dvARB); + SET_ProgramLocalParameter4fARB(disp, glProgramLocalParameter4fARB); + SET_ProgramLocalParameter4fvARB(disp, glProgramLocalParameter4fvARB); + SET_ProgramStringARB(disp, glProgramStringARB); + SET_VertexAttrib1dARB(disp, glVertexAttrib1dARB); + SET_VertexAttrib1dvARB(disp, glVertexAttrib1dvARB); + SET_VertexAttrib1fARB(disp, glVertexAttrib1fARB); + SET_VertexAttrib1fvARB(disp, glVertexAttrib1fvARB); + SET_VertexAttrib1sARB(disp, glVertexAttrib1sARB); + SET_VertexAttrib1svARB(disp, glVertexAttrib1svARB); + SET_VertexAttrib2dARB(disp, glVertexAttrib2dARB); + SET_VertexAttrib2dvARB(disp, glVertexAttrib2dvARB); + SET_VertexAttrib2fARB(disp, glVertexAttrib2fARB); + SET_VertexAttrib2fvARB(disp, glVertexAttrib2fvARB); + SET_VertexAttrib2sARB(disp, glVertexAttrib2sARB); + SET_VertexAttrib2svARB(disp, glVertexAttrib2svARB); + SET_VertexAttrib3dARB(disp, glVertexAttrib3dARB); + SET_VertexAttrib3dvARB(disp, glVertexAttrib3dvARB); + SET_VertexAttrib3fARB(disp, glVertexAttrib3fARB); + SET_VertexAttrib3fvARB(disp, glVertexAttrib3fvARB); + SET_VertexAttrib3sARB(disp, glVertexAttrib3sARB); + SET_VertexAttrib3svARB(disp, glVertexAttrib3svARB); + SET_VertexAttrib4NbvARB(disp, glVertexAttrib4NbvARB); + SET_VertexAttrib4NivARB(disp, glVertexAttrib4NivARB); + SET_VertexAttrib4NsvARB(disp, glVertexAttrib4NsvARB); + SET_VertexAttrib4NubARB(disp, glVertexAttrib4NubARB); + SET_VertexAttrib4NubvARB(disp, glVertexAttrib4NubvARB); + SET_VertexAttrib4NuivARB(disp, glVertexAttrib4NuivARB); + SET_VertexAttrib4NusvARB(disp, glVertexAttrib4NusvARB); + SET_VertexAttrib4bvARB(disp, glVertexAttrib4bvARB); + SET_VertexAttrib4dARB(disp, glVertexAttrib4dARB); + SET_VertexAttrib4dvARB(disp, glVertexAttrib4dvARB); + SET_VertexAttrib4fARB(disp, glVertexAttrib4fARB); + SET_VertexAttrib4fvARB(disp, glVertexAttrib4fvARB); + SET_VertexAttrib4ivARB(disp, glVertexAttrib4ivARB); + SET_VertexAttrib4sARB(disp, glVertexAttrib4sARB); + SET_VertexAttrib4svARB(disp, glVertexAttrib4svARB); + SET_VertexAttrib4ubvARB(disp, glVertexAttrib4ubvARB); + SET_VertexAttrib4uivARB(disp, glVertexAttrib4uivARB); + SET_VertexAttrib4usvARB(disp, glVertexAttrib4usvARB); + SET_VertexAttribPointerARB(disp, glVertexAttribPointerARB); +#endif + +#if GL_ARB_vertex_shader + SET_BindAttribLocationARB(disp, glBindAttribLocationARB); + SET_GetActiveAttribARB(disp, glGetActiveAttribARB); + SET_GetAttribLocationARB(disp, glGetAttribLocationARB); +#endif + +#if GL_ARB_window_pos + SET_WindowPos2dMESA(disp, glWindowPos2dARB); + SET_WindowPos2dvMESA(disp, glWindowPos2dvARB); + SET_WindowPos2fMESA(disp, glWindowPos2fARB); + SET_WindowPos2fvMESA(disp, glWindowPos2fvARB); + SET_WindowPos2iMESA(disp, glWindowPos2iARB); + SET_WindowPos2ivMESA(disp, glWindowPos2ivARB); + SET_WindowPos2sMESA(disp, glWindowPos2sARB); + SET_WindowPos2svMESA(disp, glWindowPos2svARB); + SET_WindowPos3dMESA(disp, glWindowPos3dARB); + SET_WindowPos3dvMESA(disp, glWindowPos3dvARB); + SET_WindowPos3fMESA(disp, glWindowPos3fARB); + SET_WindowPos3fvMESA(disp, glWindowPos3fvARB); + SET_WindowPos3iMESA(disp, glWindowPos3iARB); + SET_WindowPos3ivMESA(disp, glWindowPos3ivARB); + SET_WindowPos3sMESA(disp, glWindowPos3sARB); + SET_WindowPos3svMESA(disp, glWindowPos3svARB); +#endif + +#if GL_ATI_fragment_shader + SET_AlphaFragmentOp1ATI(disp, glAlphaFragmentOp1ATI); + SET_AlphaFragmentOp2ATI(disp, glAlphaFragmentOp2ATI); + SET_AlphaFragmentOp3ATI(disp, glAlphaFragmentOp3ATI); + SET_BeginFragmentShaderATI(disp, glBeginFragmentShaderATI); + SET_BindFragmentShaderATI(disp, glBindFragmentShaderATI); + SET_ColorFragmentOp1ATI(disp, glColorFragmentOp1ATI); + SET_ColorFragmentOp2ATI(disp, glColorFragmentOp2ATI); + SET_ColorFragmentOp3ATI(disp, glColorFragmentOp3ATI); + SET_DeleteFragmentShaderATI(disp, glDeleteFragmentShaderATI); + SET_EndFragmentShaderATI(disp, glEndFragmentShaderATI); + SET_GenFragmentShadersATI(disp, glGenFragmentShadersATI); + SET_PassTexCoordATI(disp, glPassTexCoordATI); + SET_SampleMapATI(disp, glSampleMapATI); + SET_SetFragmentShaderConstantATI(disp, glSetFragmentShaderConstantATI); +#elif GL_EXT_fragment_shader + SET_AlphaFragmentOp1ATI(disp, glAlphaFragmentOp1EXT); + SET_AlphaFragmentOp2ATI(disp, glAlphaFragmentOp2EXT); + SET_AlphaFragmentOp3ATI(disp, glAlphaFragmentOp3EXT); + SET_BeginFragmentShaderATI(disp, glBeginFragmentShaderEXT); + SET_BindFragmentShaderATI(disp, glBindFragmentShaderEXT); + SET_ColorFragmentOp1ATI(disp, glColorFragmentOp1EXT); + SET_ColorFragmentOp2ATI(disp, glColorFragmentOp2EXT); + SET_ColorFragmentOp3ATI(disp, glColorFragmentOp3EXT); + SET_DeleteFragmentShaderATI(disp, glDeleteFragmentShaderEXT); + SET_EndFragmentShaderATI(disp, glEndFragmentShaderEXT); + SET_GenFragmentShadersATI(disp, glGenFragmentShadersEXT); + SET_PassTexCoordATI(disp, glPassTexCoordEXT); + SET_SampleMapATI(disp, glSampleMapEXT); + SET_SetFragmentShaderConstantATI(disp, glSetFragmentShaderConstantEXT); +#endif + +#if GL_ATI_separate_stencil + SET_StencilFuncSeparateATI(disp, glStencilFuncSeparateATI); +#endif + +#if GL_EXT_blend_equation_separate + SET_BlendEquationSeparateEXT(disp, glBlendEquationSeparateEXT); +#endif + +#if GL_EXT_blend_func_separate + SET_BlendFuncSeparateEXT(disp, glBlendFuncSeparateEXT); +#endif + +#if GL_EXT_depth_bounds_test + SET_DepthBoundsEXT(disp, glDepthBoundsEXT); +#endif + +#if GL_EXT_compiled_vertex_array + SET_LockArraysEXT(disp, glLockArraysEXT); + SET_UnlockArraysEXT(disp, glUnlockArraysEXT); +#endif + +#if GL_EXT_cull_vertex + SET_CullParameterdvEXT(disp, glCullParameterdvEXT); + SET_CullParameterfvEXT(disp, glCullParameterfvEXT); +#endif + +#if GL_EXT_fog_coord + SET_FogCoordPointerEXT(disp, glFogCoordPointerEXT); + SET_FogCoorddEXT(disp, glFogCoorddEXT); + SET_FogCoorddvEXT(disp, glFogCoorddvEXT); + SET_FogCoordfEXT(disp, glFogCoordfEXT); + SET_FogCoordfvEXT(disp, glFogCoordfvEXT); +#endif + +#if GL_EXT_framebuffer_blit + SET_BlitFramebufferEXT(disp, glBlitFramebufferEXT); +#endif + +#if GL_EXT_framebuffer_object + SET_BindFramebufferEXT(disp, glBindFramebufferEXT); + SET_BindRenderbufferEXT(disp, glBindRenderbufferEXT); + SET_CheckFramebufferStatusEXT(disp, glCheckFramebufferStatusEXT); + SET_DeleteFramebuffersEXT(disp, glDeleteFramebuffersEXT); + SET_DeleteRenderbuffersEXT(disp, glDeleteRenderbuffersEXT); + SET_FramebufferRenderbufferEXT(disp, glFramebufferRenderbufferEXT); + SET_FramebufferTexture1DEXT(disp, glFramebufferTexture1DEXT); + SET_FramebufferTexture2DEXT(disp, glFramebufferTexture2DEXT); + SET_FramebufferTexture3DEXT(disp, glFramebufferTexture3DEXT); + SET_GenerateMipmapEXT(disp, glGenerateMipmapEXT); + SET_GenFramebuffersEXT(disp, glGenFramebuffersEXT); + SET_GenRenderbuffersEXT(disp, glGenRenderbuffersEXT); + SET_GetFramebufferAttachmentParameterivEXT(disp, glGetFramebufferAttachmentParameterivEXT); + SET_GetRenderbufferParameterivEXT(disp, glGetRenderbufferParameterivEXT); + SET_IsFramebufferEXT(disp, glIsFramebufferEXT); + SET_IsRenderbufferEXT(disp, glIsRenderbufferEXT); + SET_RenderbufferStorageEXT(disp, glRenderbufferStorageEXT); +#endif + +#if GL_EXT_gpu_program_parameters + SET_ProgramEnvParameters4fvEXT(disp, glProgramEnvParameters4fvEXT); + SET_ProgramLocalParameters4fvEXT(disp, glProgramLocalParameters4fvEXT); +#endif + +#if GL_EXT_multi_draw_arrays + /* Pointer Incompatability: + * This warning can be safely ignored. OpenGL.framework adds const to the + * two pointers. + * + * extern void glMultiDrawArraysEXT (GLenum, const GLint *, const GLsizei *, GLsizei); + * + * void ( * MultiDrawArraysEXT)(GLenum mode, GLint * first, GLsizei * count, GLsizei primcount); + */ + SET_MultiDrawArraysEXT(disp, (void *)glMultiDrawArraysEXT); + SET_MultiDrawElementsEXT(disp, glMultiDrawElementsEXT); +#endif + +#if GL_EXT_point_parameters + SET_PointParameterfEXT(disp, glPointParameterfEXT); + SET_PointParameterfvEXT(disp, glPointParameterfvEXT); +#elif GL_ARB_point_parameters + SET_PointParameterfEXT(disp, glPointParameterfARB); + SET_PointParameterfvEXT(disp, glPointParameterfvARB); +#endif + +#if GL_EXT_polygon_offset + SET_PolygonOffsetEXT(disp, glPolygonOffsetEXT); +#endif + +#if GL_EXT_secondary_color + SET_SecondaryColor3bEXT(disp, glSecondaryColor3bEXT); + SET_SecondaryColor3bvEXT(disp, glSecondaryColor3bvEXT); + SET_SecondaryColor3dEXT(disp, glSecondaryColor3dEXT); + SET_SecondaryColor3dvEXT(disp, glSecondaryColor3dvEXT); + SET_SecondaryColor3fEXT(disp, glSecondaryColor3fEXT); + SET_SecondaryColor3fvEXT(disp, glSecondaryColor3fvEXT); + SET_SecondaryColor3iEXT(disp, glSecondaryColor3iEXT); + SET_SecondaryColor3ivEXT(disp, glSecondaryColor3ivEXT); + SET_SecondaryColor3sEXT(disp, glSecondaryColor3sEXT); + SET_SecondaryColor3svEXT(disp, glSecondaryColor3svEXT); + SET_SecondaryColor3ubEXT(disp, glSecondaryColor3ubEXT); + SET_SecondaryColor3ubvEXT(disp, glSecondaryColor3ubvEXT); + SET_SecondaryColor3uiEXT(disp, glSecondaryColor3uiEXT); + SET_SecondaryColor3uivEXT(disp, glSecondaryColor3uivEXT); + SET_SecondaryColor3usEXT(disp, glSecondaryColor3usEXT); + SET_SecondaryColor3usvEXT(disp, glSecondaryColor3usvEXT); + SET_SecondaryColorPointerEXT(disp, glSecondaryColorPointerEXT); +#endif + +#if GL_EXT_stencil_two_side + SET_ActiveStencilFaceEXT(disp, glActiveStencilFaceEXT); +#endif + +#if GL_EXT_timer_query + SET_GetQueryObjecti64vEXT(disp, glGetQueryObjecti64vEXT); + SET_GetQueryObjectui64vEXT(disp, glGetQueryObjectui64vEXT); +#endif + +#if GL_EXT_vertex_array + SET_ColorPointerEXT(disp, glColorPointerEXT); + SET_EdgeFlagPointerEXT(disp, glEdgeFlagPointerEXT); + SET_IndexPointerEXT(disp, glIndexPointerEXT); + SET_NormalPointerEXT(disp, glNormalPointerEXT); + SET_TexCoordPointerEXT(disp, glTexCoordPointerEXT); + SET_VertexPointerEXT(disp, glVertexPointerEXT); +#endif + +#if GL_IBM_multimode_draw_arrays + SET_MultiModeDrawArraysIBM(disp, glMultiModeDrawArraysIBM); + SET_MultiModeDrawElementsIBM(disp, glMultiModeDrawElementsIBM); +#endif + +#if GL_MESA_resize_buffers + SET_ResizeBuffersMESA(disp, glResizeBuffersMESA); +#endif + +#if GL_MESA_window_pos + SET_WindowPos4dMESA(disp, glWindowPos4dMESA); + SET_WindowPos4dvMESA(disp, glWindowPos4dvMESA); + SET_WindowPos4fMESA(disp, glWindowPos4fMESA); + SET_WindowPos4fvMESA(disp, glWindowPos4fvMESA); + SET_WindowPos4iMESA(disp, glWindowPos4iMESA); + SET_WindowPos4ivMESA(disp, glWindowPos4ivMESA); + SET_WindowPos4sMESA(disp, glWindowPos4sMESA); + SET_WindowPos4svMESA(disp, glWindowPos4svMESA); +#endif + +#if GL_NV_fence + SET_DeleteFencesNV(disp, glDeleteFencesNV); + SET_FinishFenceNV(disp, glFinishFenceNV); + SET_GenFencesNV(disp, glGenFencesNV); + SET_GetFenceivNV(disp, glGetFenceivNV); + SET_IsFenceNV(disp, glIsFenceNV); + SET_SetFenceNV(disp, glSetFenceNV); + SET_TestFenceNV(disp, glTestFenceNV); +#endif + +#if GL_NV_fragment_program + SET_GetProgramNamedParameterdvNV(disp, glGetProgramNamedParameterdvNV); + SET_GetProgramNamedParameterfvNV(disp, glGetProgramNamedParameterfvNV); + SET_ProgramNamedParameter4dNV(disp, glProgramNamedParameter4dNV); + SET_ProgramNamedParameter4dvNV(disp, glProgramNamedParameter4dvNV); + SET_ProgramNamedParameter4fNV(disp, glProgramNamedParameter4fNV); + SET_ProgramNamedParameter4fvNV(disp, glProgramNamedParameter4fvNV); +#endif + +#if GL_NV_geometry_program4 + SET_FramebufferTextureLayerEXT(disp, glFramebufferTextureLayerEXT); +#endif + +#if GL_NV_point_sprite + SET_PointParameteriNV(disp, glPointParameteriNV); + SET_PointParameterivNV(disp, glPointParameterivNV); +#endif + +#if GL_NV_register_combiners + SET_CombinerInputNV(disp, glCombinerInputNV); + SET_CombinerOutputNV(disp, glCombinerOutputNV); + SET_CombinerParameterfNV(disp, glCombinerParameterfNV); + SET_CombinerParameterfvNV(disp, glCombinerParameterfvNV); + SET_CombinerParameteriNV(disp, glCombinerParameteriNV); + SET_CombinerParameterivNV(disp, glCombinerParameterivNV); + SET_FinalCombinerInputNV(disp, glFinalCombinerInputNV); + SET_GetCombinerInputParameterfvNV(disp, glGetCombinerInputParameterfvNV); + SET_GetCombinerInputParameterivNV(disp, glGetCombinerInputParameterivNV); + SET_GetCombinerOutputParameterfvNV(disp, glGetCombinerOutputParameterfvNV); + SET_GetCombinerOutputParameterivNV(disp, glGetCombinerOutputParameterivNV); + SET_GetFinalCombinerInputParameterfvNV(disp, glGetFinalCombinerInputParameterfvNV); + SET_GetFinalCombinerInputParameterivNV(disp, glGetFinalCombinerInputParameterivNV); +#endif + +#if GL_NV_vertex_array_range + SET_FlushVertexArrayRangeNV(disp, glFlushVertexArrayRangeNV); + SET_VertexArrayRangeNV(disp, glVertexArrayRangeNV); +#endif + +#if GL_NV_vertex_program + SET_AreProgramsResidentNV(disp, glAreProgramsResidentNV); + SET_BindProgramNV(disp, glBindProgramNV); + SET_DeleteProgramsNV(disp, glDeleteProgramsNV); + SET_ExecuteProgramNV(disp, glExecuteProgramNV); + SET_GenProgramsNV(disp, glGenProgramsNV); + SET_GetProgramParameterdvNV(disp, glGetProgramParameterdvNV); + SET_GetProgramParameterfvNV(disp, glGetProgramParameterfvNV); + SET_GetProgramStringNV(disp, glGetProgramStringNV); + SET_GetProgramivNV(disp, glGetProgramivNV); + SET_GetTrackMatrixivNV(disp, glGetTrackMatrixivNV); + SET_GetVertexAttribPointervNV(disp, glGetVertexAttribPointervNV); + SET_GetVertexAttribdvNV(disp, glGetVertexAttribdvNV); + SET_GetVertexAttribfvNV(disp, glGetVertexAttribfvNV); + SET_GetVertexAttribivNV(disp, glGetVertexAttribivNV); + SET_IsProgramNV(disp, glIsProgramNV); + SET_LoadProgramNV(disp, glLoadProgramNV); + SET_ProgramParameters4dvNV(disp, glProgramParameters4dvNV); + SET_ProgramParameters4fvNV(disp, glProgramParameters4fvNV); + SET_RequestResidentProgramsNV(disp, glRequestResidentProgramsNV); + SET_TrackMatrixNV(disp, glTrackMatrixNV); + SET_VertexAttrib1dNV(disp, glVertexAttrib1dNV) + SET_VertexAttrib1dvNV(disp, glVertexAttrib1dvNV) + SET_VertexAttrib1fNV(disp, glVertexAttrib1fNV) + SET_VertexAttrib1fvNV(disp, glVertexAttrib1fvNV) + SET_VertexAttrib1sNV(disp, glVertexAttrib1sNV) + SET_VertexAttrib1svNV(disp, glVertexAttrib1svNV) + SET_VertexAttrib2dNV(disp, glVertexAttrib2dNV) + SET_VertexAttrib2dvNV(disp, glVertexAttrib2dvNV) + SET_VertexAttrib2fNV(disp, glVertexAttrib2fNV) + SET_VertexAttrib2fvNV(disp, glVertexAttrib2fvNV) + SET_VertexAttrib2sNV(disp, glVertexAttrib2sNV) + SET_VertexAttrib2svNV(disp, glVertexAttrib2svNV) + SET_VertexAttrib3dNV(disp, glVertexAttrib3dNV) + SET_VertexAttrib3dvNV(disp, glVertexAttrib3dvNV) + SET_VertexAttrib3fNV(disp, glVertexAttrib3fNV) + SET_VertexAttrib3fvNV(disp, glVertexAttrib3fvNV) + SET_VertexAttrib3sNV(disp, glVertexAttrib3sNV) + SET_VertexAttrib3svNV(disp, glVertexAttrib3svNV) + SET_VertexAttrib4dNV(disp, glVertexAttrib4dNV) + SET_VertexAttrib4dvNV(disp, glVertexAttrib4dvNV) + SET_VertexAttrib4fNV(disp, glVertexAttrib4fNV) + SET_VertexAttrib4fvNV(disp, glVertexAttrib4fvNV) + SET_VertexAttrib4sNV(disp, glVertexAttrib4sNV) + SET_VertexAttrib4svNV(disp, glVertexAttrib4svNV) + SET_VertexAttrib4ubNV(disp, glVertexAttrib4ubNV) + SET_VertexAttrib4ubvNV(disp, glVertexAttrib4ubvNV) + SET_VertexAttribPointerNV(disp, glVertexAttribPointerNV) + SET_VertexAttribs1dvNV(disp, glVertexAttribs1dvNV) + SET_VertexAttribs1fvNV(disp, glVertexAttribs1fvNV) + SET_VertexAttribs1svNV(disp, glVertexAttribs1svNV) + SET_VertexAttribs2dvNV(disp, glVertexAttribs2dvNV) + SET_VertexAttribs2fvNV(disp, glVertexAttribs2fvNV) + SET_VertexAttribs2svNV(disp, glVertexAttribs2svNV) + SET_VertexAttribs3dvNV(disp, glVertexAttribs3dvNV) + SET_VertexAttribs3fvNV(disp, glVertexAttribs3fvNV) + SET_VertexAttribs3svNV(disp, glVertexAttribs3svNV) + SET_VertexAttribs4dvNV(disp, glVertexAttribs4dvNV) + SET_VertexAttribs4fvNV(disp, glVertexAttribs4fvNV) + SET_VertexAttribs4svNV(disp, glVertexAttribs4svNV) + SET_VertexAttribs4ubvNV(disp, glVertexAttribs4ubvNV) +#endif + +#if GL_SGIS_multisample + SET_SampleMaskSGIS(disp, glSampleMaskSGIS); + SET_SamplePatternSGIS(disp, glSamplePatternSGIS); +#endif + +#if GL_SGIS_pixel_texture + SET_GetPixelTexGenParameterfvSGIS(disp, glGetPixelTexGenParameterfvSGIS); + SET_GetPixelTexGenParameterivSGIS(disp, glGetPixelTexGenParameterivSGIS); + SET_PixelTexGenParameterfSGIS(disp, glPixelTexGenParameterfSGIS); + SET_PixelTexGenParameterfvSGIS(disp, glPixelTexGenParameterfvSGIS); + SET_PixelTexGenParameteriSGIS(disp, glPixelTexGenParameteriSGIS); + SET_PixelTexGenParameterivSGIS(disp, glPixelTexGenParameterivSGIS); + SET_PixelTexGenSGIX(disp, glPixelTexGenSGIX); +#endif +} diff --git a/xorg-server/hw/xquartz/GL/visualConfigs.c b/xorg-server/hw/xquartz/GL/visualConfigs.c index 0d5793262..2c2a9a29e 100644 --- a/xorg-server/hw/xquartz/GL/visualConfigs.c +++ b/xorg-server/hw/xquartz/GL/visualConfigs.c @@ -1,285 +1,284 @@ -/*
- * 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 <dix-config.h>
-#endif
-
-#include "dri.h"
-
-#include <OpenGL/OpenGL.h>
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-#include <OpenGL/CGLContext.h>
-
-#include <GL/glxproto.h>
-#include <windowstr.h>
-#include <resource.h>
-#include <GL/glxint.h>
-#include <GL/glxtokens.h>
-#include <scrnintstr.h>
-#include <glxserver.h>
-#include <glxscreens.h>
-#include <glxdrawable.h>
-#include <glxcontext.h>
-#include <glxext.h>
-#include <glxutil.h>
-#include <glxscreens.h>
-#include <GL/internal/glcore.h>
-
-#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;
-}
+/* + * 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 <dix-config.h> +#endif + +#include "dri.h" + +#include <OpenGL/OpenGL.h> +#include <OpenGL/gl.h> +#include <OpenGL/glext.h> +#include <OpenGL/CGLContext.h> + +#include <GL/glxproto.h> +#include <windowstr.h> +#include <resource.h> +#include <GL/glxint.h> +#include <GL/glxtokens.h> +#include <scrnintstr.h> +#include <glxserver.h> +#include <glxscreens.h> +#include <glxdrawable.h> +#include <glxcontext.h> +#include <glxext.h> +#include <glxutil.h> +#include <GL/internal/glcore.h> + +#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/Makefile.am b/xorg-server/hw/xquartz/Makefile.am index 61b04e0e1..76f624d78 100644 --- a/xorg-server/hw/xquartz/Makefile.am +++ b/xorg-server/hw/xquartz/Makefile.am @@ -33,8 +33,7 @@ libXquartz_la_SOURCES = \ quartzCocoa.m \ quartzKeyboard.c \ quartzStartup.c \ - quartzRandR.c \ - threadSafety.c + quartzRandR.c EXTRA_DIST = \ X11Application.h \ @@ -50,5 +49,4 @@ EXTRA_DIST = \ quartzKeyboard.h \ quartzRandR.h \ sanitizedCarbon.h \ - sanitizedCocoa.h \ - threadSafety.h + sanitizedCocoa.h diff --git a/xorg-server/hw/xquartz/X11Application.m b/xorg-server/hw/xquartz/X11Application.m index e56bf0cf3..283132e75 100644 --- a/xorg-server/hw/xquartz/X11Application.m +++ b/xorg-server/hw/xquartz/X11Application.m @@ -41,7 +41,6 @@ #include "quartz.h" #include "darwinEvents.h" #include "quartzKeyboard.h" -#include "quartz.h" #include <X11/extensions/applewmconst.h> #include "micmap.h" #include "exglobals.h" @@ -237,8 +236,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { if ([self isActive]) { [self deactivate]; - if (!_x_active && quartzProcs->IsX11Window([e window], - [e windowNumber])) + if (!_x_active && quartzProcs->IsX11Window([e windowNumber])) [self activateX:YES]; } } @@ -980,7 +978,7 @@ static inline pthread_t create_thread(void *(*func)(void *), void *arg) { static void *xpbproxy_x_thread(void *args) { xpbproxy_run(); - fprintf(stderr, "xpbproxy thread is terminating unexpectedly.\n"); + ErrorF("xpbproxy thread is terminating unexpectedly.\n"); return NULL; } @@ -1014,7 +1012,7 @@ void X11ApplicationMain (int argc, char **argv, char **envp) { NSMaxY([[NSScreen mainScreen] visibleFrame]); #ifdef HAVE_LIBDISPATCH - eventTranslationQueue = dispatch_queue_create(LAUNCHD_ID_PREFIX".X11.NSEventsToX11EventsQueue", NULL); + eventTranslationQueue = dispatch_queue_create(BUNDLE_ID_PREFIX".X11.NSEventsToX11EventsQueue", NULL); assert(eventTranslationQueue != NULL); #endif @@ -1023,15 +1021,15 @@ void X11ApplicationMain (int argc, char **argv, char **envp) { last_key_layout = TISCopyCurrentKeyboardLayoutInputSource(); if(!last_key_layout) - fprintf(stderr, "X11ApplicationMain: Unable to determine TISCopyCurrentKeyboardLayoutInputSource() at startup.\n"); + ErrorF("X11ApplicationMain: Unable to determine TISCopyCurrentKeyboardLayoutInputSource() at startup.\n"); #else KLGetCurrentKeyboardLayout(&last_key_layout); if(!last_key_layout) - fprintf(stderr, "X11ApplicationMain: Unable to determine KLGetCurrentKeyboardLayout() at startup.\n"); + ErrorF("X11ApplicationMain: Unable to determine KLGetCurrentKeyboardLayout() at startup.\n"); #endif if (!QuartsResyncKeymap(FALSE)) { - fprintf(stderr, "X11ApplicationMain: Could not build a valid keymap.\n"); + ErrorF("X11ApplicationMain: Could not build a valid keymap.\n"); } /* Tell the server thread that it can proceed */ @@ -1372,7 +1370,7 @@ static const char *untrusted_str(NSEvent *e) { #endif /* Update keyInfo */ if (!QuartsResyncKeymap(TRUE)) { - fprintf(stderr, "sendX11NSEvent: Could not build a valid keymap.\n"); + ErrorF("sendX11NSEvent: Could not build a valid keymap.\n"); } } } diff --git a/xorg-server/hw/xquartz/applewmExt.h b/xorg-server/hw/xquartz/applewmExt.h index 5ef8b5496..f622f79b4 100644 --- a/xorg-server/hw/xquartz/applewmExt.h +++ b/xorg-server/hw/xquartz/applewmExt.h @@ -32,10 +32,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define _APPLEWMEXT_H_ #include "window.h" +#include <Xplugin.h> typedef int (*DisableUpdateProc)(void); typedef int (*EnableUpdateProc)(void); typedef int (*SetWindowLevelProc)(WindowPtr pWin, int level); +#if XPLUGIN_VERSION < 4 typedef int (*FrameGetRectProc)(int type, int class, const BoxRec *outer, const BoxRec *inner, BoxRec *ret); typedef int (*FrameHitTestProc)(int class, int x, int y, @@ -45,6 +47,17 @@ typedef int (*FrameDrawProc)(WindowPtr pWin, int class, unsigned int attr, const BoxRec *outer, const BoxRec *inner, unsigned int title_len, const unsigned char *title_bytes); +#else +typedef int (*FrameGetRectProc)(xp_frame_rect type, xp_frame_class class, const BoxRec *outer, + const BoxRec *inner, BoxRec *ret); +typedef int (*FrameHitTestProc)(xp_frame_class class, int x, int y, + const BoxRec *outer, + const BoxRec *inner, int *ret); +typedef int (*FrameDrawProc)(WindowPtr pWin, xp_frame_class class, xp_frame_attr attr, + const BoxRec *outer, const BoxRec *inner, + unsigned int title_len, + const unsigned char *title_bytes); +#endif typedef int (*SendPSNProc)(uint32_t hi, uint32_t lo); typedef int (*AttachTransientProc)(WindowPtr pWinChild, WindowPtr pWinParent); diff --git a/xorg-server/hw/xquartz/bundle/Info.plist.cpp b/xorg-server/hw/xquartz/bundle/Info.plist.cpp index 0e98218be..a4b8e1926 100644 --- a/xorg-server/hw/xquartz/bundle/Info.plist.cpp +++ b/xorg-server/hw/xquartz/bundle/Info.plist.cpp @@ -7,11 +7,11 @@ <key>CFBundleExecutable</key> <string>X11</string> <key>CFBundleGetInfoString</key> - <string>LAUNCHD_ID_PREFIX.X11</string> + <string>BUNDLE_ID_PREFIX.X11</string> <key>CFBundleIconFile</key> <string>X11.icns</string> <key>CFBundleIdentifier</key> - <string>LAUNCHD_ID_PREFIX.X11</string> + <string>BUNDLE_ID_PREFIX.X11</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> @@ -19,9 +19,9 @@ <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> - <string>2.6.1</string> + <string>2.7.0</string> <key>CFBundleVersion</key> - <string>2.6.1</string> + <string>2.7.0</string> <key>CFBundleSignature</key> <string>x11a</string> <key>CSResourcesFileMapped</key> diff --git a/xorg-server/hw/xquartz/bundle/Makefile.am b/xorg-server/hw/xquartz/bundle/Makefile.am index 34598aa6a..6deecae55 100644 --- a/xorg-server/hw/xquartz/bundle/Makefile.am +++ b/xorg-server/hw/xquartz/bundle/Makefile.am @@ -1,92 +1,92 @@ -include cpprules.in
-
-CPP_FILES_FLAGS = \
- -DLAUNCHD_ID_PREFIX="$(LAUNCHD_ID_PREFIX)" \
- -DAPPLE_APPLICATION_NAME="$(APPLE_APPLICATION_NAME)"
-
-if XQUARTZ_SPARKLE
-CPP_FILES_FLAGS += -DXQUARTZ_SPARKLE
-endif
-
-install-data-hook:
- $(srcdir)/mk_bundke.sh $(srcdir) $(builddir) $(DESTDIR)$(APPLE_APPLICATIONS_DIR)/$(APPLE_APPLICATION_NAME).app install
-
-uninstall-hook:
- $(RM) -rf $(DESTDIR)$(APPLE_APPLICATIONS_DIR)/$(APPLE_APPLICATION_NAME).app/Contents/Resources
- $(RM) -rf $(DESTDIR)$(APPLE_APPLICATIONS_DIR)/$(APPLE_APPLICATION_NAME).app/Contents/Info.plist
- $(RM) -rf $(DESTDIR)$(APPLE_APPLICATIONS_DIR)/$(APPLE_APPLICATION_NAME).app/Contents/PkgInfo
-
-noinst_PRE = Info.plist.cpp
-noinst_DATA = $(noinst_PRE:plist.cpp=plist)
-
-CLEANFILES = $(noinst_DATA)
-
-resourcedir=$(libdir)/X11/xserver
-resource_DATA = Xquartz.plist
-
-EXTRA_DIST = \
- mk_bundke.sh \
- X11.sh \
- Info.plist.cpp \
- PkgInfo \
- $(resource_DATA) \
- Resources/ar.lproj/InfoPlist.strings \
- Resources/ar.lproj/Localizable.strings \
- Resources/ar.lproj/main.nib/designable.nib \
- Resources/ar.lproj/main.nib/keyedobjects.nib \
- Resources/da.lproj/InfoPlist.strings \
- Resources/da.lproj/Localizable.strings \
- Resources/da.lproj/main.nib/keyedobjects.nib \
- Resources/Dutch.lproj/InfoPlist.strings \
- Resources/Dutch.lproj/Localizable.strings \
- Resources/Dutch.lproj/main.nib/keyedobjects.nib \
- Resources/English.lproj/InfoPlist.strings \
- Resources/English.lproj/Localizable.strings \
- Resources/English.lproj/main.nib/designable.nib \
- Resources/English.lproj/main.nib/keyedobjects.nib \
- Resources/fi.lproj/InfoPlist.strings \
- Resources/fi.lproj/Localizable.strings \
- Resources/fi.lproj/main.nib/keyedobjects.nib \
- Resources/French.lproj/InfoPlist.strings \
- Resources/French.lproj/Localizable.strings \
- Resources/French.lproj/main.nib/keyedobjects.nib \
- Resources/German.lproj/InfoPlist.strings \
- Resources/German.lproj/Localizable.strings \
- Resources/German.lproj/main.nib/keyedobjects.nib \
- Resources/Italian.lproj/InfoPlist.strings \
- Resources/Italian.lproj/Localizable.strings \
- Resources/Italian.lproj/main.nib/keyedobjects.nib \
- Resources/Japanese.lproj/InfoPlist.strings \
- Resources/Japanese.lproj/Localizable.strings \
- Resources/Japanese.lproj/main.nib/keyedobjects.nib \
- Resources/ko.lproj/InfoPlist.strings \
- Resources/ko.lproj/Localizable.strings \
- Resources/ko.lproj/main.nib/keyedobjects.nib \
- Resources/no.lproj/InfoPlist.strings \
- Resources/no.lproj/Localizable.strings \
- Resources/no.lproj/main.nib/keyedobjects.nib \
- Resources/pl.lproj/InfoPlist.strings \
- Resources/pl.lproj/Localizable.strings \
- Resources/pl.lproj/main.nib/keyedobjects.nib \
- Resources/pt.lproj/InfoPlist.strings \
- Resources/pt.lproj/Localizable.strings \
- Resources/pt.lproj/main.nib/keyedobjects.nib \
- Resources/pt_PT.lproj/InfoPlist.strings \
- Resources/pt_PT.lproj/Localizable.strings \
- Resources/pt_PT.lproj/main.nib/keyedobjects.nib \
- Resources/ru.lproj/InfoPlist.strings \
- Resources/ru.lproj/Localizable.strings \
- Resources/ru.lproj/main.nib/keyedobjects.nib \
- Resources/Spanish.lproj/InfoPlist.strings \
- Resources/Spanish.lproj/Localizable.strings \
- Resources/Spanish.lproj/main.nib/keyedobjects.nib \
- Resources/sv.lproj/InfoPlist.strings \
- Resources/sv.lproj/Localizable.strings \
- Resources/sv.lproj/main.nib/keyedobjects.nib \
- Resources/X11.icns \
- Resources/zh_CN.lproj/InfoPlist.strings \
- Resources/zh_CN.lproj/Localizable.strings \
- Resources/zh_CN.lproj/main.nib/keyedobjects.nib \
- Resources/zh_TW.lproj/InfoPlist.strings \
- Resources/zh_TW.lproj/Localizable.strings \
- Resources/zh_TW.lproj/main.nib/keyedobjects.nib
+include cpprules.in + +CPP_FILES_FLAGS = \ + -DBUNDLE_ID_PREFIX="$(BUNDLE_ID_PREFIX)" \ + -DAPPLE_APPLICATION_NAME="$(APPLE_APPLICATION_NAME)" + +if XQUARTZ_SPARKLE +CPP_FILES_FLAGS += -DXQUARTZ_SPARKLE +endif + +install-data-hook: + $(srcdir)/mk_bundke.sh $(srcdir) $(builddir) $(DESTDIR)$(APPLE_APPLICATIONS_DIR)/$(APPLE_APPLICATION_NAME).app install + +uninstall-hook: + $(RM) -rf $(DESTDIR)$(APPLE_APPLICATIONS_DIR)/$(APPLE_APPLICATION_NAME).app/Contents/Resources + $(RM) -rf $(DESTDIR)$(APPLE_APPLICATIONS_DIR)/$(APPLE_APPLICATION_NAME).app/Contents/Info.plist + $(RM) -rf $(DESTDIR)$(APPLE_APPLICATIONS_DIR)/$(APPLE_APPLICATION_NAME).app/Contents/PkgInfo + +noinst_PRE = Info.plist.cpp +noinst_DATA = $(noinst_PRE:plist.cpp=plist) + +CLEANFILES = $(noinst_DATA) + +resourcedir=$(libdir)/X11/xserver +resource_DATA = Xquartz.plist + +EXTRA_DIST = \ + mk_bundke.sh \ + X11.sh \ + Info.plist.cpp \ + PkgInfo \ + $(resource_DATA) \ + Resources/ar.lproj/InfoPlist.strings \ + Resources/ar.lproj/Localizable.strings \ + Resources/ar.lproj/main.nib/designable.nib \ + Resources/ar.lproj/main.nib/keyedobjects.nib \ + Resources/da.lproj/InfoPlist.strings \ + Resources/da.lproj/Localizable.strings \ + Resources/da.lproj/main.nib/keyedobjects.nib \ + Resources/Dutch.lproj/InfoPlist.strings \ + Resources/Dutch.lproj/Localizable.strings \ + Resources/Dutch.lproj/main.nib/keyedobjects.nib \ + Resources/English.lproj/InfoPlist.strings \ + Resources/English.lproj/Localizable.strings \ + Resources/English.lproj/main.nib/designable.nib \ + Resources/English.lproj/main.nib/keyedobjects.nib \ + Resources/fi.lproj/InfoPlist.strings \ + Resources/fi.lproj/Localizable.strings \ + Resources/fi.lproj/main.nib/keyedobjects.nib \ + Resources/French.lproj/InfoPlist.strings \ + Resources/French.lproj/Localizable.strings \ + Resources/French.lproj/main.nib/keyedobjects.nib \ + Resources/German.lproj/InfoPlist.strings \ + Resources/German.lproj/Localizable.strings \ + Resources/German.lproj/main.nib/keyedobjects.nib \ + Resources/Italian.lproj/InfoPlist.strings \ + Resources/Italian.lproj/Localizable.strings \ + Resources/Italian.lproj/main.nib/keyedobjects.nib \ + Resources/Japanese.lproj/InfoPlist.strings \ + Resources/Japanese.lproj/Localizable.strings \ + Resources/Japanese.lproj/main.nib/keyedobjects.nib \ + Resources/ko.lproj/InfoPlist.strings \ + Resources/ko.lproj/Localizable.strings \ + Resources/ko.lproj/main.nib/keyedobjects.nib \ + Resources/no.lproj/InfoPlist.strings \ + Resources/no.lproj/Localizable.strings \ + Resources/no.lproj/main.nib/keyedobjects.nib \ + Resources/pl.lproj/InfoPlist.strings \ + Resources/pl.lproj/Localizable.strings \ + Resources/pl.lproj/main.nib/keyedobjects.nib \ + Resources/pt.lproj/InfoPlist.strings \ + Resources/pt.lproj/Localizable.strings \ + Resources/pt.lproj/main.nib/keyedobjects.nib \ + Resources/pt_PT.lproj/InfoPlist.strings \ + Resources/pt_PT.lproj/Localizable.strings \ + Resources/pt_PT.lproj/main.nib/keyedobjects.nib \ + Resources/ru.lproj/InfoPlist.strings \ + Resources/ru.lproj/Localizable.strings \ + Resources/ru.lproj/main.nib/keyedobjects.nib \ + Resources/Spanish.lproj/InfoPlist.strings \ + Resources/Spanish.lproj/Localizable.strings \ + Resources/Spanish.lproj/main.nib/keyedobjects.nib \ + Resources/sv.lproj/InfoPlist.strings \ + Resources/sv.lproj/Localizable.strings \ + Resources/sv.lproj/main.nib/keyedobjects.nib \ + Resources/X11.icns \ + Resources/zh_CN.lproj/InfoPlist.strings \ + Resources/zh_CN.lproj/Localizable.strings \ + Resources/zh_CN.lproj/main.nib/keyedobjects.nib \ + Resources/zh_TW.lproj/InfoPlist.strings \ + Resources/zh_TW.lproj/Localizable.strings \ + Resources/zh_TW.lproj/main.nib/keyedobjects.nib diff --git a/xorg-server/hw/xquartz/darwin.c b/xorg-server/hw/xquartz/darwin.c index 00be74ba0..50234f243 100644 --- a/xorg-server/hw/xquartz/darwin.c +++ b/xorg-server/hw/xquartz/darwin.c @@ -133,28 +133,12 @@ static PixmapFormatRec formats[] = { }; 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 ); + ErrorF("X.Org X Server %s\n", XSERVER_VERSION); + ErrorF("Build Date: %s\n", BUILD_DATE ); } @@ -605,6 +589,13 @@ void OsVendorFatalError( void ) void OsVendorInit(void) { if (serverGeneration == 1) { + char *lf; + char *home = getenv("HOME"); + assert(home); + assert(0 < asprintf(&lf, "%s/Library/Logs/X11.%s.log", home, bundle_id_prefix)); + LogInit(lf, ".old"); + free(lf); + DarwinPrintBanner(); #ifdef ENABLE_DEBUG_LOG { diff --git a/xorg-server/hw/xquartz/darwin.h b/xorg-server/hw/xquartz/darwin.h index 360225742..507c6f7f6 100644 --- a/xorg-server/hw/xquartz/darwin.h +++ b/xorg-server/hw/xquartz/darwin.h @@ -34,8 +34,6 @@ #include <X11/extensions/XKB.h> #include <assert.h> -#include "threadSafety.h" - #include "darwinfb.h" // From darwin.c @@ -75,12 +73,15 @@ extern int darwinDesiredDepth; extern int darwinMainScreenX; extern int darwinMainScreenY; +// bundle-main.c +extern char *bundle_id_prefix; + #define ENABLE_DEBUG_LOG 1 #ifdef ENABLE_DEBUG_LOG extern FILE *debug_log_fp; #define DEBUG_LOG_NAME "x11-debug.txt" -#define DEBUG_LOG(msg, args...) if (debug_log_fp) fprintf(debug_log_fp, "%s:%s:%s:%d " msg, threadSafetyID(pthread_self()), __FILE__, __FUNCTION__, __LINE__, ##args ); fflush(debug_log_fp); +#define DEBUG_LOG(msg, args...) if (debug_log_fp) fprintf(debug_log_fp, "%s:%s:%d " msg, __FILE__, __FUNCTION__, __LINE__, ##args ); fflush(debug_log_fp); #else #define DEBUG_LOG(msg, args...) #endif diff --git a/xorg-server/hw/xquartz/darwinEvents.c b/xorg-server/hw/xquartz/darwinEvents.c index 40d8a4e9e..f3e12250e 100644 --- a/xorg-server/hw/xquartz/darwinEvents.c +++ b/xorg-server/hw/xquartz/darwinEvents.c @@ -113,7 +113,7 @@ void darwinEvents_lock(void) { if((err = pthread_mutex_lock(&mieq_lock))) { ErrorF("%s:%s:%d: Failed to lock mieq_lock: %d\n", __FILE__, __FUNCTION__, __LINE__, err); - spewCallStack(); + xorg_backtrace(); } if(darwinEvents == NULL) { pthread_cond_wait(&mieq_ready_cond, &mieq_lock); @@ -126,7 +126,7 @@ void darwinEvents_unlock(void) { if((err = pthread_mutex_unlock(&mieq_lock))) { ErrorF("%s:%s:%d: Failed to unlock mieq_lock: %d\n", __FILE__, __FUNCTION__, __LINE__, err); - spewCallStack(); + xorg_backtrace(); } } @@ -197,8 +197,6 @@ static void DarwinUpdateModifiers( static void DarwinEventHandler(int screenNum, InternalEvent *ie, DeviceIntPtr dev) { XQuartzEvent *e = &(ie->xquartz_event); - TA_SERVER(); - switch(e->subtype) { case kXquartzControllerNotify: DEBUG_LOG("kXquartzControllerNotify\n"); @@ -381,8 +379,6 @@ void ProcessInputEvents(void) { char nullbyte; int x = sizeof(nullbyte); - TA_SERVER(); - mieqProcessInputEvents(); // Empty the signaling pipe diff --git a/xorg-server/hw/xquartz/mach-startup/bundle-main.c b/xorg-server/hw/xquartz/mach-startup/bundle-main.c index 6a6c01c3b..846025b44 100644 --- a/xorg-server/hw/xquartz/mach-startup/bundle-main.c +++ b/xorg-server/hw/xquartz/mach-startup/bundle-main.c @@ -64,6 +64,9 @@ /* From darwinEvents.c ... but don't want to pull in all the server cruft */ void DarwinListenOnOpenFD(int fd); +/* Ditto, from os/log.c */ +extern void ErrorF(const char *f, ...) _X_ATTRIBUTE_PRINTF(1,2); + extern int noPanoramiXExtension; #define DEFAULT_CLIENT X11BINDIR "/xterm" @@ -88,7 +91,7 @@ asm (".desc ___crashreporter_info__, 0x10"); static const char *__crashreporter_info__base = "X.Org X Server " XSERVER_VERSION " Build Date: " BUILD_DATE; -static char *launchd_id_prefix = NULL; +char *bundle_id_prefix = NULL; static char *server_bootstrap_name = NULL; #define DEBUG 1 @@ -134,19 +137,27 @@ static mach_port_t checkin_or_register(char *bname) { /* We probably were not started by launchd or the old mach_init */ kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp); if (kr != KERN_SUCCESS) { - fprintf(stderr, "mach_port_allocate(): %s\n", mach_error_string(kr)); + ErrorF("mach_port_allocate(): %s\n", mach_error_string(kr)); exit(EXIT_FAILURE); } kr = mach_port_insert_right(mach_task_self(), mp, mp, MACH_MSG_TYPE_MAKE_SEND); if (kr != KERN_SUCCESS) { - fprintf(stderr, "mach_port_insert_right(): %s\n", mach_error_string(kr)); + ErrorF("mach_port_insert_right(): %s\n", mach_error_string(kr)); exit(EXIT_FAILURE); } +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // bootstrap_register +#endif kr = bootstrap_register(bootstrap_port, bname, mp); +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + if (kr != KERN_SUCCESS) { - fprintf(stderr, "bootstrap_register(): %s\n", mach_error_string(kr)); + ErrorF("bootstrap_register(): %s\n", mach_error_string(kr)); exit(EXIT_FAILURE); } @@ -189,7 +200,7 @@ static int accept_fd_handoff(int connected_fd) { *((int*)CMSG_DATA(cmsg)) = -1; if(recvmsg(connected_fd, &msg, 0) < 0) { - fprintf(stderr, "X11.app: Error receiving $DISPLAY file descriptor. recvmsg() error: %s\n", strerror(errno)); + ErrorF("X11.app: Error receiving $DISPLAY file descriptor. recvmsg() error: %s\n", strerror(errno)); return -1; } @@ -222,14 +233,14 @@ static void *socket_handoff_thread(void *arg) { while(launchd_fd == -1) { connected_fd = accept(handoff_data->fd, NULL, NULL); if(connected_fd == -1) { - fprintf(stderr, "X11.app: Failed to accept incoming connection on socket (fd=%d): %s\n", handoff_data->fd, strerror(errno)); + ErrorF("X11.app: Failed to accept incoming connection on socket (fd=%d): %s\n", handoff_data->fd, strerror(errno)); sleep(2); continue; } launchd_fd = accept_fd_handoff(connected_fd); if(launchd_fd == -1) - fprintf(stderr, "X11.app: Error receiving $DISPLAY file descriptor, no descriptor received? Waiting for another connection.\n"); + ErrorF("X11.app: Error receiving $DISPLAY file descriptor, no descriptor received? Waiting for another connection.\n"); close(connected_fd); } @@ -238,7 +249,7 @@ static void *socket_handoff_thread(void *arg) { unlink(handoff_data->filename); free(handoff_data); - fprintf(stderr, "X11.app Handing off fd to server thread via DarwinListenOnOpenFD(%d)\n", launchd_fd); + ErrorF("X11.app Handing off fd to server thread via DarwinListenOnOpenFD(%d)\n", launchd_fd); DarwinListenOnOpenFD(launchd_fd); #ifndef HAVE_LIBDISPATCH @@ -266,24 +277,24 @@ static int create_socket(char *filename_out) { ret_fd = socket(PF_UNIX, SOCK_STREAM, 0); if(ret_fd == -1) { - fprintf(stderr, "X11.app: Failed to create socket (try %d / %d): %s - %s\n", (int)try+1, (int)try_max, filename_out, strerror(errno)); + ErrorF("X11.app: Failed to create socket (try %d / %d): %s - %s\n", (int)try+1, (int)try_max, filename_out, strerror(errno)); continue; } if(bind(ret_fd, servaddr, servaddr_len) != 0) { - fprintf(stderr, "X11.app: Failed to bind socket: %d - %s\n", errno, strerror(errno)); + ErrorF("X11.app: Failed to bind socket: %d - %s\n", errno, strerror(errno)); close(ret_fd); return 0; } if(listen(ret_fd, 10) != 0) { - fprintf(stderr, "X11.app: Failed to listen to socket: %s - %d - %s\n", filename_out, errno, strerror(errno)); + ErrorF("X11.app: Failed to listen to socket: %s - %d - %s\n", filename_out, errno, strerror(errno)); close(ret_fd); return 0; } #ifdef DEBUG - fprintf(stderr, "X11.app: Listening on socket for fd handoff: (%d) %s\n", ret_fd, filename_out); + ErrorF("X11.app: Listening on socket for fd handoff: (%d) %s\n", ret_fd, filename_out); #endif return ret_fd; @@ -301,7 +312,7 @@ kern_return_t do_request_fd_handoff_socket(mach_port_t port, string_t filename) handoff_data = (socket_handoff_t *)calloc(1,sizeof(socket_handoff_t)); if(!handoff_data) { - fprintf(stderr, "X11.app: Error allocating memory for handoff_data\n"); + ErrorF("X11.app: Error allocating memory for handoff_data\n"); return KERN_FAILURE; } @@ -322,7 +333,7 @@ kern_return_t do_request_fd_handoff_socket(mach_port_t port, string_t filename) #endif #ifdef DEBUG - fprintf(stderr, "X11.app: Thread created for handoff. Returning success to tell caller to connect and push the fd.\n"); + ErrorF("X11.app: Thread created for handoff. Returning success to tell caller to connect and push the fd.\n"); #endif return KERN_SUCCESS; @@ -347,7 +358,7 @@ kern_return_t do_start_x11_server(mach_port_t port, string_array_t argv, * unset DISPLAY or we can run into problems with pbproxy */ if(!launchd_socket_handed_off) { - fprintf(stderr, "X11.app: No launchd socket handed off, unsetting DISPLAY\n"); + ErrorF("X11.app: No launchd socket handed off, unsetting DISPLAY\n"); unsetenv("DISPLAY"); } @@ -355,10 +366,10 @@ kern_return_t do_start_x11_server(mach_port_t port, string_array_t argv, return KERN_FAILURE; } - fprintf(stderr, "X11.app: do_start_x11_server(): argc=%d\n", argvCnt); + ErrorF("X11.app: do_start_x11_server(): argc=%d\n", argvCnt); for(i=0; i < argvCnt; i++) { _argv[i] = argv[i]; - fprintf(stderr, "\targv[%u] = %s\n", (unsigned)i, argv[i]); + ErrorF("\targv[%u] = %s\n", (unsigned)i, argv[i]); } _argv[argvCnt] = NULL; @@ -396,7 +407,7 @@ static int startup_trigger(int argc, char **argv, char **envp) { newenvp = (string_array_t)alloca(envpc * sizeof(string_t)); if(!newargv || !newenvp) { - fprintf(stderr, "Memory allocation failure\n"); + ErrorF("Memory allocation failure\n"); exit(EXIT_FAILURE); } @@ -410,16 +421,16 @@ static int startup_trigger(int argc, char **argv, char **envp) { kr = bootstrap_look_up(bootstrap_port, server_bootstrap_name, &mp); if (kr != KERN_SUCCESS) { #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 - fprintf(stderr, "bootstrap_look_up(%s): %s\n", server_bootstrap_name, bootstrap_strerror(kr)); + ErrorF("bootstrap_look_up(%s): %s\n", server_bootstrap_name, bootstrap_strerror(kr)); #else - fprintf(stderr, "bootstrap_look_up(%s): %ul\n", server_bootstrap_name, (unsigned long)kr); + ErrorF("bootstrap_look_up(%s): %ul\n", server_bootstrap_name, (unsigned long)kr); #endif exit(EXIT_FAILURE); } kr = start_x11_server(mp, newargv, argc, newenvp, envpc); if (kr != KERN_SUCCESS) { - fprintf(stderr, "start_x11_server: %s\n", mach_error_string(kr)); + ErrorF("start_x11_server: %s\n", mach_error_string(kr)); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); @@ -441,10 +452,10 @@ static int startup_trigger(int argc, char **argv, char **envp) { /* Start the server */ if((s = getenv("DISPLAY"))) { - fprintf(stderr, "X11.app: Could not connect to server (DISPLAY=\"%s\", unsetting). Starting X server.\n", s); + ErrorF("X11.app: Could not connect to server (DISPLAY=\"%s\", unsetting). Starting X server.\n", s); unsetenv("DISPLAY"); } else { - fprintf(stderr, "X11.app: Could not connect to server (DISPLAY is not set). Starting X server.\n"); + ErrorF("X11.app: Could not connect to server (DISPLAY is not set). Starting X server.\n"); } return execute(command_from_prefs("startx_script", DEFAULT_STARTX)); } @@ -483,23 +494,23 @@ static void setup_env(void) { /* fallback to hardcoded value if we can't discover it */ if(!pds) { - pds = LAUNCHD_ID_PREFIX".X11"; + pds = BUNDLE_ID_PREFIX".X11"; } server_bootstrap_name = strdup(pds); if(!server_bootstrap_name) { - fprintf(stderr, "X11.app: Memory allocation error.\n"); + ErrorF("X11.app: Memory allocation error.\n"); exit(1); } setenv("X11_PREFS_DOMAIN", server_bootstrap_name, 1); len = strlen(server_bootstrap_name); - launchd_id_prefix = malloc(sizeof(char) * (len - 3)); - if(!launchd_id_prefix) { - fprintf(stderr, "X11.app: Memory allocation error.\n"); + bundle_id_prefix = malloc(sizeof(char) * (len - 3)); + if(!bundle_id_prefix) { + ErrorF("X11.app: Memory allocation error.\n"); exit(1); } - strlcpy(launchd_id_prefix, server_bootstrap_name, len - 3); + strlcpy(bundle_id_prefix, server_bootstrap_name, len - 3); /* We need to unset DISPLAY if it is not our socket */ if(disp) { @@ -511,27 +522,27 @@ static void setup_env(void) { } if(s && *s) { - if(strcmp(launchd_id_prefix, "org.x") == 0 && strcmp(s, ":0") == 0) { - fprintf(stderr, "X11.app: Detected old style launchd DISPLAY, please update xinit.\n"); + if(strcmp(bundle_id_prefix, "org.x") == 0 && strcmp(s, ":0") == 0) { + ErrorF("X11.app: Detected old style launchd DISPLAY, please update xinit.\n"); } else { temp = (char *)malloc(sizeof(char) * len); if(!temp) { - fprintf(stderr, "X11.app: Memory allocation error creating space for socket name test.\n"); + ErrorF("X11.app: Memory allocation error creating space for socket name test.\n"); exit(1); } - strlcpy(temp, launchd_id_prefix, len); + strlcpy(temp, bundle_id_prefix, len); strlcat(temp, ":0", len); if(strcmp(temp, s) != 0) { /* If we don't have a match, unset it. */ - fprintf(stderr, "X11.app: DISPLAY (\"%s\") does not match our id (\"%s\"), unsetting.\n", disp, launchd_id_prefix); + ErrorF("X11.app: DISPLAY (\"%s\") does not match our id (\"%s\"), unsetting.\n", disp, bundle_id_prefix); unsetenv("DISPLAY"); } free(temp); } } else { /* The DISPLAY environment variable is not formatted like a launchd socket, so reset. */ - fprintf(stderr, "X11.app: DISPLAY does not look like a launchd set variable, unsetting.\n"); + ErrorF("X11.app: DISPLAY does not look like a launchd set variable, unsetting.\n"); unsetenv("DISPLAY"); } } @@ -562,9 +573,9 @@ int main(int argc, char **argv, char **envp) { /* Setup the initial crasherporter info */ strlcpy(__crashreporter_info_buff__, __crashreporter_info__base, sizeof(__crashreporter_info_buff__)); - fprintf(stderr, "X11.app: main(): argc=%d\n", argc); + ErrorF("X11.app: main(): argc=%d\n", argc); for(i=0; i < argc; i++) { - fprintf(stderr, "\targv[%u] = %s\n", (unsigned)i, argv[i]); + ErrorF("\targv[%u] = %s\n", (unsigned)i, argv[i]); if(!strcmp(argv[i], "--listenonly")) { listenOnly = TRUE; } @@ -572,7 +583,7 @@ int main(int argc, char **argv, char **envp) { mp = checkin_or_register(server_bootstrap_name); if(mp == MACH_PORT_NULL) { - fprintf(stderr, "NULL mach service: %s", server_bootstrap_name); + ErrorF("NULL mach service: %s", server_bootstrap_name); return EXIT_FAILURE; } @@ -621,10 +632,10 @@ int main(int argc, char **argv, char **envp) { } /* Main event loop */ - fprintf(stderr, "Waiting for startup parameters via Mach IPC.\n"); + ErrorF("Waiting for startup parameters via Mach IPC.\n"); kr = mach_msg_server(mach_startup_server, mxmsgsz, mp, 0); if (kr != KERN_SUCCESS) { - fprintf(stderr, "%s.X11(mp): %s\n", LAUNCHD_ID_PREFIX, mach_error_string(kr)); + ErrorF("%s.X11(mp): %s\n", BUNDLE_ID_PREFIX, mach_error_string(kr)); return EXIT_FAILURE; } @@ -640,9 +651,9 @@ static int execute(const char *command) { newargv[2] = command; newargv[3] = NULL; - fprintf(stderr, "X11.app: Launching %s:\n", command); + ErrorF("X11.app: Launching %s:\n", command); for(p=newargv; *p; p++) { - fprintf(stderr, "\targv[%ld] = %s\n", (long int)(p - newargv), *p); + ErrorF("\targv[%ld] = %s\n", (long int)(p - newargv), *p); } execvp (newargv[0], (char * const *) newargv); diff --git a/xorg-server/hw/xquartz/mach-startup/launchd_fd.c b/xorg-server/hw/xquartz/mach-startup/launchd_fd.c index 6dace8ea1..5c7e03cf3 100644 --- a/xorg-server/hw/xquartz/mach-startup/launchd_fd.c +++ b/xorg-server/hw/xquartz/mach-startup/launchd_fd.c @@ -69,11 +69,11 @@ int launchd_display_fd(void) { return ERROR_FD; } - listening_fd_array = launch_data_dict_lookup(sockets_dict, LAUNCHD_ID_PREFIX":0"); + listening_fd_array = launch_data_dict_lookup(sockets_dict, BUNDLE_ID_PREFIX":0"); if (NULL == listening_fd_array) { listening_fd_array = launch_data_dict_lookup(sockets_dict, ":0"); if (NULL == listening_fd_array) { - fprintf(stderr,"launchd check-in: No known sockets found to answer requests on! \"%s:0\" and \":0\" failed.\n", LAUNCHD_ID_PREFIX); + fprintf(stderr,"launchd check-in: No known sockets found to answer requests on! \"%s:0\" and \":0\" failed.\n", BUNDLE_ID_PREFIX); return ERROR_FD; } } diff --git a/xorg-server/hw/xquartz/mach-startup/stub.c b/xorg-server/hw/xquartz/mach-startup/stub.c index ccf5ab426..c8a628311 100644 --- a/xorg-server/hw/xquartz/mach-startup/stub.c +++ b/xorg-server/hw/xquartz/mach-startup/stub.c @@ -40,7 +40,7 @@ #include <sys/socket.h> #include <sys/un.h> -#define kX11AppBundleId LAUNCHD_ID_PREFIX".X11" +#define kX11AppBundleId BUNDLE_ID_PREFIX".X11" #define kX11AppBundlePath "/Contents/MacOS/X11" static char *server_bootstrap_name = kX11AppBundleId; @@ -56,15 +56,6 @@ static char *server_bootstrap_name = kX11AppBundleId; #include "launchd_fd.h" -#ifndef BUILD_DATE -#define BUILD_DATE "?" -#endif -#ifndef XSERVER_VERSION -#define XSERVER_VERSION "?" -#endif - -#define DEBUG 1 - static char x11_path[PATH_MAX + 1]; static pid_t x11app_pid = 0; @@ -197,13 +188,6 @@ int main(int argc, char **argv, char **envp) { string_t handoff_socket_filename; sig_t handler; - if(argc == 2 && !strcmp(argv[1], "-version")) { - fprintf(stderr, "X.org Release 7.5\n"); - fprintf(stderr, "X.Org X Server %s\n", XSERVER_VERSION); - fprintf(stderr, "Build Date: %s\n", BUILD_DATE); - return EXIT_SUCCESS; - } - if(getenv("X11_PREFS_DOMAIN")) server_bootstrap_name = getenv("X11_PREFS_DOMAIN"); @@ -300,8 +284,8 @@ int main(int argc, char **argv, char **envp) { /* We have fixed-size string lengths due to limitations in IPC, * so we need to copy our argv and envp. */ - newargv = (string_array_t)malloc(argc * sizeof(string_t)); - newenvp = (string_array_t)malloc(envpc * sizeof(string_t)); + newargv = (string_array_t)calloc((1 + argc), sizeof(string_t)); + newenvp = (string_array_t)calloc((1 + envpc), sizeof(string_t)); if(!newargv || !newenvp) { fprintf(stderr, "Xquartz: Memory allocation failure\n"); diff --git a/xorg-server/hw/xquartz/pbproxy/Makefile.am b/xorg-server/hw/xquartz/pbproxy/Makefile.am index 188664259..b8b95d232 100644 --- a/xorg-server/hw/xquartz/pbproxy/Makefile.am +++ b/xorg-server/hw/xquartz/pbproxy/Makefile.am @@ -1,5 +1,5 @@ AM_CPPFLAGS=-F/System/Library/Frameworks/ApplicationServices.framework/Frameworks \ - -DLAUNCHD_ID_PREFIX=\"$(LAUNCHD_ID_PREFIX)\" + -DBUNDLE_ID_PREFIX=\"$(BUNDLE_ID_PREFIX)\" AM_CFLAGS=$(XPBPROXY_CFLAGS) diff --git a/xorg-server/hw/xquartz/pbproxy/app-main.m b/xorg-server/hw/xquartz/pbproxy/app-main.m index b00e90a6d..9055bad06 100644 --- a/xorg-server/hw/xquartz/pbproxy/app-main.m +++ b/xorg-server/hw/xquartz/pbproxy/app-main.m @@ -34,7 +34,7 @@ #include <unistd.h> /*for getpid*/ #include <Cocoa/Cocoa.h> -static const char *app_prefs_domain = LAUNCHD_ID_PREFIX".xpbproxy"; +static const char *app_prefs_domain = BUNDLE_ID_PREFIX".xpbproxy"; CFStringRef app_prefs_domain_cfstr; /* Stubs */ @@ -53,12 +53,22 @@ static void signal_handler (int sig) { } } +void +ErrorF(const char * f, ...) +{ + va_list args; + + va_start(args, f); + vfprintf(stderr, f, args); + va_end(args); +} + int main (int argc, const char *argv[]) { const char *s; int i; #ifdef DEBUG - printf("pid: %u\n", getpid()); + ErrorF("pid: %u\n", getpid()); #endif xpbproxy_is_standalone = YES; @@ -70,13 +80,13 @@ int main (int argc, const char *argv[]) { if(strcmp (argv[i], "--prefs-domain") == 0 && i+1 < argc) { app_prefs_domain = argv[++i]; } else if (strcmp (argv[i], "--help") == 0) { - printf("usage: xpbproxy OPTIONS\n" + ErrorF("usage: xpbproxy OPTIONS\n" "Pasteboard proxying for X11.\n\n" "--prefs-domain <domain> Change the domain used for reading preferences\n" " (default: %s)\n", app_prefs_domain); return 0; } else { - fprintf(stderr, "usage: xpbproxy OPTIONS...\n" + ErrorF("usage: xpbproxy OPTIONS...\n" "Try 'xpbproxy --help' for more information.\n"); return 1; } diff --git a/xorg-server/hw/xquartz/pbproxy/main.m b/xorg-server/hw/xquartz/pbproxy/main.m index cfdc7696d..dbdb6d05c 100644 --- a/xorg-server/hw/xquartz/pbproxy/main.m +++ b/xorg-server/hw/xquartz/pbproxy/main.m @@ -1,165 +1,149 @@ -/* main.m
- Copyright (c) 2002, 2008 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 "pbproxy.h"
-#import "x-selection.h"
-
-#include <pthread.h>
-#include <unistd.h>
-#include <X11/extensions/applewm.h>
-
-Display *xpbproxy_dpy;
-int xpbproxy_apple_wm_event_base, xpbproxy_apple_wm_error_base;
-int xpbproxy_xfixes_event_base, xpbproxy_xfixes_error_base;
-BOOL xpbproxy_have_xfixes;
-
-extern char *display;
-
-#ifdef STANDALONE_XPBPROXY
-BOOL xpbproxy_is_standalone = NO;
-#endif
-
-x_selection *_selection_object;
-
-extern BOOL serverInitComplete;
-extern pthread_mutex_t serverInitCompleteMutex;
-extern pthread_cond_t serverInitCompleteCond;
-
-static inline void wait_for_server_init(void) {
- /* If the server hasn't finished initializing, wait for it... */
- if(!serverInitComplete) {
- pthread_mutex_lock(&serverInitCompleteMutex);
- while(!serverInitComplete)
- pthread_cond_wait(&serverInitCompleteCond, &serverInitCompleteMutex);
- pthread_mutex_unlock(&serverInitCompleteMutex);
- }
-}
-
-static int x_io_error_handler (Display *dpy) {
- /* We lost our connection to the server. */
-
- TRACE ();
-
- /* trigger the thread to restart?
- * NO - this would be to a "deeper" problem, and restarts would just
- * make things worse...
- */
-#ifdef STANDALONE_XPBPROXY
- if(xpbproxy_is_standalone)
- exit(EXIT_FAILURE);
-#endif
-
- /* Prevent _XIOError from calling exit() */
- pthread_exit(NULL);
- return 0;
-}
-
-static int x_error_handler (Display *dpy, XErrorEvent *errevent) {
- return 0;
-}
-
-int xpbproxy_run (void) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- size_t i;
-
- wait_for_server_init();
-
- for(i=0, xpbproxy_dpy=NULL; !xpbproxy_dpy && i<5; i++) {
- xpbproxy_dpy = XOpenDisplay(NULL);
-
- if(!xpbproxy_dpy && display) {
- char _display[32];
- snprintf(_display, sizeof(_display), ":%s", display);
- setenv("DISPLAY", _display, TRUE);
-
- xpbproxy_dpy=XOpenDisplay(_display);
- }
- if(!xpbproxy_dpy)
- sleep(1);
- }
-
- if (xpbproxy_dpy == NULL) {
- fprintf (stderr, "xpbproxy: can't open default display\n");
- [pool release];
- return EXIT_FAILURE;
- }
-
- XSetIOErrorHandler (x_io_error_handler);
- XSetErrorHandler (x_error_handler);
-
- if (!XAppleWMQueryExtension (xpbproxy_dpy, &xpbproxy_apple_wm_event_base,
- &xpbproxy_apple_wm_error_base)) {
- fprintf (stderr, "xpbproxy: can't open AppleWM server extension\n");
- [pool release];
- return EXIT_FAILURE;
- }
-
- xpbproxy_have_xfixes = XFixesQueryExtension(xpbproxy_dpy, &xpbproxy_xfixes_event_base, &xpbproxy_xfixes_error_base);
-
- XAppleWMSelectInput (xpbproxy_dpy, AppleWMActivationNotifyMask |
- AppleWMPasteboardNotifyMask);
-
- _selection_object = [[x_selection alloc] init];
-
- if(!xpbproxy_input_register()) {
- [pool release];
- return EXIT_FAILURE;
- }
-
- [pool release];
-
- CFRunLoopRun();
-
- return EXIT_SUCCESS;
-}
-
-id xpbproxy_selection_object (void) {
- return _selection_object;
-}
-
-Time xpbproxy_current_timestamp (void) {
- /* FIXME: may want to fetch a timestamp from the server.. */
- return CurrentTime;
-}
-
-void debug_printf (const char *fmt, ...) {
- static int spew = -1;
-
- if (spew == -1) {
- char *x = getenv ("DEBUG");
- spew = (x != NULL && atoi (x) != 0);
- }
-
- if (spew) {
- va_list args;
- va_start(args, fmt);
- vfprintf (stderr, fmt, args);
- va_end(args);
- }
-}
+/* main.m + Copyright (c) 2002, 2008 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 "pbproxy.h" +#import "x-selection.h" + +#include <pthread.h> +#include <unistd.h> +#include <X11/extensions/applewm.h> + +Display *xpbproxy_dpy; +int xpbproxy_apple_wm_event_base, xpbproxy_apple_wm_error_base; +int xpbproxy_xfixes_event_base, xpbproxy_xfixes_error_base; +BOOL xpbproxy_have_xfixes; + +extern char *display; + +#ifdef STANDALONE_XPBPROXY +BOOL xpbproxy_is_standalone = NO; +#endif + +x_selection *_selection_object; + +extern BOOL serverInitComplete; +extern pthread_mutex_t serverInitCompleteMutex; +extern pthread_cond_t serverInitCompleteCond; + +static inline void wait_for_server_init(void) { + /* If the server hasn't finished initializing, wait for it... */ + if(!serverInitComplete) { + pthread_mutex_lock(&serverInitCompleteMutex); + while(!serverInitComplete) + pthread_cond_wait(&serverInitCompleteCond, &serverInitCompleteMutex); + pthread_mutex_unlock(&serverInitCompleteMutex); + } +} + +static int x_io_error_handler (Display *dpy) { + /* We lost our connection to the server. */ + + TRACE (); + + /* trigger the thread to restart? + * NO - this would be to a "deeper" problem, and restarts would just + * make things worse... + */ +#ifdef STANDALONE_XPBPROXY + if(xpbproxy_is_standalone) + exit(EXIT_FAILURE); +#endif + + /* Prevent _XIOError from calling exit() */ + pthread_exit(NULL); + return 0; +} + +static int x_error_handler (Display *dpy, XErrorEvent *errevent) { + return 0; +} + +int xpbproxy_run (void) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + size_t i; + + wait_for_server_init(); + + for(i=0, xpbproxy_dpy=NULL; !xpbproxy_dpy && i<5; i++) { + xpbproxy_dpy = XOpenDisplay(NULL); + + if(!xpbproxy_dpy && display) { + char _display[32]; + snprintf(_display, sizeof(_display), ":%s", display); + setenv("DISPLAY", _display, TRUE); + + xpbproxy_dpy=XOpenDisplay(_display); + } + if(!xpbproxy_dpy) + sleep(1); + } + + if (xpbproxy_dpy == NULL) { + ErrorF("xpbproxy: can't open default display\n"); + [pool release]; + return EXIT_FAILURE; + } + + XSetIOErrorHandler (x_io_error_handler); + XSetErrorHandler (x_error_handler); + + if (!XAppleWMQueryExtension (xpbproxy_dpy, &xpbproxy_apple_wm_event_base, + &xpbproxy_apple_wm_error_base)) { + ErrorF("xpbproxy: can't open AppleWM server extension\n"); + [pool release]; + return EXIT_FAILURE; + } + + xpbproxy_have_xfixes = XFixesQueryExtension(xpbproxy_dpy, &xpbproxy_xfixes_event_base, &xpbproxy_xfixes_error_base); + + XAppleWMSelectInput (xpbproxy_dpy, AppleWMActivationNotifyMask | + AppleWMPasteboardNotifyMask); + + _selection_object = [[x_selection alloc] init]; + + if(!xpbproxy_input_register()) { + [pool release]; + return EXIT_FAILURE; + } + + [pool release]; + + CFRunLoopRun(); + + return EXIT_SUCCESS; +} + +id xpbproxy_selection_object (void) { + return _selection_object; +} + +Time xpbproxy_current_timestamp (void) { + /* FIXME: may want to fetch a timestamp from the server.. */ + return CurrentTime; +} diff --git a/xorg-server/hw/xquartz/pbproxy/pbproxy.h b/xorg-server/hw/xquartz/pbproxy/pbproxy.h index 013f981d4..fcbf4c4ba 100644 --- a/xorg-server/hw/xquartz/pbproxy/pbproxy.h +++ b/xorg-server/hw/xquartz/pbproxy/pbproxy.h @@ -77,14 +77,16 @@ extern BOOL xpbproxy_have_xfixes; /* from x-input.m */ extern BOOL xpbproxy_input_register (void); +/* os/log.c or app-main.m */ +extern void ErrorF(const char *f, ...) _X_ATTRIBUTE_PRINTF(1,2); + #ifdef DEBUG /* BEWARE: this can cause a string memory leak, according to the leaks program. */ -# define DB(msg, args...) debug_printf("%s:%s:%d " msg, __FILE__, __FUNCTION__, __LINE__, ##args) +# define DebugF(msg, args...) ErrorF("%s:%s:%d " msg, __FILE__, __FUNCTION__, __LINE__, ##args) #else -# define DB(msg, args...) do {} while (0) +# define DebugF(...) /* */ #endif -#define TRACE() DB("TRACE\n") -extern void debug_printf (const char *fmt, ...); +#define TRACE() DebugF("TRACE\n") #endif /* PBPROXY_H */ diff --git a/xorg-server/hw/xquartz/pbproxy/x-input.m b/xorg-server/hw/xquartz/pbproxy/x-input.m index 405ba3c73..ebb89980f 100644 --- a/xorg-server/hw/xquartz/pbproxy/x-input.m +++ b/xorg-server/hw/xquartz/pbproxy/x-input.m @@ -87,7 +87,7 @@ static void xpbproxy_process_xevents(void) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; if(pool == nil) { - fprintf(stderr, "unable to allocate/init auto release pool!\n"); + ErrorF("unable to allocate/init auto release pool!\n"); return; } diff --git a/xorg-server/hw/xquartz/pbproxy/x-selection.m b/xorg-server/hw/xquartz/pbproxy/x-selection.m index ef84f8bfb..7964f5193 100644 --- a/xorg-server/hw/xquartz/pbproxy/x-selection.m +++ b/xorg-server/hw/xquartz/pbproxy/x-selection.m @@ -81,19 +81,19 @@ static struct propdata null_propdata = {NULL, 0, 0}; #ifdef DEBUG static void -dump_prefs (FILE *fp) { - fprintf(fp, - "pbproxy preferences:\n" - "\tactive %u\n" - "\tprimary_on_grab %u\n" - "\tclipboard_to_pasteboard %u\n" - "\tpasteboard_to_primary %u\n" - "\tpasteboard_to_clipboard %u\n", - pbproxy_prefs.active, - pbproxy_prefs.primary_on_grab, - pbproxy_prefs.clipboard_to_pasteboard, - pbproxy_prefs.pasteboard_to_primary, - pbproxy_prefs.pasteboard_to_clipboard); +dump_prefs() { + ErrorF(fp, + "pbproxy preferences:\n" + "\tactive %u\n" + "\tprimary_on_grab %u\n" + "\tclipboard_to_pasteboard %u\n" + "\tpasteboard_to_primary %u\n" + "\tpasteboard_to_clipboard %u\n", + pbproxy_prefs.active, + pbproxy_prefs.primary_on_grab, + pbproxy_prefs.clipboard_to_pasteboard, + pbproxy_prefs.pasteboard_to_primary, + pbproxy_prefs.pasteboard_to_clipboard); } #endif @@ -152,7 +152,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato unsigned char *newbuf = NULL; #ifdef TEST - printf("bytesleft %lu\n", bytesleft); + ErrorF("bytesleft %lu\n", bytesleft); #endif if (Success != XGetWindowProperty (xpbproxy_dpy, win, property, @@ -161,24 +161,29 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato type, &format, &numitems, &bytesleft, &chunk)) { - DB ("Error while getting window property.\n"); + DebugF ("Error while getting window property.\n"); *pdata = null_propdata; free (buf); return True; } #ifdef TEST - printf("format %d numitems %lu bytesleft %lu\n", + ErrorF("format %d numitems %lu bytesleft %lu\n", format, numitems, bytesleft); - printf("type %s\n", XGetAtomName (xpbproxy_dpy, *type)); + ErrorF("type %s\n", XGetAtomName (xpbproxy_dpy, *type)); #endif /* Format is the number of bits. */ - chunkbytesize = numitems * (format / 8); + if (format == 8) + chunkbytesize = numitems; + else if (format == 16) + chunkbytesize = numitems * sizeof(short); + else if (format == 32) + chunkbytesize = numitems * sizeof(long); #ifdef TEST - printf("chunkbytesize %zu\n", chunkbytesize); + ErrorF("chunkbytesize %zu\n", chunkbytesize); #endif newbuflen = buflen + chunkbytesize; if (newbuflen > 0) @@ -206,7 +211,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato } #ifdef TEST - printf("bytesleft %lu\n", bytesleft); + ErrorF("bytesleft %lu\n", bytesleft); #endif } while (bytesleft > 0); @@ -231,13 +236,13 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato if (pdata->format != 32) { - fprintf(stderr, "Atom list is expected to be formatted as an array of 32bit values.\n"); + ErrorF("Atom list is expected to be formatted as an array of 32bit values.\n"); return None; } - for (i = 0, step = pdata->format >> 3; i < pdata->length; i += step) + for (i = 0, step = sizeof(long); i < pdata->length; i += step) { - a = (Atom)*(uint32_t *)(pdata->data + i); + a = (Atom)*(long *)(pdata->data + i); if (a == atoms->image_png) { @@ -260,7 +265,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato char *type = XGetAtomName(xpbproxy_dpy, a); if (type) { - DB("Unhandled X11 mime type: %s", type); + DebugF("Unhandled X11 mime type: %s", type); XFree(type); } } @@ -373,7 +378,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato if (countNow != changeCount) { - DB ("changed pasteboard!\n"); + DebugF ("changed pasteboard!\n"); changeCount = countNow; if (pbproxy_prefs.pasteboard_to_primary) @@ -457,9 +462,8 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato return TRUE; if(owner != None) { - fprintf (stderr, "A clipboard manager using window 0x%lx " - "already owns the clipboard selection. " - "pbproxy will not sync clipboard to pasteboard.\n", owner); + ErrorF("A clipboard manager using window 0x%lx already owns the clipboard selection. " + "pbproxy will not sync clipboard to pasteboard.\n", owner); return FALSE; } @@ -486,7 +490,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato TRACE (); - DB ("e->selection %s\n", XGetAtomName (xpbproxy_dpy, e->selection)); + DebugF ("e->selection %s\n", XGetAtomName (xpbproxy_dpy, e->selection)); if(e->selection == atoms->clipboard) { /* @@ -503,7 +507,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato /* Another CLIPBOARD_MANAGER has set itself as owner. Disable syncing * to avoid a race. */ - fprintf(stderr, "Another clipboard manager was started! " + ErrorF("Another clipboard manager was started! " "xpbproxy is disabling syncing with clipboard.\n"); pbproxy_prefs.clipboard_to_pasteboard = NO; } @@ -528,7 +532,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato * The owner probably died or we are just starting up pbproxy. * Set pbproxy's _selection_window as the owner, and continue. */ - DB ("No clipboard owner.\n"); + DebugF ("No clipboard owner.\n"); [self copy_completed:atoms->clipboard]; return; } else if (owner == _selection_window) { @@ -536,7 +540,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato return; } - DB ("requesting targets\n"); + DebugF ("requesting targets\n"); request_atom = atoms->targets; XConvertSelection (xpbproxy_dpy, atoms->clipboard, atoms->targets, @@ -576,7 +580,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato * We are supposed to use an empty event mask, and not propagate * the event, according to the ICCCM. */ - DB ("reply->xselection.requestor 0x%lx\n", reply->xselection.requestor); + DebugF ("reply->xselection.requestor 0x%lx\n", reply->xselection.requestor); XSendEvent (xpbproxy_dpy, reply->xselection.requestor, False, 0, reply); XFlush (xpbproxy_dpy); @@ -613,7 +617,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato if ([pbtypes containsObject:NSStringPboardType]) { /* We have a string type that we can convert to UTF8, or Latin-1... */ - DB ("NSStringPboardType\n"); + DebugF ("NSStringPboardType\n"); list[count] = atoms->utf8_string; ++count; list[count] = atoms->string; @@ -625,18 +629,26 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato /* TODO add the NSPICTPboardType back again, once we have conversion * functionality in send_image. */ +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // NSPICTPboardType +#endif if ([pbtypes containsObject:NSPICTPboardType] || [pbtypes containsObject:NSTIFFPboardType]) { /* We can convert a TIFF to a PNG or JPEG. */ - DB ("NSTIFFPboardType\n"); + DebugF ("NSTIFFPboardType\n"); list[count] = atoms->image_png; ++count; list[count] = atoms->image_jpeg; ++count; } +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + if (count) { /* We have a list of ATOMs to send. */ @@ -671,7 +683,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato return; } - DB ("pbtypes retainCount after containsObject: %u\n", [pbtypes retainCount]); + DebugF ("pbtypes retainCount after containsObject: %u\n", [pbtypes retainCount]); data = [pb stringForType:NSStringPboardType]; @@ -691,19 +703,19 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato length = strlen (bytes); if (length < 50) { - DB ("UTF-8: %s\n", bytes); - DB ("UTF-8 length: %u\n", length); + DebugF ("UTF-8: %s\n", bytes); + DebugF ("UTF-8 length: %u\n", length); } } else { - DB ("Latin-1\n"); + DebugF ("Latin-1\n"); bytes = [data cStringUsingEncoding:NSISOLatin1StringEncoding]; /*WARNING: bytes is not NUL-terminated. */ length = [data lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding]; } - DB ("e->target %s\n", XGetAtomName (xpbproxy_dpy, e->target)); + DebugF ("e->target %s\n", XGetAtomName (xpbproxy_dpy, e->target)); XChangeProperty (xpbproxy_dpy, e->requestor, e->property, e->target, 8, PropModeReplace, (unsigned char *) bytes, length); @@ -745,7 +757,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato { if (8 != textprop.format) - DB ("textprop.format is unexpectedly not 8 - it's %d instead\n", + DebugF ("textprop.format is unexpectedly not 8 - it's %d instead\n", textprop.format); XChangeProperty (xpbproxy_dpy, e->requestor, e->property, @@ -837,7 +849,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato if (nil == data) { [img autorelease]; - fprintf(stderr, "unable to convert PICT to TIFF!\n"); + ErrorF("unable to convert PICT to TIFF!\n"); return YES; } @@ -913,7 +925,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato imagetype = NSJPEGFileType; else { - fprintf(stderr, "internal failure in xpbproxy! imagetype being sent isn't PNG or JPEG.\n"); + ErrorF("internal failure in xpbproxy! imagetype being sent isn't PNG or JPEG.\n"); } pbtypes = [pb types]; @@ -925,7 +937,14 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato if (NO == [self send_image_tiff_reply:e pasteboard:pb type:imagetype]) return; } +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // NSPICTPboardType +#endif else if ([pbtypes containsObject:NSPICTPboardType]) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif { if (NO == [self send_image_pict_reply:e pasteboard:pb type:imagetype]) return; @@ -977,7 +996,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato if (None != e->target) - DB ("e->target %s\n", XGetAtomName (xpbproxy_dpy, e->target)); + DebugF ("e->target %s\n", XGetAtomName (xpbproxy_dpy, e->target)); if (e->target == atoms->targets) { @@ -1029,15 +1048,15 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato [self release_pending]; if (None == e->property) { - DB ("e->property is None.\n"); + DebugF ("e->property is None.\n"); [self copy_completed:e->selection]; /* Nothing is selected. */ return; } #if 0 - printf ("e->selection %s\n", XGetAtomName (xpbproxy_dpy, e->selection)); - printf ("e->property %s\n", XGetAtomName (xpbproxy_dpy, e->property)); + ErrorF("e->selection %s\n", XGetAtomName (xpbproxy_dpy, e->selection)); + ErrorF("e->property %s\n", XGetAtomName (xpbproxy_dpy, e->property)); #endif if ([self is_incr_type:e]) @@ -1046,7 +1065,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato * This is an INCR-style transfer, which means that we * will get the data after a series of PropertyNotify events. */ - DB ("is INCR\n"); + DebugF ("is INCR\n"); if (get_property (e->requestor, e->property, &pdata, /*Delete*/ True, &type)) { @@ -1063,7 +1082,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato pending.requestor = e->requestor; pending.selection = e->selection; - DB ("set pending.requestor to 0x%lx\n", pending.requestor); + DebugF ("set pending.requestor to 0x%lx\n", pending.requestor); } else { @@ -1076,7 +1095,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato /* We have the complete selection data.*/ [self handle_selection:e->selection type:type propdata:&pdata]; - DB ("handled selection with the first notify_event\n"); + DebugF ("handled selection with the first notify_event\n"); } } @@ -1096,7 +1115,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato if (name) { - DB ("e->atom %s\n", name); + DebugF ("e->atom %s\n", name); XFree(name); } #endif @@ -1104,7 +1123,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato if (None != pending.requestor && PropertyNewValue == e->state) { - DB ("pending.requestor 0x%lx\n", pending.requestor); + DebugF ("pending.requestor 0x%lx\n", pending.requestor); if (get_property (e->window, e->atom, &pdata, /*Delete*/ True, &type)) { @@ -1146,7 +1165,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato case XFixesSelectionWindowDestroyNotify: case XFixesSelectionClientCloseNotify: default: - fprintf(stderr, "Unhandled XFixesSelectionNotifyEvent: subtype=%d\n", e->subtype); + ErrorF("Unhandled XFixesSelectionNotifyEvent: subtype=%d\n", e->subtype); break; } } @@ -1176,7 +1195,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato if (name) { - DB ("requesting %s\n", name); + DebugF ("requesting %s\n", name); } #endif request_atom = preferred; @@ -1200,11 +1219,11 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato if (nil == data) { - DB ("unable to create NSData object!\n"); + DebugF ("unable to create NSData object!\n"); return; } - DB ("data retainCount before NSBitmapImageRep initWithData: %u\n", + DebugF ("data retainCount before NSBitmapImageRep initWithData: %u\n", [data retainCount]); bmimage = [[NSBitmapImageRep alloc] initWithData:data]; @@ -1212,11 +1231,11 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato if (nil == bmimage) { [data autorelease]; - DB ("unable to create NSBitmapImageRep!\n"); + DebugF ("unable to create NSBitmapImageRep!\n"); return; } - DB ("data retainCount after NSBitmapImageRep initWithData: %u\n", + DebugF ("data retainCount after NSBitmapImageRep initWithData: %u\n", [data retainCount]); @try @@ -1226,13 +1245,13 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato @catch (NSException *e) { - DB ("NSTIFFException!\n"); + DebugF ("NSTIFFException!\n"); [data autorelease]; [bmimage autorelease]; return; } - DB ("bmimage retainCount after TIFFRepresentation %u\n", [bmimage retainCount]); + DebugF ("bmimage retainCount after TIFFRepresentation %u\n", [bmimage retainCount]); pbtypes = [NSArray arrayWithObjects:NSTIFFPboardType, nil]; @@ -1246,12 +1265,12 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato [pb declareTypes:pbtypes owner:nil]; if (YES != [pb setData:tiff forType:NSTIFFPboardType]) { - DB ("writing pasteboard data failed!\n"); + DebugF ("writing pasteboard data failed!\n"); } [data autorelease]; - DB ("bmimage retainCount before release %u\n", [bmimage retainCount]); + DebugF ("bmimage retainCount before release %u\n", [bmimage retainCount]); [bmimage autorelease]; } @@ -1279,10 +1298,10 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato [pb declareTypes:pbtypes owner:nil]; if (YES != [pb setString:string forType:NSStringPboardType]) { - fprintf(stderr, "pasteboard setString:forType: failed!\n"); + ErrorF("pasteboard setString:forType: failed!\n"); } [string autorelease]; - DB ("done handling utf8 string\n"); + DebugF ("done handling utf8 string\n"); } /* This handles the STRING type, which should be in Latin-1. */ @@ -1308,7 +1327,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato [pb declareTypes:pbtypes owner:nil]; if (YES != [pb setString:string forType:NSStringPboardType]) { - fprintf(stderr, "pasteboard setString:forType failed in handle_string!\n"); + ErrorF("pasteboard setString:forType failed in handle_string!\n"); } [string autorelease]; } @@ -1374,7 +1393,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato name = XGetAtomName (xpbproxy_dpy, selection); if (name) { - DB ("copy_completed: %s\n", name); + DebugF ("copy_completed: %s\n", name); XFree (name); } #endif @@ -1435,10 +1454,10 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato pbproxy_prefs.pasteboard_to_clipboard = prefs_get_bool(CFSTR("sync_pasteboard_to_clipboard"), pbproxy_prefs.pasteboard_to_clipboard); /* This is used for debugging. */ - //dump_prefs(stdout); + //dump_prefs(); if(pbproxy_prefs.active && pbproxy_prefs.primary_on_grab && !xpbproxy_have_xfixes) { - fprintf(stderr, "Disabling sync_primary_on_select functionality due to missing XFixes extension.\n"); + ErrorF("Disabling sync_primary_on_select functionality due to missing XFixes extension.\n"); pbproxy_prefs.primary_on_grab = NO; } diff --git a/xorg-server/hw/xquartz/quartz.c b/xorg-server/hw/xquartz/quartz.c index 4b72a89d3..0e71d3629 100644 --- a/xorg-server/hw/xquartz/quartz.c +++ b/xorg-server/hw/xquartz/quartz.c @@ -62,7 +62,7 @@ #include <sys/stat.h> #include <fcntl.h> #include <IOKit/pwr_mgt/IOPMLib.h> -#include <pthread.h> +#include <libkern/OSAtomic.h> #include <signal.h> #include <rootlessCommon.h> @@ -279,10 +279,10 @@ static void pokeActivityCallback(CFRunLoopTimerRef timer, void *info) { static void QuartzScreenSaver(int state) { static CFRunLoopTimerRef pokeActivityTimer = NULL; static CFRunLoopTimerContext pokeActivityContext = { 0, NULL, NULL, NULL, NULL }; - static pthread_mutex_t pokeActivityMutex = PTHREAD_MUTEX_INITIALIZER; + static OSSpinLock pokeActivitySpinLock = OS_SPINLOCK_INIT; + + OSSpinLockLock(&pokeActivitySpinLock); - pthread_mutex_lock(&pokeActivityMutex); - if(state) { if(pokeActivityTimer == NULL) goto QuartzScreenSaverEnd; @@ -303,7 +303,7 @@ static void QuartzScreenSaver(int state) { CFRunLoopAddTimer(CFRunLoopGetMain(), pokeActivityTimer, kCFRunLoopCommonModes); } QuartzScreenSaverEnd: - pthread_mutex_unlock(&pokeActivityMutex); + OSSpinLockUnlock(&pokeActivitySpinLock); } void QuartzShowFullscreen(int state) { diff --git a/xorg-server/hw/xquartz/quartz.h b/xorg-server/hw/xquartz/quartz.h index 67a7919b2..0a9c47a6b 100644 --- a/xorg-server/hw/xquartz/quartz.h +++ b/xorg-server/hw/xquartz/quartz.h @@ -70,7 +70,7 @@ typedef void (*UpdateScreenProc)(ScreenPtr pScreen); /* * Rootless helper functions */ -typedef Bool (*IsX11WindowProc)(void *nsWindow, int windowNumber); +typedef Bool (*IsX11WindowProc)(int windowNumber); typedef void (*HideWindowsProc)(Bool hide); /* diff --git a/xorg-server/hw/xquartz/quartzKeyboard.c b/xorg-server/hw/xquartz/quartzKeyboard.c index 54f709a8b..c54011488 100644 --- a/xorg-server/hw/xquartz/quartzKeyboard.c +++ b/xorg-server/hw/xquartz/quartzKeyboard.c @@ -56,8 +56,6 @@ #include "X11Application.h" -#include "threadSafety.h" - #ifdef NDEBUG #undef NDEBUG #include <assert.h> @@ -369,9 +367,9 @@ static void DarwinKeyboardSetRepeat(DeviceIntPtr pDev, int initialKeyRepeatValue if (pDev->kbdfeed) memcpy(pDev->kbdfeed->ctrl.autoRepeats, ctrl->per_key_repeat, XkbPerKeyBitArraySize); - //fprintf(stderr, "per_key_repeat =\n"); + //ErrorF("per_key_repeat =\n"); //for(i=0; i < XkbPerKeyBitArraySize; i++) - // fprintf(stderr, "%02x%s", ctrl->per_key_repeat[i], (i + 1) & 7 ? "" : "\n"); + // ErrorF("%02x%s", ctrl->per_key_repeat[i], (i + 1) & 7 ? "" : "\n"); /* And now we notify the puppies about the changes */ XkbDDXChangeControls(pDev, &old, ctrl); @@ -686,6 +684,11 @@ static Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info) { } #endif +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // KLGetCurrentKeyboardLayout, KLGetKeyboardLayoutProperty +#endif + #if !defined(__LP64__) || MAC_OS_X_VERSION_MIN_REQUIRED < 1050 if (chr_data == NULL) { #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 @@ -719,6 +722,10 @@ static Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info) { } #endif +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 if(currentKeyLayoutRef) CFRelease(currentKeyLayoutRef); @@ -775,10 +782,16 @@ static Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info) { } #if !defined(__LP64__) || MAC_OS_X_VERSION_MIN_REQUIRED < 1050 } else { // kchr - UInt32 c, state = 0, state2 = 0; + UInt32 c, state = 0, state2 = 0; UInt16 code; code = i | mods[j]; + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // KeyTranslate +#endif + c = KeyTranslate (chr_data, code, &state); /* Dead keys are only processed on key-down, so ask @@ -789,6 +802,10 @@ static Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info) { if (state != 0) c = KeyTranslate (chr_data, code | 128, &state2); +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + /* Characters seem to be in MacRoman encoding. */ if (c != 0 && c != 0x0010) { diff --git a/xorg-server/hw/xquartz/quartzKeyboard.h b/xorg-server/hw/xquartz/quartzKeyboard.h index 1151a0035..de4aed868 100644 --- a/xorg-server/hw/xquartz/quartzKeyboard.h +++ b/xorg-server/hw/xquartz/quartzKeyboard.h @@ -32,8 +32,6 @@ #include "X11/keysym.h" #include "inputstr.h" -#include <pthread.h> - // Each key can generate 4 glyphs. They are, in order: // unshifted, shifted, modeswitch unshifted, modeswitch shifted #define GLYPHS_PER_KEY 4 diff --git a/xorg-server/hw/xquartz/quartzStartup.c b/xorg-server/hw/xquartz/quartzStartup.c index 36c8182ae..00a9e48fd 100644 --- a/xorg-server/hw/xquartz/quartzStartup.c +++ b/xorg-server/hw/xquartz/quartzStartup.c @@ -84,10 +84,7 @@ void QuartzInitServer(int argc, char **argv, char **envp) { args->argv = argv; args->envp = envp; - APPKIT_THREAD_ID = pthread_self(); - SERVER_THREAD_ID = create_thread(server_thread, args); - - if (!SERVER_THREAD_ID) { + if (!create_thread(server_thread, args)) { FatalError("can't create secondary thread\n"); } } diff --git a/xorg-server/hw/xquartz/threadSafety.c b/xorg-server/hw/xquartz/threadSafety.c deleted file mode 100644 index 85f85bd0a..000000000 --- a/xorg-server/hw/xquartz/threadSafety.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2008 Apple, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include "threadSafety.h" -#include "os.h" - -pthread_t APPKIT_THREAD_ID; -pthread_t SERVER_THREAD_ID; - -#include <AvailabilityMacros.h> - -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 -#include <execinfo.h> - -void spewCallStack(void) { - void* callstack[128]; - int i, frames = backtrace(callstack, 128); - char** strs = backtrace_symbols(callstack, frames); - - for (i = 0; i < frames; ++i) { - ErrorF("%s\n", strs[i]); - } - - free(strs); -} -#else -void spewCallStack(void) { - return; -} -#endif - -void _threadSafetyAssert(pthread_t tid, const char *file, const char *fun, int line) { - if(pthread_equal(pthread_self(), tid)) - return; - - /* NOOOO! */ - ErrorF("Thread Assertion Failed: self=%s, expected=%s\n%s:%s:%d\n", - threadSafetyID(pthread_self()), threadSafetyID(tid), - file, fun, line); - spewCallStack(); -} - -const char *threadSafetyID(pthread_t tid) { - if(pthread_equal(tid, APPKIT_THREAD_ID)) { - return "Appkit Thread"; - } else if(pthread_equal(tid, SERVER_THREAD_ID)) { - return "Xserver Thread"; - } else { - return "Unknown Thread"; - } -} diff --git a/xorg-server/hw/xquartz/threadSafety.h b/xorg-server/hw/xquartz/threadSafety.h deleted file mode 100644 index 3ff9eaf7e..000000000 --- a/xorg-server/hw/xquartz/threadSafety.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2008 Apple, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ - -#ifndef _XQ_THREAD_SAFETY_H_ -#define _XQ_THREAD_SAFETY_H_ - -#define DEBUG_THREADS 1 - -#include <pthread.h> - -extern pthread_t APPKIT_THREAD_ID; -extern pthread_t SERVER_THREAD_ID; - -/* Dump the call stack */ -void spewCallStack(void); - -/* Print message to ErrorF if we're in the wrong thread */ -void _threadSafetyAssert(pthread_t tid, const char *file, const char *fun, int line); - -/* Get a string that identifies our thread nicely */ -const char *threadSafetyID(pthread_t tid); - -#define threadSafetyAssert(tid) _threadSafetyAssert(tid, __FILE__, __FUNCTION__, __LINE__) - -#ifdef DEBUG_THREADS -#define TA_APPKIT() threadSafetyAssert(APPKIT_THREAD_ID) -#define TA_SERVER() threadSafetyAssert(SERVER_THREAD_ID) -#else -#define TA_SERVER() -#define TA_APPKIT() -#endif - -#endif /* _XQ_THREAD_SAFETY_H_ */ diff --git a/xorg-server/hw/xquartz/xpr/dri.c b/xorg-server/hw/xquartz/xpr/dri.c index 7b730df8e..8fef3b793 100644 --- a/xorg-server/hw/xquartz/xpr/dri.c +++ b/xorg-server/hw/xquartz/xpr/dri.c @@ -1,850 +1,845 @@ -/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, Inc.
-Copyright (c) 2002, 2009 Apple Computer, Inc.
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Jens Owen <jens@valinux.com>
- * Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifdef XFree86LOADER
-#include "xf86.h"
-#include "xf86_ansic.h"
-#else
-#include <sys/time.h>
-#include <unistd.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "misc.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "servermd.h"
-#define _APPLEDRI_SERVER_
-#include "appledristr.h"
-#include "swaprep.h"
-#include "dri.h"
-#include "dristruct.h"
-#include "mi.h"
-#include "mipointer.h"
-#include "rootless.h"
-#include "x-hash.h"
-#include "x-hook.h"
-#include "driWrap.h"
-
-#include <AvailabilityMacros.h>
-
-static DevPrivateKeyRec DRIScreenPrivKeyRec;
-#define DRIScreenPrivKey (&DRIScreenPrivKeyRec)
-static DevPrivateKeyRec DRIWindowPrivKeyRec;
-#define DRIWindowPrivKey (&DRIWindowPrivKeyRec)
-static DevPrivateKeyRec DRIPixmapPrivKeyRec;
-#define DRIPixmapPrivKey (&DRIPixmapPrivKeyRec)
-static DevPrivateKeyRec DRIPixmapBufferPrivKeyRec;
-#define DRIPixmapBufferPrivKey (&DRIPixmapBufferPrivKeyRec)
-
-static RESTYPE DRIDrawablePrivResType;
-
-static x_hash_table *surface_hash; /* maps surface ids -> drawablePrivs */
-
-static Bool DRIFreePixmapImp(DrawablePtr pDrawable);
-
-typedef struct {
- DrawablePtr pDrawable;
- int refCount;
- int bytesPerPixel;
- int width;
- int height;
- char shmPath[PATH_MAX];
- int fd; /* From shm_open (for now) */
- size_t length; /* length of buffer */
- void *buffer;
-} DRIPixmapBuffer, *DRIPixmapBufferPtr;
-
-Bool
-DRIScreenInit(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv;
- int i;
-
- if (!dixRegisterPrivateKey(&DRIScreenPrivKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
- if (!dixRegisterPrivateKey(&DRIWindowPrivKeyRec, PRIVATE_WINDOW, 0))
- return FALSE;
- if (!dixRegisterPrivateKey(&DRIPixmapPrivKeyRec, PRIVATE_PIXMAP, 0))
- return FALSE;
- if (!dixRegisterPrivateKey(&DRIPixmapBufferPrivKeyRec, PRIVATE_PIXMAP, 0))
- return FALSE;
-
- pDRIPriv = (DRIScreenPrivPtr) calloc(1, sizeof(DRIScreenPrivRec));
- if (!pDRIPriv) {
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- return FALSE;
- }
-
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, pDRIPriv);
- pDRIPriv->directRenderingSupport = TRUE;
- pDRIPriv->nrWindows = 0;
-
- /* Initialize drawable tables */
- for (i = 0; i < DRI_MAX_DRAWABLES; i++) {
- pDRIPriv->DRIDrawables[i] = NULL;
- }
-
- return TRUE;
-}
-
-Bool
-DRIFinishScreenInit(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- /* Wrap DRI support */
- pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
- pScreen->ValidateTree = DRIValidateTree;
-
- pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
- pScreen->PostValidateTree = DRIPostValidateTree;
-
- pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
- pScreen->WindowExposures = DRIWindowExposures;
-
- pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
- pScreen->CopyWindow = DRICopyWindow;
-
- pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
- pScreen->ClipNotify = DRIClipNotify;
-
- // ErrorF("[DRI] screen %d installation complete\n", pScreen->myNum);
-
- return DRIWrapInit(pScreen);
-}
-
-void
-DRICloseScreen(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv && pDRIPriv->directRenderingSupport) {
- free(pDRIPriv);
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- }
-}
-
-Bool
-DRIExtensionInit(void)
-{
- DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete,
- "DRIDrawable");
-
- return DRIDrawablePrivResType != 0;
-}
-
-void
-DRIReset(void)
-{
- /*
- * This stub routine is called when the X Server recycles, resources
- * allocated by DRIExtensionInit need to be managed here.
- *
- * Currently this routine is a stub because all the interesting resources
- * are managed via the screen init process.
- */
-}
-
-Bool
-DRIQueryDirectRenderingCapable(ScreenPtr pScreen, Bool* isCapable)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv)
- *isCapable = pDRIPriv->directRenderingSupport;
- else
- *isCapable = FALSE;
-
- return TRUE;
-}
-
-Bool
-DRIAuthConnection(ScreenPtr pScreen, unsigned int magic)
-{
-#if 0
- /* FIXME: something? */
-
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (drmAuthMagic(pDRIPriv->drmFD, magic)) return FALSE;
-#endif
- return TRUE;
-}
-
-static void
-DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv, DrawablePtr pDraw)
-{
- xp_window_changes wc;
- unsigned int flags = 0;
-
- if (pDRIDrawablePriv->sid == 0)
- return;
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
- wc.depth = (pDraw->bitsPerPixel == 32 ? XP_DEPTH_ARGB8888
- : pDraw->bitsPerPixel == 16 ? XP_DEPTH_RGB555 : XP_DEPTH_NIL);
- if (wc.depth != XP_DEPTH_NIL)
- flags |= XP_DEPTH;
-#endif
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- WindowPtr pWin = (WindowPtr) pDraw;
- WindowPtr pTopWin = TopLevelParent(pWin);
-
- wc.x = pWin->drawable.x - (pTopWin->drawable.x - pTopWin->borderWidth);
- wc.y = pWin->drawable.y - (pTopWin->drawable.y - pTopWin->borderWidth);
- wc.width = pWin->drawable.width + 2 * pWin->borderWidth;
- wc.height = pWin->drawable.height + 2 * pWin->borderWidth;
- wc.bit_gravity = XP_GRAVITY_NONE;
-
- wc.shape_nrects = RegionNumRects(&pWin->clipList);
- wc.shape_rects = RegionRects(&pWin->clipList);
- wc.shape_tx = - (pTopWin->drawable.x - pTopWin->borderWidth);
- wc.shape_ty = - (pTopWin->drawable.y - pTopWin->borderWidth);
-
- flags |= XP_BOUNDS | XP_SHAPE;
-
- } else if (pDraw->type == DRAWABLE_PIXMAP) {
- wc.x = 0;
- wc.y = 0;
- wc.width = pDraw->width;
- wc.height = pDraw->height;
- wc.bit_gravity = XP_GRAVITY_NONE;
- flags |= XP_BOUNDS;
- }
-
- xp_configure_surface(pDRIDrawablePriv->sid, flags, &wc);
-}
-
-/* Return NULL if an error occurs. */
-static DRIDrawablePrivPtr
-CreateSurfaceForWindow(ScreenPtr pScreen, WindowPtr pWin, xp_window_id *widPtr) {
- DRIDrawablePrivPtr pDRIDrawablePriv;
- xp_window_id wid = 0;
-
- *widPtr = 0;
-
- pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
-
- if (pDRIDrawablePriv == NULL) {
- xp_error err;
- xp_window_changes wc;
-
- /* allocate a DRI Window Private record */
- if (!(pDRIDrawablePriv = malloc(sizeof(*pDRIDrawablePriv)))) {
- return NULL;
- }
-
- pDRIDrawablePriv->pDraw = (DrawablePtr)pWin;
- pDRIDrawablePriv->pScreen = pScreen;
- pDRIDrawablePriv->refCount = 0;
- pDRIDrawablePriv->drawableIndex = -1;
- pDRIDrawablePriv->notifiers = NULL;
-
- /* find the physical window */
- wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWin, TRUE));
-
- if (wid == 0) {
- free(pDRIDrawablePriv);
- return NULL;
- }
-
- /* allocate the physical surface */
- err = xp_create_surface(wid, &pDRIDrawablePriv->sid);
-
- if (err != Success) {
- free(pDRIDrawablePriv);
- return NULL;
- }
-
- /* Make it visible */
- wc.stack_mode = XP_MAPPED_ABOVE;
- wc.sibling = 0;
- err = xp_configure_surface(pDRIDrawablePriv->sid, XP_STACKING, &wc);
-
- if (err != Success) {
- xp_destroy_surface(pDRIDrawablePriv->sid);
- free(pDRIDrawablePriv);
- return NULL;
- }
-
- /* save private off of preallocated index */
- dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey,
- pDRIDrawablePriv);
- }
-
- *widPtr = wid;
-
- return pDRIDrawablePriv;
-}
-
-/* Return NULL if an error occurs. */
-static DRIDrawablePrivPtr
-CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
- DRIDrawablePrivPtr pDRIDrawablePriv;
-
- pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
-
- if (pDRIDrawablePriv == NULL) {
- xp_error err;
-
- /* allocate a DRI Window Private record */
- if (!(pDRIDrawablePriv = calloc(1, sizeof(*pDRIDrawablePriv)))) {
- return NULL;
- }
-
- pDRIDrawablePriv->pDraw = (DrawablePtr)pPix;
- pDRIDrawablePriv->pScreen = pScreen;
- pDRIDrawablePriv->refCount = 0;
- pDRIDrawablePriv->drawableIndex = -1;
- pDRIDrawablePriv->notifiers = NULL;
-
- /* Passing a null window id to Xplugin in 10.3+ asks for
- an accelerated offscreen surface. */
-
- err = xp_create_surface(0, &pDRIDrawablePriv->sid);
- if (err != Success) {
- free(pDRIDrawablePriv);
- return NULL;
- }
-
- /*
- * The DRIUpdateSurface will be called to resize the surface
- * after this function, if the export is successful.
- */
-
- /* save private off of preallocated index */
- dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey,
- pDRIDrawablePriv);
- }
-
- return pDRIDrawablePriv;
-}
-
-
-Bool
-DRICreateSurface(ScreenPtr pScreen, Drawable id,
- DrawablePtr pDrawable, xp_client_id client_id,
- xp_surface_id *surface_id, unsigned int ret_key[2],
- void (*notify) (void *arg, void *data), void *notify_data)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- xp_window_id wid = 0;
- DRIDrawablePrivPtr pDRIDrawablePriv;
-
- if (pDrawable->type == DRAWABLE_WINDOW) {
- pDRIDrawablePriv = CreateSurfaceForWindow(pScreen,
- (WindowPtr)pDrawable, &wid);
-
- if(NULL == pDRIDrawablePriv)
- return FALSE; /*error*/
- }
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
- else if (pDrawable->type == DRAWABLE_PIXMAP) {
- pDRIDrawablePriv = CreateSurfaceForPixmap(pScreen,
- (PixmapPtr)pDrawable);
-
- if(NULL == pDRIDrawablePriv)
- return FALSE; /*error*/
- }
-#endif
- else { /* 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);
-
-}
+/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +Copyright (c) 2002, 2009 Apple Computer, Inc. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Jens Owen <jens@valinux.com> + * Rickard E. (Rik) Faith <faith@valinux.com> + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifdef XFree86LOADER +#include "xf86.h" +#include "xf86_ansic.h" +#else +#include <sys/time.h> +#include <unistd.h> +#endif + +#include <X11/X.h> +#include <X11/Xproto.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "misc.h" +#include "dixstruct.h" +#include "extnsionst.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "servermd.h" +#define _APPLEDRI_SERVER_ +#include "appledristr.h" +#include "swaprep.h" +#include "dri.h" +#include "dristruct.h" +#include "mi.h" +#include "mipointer.h" +#include "rootless.h" +#include "x-hash.h" +#include "x-hook.h" +#include "driWrap.h" + +#include <AvailabilityMacros.h> + +static DevPrivateKeyRec DRIScreenPrivKeyRec; +#define DRIScreenPrivKey (&DRIScreenPrivKeyRec) +static DevPrivateKeyRec DRIWindowPrivKeyRec; +#define DRIWindowPrivKey (&DRIWindowPrivKeyRec) +static DevPrivateKeyRec DRIPixmapPrivKeyRec; +#define DRIPixmapPrivKey (&DRIPixmapPrivKeyRec) +static DevPrivateKeyRec DRIPixmapBufferPrivKeyRec; +#define DRIPixmapBufferPrivKey (&DRIPixmapBufferPrivKeyRec) + +static RESTYPE DRIDrawablePrivResType; + +static x_hash_table *surface_hash; /* maps surface ids -> drawablePrivs */ + +static Bool DRIFreePixmapImp(DrawablePtr pDrawable); + +typedef struct { + DrawablePtr pDrawable; + int refCount; + int bytesPerPixel; + int width; + int height; + char shmPath[PATH_MAX]; + int fd; /* From shm_open (for now) */ + size_t length; /* length of buffer */ + void *buffer; +} DRIPixmapBuffer, *DRIPixmapBufferPtr; + +Bool +DRIScreenInit(ScreenPtr pScreen) +{ + DRIScreenPrivPtr pDRIPriv; + int i; + + if (!dixRegisterPrivateKey(&DRIScreenPrivKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + if (!dixRegisterPrivateKey(&DRIWindowPrivKeyRec, PRIVATE_WINDOW, 0)) + return FALSE; + if (!dixRegisterPrivateKey(&DRIPixmapPrivKeyRec, PRIVATE_PIXMAP, 0)) + return FALSE; + if (!dixRegisterPrivateKey(&DRIPixmapBufferPrivKeyRec, PRIVATE_PIXMAP, 0)) + return FALSE; + + pDRIPriv = (DRIScreenPrivPtr) calloc(1, sizeof(DRIScreenPrivRec)); + if (!pDRIPriv) { + dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL); + return FALSE; + } + + dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, pDRIPriv); + pDRIPriv->directRenderingSupport = TRUE; + pDRIPriv->nrWindows = 0; + + /* Initialize drawable tables */ + for (i = 0; i < DRI_MAX_DRAWABLES; i++) { + pDRIPriv->DRIDrawables[i] = NULL; + } + + return TRUE; +} + +Bool +DRIFinishScreenInit(ScreenPtr pScreen) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + /* Wrap DRI support */ + pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree; + pScreen->ValidateTree = DRIValidateTree; + + pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree; + pScreen->PostValidateTree = DRIPostValidateTree; + + pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures; + pScreen->WindowExposures = DRIWindowExposures; + + pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow; + pScreen->CopyWindow = DRICopyWindow; + + pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify; + pScreen->ClipNotify = DRIClipNotify; + + // ErrorF("[DRI] screen %d installation complete\n", pScreen->myNum); + + return DRIWrapInit(pScreen); +} + +void +DRICloseScreen(ScreenPtr pScreen) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + if (pDRIPriv && pDRIPriv->directRenderingSupport) { + free(pDRIPriv); + dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL); + } +} + +Bool +DRIExtensionInit(void) +{ + DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete, + "DRIDrawable"); + + return DRIDrawablePrivResType != 0; +} + +void +DRIReset(void) +{ + /* + * This stub routine is called when the X Server recycles, resources + * allocated by DRIExtensionInit need to be managed here. + * + * Currently this routine is a stub because all the interesting resources + * are managed via the screen init process. + */ +} + +Bool +DRIQueryDirectRenderingCapable(ScreenPtr pScreen, Bool* isCapable) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + if (pDRIPriv) + *isCapable = pDRIPriv->directRenderingSupport; + else + *isCapable = FALSE; + + return TRUE; +} + +Bool +DRIAuthConnection(ScreenPtr pScreen, unsigned int magic) +{ +#if 0 + /* FIXME: something? */ + + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + if (drmAuthMagic(pDRIPriv->drmFD, magic)) return FALSE; +#endif + return TRUE; +} + +static void +DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv, DrawablePtr pDraw) +{ + xp_window_changes wc; + unsigned int flags = 0; + + if (pDRIDrawablePriv->sid == 0) + return; + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + wc.depth = (pDraw->bitsPerPixel == 32 ? XP_DEPTH_ARGB8888 + : pDraw->bitsPerPixel == 16 ? XP_DEPTH_RGB555 : XP_DEPTH_NIL); + if (wc.depth != XP_DEPTH_NIL) + flags |= XP_DEPTH; +#endif + + if (pDraw->type == DRAWABLE_WINDOW) { + WindowPtr pWin = (WindowPtr) pDraw; + WindowPtr pTopWin = TopLevelParent(pWin); + + wc.x = pWin->drawable.x - (pTopWin->drawable.x - pTopWin->borderWidth); + wc.y = pWin->drawable.y - (pTopWin->drawable.y - pTopWin->borderWidth); + wc.width = pWin->drawable.width + 2 * pWin->borderWidth; + wc.height = pWin->drawable.height + 2 * pWin->borderWidth; + wc.bit_gravity = XP_GRAVITY_NONE; + + wc.shape_nrects = RegionNumRects(&pWin->clipList); + wc.shape_rects = RegionRects(&pWin->clipList); + wc.shape_tx = - (pTopWin->drawable.x - pTopWin->borderWidth); + wc.shape_ty = - (pTopWin->drawable.y - pTopWin->borderWidth); + + flags |= XP_BOUNDS | XP_SHAPE; + + } else if (pDraw->type == DRAWABLE_PIXMAP) { + wc.x = 0; + wc.y = 0; + wc.width = pDraw->width; + wc.height = pDraw->height; + wc.bit_gravity = XP_GRAVITY_NONE; + flags |= XP_BOUNDS; + } + + xp_configure_surface(pDRIDrawablePriv->sid, flags, &wc); +} + +/* Return NULL if an error occurs. */ +static DRIDrawablePrivPtr +CreateSurfaceForWindow(ScreenPtr pScreen, WindowPtr pWin, xp_window_id *widPtr) { + DRIDrawablePrivPtr pDRIDrawablePriv; + xp_window_id wid = 0; + + *widPtr = 0; + + pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); + + if (pDRIDrawablePriv == NULL) { + xp_error err; + xp_window_changes wc; + + /* allocate a DRI Window Private record */ + if (!(pDRIDrawablePriv = malloc(sizeof(*pDRIDrawablePriv)))) { + return NULL; + } + + pDRIDrawablePriv->pDraw = (DrawablePtr)pWin; + pDRIDrawablePriv->pScreen = pScreen; + pDRIDrawablePriv->refCount = 0; + pDRIDrawablePriv->drawableIndex = -1; + pDRIDrawablePriv->notifiers = NULL; + + /* find the physical window */ + wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWin, TRUE)); + + if (wid == 0) { + free(pDRIDrawablePriv); + return NULL; + } + + /* allocate the physical surface */ + err = xp_create_surface(wid, &pDRIDrawablePriv->sid); + + if (err != Success) { + free(pDRIDrawablePriv); + return NULL; + } + + /* Make it visible */ + wc.stack_mode = XP_MAPPED_ABOVE; + wc.sibling = 0; + err = xp_configure_surface(pDRIDrawablePriv->sid, XP_STACKING, &wc); + + if (err != Success) { + xp_destroy_surface(pDRIDrawablePriv->sid); + free(pDRIDrawablePriv); + return NULL; + } + + /* save private off of preallocated index */ + dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, + pDRIDrawablePriv); + } + + *widPtr = wid; + + return pDRIDrawablePriv; +} + +/* Return NULL if an error occurs. */ +static DRIDrawablePrivPtr +CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) { + DRIDrawablePrivPtr pDRIDrawablePriv; + + pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix); + + if (pDRIDrawablePriv == NULL) { + xp_error err; + + /* allocate a DRI Window Private record */ + if (!(pDRIDrawablePriv = calloc(1, sizeof(*pDRIDrawablePriv)))) { + return NULL; + } + + pDRIDrawablePriv->pDraw = (DrawablePtr)pPix; + pDRIDrawablePriv->pScreen = pScreen; + pDRIDrawablePriv->refCount = 0; + pDRIDrawablePriv->drawableIndex = -1; + pDRIDrawablePriv->notifiers = NULL; + + /* Passing a null window id to Xplugin in 10.3+ asks for + an accelerated offscreen surface. */ + + err = xp_create_surface(0, &pDRIDrawablePriv->sid); + if (err != Success) { + free(pDRIDrawablePriv); + return NULL; + } + + /* + * The DRIUpdateSurface will be called to resize the surface + * after this function, if the export is successful. + */ + + /* save private off of preallocated index */ + dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, + pDRIDrawablePriv); + } + + return pDRIDrawablePriv; +} + + +Bool +DRICreateSurface(ScreenPtr pScreen, Drawable id, + DrawablePtr pDrawable, xp_client_id client_id, + xp_surface_id *surface_id, unsigned int ret_key[2], + void (*notify) (void *arg, void *data), void *notify_data) +{ + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + xp_window_id wid = 0; + DRIDrawablePrivPtr pDRIDrawablePriv; + + if (pDrawable->type == DRAWABLE_WINDOW) { + pDRIDrawablePriv = CreateSurfaceForWindow(pScreen, + (WindowPtr)pDrawable, &wid); + + if(NULL == pDRIDrawablePriv) + return FALSE; /*error*/ + } +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + else if (pDrawable->type == DRAWABLE_PIXMAP) { + pDRIDrawablePriv = CreateSurfaceForPixmap(pScreen, + (PixmapPtr)pDrawable); + + if(NULL == pDRIDrawablePriv) + return FALSE; /*error*/ + } +#endif + else { /* 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); + + pScreen->WindowExposures = DRIWindowExposures; +} + +void +DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + DRIDrawablePrivPtr pDRIDrawablePriv; + + if (pDRIPriv->nrWindows > 0) { + pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); + if (pDRIDrawablePriv != NULL) { + DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable); + } + } + + /* unwrap */ + pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow; + + /* call lower layers */ + (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc); + + /* rewrap */ + pScreen->CopyWindow = DRICopyWindow; +} + +int +DRIValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) +{ + ScreenPtr pScreen = pParent->drawable.pScreen; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + int returnValue; + + /* unwrap */ + pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree; + + /* call lower layers */ + returnValue = (*pScreen->ValidateTree)(pParent, pChild, kind); + + /* rewrap */ + pScreen->ValidateTree = DRIValidateTree; + + return returnValue; +} + +void +DRIPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) +{ + ScreenPtr pScreen; + DRIScreenPrivPtr pDRIPriv; + + if (pParent) { + pScreen = pParent->drawable.pScreen; + } else { + pScreen = pChild->drawable.pScreen; + } + pDRIPriv = DRI_SCREEN_PRIV(pScreen); + + if (pDRIPriv->wrap.PostValidateTree) { + /* unwrap */ + pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree; + + /* call lower layers */ + (*pScreen->PostValidateTree)(pParent, pChild, kind); + + /* rewrap */ + pScreen->PostValidateTree = DRIPostValidateTree; + } +} + +void +DRIClipNotify(WindowPtr pWin, int dx, int dy) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); + DRIDrawablePrivPtr pDRIDrawablePriv; + + if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) { + DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable); + } + + if (pDRIPriv->wrap.ClipNotify) { + pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify; + + (*pScreen->ClipNotify)(pWin, dx, dy); + + pScreen->ClipNotify = DRIClipNotify; + } +} + +/* This lets us get at the unwrapped functions so that they can correctly + * call the lower level functions, and choose whether they will be + * called at every level of recursion (eg in validatetree). + */ +DRIWrappedFuncsRec * +DRIGetWrappedFuncs(ScreenPtr pScreen) +{ + return &(DRI_SCREEN_PRIV(pScreen)->wrap); +} + +void +DRIQueryVersion(int *majorVersion, + int *minorVersion, + int *patchVersion) +{ + *majorVersion = APPLE_DRI_MAJOR_VERSION; + *minorVersion = APPLE_DRI_MINOR_VERSION; + *patchVersion = APPLE_DRI_PATCH_VERSION; +} + +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/xpr.h b/xorg-server/hw/xquartz/xpr/xpr.h index af1a90ca0..ebd89de3a 100644 --- a/xorg-server/hw/xquartz/xpr/xpr.h +++ b/xorg-server/hw/xquartz/xpr/xpr.h @@ -38,7 +38,7 @@ Bool QuartzModeBundleInit(void); void AppleDRIExtensionInit(void); void xprAppleWMInit(void); Bool xprInit(ScreenPtr pScreen); -Bool xprIsX11Window(void *nsWindow, int windowNumber); +Bool xprIsX11Window(int windowNumber); WindowPtr xprGetXWindow(xp_window_id wid); void xprHideWindows(Bool hide); diff --git a/xorg-server/hw/xquartz/xpr/xprAppleWM.c b/xorg-server/hw/xquartz/xpr/xprAppleWM.c index 21e6f98fa..b6b9a5fc8 100644 --- a/xorg-server/hw/xquartz/xpr/xprAppleWM.c +++ b/xorg-server/hw/xquartz/xpr/xprAppleWM.c @@ -114,8 +114,8 @@ static int xprAttachTransient(WindowPtr pWinChild, WindowPtr pWinParent) { static int xprFrameDraw( WindowPtr pWin, - int class, - unsigned int attr, + xp_frame_class class, + xp_frame_attr attr, const BoxRec *outer, const BoxRec *inner, unsigned int title_len, diff --git a/xorg-server/hw/xquartz/xpr/xprEvent.c b/xorg-server/hw/xquartz/xpr/xprEvent.c index 38952b091..cc86c473d 100644 --- a/xorg-server/hw/xquartz/xpr/xprEvent.c +++ b/xorg-server/hw/xquartz/xpr/xprEvent.c @@ -1,81 +1,79 @@ -/* Copyright (c) 2008 Apple Inc.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
- * HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name(s) of the above
- * copyright holders shall not be used in advertising or otherwise to
- * promote the sale, use or other dealings in this Software without
- * prior written authorization.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "xpr.h"
-
-#include <X11/X.h>
-#include <X11/Xmd.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "inputstr.h"
-#include "eventstr.h"
-#include "mi.h"
-#include "scrnintstr.h"
-#include "mipointer.h"
-
-#include "darwin.h"
-#include "quartz.h"
-#include "quartzKeyboard.h"
-#include "darwinEvents.h"
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-
-#include "rootlessWindow.h"
-#include "xprEvent.h"
-
-Bool QuartzModeEventHandler(int screenNum, XQuartzEvent *e, DeviceIntPtr dev) {
- TA_SERVER();
-
- switch(e->subtype) {
- case kXquartzWindowState:
- DEBUG_LOG("kXquartzWindowState\n");
- RootlessNativeWindowStateChanged(xprGetXWindow(e->data[0]),
- e->data[1]);
- return TRUE;
-
- case kXquartzWindowMoved:
- DEBUG_LOG("kXquartzWindowMoved\n");
- RootlessNativeWindowMoved(xprGetXWindow(e->data[0]));
- return TRUE;
-
- case kXquartzBringAllToFront:
- DEBUG_LOG("kXquartzBringAllToFront\n");
- RootlessOrderAllWindows(e->data[0]);
- return TRUE;
- default:
- return FALSE;
- }
-}
+/* Copyright (c) 2008 Apple Inc. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + * HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above + * copyright holders shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "xpr.h" + +#include <X11/X.h> +#include <X11/Xmd.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "inputstr.h" +#include "eventstr.h" +#include "mi.h" +#include "scrnintstr.h" +#include "mipointer.h" + +#include "darwin.h" +#include "quartz.h" +#include "quartzKeyboard.h" +#include "darwinEvents.h" + +#include <sys/types.h> +#include <sys/uio.h> +#include <unistd.h> + +#include "rootlessWindow.h" +#include "xprEvent.h" + +Bool QuartzModeEventHandler(int screenNum, XQuartzEvent *e, DeviceIntPtr dev) { + switch(e->subtype) { + case kXquartzWindowState: + DEBUG_LOG("kXquartzWindowState\n"); + RootlessNativeWindowStateChanged(xprGetXWindow(e->data[0]), + e->data[1]); + return TRUE; + + case kXquartzWindowMoved: + DEBUG_LOG("kXquartzWindowMoved\n"); + RootlessNativeWindowMoved(xprGetXWindow(e->data[0])); + return TRUE; + + case kXquartzBringAllToFront: + DEBUG_LOG("kXquartzBringAllToFront\n"); + RootlessOrderAllWindows(e->data[0]); + return TRUE; + default: + return FALSE; + } +} diff --git a/xorg-server/hw/xquartz/xpr/xprFrame.c b/xorg-server/hw/xquartz/xpr/xprFrame.c index 15598e942..5f6b1cb7b 100644 --- a/xorg-server/hw/xquartz/xpr/xprFrame.c +++ b/xorg-server/hw/xquartz/xpr/xprFrame.c @@ -1,7 +1,7 @@ /* * Xplugin rootless implementation frame functions * - * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2002-2011 Apple Computer, Inc. All rights reserved. * Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -35,7 +35,6 @@ #include "rootlessCommon.h" #include <Xplugin.h> #include "x-hash.h" -#include "x-list.h" #include "applewmExt.h" #include "propertyst.h" @@ -44,9 +43,11 @@ #include "windowstr.h" #include "quartz.h" -#include "threadSafety.h" - +#ifdef HAVE_LIBDISPATCH +#include <dispatch/dispatch.h> +#else #include <pthread.h> +#endif #define DEFINE_ATOM_HELPER(func,atom_name) \ static Atom func (void) { \ @@ -63,7 +64,13 @@ DEFINE_ATOM_HELPER(xa_native_window_id, "_NATIVE_WINDOW_ID") /* Maps xp_window_id -> RootlessWindowRec */ static x_hash_table *window_hash; + +/* Need to guard window_hash since xprIsX11Window can be called from any thread. */ +#ifdef HAVE_LIBDISPATCH +static dispatch_queue_t window_hash_serial_q; +#else static pthread_mutex_t window_hash_mutex; +#endif /* Prototypes for static functions */ static Bool xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen, @@ -93,8 +100,6 @@ static inline xp_error xprConfigureWindow(xp_window_id id, unsigned int mask, const xp_window_changes *values) { - TA_SERVER(); - return xp_configure_window(id, mask, values); } @@ -106,8 +111,6 @@ xprSetNativeProperty(RootlessWindowPtr pFrame) unsigned int native_id; long data; - TA_SERVER(); - err = xp_get_native_window(x_cvt_vptr_to_uint(pFrame->wid), &native_id); if (err == Success) { @@ -137,8 +140,6 @@ xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen, unsigned int mask = 0; xp_error err; - TA_SERVER(); - wc.x = newX; wc.y = newY; wc.width = pFrame->width; @@ -186,15 +187,15 @@ xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen, return FALSE; } - if (window_hash == NULL) - { - window_hash = x_hash_table_new(NULL, NULL, NULL, NULL); - pthread_mutex_init(&window_hash_mutex, NULL); - } - +#ifdef HAVE_LIBDISPATCH + dispatch_async(window_hash_serial_q, ^{ + x_hash_table_insert(window_hash, pFrame->wid, pFrame); + }); +#else pthread_mutex_lock(&window_hash_mutex); x_hash_table_insert(window_hash, pFrame->wid, pFrame); pthread_mutex_unlock(&window_hash_mutex); +#endif xprSetNativeProperty(pFrame); @@ -209,11 +210,16 @@ static void xprDestroyFrame(RootlessFrameID wid) { xp_error err; - TA_SERVER(); - + +#ifdef HAVE_LIBDISPATCH + dispatch_async(window_hash_serial_q, ^{ + x_hash_table_remove(window_hash, wid); + }); +#else pthread_mutex_lock(&window_hash_mutex); x_hash_table_remove(window_hash, wid); pthread_mutex_unlock(&window_hash_mutex); +#endif err = xp_destroy_window(x_cvt_vptr_to_uint(wid)); if (err != Success) @@ -229,8 +235,6 @@ xprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY) { xp_window_changes wc; - TA_SERVER(); - wc.x = newX; wc.y = newY; // ErrorF("xprMoveFrame(%d, %p, %d, %d)\n", wid, pScreen, newX, newY); @@ -248,8 +252,6 @@ xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen, { xp_window_changes wc; - TA_SERVER(); - wc.x = newX; wc.y = newY; wc.width = newW; @@ -269,9 +271,11 @@ xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen, static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) { xp_window_changes wc; unsigned int mask = XP_STACKING; +#ifdef HAVE_LIBDISPATCH + __block +#endif + RootlessWindowRec *winRec; - TA_SERVER(); - /* Stack frame below nextWid it if it exists, or raise frame above everything otherwise. */ @@ -283,18 +287,24 @@ static void xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid) { wc.sibling = x_cvt_vptr_to_uint(nextWid); } - if(window_hash) { - RootlessWindowRec *winRec = x_hash_table_lookup(window_hash, wid, NULL); - - if(winRec) { - if(XQuartzIsRootless) - wc.window_level = normal_window_levels[winRec->level]; - else if(XQuartzShieldingWindowLevel) - wc.window_level = XQuartzShieldingWindowLevel + 1; - else - wc.window_level = rooted_window_levels[winRec->level]; - mask |= XP_WINDOW_LEVEL; - } +#ifdef HAVE_LIBDISPATCH + dispatch_sync(window_hash_serial_q, ^{ + winRec = x_hash_table_lookup(window_hash, wid, NULL); + }); +#else + pthread_mutex_lock(&window_hash_mutex); + winRec = x_hash_table_lookup(window_hash, wid, NULL); + pthread_mutex_unlock(&window_hash_mutex); +#endif + + if(winRec) { + if(XQuartzIsRootless) + wc.window_level = normal_window_levels[winRec->level]; + else if(XQuartzShieldingWindowLevel) + wc.window_level = XQuartzShieldingWindowLevel + 1; + else + wc.window_level = rooted_window_levels[winRec->level]; + mask |= XP_WINDOW_LEVEL; } xprConfigureWindow(x_cvt_vptr_to_uint(wid), mask, &wc); @@ -309,8 +319,6 @@ xprReshapeFrame(RootlessFrameID wid, RegionPtr pShape) { xp_window_changes wc; - TA_SERVER(); - if (pShape != NULL) { wc.shape_nrects = RegionNumRects(pShape); @@ -336,8 +344,6 @@ xprUnmapFrame(RootlessFrameID wid) { xp_window_changes wc; - TA_SERVER(); - wc.stack_mode = XP_UNMAPPED; wc.sibling = 0; @@ -356,8 +362,6 @@ xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow) unsigned int rowbytes[2]; xp_error err; - TA_SERVER(); - err = xp_lock_window(x_cvt_vptr_to_uint(wid), NULL, NULL, data, rowbytes, NULL); if (err != Success) FatalError("Could not lock window %i for drawing.", (int)x_cvt_vptr_to_uint(wid)); @@ -374,8 +378,7 @@ static void xprStopDrawing(RootlessFrameID wid, Bool flush) { xp_error err; - TA_SERVER(); - + err = xp_unlock_window(x_cvt_vptr_to_uint(wid), flush); if(err != Success) FatalError("Could not unlock window %i after drawing.", (int)x_cvt_vptr_to_uint(wid)); @@ -388,8 +391,6 @@ xprStopDrawing(RootlessFrameID wid, Bool flush) static void xprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage) { - TA_SERVER(); - xp_flush_window(x_cvt_vptr_to_uint(wid)); } @@ -401,8 +402,6 @@ static void xprDamageRects(RootlessFrameID wid, int nrects, const BoxRec *rects, int shift_x, int shift_y) { - TA_SERVER(); - xp_mark_window(x_cvt_vptr_to_uint(wid), nrects, rects, shift_x, shift_y); } @@ -416,8 +415,6 @@ xprSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin) { DeleteProperty(serverClient, oldWin, xa_native_window_id()); - TA_SERVER(); - xprSetNativeProperty(pFrame); } @@ -429,8 +426,6 @@ static Bool xprDoReorderWindow(RootlessWindowPtr pFrame) { WindowPtr pWin = pFrame->win; - TA_SERVER(); - return AppleWMDoReorderWindow(pWin); } @@ -443,8 +438,6 @@ static void xprCopyWindow(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, int dx, int dy) { - TA_SERVER(); - xp_copy_window(x_cvt_vptr_to_uint(wid), x_cvt_vptr_to_uint(wid), dstNrects, dstRects, dx, dy); } @@ -479,11 +472,16 @@ xprInit(ScreenPtr pScreen) { RootlessInit(pScreen, &xprRootlessProcs); - TA_SERVER(); - rootless_CopyBytes_threshold = xp_copy_bytes_threshold; rootless_CopyWindow_threshold = xp_scroll_area_threshold; + assert((window_hash = x_hash_table_new(NULL, NULL, NULL, NULL))); +#ifdef HAVE_LIBDISPATCH + assert((window_hash_serial_q = dispatch_queue_create(BUNDLE_ID_PREFIX".X11.xpr_window_hash", NULL))); +#else + assert(0 == pthread_mutex_init(&window_hash_mutex, NULL)); +#endif + return TRUE; } @@ -495,73 +493,36 @@ xprInit(ScreenPtr pScreen) WindowPtr xprGetXWindow(xp_window_id wid) { +#ifdef HAVE_LIBDISPATCH + RootlessWindowRec *winRec __block; + dispatch_sync(window_hash_serial_q, ^{ + winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL); + }); +#else RootlessWindowRec *winRec; - - if (window_hash == NULL) - return NULL; - - winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL); - - return winRec != NULL ? winRec->win : NULL; -} - -#ifdef UNUSED_CODE -/* - * Given the id of a physical window, try to find the top-level (or root) - * X window that it represents. - */ -WindowPtr -xprGetXWindowFromAppKit(int windowNumber) -{ - RootlessWindowRec *winRec; - Bool ret; - xp_window_id wid; - - if (window_hash == NULL) - return FALSE; - - /* need to lock, since this function can be called by any thread */ - pthread_mutex_lock(&window_hash_mutex); - - if (xp_lookup_native_window(windowNumber, &wid)) - ret = xprGetXWindow(wid) != NULL; - else - ret = FALSE; - - pthread_mutex_unlock(&window_hash_mutex); - - if (!ret) return NULL; winRec = x_hash_table_lookup(window_hash, x_cvt_uint_to_vptr(wid), NULL); + pthread_mutex_unlock(&window_hash_mutex); +#endif return winRec != NULL ? winRec->win : NULL; } -#endif /* * The windowNumber is an AppKit window number. Returns TRUE if xpr is * displaying a window with that number. */ Bool -xprIsX11Window(void *nsWindow, int windowNumber) +xprIsX11Window(int windowNumber) { Bool ret; xp_window_id wid; - if (window_hash == NULL) - return FALSE; - - /* need to lock, since this function can be called by any thread */ - - pthread_mutex_lock(&window_hash_mutex); - if (xp_lookup_native_window(windowNumber, &wid)) ret = xprGetXWindow(wid) != NULL; else ret = FALSE; - pthread_mutex_unlock(&window_hash_mutex); - return ret; } @@ -578,8 +539,6 @@ xprHideWindows(Bool hide) int screen; WindowPtr pRoot, pWin; - TA_SERVER(); - for (screen = 0; screen < screenInfo.numScreens; screen++) { RootlessFrameID prevWid = NULL; pRoot = screenInfo.screens[screen]->root; diff --git a/xorg-server/hw/xwin/InitOutput.c b/xorg-server/hw/xwin/InitOutput.c index 7faed0170..22ef8da76 100644 --- a/xorg-server/hw/xwin/InitOutput.c +++ b/xorg-server/hw/xwin/InitOutput.c @@ -49,7 +49,7 @@ from The Open Group. #endif #ifdef RELOCATE_PROJECTROOT #include <shlobj.h> -typedef HRESULT (*SHGETFOLDERPATHPROC)( +typedef WINAPI HRESULT (*SHGETFOLDERPATHPROC)( HWND hwndOwner, int nFolder, HANDLE hToken, diff --git a/xorg-server/hw/xwin/man/XWin.man b/xorg-server/hw/xwin/man/XWin.man index e7933c9c8..aad29cf25 100644 --- a/xorg-server/hw/xwin/man/XWin.man +++ b/xorg-server/hw/xwin/man/XWin.man @@ -67,7 +67,7 @@ The default behaviour is to create a single screen 0 that is roughly the size of useful area of the primary monitor (allowing for any window decorations and the task-bar). -Screen specific parameters, such as \fB\-fullscreen\fP, can be applied as a +Screen specific parameters can be applied as a default to all screens by placing those screen specific parameters before any \fB\-screen\fP parameter. Screen specific parameters placed after the first \fB\-screen\fP parameter will apply only to the immediately @@ -108,6 +108,7 @@ in \fB-multiwindow\fP or \fB-rootless\fP mode. .B "\-fullscreen" The X server window takes the full screen, covering completely the \fIWindows\fP desktop. +Currently \fB\-fullscreen\fP may only be applied to one X screen. .TP 8 .B \-nodecoration Do not give the Cygwin/X window a \fIWindows\fP window border, title bar, diff --git a/xorg-server/hw/xwin/win.h b/xorg-server/hw/xwin/win.h index e57cb4fa2..9bee9b64f 100644 --- a/xorg-server/hw/xwin/win.h +++ b/xorg-server/hw/xwin/win.h @@ -1,1491 +1,1490 @@ -/*
- *Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from the XFree86 Project.
- *
- * Authors: Dakshinamurthy Karra
- * Suhaib M Siddiqi
- * Peter Busch
- * Harold L Hunt II
- * Kensuke Matsuzaki
- */
-
-#ifndef _WIN_H_
-#define _WIN_H_
-
-#ifndef NO
-#define NO 0
-#endif
-#ifndef YES
-#define YES 1
-#endif
-
-/* Turn debug messages on or off */
-#ifndef CYGDEBUG
-#define CYGDEBUG NO
-#endif
-
-/* WM_XBUTTON Messages. They should go into w32api. */
-#ifndef WM_XBUTTONDOWN
-# define WM_XBUTTONDOWN 523
-#endif
-#ifndef WM_XBUTTONUP
-# define WM_XBUTTONUP 524
-#endif
-#ifndef WM_XBUTTONDBLCLK
-# define WM_XBUTTONDBLCLK 525
-#endif
-
-
-#define WIN_DEFAULT_BPP 0
-#define WIN_DEFAULT_WHITEPIXEL 255
-#define WIN_DEFAULT_BLACKPIXEL 0
-#define WIN_DEFAULT_LINEBIAS 0
-#define WIN_DEFAULT_E3B_TIME 50 /* milliseconds */
-#define WIN_DEFAULT_DPI 75
-#define WIN_DEFAULT_REFRESH 0
-#define WIN_DEFAULT_WIN_KILL TRUE
-#define WIN_DEFAULT_UNIX_KILL FALSE
-#define WIN_DEFAULT_CLIP_UPDATES_NBOXES 0
-#ifdef XWIN_EMULATEPSEUDO
-#define WIN_DEFAULT_EMULATE_PSEUDO FALSE
-#endif
-#define WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH FALSE
-
-/*
- * Windows only supports 256 color palettes
- */
-#define WIN_NUM_PALETTE_ENTRIES 256
-
-/*
- * Number of times to call Restore in an attempt to restore the primary surface
- */
-#define WIN_REGAIN_SURFACE_RETRIES 1
-
-/*
- * Build a supported display depths mask by shifting one to the left
- * by the number of bits in the supported depth.
- */
-#define WIN_SUPPORTED_BPPS ( (1 << (32 - 1)) | (1 << (24 - 1)) \
- | (1 << (16 - 1)) | (1 << (15 - 1)) \
- | (1 << ( 8 - 1)))
-#define WIN_CHECK_DEPTH YES
-
-/*
- * Timer IDs for WM_TIMER
- */
-#define WIN_E3B_TIMER_ID 1
-#define WIN_POLLING_MOUSE_TIMER_ID 2
-
-#define MOUSE_POLLING_INTERVAL 50
-
-#define WIN_E3B_OFF -1
-#define WIN_FD_INVALID -1
-
-#define WIN_SERVER_NONE 0x0L /* 0 */
-#define WIN_SERVER_SHADOW_GDI 0x1L /* 1 */
-#define WIN_SERVER_SHADOW_DD 0x2L /* 2 */
-#define WIN_SERVER_SHADOW_DDNL 0x4L /* 4 */
-#ifdef XWIN_PRIMARYFB
-#define WIN_SERVER_PRIMARY_DD 0x8L /* 8 */
-#endif
-#ifdef XWIN_NATIVEGDI
-# define WIN_SERVER_NATIVE_GDI 0x10L /* 16 */
-#endif
-
-#define AltMapIndex Mod1MapIndex
-#define NumLockMapIndex Mod2MapIndex
-#define AltLangMapIndex Mod3MapIndex
-#define KanaMapIndex Mod4MapIndex
-#define ScrollLockMapIndex Mod5MapIndex
-
-#define WIN_MOD_LALT 0x00000001
-#define WIN_MOD_RALT 0x00000002
-#define WIN_MOD_LCONTROL 0x00000004
-#define WIN_MOD_RCONTROL 0x00000008
-
-#define WIN_24BPP_MASK_RED 0x00FF0000
-#define WIN_24BPP_MASK_GREEN 0x0000FF00
-#define WIN_24BPP_MASK_BLUE 0x000000FF
-
-#define WIN_MAX_KEYS_PER_KEY 4
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-
-#include <errno.h>
-#if defined(XWIN_MULTIWINDOWEXTWM) || defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
-#define HANDLE void *
-#include <pthread.h>
-#undef HANDLE
-#endif
-
-#ifdef HAS_MMAP
-#include <sys/mman.h>
-#ifndef MAP_FILE
-#define MAP_FILE 0
-#endif /* MAP_FILE */
-#endif /* HAS_MMAP */
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/Xos.h>
-#include <X11/Xprotostr.h>
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "pixmap.h"
-#include "region.h"
-#include "gcstruct.h"
-#include "colormap.h"
-#include "colormapst.h"
-#include "miscstruct.h"
-#include "servermd.h"
-#include "windowstr.h"
-#include "mi.h"
-#include "micmap.h"
-#include "mifillarc.h"
-#include "mifpoly.h"
-#include "mibstore.h"
-#include "input.h"
-#include "mipointer.h"
-#include "X11/keysym.h"
-#include "mibstore.h"
-#include "micoord.h"
-#include "dix.h"
-#include "miline.h"
-#include "shadow.h"
-#include "fb.h"
-#include "rootless.h"
-
-#include "mipict.h"
-#include "picturestr.h"
-
-#ifdef RANDR
-#include "randrstr.h"
-#endif
-
-/*
- * Windows headers
- */
-#include "winms.h"
-#include "winresource.h"
-
-
-/*
- * Define Windows constants
- */
-
-#define WM_TRAYICON (WM_USER + 1000)
-#define WM_INIT_SYS_MENU (WM_USER + 1001)
-#define WM_GIVEUP (WM_USER + 1002)
-
-
-/* Local includes */
-#include "winwindow.h"
-#include "winmsg.h"
-
-
-/*
- * Debugging macros
- */
-
-#if CYGDEBUG
-#define DEBUG_MSG(str,...) \
-if (fDebugProcMsg) \
-{ \
- char *pszTemp; \
- int iLength; \
- if (asprintf (&pszTemp, str, ##__VA_ARGS__) != -1) { \
- MessageBox (NULL, pszTemp, szFunctionName, MB_OK); \
- free (pszTemp); \
- } \
-}
-#else
-#define DEBUG_MSG(str,...)
-#endif
-
-#if CYGDEBUG
-#define DEBUG_FN_NAME(str) PTSTR szFunctionName = str
-#else
-#define DEBUG_FN_NAME(str)
-#endif
-
-#if CYGDEBUG || YES
-#define DEBUGVARS BOOL fDebugProcMsg = FALSE
-#else
-#define DEBUGVARS
-#endif
-
-#if CYGDEBUG || YES
-#define DEBUGPROC_MSG fDebugProcMsg = TRUE
-#else
-#define DEBUGPROC_MSG
-#endif
-
-#define PROFILEPOINT(point,thresh)\
-{\
-static unsigned int PROFPT##point = 0;\
-if (++PROFPT##point % thresh == 0)\
-ErrorF (#point ": PROFILEPOINT hit %u times\n", PROFPT##point);\
-}
-
-
-/* We use xor this macro for detecting toggle key state changes */
-#define WIN_XOR(a,b) ((!(a) && (b)) || ((a) && !(b)))
-
-#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; \
-}
-
-/*
- * Typedefs for engine dependent function pointers
- */
-
-typedef Bool (*winAllocateFBProcPtr)(ScreenPtr);
-
-typedef void (*winFreeFBProcPtr)(ScreenPtr);
-
-typedef void (*winShadowUpdateProcPtr)(ScreenPtr, shadowBufPtr);
-
-typedef Bool (*winInitScreenProcPtr)(ScreenPtr);
-
-typedef Bool (*winCloseScreenProcPtr)(int, ScreenPtr);
-
-typedef Bool (*winInitVisualsProcPtr)(ScreenPtr);
-
-typedef Bool (*winAdjustVideoModeProcPtr)(ScreenPtr);
-
-typedef Bool (*winCreateBoundingWindowProcPtr)(ScreenPtr);
-
-typedef Bool (*winFinishScreenInitProcPtr)(int, ScreenPtr, int, char **);
-
-typedef Bool (*winBltExposedRegionsProcPtr)(ScreenPtr);
-
-typedef Bool (*winActivateAppProcPtr)(ScreenPtr);
-
-typedef Bool (*winRedrawScreenProcPtr)(ScreenPtr pScreen);
-
-typedef Bool (*winRealizeInstalledPaletteProcPtr)(ScreenPtr pScreen);
-
-typedef Bool (*winInstallColormapProcPtr)(ColormapPtr pColormap);
-
-typedef Bool (*winStoreColorsProcPtr)(ColormapPtr pmap,
- int ndef, xColorItem *pdefs);
-
-typedef Bool (*winCreateColormapProcPtr)(ColormapPtr pColormap);
-
-typedef Bool (*winDestroyColormapProcPtr)(ColormapPtr pColormap);
-
-typedef Bool (*winHotKeyAltTabProcPtr)(ScreenPtr);
-
-typedef Bool (*winCreatePrimarySurfaceProcPtr)(ScreenPtr);
-
-typedef Bool (*winReleasePrimarySurfaceProcPtr)(ScreenPtr);
-
-typedef Bool (*winFinishCreateWindowsWindowProcPtr)(WindowPtr pWin);
-
-typedef Bool (*winCreateScreenResourcesProc)(ScreenPtr);
-
-#ifdef XWIN_NATIVEGDI
-/* Typedefs for native GDI wrappers */
-typedef Bool (*RealizeFontPtr) (ScreenPtr pScreen, FontPtr pFont);
-typedef Bool (*UnrealizeFontPtr)(ScreenPtr pScreen, FontPtr pFont);
-#endif
-
-
-/*
- * GC (graphics context) privates
- */
-
-typedef struct
-{
- HDC hdc;
- HDC hdcMem;
-} winPrivGCRec, *winPrivGCPtr;
-
-
-/*
- * Pixmap privates
- */
-
-typedef struct
-{
- HDC hdcSelected;
- HBITMAP hBitmap;
- BYTE *pbBits;
- DWORD dwScanlineBytes;
- BITMAPINFOHEADER *pbmih;
-} winPrivPixmapRec, *winPrivPixmapPtr;
-
-
-/*
- * Colormap privates
- */
-
-typedef struct
-{
- HPALETTE hPalette;
- LPDIRECTDRAWPALETTE lpDDPalette;
- RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES];
- PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES];
-} winPrivCmapRec, *winPrivCmapPtr;
-
-/*
- * Windows Cursor handling.
- */
-
-typedef struct {
- /* from GetSystemMetrics */
- int sm_cx;
- int sm_cy;
-
- BOOL visible;
- HCURSOR handle;
- QueryBestSizeProcPtr QueryBestSize;
- miPointerSpriteFuncPtr spriteFuncs;
-} winCursorRec;
-
-/*
- * Resize modes
- */
-typedef enum {
- notAllowed,
- resizeWithScrollbars,
- resizeWithRandr
-} winResizeMode;
-
-/*
- * Screen information structure that we need before privates are available
- * in the server startup sequence.
- */
-
-typedef struct
-{
- ScreenPtr pScreen;
-
- /* Did the user specify a height and width? */
- Bool fUserGaveHeightAndWidth;
-
- DWORD dwScreen;
-
- int iMonitor;
- DWORD dwUserWidth;
- DWORD dwUserHeight;
- DWORD dwWidth;
- DWORD dwHeight;
- DWORD dwPaddedWidth;
-
- /* Did the user specify a screen position? */
- Bool fUserGavePosition;
- DWORD dwInitialX;
- DWORD dwInitialY;
-
- /*
- * dwStride is the number of whole pixels that occupy a scanline,
- * including those pixels that are not displayed. This is basically
- * a rounding up of the width.
- */
- DWORD dwStride;
-
- /* Offset of the screen in the window when using scrollbars */
- DWORD dwXOffset;
- DWORD dwYOffset;
-
- DWORD dwBPP;
- DWORD dwDepth;
- DWORD dwRefreshRate;
- char *pfb;
- DWORD dwEngine;
- DWORD dwEnginePreferred;
- DWORD dwClipUpdatesNBoxes;
-#ifdef XWIN_EMULATEPSEUDO
- Bool fEmulatePseudo;
-#endif
- Bool fFullScreen;
- Bool fDecoration;
-#ifdef XWIN_MULTIWINDOWEXTWM
- Bool fMWExtWM;
- Bool fInternalWM;
- Bool fAnotherWMRunning;
-#endif
- Bool fRootless;
-#ifdef XWIN_MULTIWINDOW
- Bool fMultiWindow;
-#endif
-#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
- Bool fMultiMonitorOverride;
-#endif
- Bool fMultipleMonitors;
- Bool fLessPointer;
- winResizeMode iResizeMode;
- Bool fNoTrayIcon;
- int iE3BTimeout;
- /* Windows (Alt+F4) and Unix (Ctrl+Alt+Backspace) Killkey */
- Bool fUseWinKillKey;
- Bool fUseUnixKillKey;
- Bool fIgnoreInput;
-
- /* Did the user explicitly set this screen? */
- Bool fExplicitScreen;
-} winScreenInfo, *winScreenInfoPtr;
-
-
-/*
- * Screen privates
- */
-
-typedef struct _winPrivScreenRec
-{
- winScreenInfoPtr pScreenInfo;
-
- Bool fEnabled;
- Bool fClosed;
- Bool fActive;
- Bool fBadDepth;
-
- int iDeltaZ;
-
- int iConnectedClients;
-
- CloseScreenProcPtr CloseScreen;
-
- DWORD dwRedMask;
- DWORD dwGreenMask;
- DWORD dwBlueMask;
- DWORD dwBitsPerRGB;
-
- DWORD dwModeKeyStates;
-
- /* Handle to icons that must be freed */
- HICON hiconNotifyIcon;
-
- /* Palette management */
- ColormapPtr pcmapInstalled;
-
- /* Pointer to the root visual so we only have to look it up once */
- VisualPtr pRootVisual;
-
- /* 3 button emulation variables */
- int iE3BCachedPress;
- Bool fE3BFakeButton2Sent;
-
- /* Privates used by shadow fb GDI server */
- HBITMAP hbmpShadow;
- HDC hdcScreen;
- HDC hdcShadow;
- HWND hwndScreen;
- BITMAPINFOHEADER *pbmih;
-
- /* Privates used by shadow fb and primary fb DirectDraw servers */
- LPDIRECTDRAW pdd;
- LPDIRECTDRAWSURFACE2 pddsPrimary;
- LPDIRECTDRAW2 pdd2;
-
- /* Privates used by shadow fb DirectDraw server */
- LPDIRECTDRAWSURFACE2 pddsShadow;
- LPDDSURFACEDESC pddsdShadow;
-
- /* Privates used by primary fb DirectDraw server */
- LPDIRECTDRAWSURFACE2 pddsOffscreen;
- LPDDSURFACEDESC pddsdOffscreen;
- LPDDSURFACEDESC pddsdPrimary;
-
- /* Privates used by shadow fb DirectDraw Nonlocking server */
- LPDIRECTDRAW4 pdd4;
- LPDIRECTDRAWSURFACE4 pddsShadow4;
- LPDIRECTDRAWSURFACE4 pddsPrimary4;
- BOOL fRetryCreateSurface;
-
- /* Privates used by both shadow fb DirectDraw servers */
- LPDIRECTDRAWCLIPPER pddcPrimary;
-
-#ifdef XWIN_MULTIWINDOWEXTWM
- /* Privates used by multi-window external window manager */
- RootlessFrameID widTop;
- Bool fRestacking;
-#endif
-
-#ifdef XWIN_MULTIWINDOW
- /* Privates used by multi-window */
- pthread_t ptWMProc;
- pthread_t ptXMsgProc;
- void *pWMInfo;
-#endif
-
-#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
- /* Privates used by both multi-window and rootless */
- Bool fRootWindowShown;
-#endif
-
-#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
- /* Privates used for any module running in a seperate thread */
- pthread_mutex_t pmServerStarted;
- Bool fServerStarted;
-#endif
-
- /* Engine specific functions */
- winAllocateFBProcPtr pwinAllocateFB;
- winFreeFBProcPtr pwinFreeFB;
- winShadowUpdateProcPtr pwinShadowUpdate;
- winInitScreenProcPtr pwinInitScreen;
- winCloseScreenProcPtr pwinCloseScreen;
- winInitVisualsProcPtr pwinInitVisuals;
- winAdjustVideoModeProcPtr pwinAdjustVideoMode;
- winCreateBoundingWindowProcPtr pwinCreateBoundingWindow;
- winFinishScreenInitProcPtr pwinFinishScreenInit;
- winBltExposedRegionsProcPtr pwinBltExposedRegions;
- winActivateAppProcPtr pwinActivateApp;
- winRedrawScreenProcPtr pwinRedrawScreen;
- winRealizeInstalledPaletteProcPtr pwinRealizeInstalledPalette;
- winInstallColormapProcPtr pwinInstallColormap;
- winStoreColorsProcPtr pwinStoreColors;
- winCreateColormapProcPtr pwinCreateColormap;
- winDestroyColormapProcPtr pwinDestroyColormap;
- winHotKeyAltTabProcPtr pwinHotKeyAltTab;
- winCreatePrimarySurfaceProcPtr pwinCreatePrimarySurface;
- winReleasePrimarySurfaceProcPtr pwinReleasePrimarySurface;
-
- winCreateScreenResourcesProc pwinCreateScreenResources;
-
-#ifdef XWIN_MULTIWINDOW
- /* Window Procedures for MultiWindow mode */
- winFinishCreateWindowsWindowProcPtr pwinFinishCreateWindowsWindow;
-#endif
-
- /* Window Procedures for Rootless mode */
- CreateWindowProcPtr CreateWindow;
- DestroyWindowProcPtr DestroyWindow;
- PositionWindowProcPtr PositionWindow;
- ChangeWindowAttributesProcPtr ChangeWindowAttributes;
- RealizeWindowProcPtr RealizeWindow;
- UnrealizeWindowProcPtr UnrealizeWindow;
- ValidateTreeProcPtr ValidateTree;
- PostValidateTreeProcPtr PostValidateTree;
- WindowExposuresProcPtr WindowExposures;
- CopyWindowProcPtr CopyWindow;
- ClearToBackgroundProcPtr ClearToBackground;
- ClipNotifyProcPtr ClipNotify;
- RestackWindowProcPtr RestackWindow;
- ReparentWindowProcPtr ReparentWindow;
- ResizeWindowProcPtr ResizeWindow;
- MoveWindowProcPtr MoveWindow;
- SetShapeProcPtr SetShape;
-
- winCursorRec cursor;
-
-#ifdef XWIN_NATIVEGDI
- RealizeFontPtr RealizeFont;
- UnrealizeFontPtr UnrealizeFont;
-#endif
-
-} winPrivScreenRec;
-
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-typedef struct {
- RootlessWindowPtr pFrame;
- HWND hWnd;
- int dwWidthBytes;
- BITMAPINFOHEADER *pbmihShadow;
- HBITMAP hbmpShadow;
- HDC hdcShadow;
- HDC hdcScreen;
- BOOL fResized;
- BOOL fRestackingNow;
- BOOL fClose;
- BOOL fMovingOrSizing;
- BOOL fDestroyed;//for debug
- char *pfb;
-} win32RootlessWindowRec, *win32RootlessWindowPtr;
-#endif
-
-
-typedef struct {
- pointer value;
- XID id;
-} WindowIDPairRec, *WindowIDPairPtr;
-
-
-/*
- * Extern declares for general global variables
- */
-
-#include "winglobals.h"
-
-extern winScreenInfo * g_ScreenInfo;
-extern miPointerScreenFuncRec g_winPointerCursorFuncs;
-extern DWORD g_dwEvents;
-#ifdef HAS_DEVWINDOWS
-extern int g_fdMessageQueue;
-#endif
-extern DevPrivateKeyRec g_iScreenPrivateKeyRec;
-#define g_iScreenPrivateKey (&g_iScreenPrivateKeyRec)
-extern DevPrivateKeyRec g_iCmapPrivateKeyRec;
-#define g_iCmapPrivateKey (&g_iCmapPrivateKeyRec)
-extern DevPrivateKeyRec g_iGCPrivateKeyRec;
-#define g_iGCPrivateKey (&g_iGCPrivateKeyRec)
-extern DevPrivateKeyRec g_iPixmapPrivateKeyRec;
-#define g_iPixmapPrivateKey (&g_iPixmapPrivateKeyRec)
-extern DevPrivateKeyRec g_iWindowPrivateKeyRec;
-#define g_iWindowPrivateKey (&g_iWindowPrivateKeyRec)
-
-extern unsigned long g_ulServerGeneration;
-extern DWORD g_dwEnginesSupported;
-extern HINSTANCE g_hInstance;
-extern int g_copyROP[];
-extern int g_patternROP[];
-extern const char * g_pszQueryHost;
-extern DeviceIntPtr g_pwinPointer;
-extern DeviceIntPtr g_pwinKeyboard;
-
-/*
- * Extern declares for dynamically loaded library function pointers
- */
-
-extern FARPROC g_fpDirectDrawCreate;
-extern FARPROC g_fpDirectDrawCreateClipper;
-extern FARPROC g_fpTrackMouseEvent;
-
-
-/*
- * Screen privates macros
- */
-
-#define winGetScreenPriv(pScreen) ((winPrivScreenPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey))
-
-#define winSetScreenPriv(pScreen,v) \
- dixSetPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey, v)
-
-#define winScreenPriv(pScreen) \
- winPrivScreenPtr pScreenPriv = winGetScreenPriv(pScreen)
-
-
-/*
- * Colormap privates macros
- */
-
-#define winGetCmapPriv(pCmap) ((winPrivCmapPtr) \
- dixLookupPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey))
-
-#define winSetCmapPriv(pCmap,v) \
- dixSetPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey, v)
-
-#define winCmapPriv(pCmap) \
- winPrivCmapPtr pCmapPriv = winGetCmapPriv(pCmap)
-
-
-/*
- * GC privates macros
- */
-
-#define winGetGCPriv(pGC) ((winPrivGCPtr) \
- dixLookupPrivate(&(pGC)->devPrivates, g_iGCPrivateKey))
-
-#define winSetGCPriv(pGC,v) \
- dixSetPrivate(&(pGC)->devPrivates, g_iGCPrivateKey, v)
-
-#define winGCPriv(pGC) \
- winPrivGCPtr pGCPriv = winGetGCPriv(pGC)
-
-
-/*
- * Pixmap privates macros
- */
-
-#define winGetPixmapPriv(pPixmap) ((winPrivPixmapPtr) \
- dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey))
-
-#define winSetPixmapPriv(pPixmap,v) \
- dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey, v)
-
-#define winPixmapPriv(pPixmap) \
- winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap)
-
-
-/*
- * Window privates macros
- */
-
-#define winGetWindowPriv(pWin) ((winPrivWinPtr) \
- dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey))
-
-#define winSetWindowPriv(pWin,v) \
- dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey, v)
-
-#define winWindowPriv(pWin) \
- winPrivWinPtr pWinPriv = winGetWindowPriv(pWin)
-
-/*
- * wrapper macros
- */
-#define _WIN_WRAP(priv, real, mem, func) {\
- priv->mem = real->mem; \
- real->mem = func; \
-}
-
-#define _WIN_UNWRAP(priv, real, mem) {\
- real->mem = priv->mem; \
-}
-
-#define WIN_WRAP(mem, func) _WIN_WRAP(pScreenPriv, pScreen, mem, func)
-
-#define WIN_UNWRAP(mem) _WIN_UNWRAP(pScreenPriv, pScreen, mem)
-
-/*
- * BEGIN DDX and DIX Function Prototypes
- */
-
-
-/*
- * winallpriv.c
- */
-
-Bool
-winAllocatePrivates (ScreenPtr pScreen);
-
-Bool
-winInitCmapPrivates (ColormapPtr pCmap, int index);
-
-Bool
-winAllocateCmapPrivates (ColormapPtr pCmap);
-
-
-/*
- * winauth.c
- */
-
-#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
-Bool
-winGenerateAuthorization (void);
-void winSetAuthorization(void);
-#endif
-
-
-/*
- * winblock.c
- */
-
-void
-winBlockHandler (int nScreen,
- pointer pBlockData,
- pointer pTimeout,
- pointer pReadMask);
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winclip.c
- */
-
-RegionPtr
-winPixmapToRegionNativeGDI (PixmapPtr pPix);
-#endif
-
-
-#ifdef XWIN_CLIPBOARD
-/*
- * winclipboardinit.c
- */
-
-Bool
-winInitClipboard (void);
-
-void
-winFixClipboardChain (void);
-#endif
-
-
-/*
- * wincmap.c
- */
-
-void
-winSetColormapFunctions (ScreenPtr pScreen);
-
-Bool
-winCreateDefColormap (ScreenPtr pScreen);
-
-
-/*
- * wincreatewnd.c
- */
-
-Bool
-winCreateBoundingWindowFullScreen (ScreenPtr pScreen);
-
-Bool
-winCreateBoundingWindowWindowed (ScreenPtr pScreen);
-
-
-/*
- * windialogs.c
- */
-
-void
-winDisplayExitDialog (winPrivScreenPtr pScreenPriv);
-
-void
-winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv);
-
-void
-winDisplayAboutDialog (winPrivScreenPtr pScreenPriv);
-
-
-/*
- * winengine.c
- */
-
-void
-winDetectSupportedEngines (void);
-
-Bool
-winSetEngine (ScreenPtr pScreen);
-
-Bool
-winGetDDProcAddresses (void);
-
-void
-winReleaseDDProcAddresses(void);
-
-
-/*
- * winerror.c
- */
-
-#ifdef DDXOSVERRORF
-void
-OSVenderVErrorF (const char *pszFormat, va_list va_args);
-#endif
-
-void
-winMessageBoxF (const char *pszError, UINT uType, ...);
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winfillsp.c
- */
-
-void
-winFillSpansNativeGDI (DrawablePtr pDrawable,
- GCPtr pGC,
- int nSpans,
- DDXPointPtr pPoints,
- int *pWidths,
- int fSorted);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winfont.c
- */
-
-Bool
-winRealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont);
-
-Bool
-winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * wingc.c
- */
-
-Bool
-winCreateGCNativeGDI (GCPtr pGC);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * wingetsp.c
- */
-
-void
-winGetSpansNativeGDI (DrawablePtr pDrawable,
- int wMax,
- DDXPointPtr pPoints,
- int *pWidths,
- int nSpans,
- char *pDst);
-#endif
-
-
-/*
- * winglobals.c
- */
-
-void
-winInitializeGlobals (void);
-
-
-/*
- * winkeybd.c
- */
-
-void
-winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode);
-
-int
-winKeybdProc (DeviceIntPtr pDeviceInt, int iState);
-
-void
-winInitializeModeKeyStates (void);
-
-void
-winRestoreModeKeyStates (void);
-
-Bool
-winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam);
-
-void
-winKeybdReleaseKeys (void);
-
-void
-winSendKeyEvent (DWORD dwKey, Bool fDown);
-
-BOOL
-winCheckKeyPressed(WPARAM wParam, LPARAM lParam);
-
-void
-winFixShiftKeys (int iScanCode);
-
-/*
- * winkeyhook.c
- */
-
-Bool
-winInstallKeyboardHookLL (void);
-
-void
-winRemoveKeyboardHookLL (void);
-
-
-/*
- * winmisc.c
- */
-
-#ifdef XWIN_NATIVEGDI
-void
-winQueryBestSizeNativeGDI (int class, unsigned short *pWidth,
- unsigned short *pHeight, ScreenPtr pScreen);
-#endif
-
-CARD8
-winCountBits (DWORD dw);
-
-Bool
-winUpdateFBPointer (ScreenPtr pScreen, void *pbits);
-
-#ifdef XWIN_NATIVEGDI
-BOOL
-winPaintBackground (HWND hwnd, COLORREF colorref);
-#endif
-
-
-/*
- * winmouse.c
- */
-
-int
-winMouseProc (DeviceIntPtr pDeviceInt, int iState);
-
-int
-winMouseWheel (ScreenPtr pScreen, int iDeltaZ);
-
-void
-winMouseButtonsSendEvent (int iEventType, int iButton);
-
-int
-winMouseButtonsHandle (ScreenPtr pScreen,
- int iEventType, int iButton,
- WPARAM wParam);
-
-void
-winEnqueueMotion(int x, int y);
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winnativegdi.c
- */
-
-HBITMAP
-winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth,
- BYTE **ppbBits, BITMAPINFO **ppbmi);
-
-Bool
-winSetEngineFunctionsNativeGDI (ScreenPtr pScreen);
-#endif
-
-
-#ifdef XWIN_PRIMARYFB
-/*
- * winpfbddd.c
- */
-
-Bool
-winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winpixmap.c
- */
-
-PixmapPtr
-winCreatePixmapNativeGDI (ScreenPtr pScreen, int width, int height, int depth,
- unsigned usage_hint);
-
-Bool
-winDestroyPixmapNativeGDI (PixmapPtr pPixmap);
-
-Bool
-winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap,
- int iWidth, int iHeight,
- int iDepth,
- int iBitsPerPixel,
- int devKind,
- pointer pPixData);
-#endif
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winpolyline.c
- */
-
-void
-winPolyLineNativeGDI (DrawablePtr pDrawable,
- GCPtr pGC,
- int mode,
- int npt,
- DDXPointPtr ppt);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winpushpxl.c
- */
-
-void
-winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable,
- int dx, int dy, int xOrg, int yOrg);
-#endif
-
-
-/*
- * winscrinit.c
- */
-
-Bool
-winScreenInit (int index,
- ScreenPtr pScreen,
- int argc, char **argv);
-
-Bool
-winFinishScreenInitFB (int index,
- ScreenPtr pScreen,
- int argc, char **argv);
-
-#if defined(XWIN_NATIVEGDI)
-Bool
-winFinishScreenInitNativeGDI (int index,
- ScreenPtr pScreen,
- int argc, char **argv);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winsetsp.c
- */
-
-void
-winSetSpansNativeGDI (DrawablePtr pDrawable,
- GCPtr pGC,
- char *pSrc,
- DDXPointPtr pPoints,
- int *pWidth,
- int nSpans,
- int fSorted);
-#endif
-
-
-/*
- * winshaddd.c
- */
-
-Bool
-winSetEngineFunctionsShadowDD (ScreenPtr pScreen);
-
-
-/*
- * winshadddnl.c
- */
-
-Bool
-winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen);
-
-
-/*
- * winshadgdi.c
- */
-
-Bool
-winSetEngineFunctionsShadowGDI (ScreenPtr pScreen);
-
-
-/*
- * winwakeup.c
- */
-
-void
-winWakeupHandler (int nScreen,
- pointer pWakeupData,
- unsigned long ulResult,
- pointer pReadmask);
-
-
-/*
- * winwindow.c
- */
-
-#ifdef XWIN_NATIVEGDI
-Bool
-winCreateWindowNativeGDI (WindowPtr pWin);
-
-Bool
-winDestroyWindowNativeGDI (WindowPtr pWin);
-
-Bool
-winPositionWindowNativeGDI (WindowPtr pWin, int x, int y);
-
-void
-winCopyWindowNativeGDI (WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgnSrc);
-
-Bool
-winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask);
-
-Bool
-winUnmapWindowNativeGDI (WindowPtr pWindow);
-
-Bool
-winMapWindowNativeGDI (WindowPtr pWindow);
-#endif
-
-Bool
-winCreateWindowRootless (WindowPtr pWindow);
-
-Bool
-winDestroyWindowRootless (WindowPtr pWindow);
-
-Bool
-winPositionWindowRootless (WindowPtr pWindow, int x, int y);
-
-Bool
-winChangeWindowAttributesRootless (WindowPtr pWindow, unsigned long mask);
-
-Bool
-winUnmapWindowRootless (WindowPtr pWindow);
-
-Bool
-winMapWindowRootless (WindowPtr pWindow);
-
-void
-winSetShapeRootless (WindowPtr pWindow, int kind);
-
-
-/*
- * winmultiwindowicons.c - Used by both multi-window and Win32Rootless
- */
-
-HICON
-winXIconToHICON (WindowPtr pWin, int iconSize);
-
-void
-winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon);
-
-#ifdef XWIN_MULTIWINDOW
-/*
- * winmultiwindowshape.c
- */
-
-void
-winReshapeMultiWindow (WindowPtr pWin);
-
-void
-winSetShapeMultiWindow (WindowPtr pWindow, int kind);
-
-void
-winUpdateRgnMultiWindow (WindowPtr pWindow);
-#endif
-
-
-#ifdef XWIN_MULTIWINDOW
-/*
- * winmultiwindowwindow.c
- */
-
-Bool
-winCreateWindowMultiWindow (WindowPtr pWindow);
-
-Bool
-winDestroyWindowMultiWindow (WindowPtr pWindow);
-
-Bool
-winPositionWindowMultiWindow (WindowPtr pWindow, int x, int y);
-
-Bool
-winChangeWindowAttributesMultiWindow (WindowPtr pWindow, unsigned long mask);
-
-Bool
-winUnmapWindowMultiWindow (WindowPtr pWindow);
-
-Bool
-winMapWindowMultiWindow (WindowPtr pWindow);
-
-void
-winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent);
-
-void
-winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib);
-
-void
-winReorderWindowsMultiWindow (void);
-
-void
-winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w,
- unsigned int h, WindowPtr pSib);
-void
-winMoveWindowMultiWindow (WindowPtr pWin, int x, int y,
- WindowPtr pSib, VTKind kind);
-
-void
-winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt,
- RegionPtr oldRegion);
-
-XID
-winGetWindowID (WindowPtr pWin);
-
-int
-winAdjustXWindow (WindowPtr pWin, HWND hwnd);
-#endif
-
-
-#ifdef XWIN_MULTIWINDOW
-/*
- * winmultiwindowwndproc.c
- */
-
-LRESULT CALLBACK
-winTopLevelWindowProc (HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam);
-#endif
-
-
-/*
- * wintrayicon.c
- */
-
-void
-winInitNotifyIcon (winPrivScreenPtr pScreenPriv);
-
-void
-winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv);
-
-LRESULT
-winHandleIconMessage (HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam,
- winPrivScreenPtr pScreenPriv);
-
-
-/*
- * winwndproc.c
- */
-
-LRESULT CALLBACK
-winWindowProc (HWND hWnd, UINT message,
- WPARAM wParam, LPARAM lParam);
-
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-/*
- * winwin32rootless.c
- */
-
-Bool
-winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen,
- int newX, int newY, RegionPtr pShape);
-
-void
-winMWExtWMDestroyFrame (RootlessFrameID wid);
-
-void
-winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);
-
-void
-winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen,
- int newX, int newY, unsigned int newW, unsigned int newH,
- unsigned int gravity);
-
-void
-winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid);
-
-void
-winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape);
-
-void
-winMWExtWMUnmapFrame (RootlessFrameID wid);
-
-void
-winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow);
-
-void
-winMWExtWMStopDrawing (RootlessFrameID wid, Bool flush);
-
-void
-winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage);
-
-void
-winMWExtWMDamageRects (RootlessFrameID wid, int count, const BoxRec *rects,
- int shift_x, int shift_y);
-
-void
-winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin);
-
-void
-winMWExtWMCopyBytes (unsigned int width, unsigned int height,
- const void *src, unsigned int srcRowBytes,
- void *dst, unsigned int dstRowBytes);
-
-void
-winMWExtWMCopyWindow (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
- int dx, int dy);
-#endif
-
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-/*
- * winwin32rootlesswindow.c
- */
-
-void
-winMWExtWMReorderWindows (ScreenPtr pScreen);
-
-void
-winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y);
-
-void
-winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h);
-
-void
-winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h);
-
-void
-winMWExtWMUpdateIcon (Window id);
-
-void
-winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv,
- winScreenInfoPtr pScreenInfo);
-
-wBOOL CALLBACK
-winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam);
-
-Bool
-winIsInternalWMRunning (winScreenInfoPtr pScreenInfo);
-
-void
-winMWExtWMRestackWindows (ScreenPtr pScreen);
-#endif
-
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-/*
- * winwin32rootlesswndproc.c
- */
-
-LRESULT CALLBACK
-winMWExtWMWindowProc (HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam);
-#endif
-
-
-/*
- * winwindowswm.c
- */
-
-void
-winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg,
- Window window, int x, int y, int w, int h);
-
-void
-winWindowsWMExtensionInit (void);
-
-/*
- * wincursor.c
- */
-
-Bool
-winInitCursor (ScreenPtr pScreen);
-
-/*
- * winprocarg.c
- */
-void
-winInitializeScreens(int maxscreens);
-
-/*
- * winrandr.c
- */
-Bool
-winRandRInit (ScreenPtr pScreen);
-void
-winDoRandRScreenSetSize (ScreenPtr pScreen,
- CARD16 width,
- CARD16 height,
- CARD32 mmWidth,
- CARD32 mmHeight);
-
-/*
- * END DDX and DIX Function Prototypes
- */
-
-#endif /* _WIN_H_ */
-
+/* + *Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Dakshinamurthy Karra + * Suhaib M Siddiqi + * Peter Busch + * Harold L Hunt II + * Kensuke Matsuzaki + */ + +#ifndef _WIN_H_ +#define _WIN_H_ + +#ifndef NO +#define NO 0 +#endif +#ifndef YES +#define YES 1 +#endif + +/* Turn debug messages on or off */ +#ifndef CYGDEBUG +#define CYGDEBUG NO +#endif + +/* WM_XBUTTON Messages. They should go into w32api. */ +#ifndef WM_XBUTTONDOWN +# define WM_XBUTTONDOWN 523 +#endif +#ifndef WM_XBUTTONUP +# define WM_XBUTTONUP 524 +#endif +#ifndef WM_XBUTTONDBLCLK +# define WM_XBUTTONDBLCLK 525 +#endif + + +#define WIN_DEFAULT_BPP 0 +#define WIN_DEFAULT_WHITEPIXEL 255 +#define WIN_DEFAULT_BLACKPIXEL 0 +#define WIN_DEFAULT_LINEBIAS 0 +#define WIN_DEFAULT_E3B_TIME 50 /* milliseconds */ +#define WIN_DEFAULT_DPI 75 +#define WIN_DEFAULT_REFRESH 0 +#define WIN_DEFAULT_WIN_KILL TRUE +#define WIN_DEFAULT_UNIX_KILL FALSE +#define WIN_DEFAULT_CLIP_UPDATES_NBOXES 0 +#ifdef XWIN_EMULATEPSEUDO +#define WIN_DEFAULT_EMULATE_PSEUDO FALSE +#endif +#define WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH FALSE + +/* + * Windows only supports 256 color palettes + */ +#define WIN_NUM_PALETTE_ENTRIES 256 + +/* + * Number of times to call Restore in an attempt to restore the primary surface + */ +#define WIN_REGAIN_SURFACE_RETRIES 1 + +/* + * Build a supported display depths mask by shifting one to the left + * by the number of bits in the supported depth. + */ +#define WIN_SUPPORTED_BPPS ( (1 << (32 - 1)) | (1 << (24 - 1)) \ + | (1 << (16 - 1)) | (1 << (15 - 1)) \ + | (1 << ( 8 - 1))) +#define WIN_CHECK_DEPTH YES + +/* + * Timer IDs for WM_TIMER + */ +#define WIN_E3B_TIMER_ID 1 +#define WIN_POLLING_MOUSE_TIMER_ID 2 + +#define MOUSE_POLLING_INTERVAL 50 + +#define WIN_E3B_OFF -1 +#define WIN_FD_INVALID -1 + +#define WIN_SERVER_NONE 0x0L /* 0 */ +#define WIN_SERVER_SHADOW_GDI 0x1L /* 1 */ +#define WIN_SERVER_SHADOW_DD 0x2L /* 2 */ +#define WIN_SERVER_SHADOW_DDNL 0x4L /* 4 */ +#ifdef XWIN_PRIMARYFB +#define WIN_SERVER_PRIMARY_DD 0x8L /* 8 */ +#endif +#ifdef XWIN_NATIVEGDI +# define WIN_SERVER_NATIVE_GDI 0x10L /* 16 */ +#endif + +#define AltMapIndex Mod1MapIndex +#define NumLockMapIndex Mod2MapIndex +#define AltLangMapIndex Mod3MapIndex +#define KanaMapIndex Mod4MapIndex +#define ScrollLockMapIndex Mod5MapIndex + +#define WIN_MOD_LALT 0x00000001 +#define WIN_MOD_RALT 0x00000002 +#define WIN_MOD_LCONTROL 0x00000004 +#define WIN_MOD_RCONTROL 0x00000008 + +#define WIN_24BPP_MASK_RED 0x00FF0000 +#define WIN_24BPP_MASK_GREEN 0x0000FF00 +#define WIN_24BPP_MASK_BLUE 0x000000FF + +#define WIN_MAX_KEYS_PER_KEY 4 + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> + +#include <errno.h> +#if defined(XWIN_MULTIWINDOWEXTWM) || defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) +#define HANDLE void * +#include <pthread.h> +#undef HANDLE +#endif + +#ifdef HAS_MMAP +#include <sys/mman.h> +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif /* MAP_FILE */ +#endif /* HAS_MMAP */ + +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/Xos.h> +#include <X11/Xprotostr.h> +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "pixmap.h" +#include "region.h" +#include "gcstruct.h" +#include "colormap.h" +#include "colormapst.h" +#include "miscstruct.h" +#include "servermd.h" +#include "windowstr.h" +#include "mi.h" +#include "micmap.h" +#include "mifillarc.h" +#include "mifpoly.h" +#include "mibstore.h" +#include "input.h" +#include "mipointer.h" +#include "X11/keysym.h" +#include "micoord.h" +#include "dix.h" +#include "miline.h" +#include "shadow.h" +#include "fb.h" +#include "rootless.h" + +#include "mipict.h" +#include "picturestr.h" + +#ifdef RANDR +#include "randrstr.h" +#endif + +/* + * Windows headers + */ +#include "winms.h" +#include "winresource.h" + + +/* + * Define Windows constants + */ + +#define WM_TRAYICON (WM_USER + 1000) +#define WM_INIT_SYS_MENU (WM_USER + 1001) +#define WM_GIVEUP (WM_USER + 1002) + + +/* Local includes */ +#include "winwindow.h" +#include "winmsg.h" + + +/* + * Debugging macros + */ + +#if CYGDEBUG +#define DEBUG_MSG(str,...) \ +if (fDebugProcMsg) \ +{ \ + char *pszTemp; \ + int iLength; \ + if (asprintf (&pszTemp, str, ##__VA_ARGS__) != -1) { \ + MessageBox (NULL, pszTemp, szFunctionName, MB_OK); \ + free (pszTemp); \ + } \ +} +#else +#define DEBUG_MSG(str,...) +#endif + +#if CYGDEBUG +#define DEBUG_FN_NAME(str) PTSTR szFunctionName = str +#else +#define DEBUG_FN_NAME(str) +#endif + +#if CYGDEBUG || YES +#define DEBUGVARS BOOL fDebugProcMsg = FALSE +#else +#define DEBUGVARS +#endif + +#if CYGDEBUG || YES +#define DEBUGPROC_MSG fDebugProcMsg = TRUE +#else +#define DEBUGPROC_MSG +#endif + +#define PROFILEPOINT(point,thresh)\ +{\ +static unsigned int PROFPT##point = 0;\ +if (++PROFPT##point % thresh == 0)\ +ErrorF (#point ": PROFILEPOINT hit %u times\n", PROFPT##point);\ +} + + +/* We use xor this macro for detecting toggle key state changes */ +#define WIN_XOR(a,b) ((!(a) && (b)) || ((a) && !(b))) + +#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; \ +} + +/* + * Typedefs for engine dependent function pointers + */ + +typedef Bool (*winAllocateFBProcPtr)(ScreenPtr); + +typedef void (*winFreeFBProcPtr)(ScreenPtr); + +typedef void (*winShadowUpdateProcPtr)(ScreenPtr, shadowBufPtr); + +typedef Bool (*winInitScreenProcPtr)(ScreenPtr); + +typedef Bool (*winCloseScreenProcPtr)(int, ScreenPtr); + +typedef Bool (*winInitVisualsProcPtr)(ScreenPtr); + +typedef Bool (*winAdjustVideoModeProcPtr)(ScreenPtr); + +typedef Bool (*winCreateBoundingWindowProcPtr)(ScreenPtr); + +typedef Bool (*winFinishScreenInitProcPtr)(int, ScreenPtr, int, char **); + +typedef Bool (*winBltExposedRegionsProcPtr)(ScreenPtr); + +typedef Bool (*winActivateAppProcPtr)(ScreenPtr); + +typedef Bool (*winRedrawScreenProcPtr)(ScreenPtr pScreen); + +typedef Bool (*winRealizeInstalledPaletteProcPtr)(ScreenPtr pScreen); + +typedef Bool (*winInstallColormapProcPtr)(ColormapPtr pColormap); + +typedef Bool (*winStoreColorsProcPtr)(ColormapPtr pmap, + int ndef, xColorItem *pdefs); + +typedef Bool (*winCreateColormapProcPtr)(ColormapPtr pColormap); + +typedef Bool (*winDestroyColormapProcPtr)(ColormapPtr pColormap); + +typedef Bool (*winHotKeyAltTabProcPtr)(ScreenPtr); + +typedef Bool (*winCreatePrimarySurfaceProcPtr)(ScreenPtr); + +typedef Bool (*winReleasePrimarySurfaceProcPtr)(ScreenPtr); + +typedef Bool (*winFinishCreateWindowsWindowProcPtr)(WindowPtr pWin); + +typedef Bool (*winCreateScreenResourcesProc)(ScreenPtr); + +#ifdef XWIN_NATIVEGDI +/* Typedefs for native GDI wrappers */ +typedef Bool (*RealizeFontPtr) (ScreenPtr pScreen, FontPtr pFont); +typedef Bool (*UnrealizeFontPtr)(ScreenPtr pScreen, FontPtr pFont); +#endif + + +/* + * GC (graphics context) privates + */ + +typedef struct +{ + HDC hdc; + HDC hdcMem; +} winPrivGCRec, *winPrivGCPtr; + + +/* + * Pixmap privates + */ + +typedef struct +{ + HDC hdcSelected; + HBITMAP hBitmap; + BYTE *pbBits; + DWORD dwScanlineBytes; + BITMAPINFOHEADER *pbmih; +} winPrivPixmapRec, *winPrivPixmapPtr; + + +/* + * Colormap privates + */ + +typedef struct +{ + HPALETTE hPalette; + LPDIRECTDRAWPALETTE lpDDPalette; + RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES]; + PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES]; +} winPrivCmapRec, *winPrivCmapPtr; + +/* + * Windows Cursor handling. + */ + +typedef struct { + /* from GetSystemMetrics */ + int sm_cx; + int sm_cy; + + BOOL visible; + HCURSOR handle; + QueryBestSizeProcPtr QueryBestSize; + miPointerSpriteFuncPtr spriteFuncs; +} winCursorRec; + +/* + * Resize modes + */ +typedef enum { + notAllowed, + resizeWithScrollbars, + resizeWithRandr +} winResizeMode; + +/* + * Screen information structure that we need before privates are available + * in the server startup sequence. + */ + +typedef struct +{ + ScreenPtr pScreen; + + /* Did the user specify a height and width? */ + Bool fUserGaveHeightAndWidth; + + DWORD dwScreen; + + int iMonitor; + DWORD dwUserWidth; + DWORD dwUserHeight; + DWORD dwWidth; + DWORD dwHeight; + DWORD dwPaddedWidth; + + /* Did the user specify a screen position? */ + Bool fUserGavePosition; + DWORD dwInitialX; + DWORD dwInitialY; + + /* + * dwStride is the number of whole pixels that occupy a scanline, + * including those pixels that are not displayed. This is basically + * a rounding up of the width. + */ + DWORD dwStride; + + /* Offset of the screen in the window when using scrollbars */ + DWORD dwXOffset; + DWORD dwYOffset; + + DWORD dwBPP; + DWORD dwDepth; + DWORD dwRefreshRate; + char *pfb; + DWORD dwEngine; + DWORD dwEnginePreferred; + DWORD dwClipUpdatesNBoxes; +#ifdef XWIN_EMULATEPSEUDO + Bool fEmulatePseudo; +#endif + Bool fFullScreen; + Bool fDecoration; +#ifdef XWIN_MULTIWINDOWEXTWM + Bool fMWExtWM; + Bool fInternalWM; + Bool fAnotherWMRunning; +#endif + Bool fRootless; +#ifdef XWIN_MULTIWINDOW + Bool fMultiWindow; +#endif +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + Bool fMultiMonitorOverride; +#endif + Bool fMultipleMonitors; + Bool fLessPointer; + winResizeMode iResizeMode; + Bool fNoTrayIcon; + int iE3BTimeout; + /* Windows (Alt+F4) and Unix (Ctrl+Alt+Backspace) Killkey */ + Bool fUseWinKillKey; + Bool fUseUnixKillKey; + Bool fIgnoreInput; + + /* Did the user explicitly set this screen? */ + Bool fExplicitScreen; +} winScreenInfo, *winScreenInfoPtr; + + +/* + * Screen privates + */ + +typedef struct _winPrivScreenRec +{ + winScreenInfoPtr pScreenInfo; + + Bool fEnabled; + Bool fClosed; + Bool fActive; + Bool fBadDepth; + + int iDeltaZ; + + int iConnectedClients; + + CloseScreenProcPtr CloseScreen; + + DWORD dwRedMask; + DWORD dwGreenMask; + DWORD dwBlueMask; + DWORD dwBitsPerRGB; + + DWORD dwModeKeyStates; + + /* Handle to icons that must be freed */ + HICON hiconNotifyIcon; + + /* Palette management */ + ColormapPtr pcmapInstalled; + + /* Pointer to the root visual so we only have to look it up once */ + VisualPtr pRootVisual; + + /* 3 button emulation variables */ + int iE3BCachedPress; + Bool fE3BFakeButton2Sent; + + /* Privates used by shadow fb GDI server */ + HBITMAP hbmpShadow; + HDC hdcScreen; + HDC hdcShadow; + HWND hwndScreen; + BITMAPINFOHEADER *pbmih; + + /* Privates used by shadow fb and primary fb DirectDraw servers */ + LPDIRECTDRAW pdd; + LPDIRECTDRAWSURFACE2 pddsPrimary; + LPDIRECTDRAW2 pdd2; + + /* Privates used by shadow fb DirectDraw server */ + LPDIRECTDRAWSURFACE2 pddsShadow; + LPDDSURFACEDESC pddsdShadow; + + /* Privates used by primary fb DirectDraw server */ + LPDIRECTDRAWSURFACE2 pddsOffscreen; + LPDDSURFACEDESC pddsdOffscreen; + LPDDSURFACEDESC pddsdPrimary; + + /* Privates used by shadow fb DirectDraw Nonlocking server */ + LPDIRECTDRAW4 pdd4; + LPDIRECTDRAWSURFACE4 pddsShadow4; + LPDIRECTDRAWSURFACE4 pddsPrimary4; + BOOL fRetryCreateSurface; + + /* Privates used by both shadow fb DirectDraw servers */ + LPDIRECTDRAWCLIPPER pddcPrimary; + +#ifdef XWIN_MULTIWINDOWEXTWM + /* Privates used by multi-window external window manager */ + RootlessFrameID widTop; + Bool fRestacking; +#endif + +#ifdef XWIN_MULTIWINDOW + /* Privates used by multi-window */ + pthread_t ptWMProc; + pthread_t ptXMsgProc; + void *pWMInfo; +#endif + +#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) + /* Privates used by both multi-window and rootless */ + Bool fRootWindowShown; +#endif + +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) + /* Privates used for any module running in a seperate thread */ + pthread_mutex_t pmServerStarted; + Bool fServerStarted; +#endif + + /* Engine specific functions */ + winAllocateFBProcPtr pwinAllocateFB; + winFreeFBProcPtr pwinFreeFB; + winShadowUpdateProcPtr pwinShadowUpdate; + winInitScreenProcPtr pwinInitScreen; + winCloseScreenProcPtr pwinCloseScreen; + winInitVisualsProcPtr pwinInitVisuals; + winAdjustVideoModeProcPtr pwinAdjustVideoMode; + winCreateBoundingWindowProcPtr pwinCreateBoundingWindow; + winFinishScreenInitProcPtr pwinFinishScreenInit; + winBltExposedRegionsProcPtr pwinBltExposedRegions; + winActivateAppProcPtr pwinActivateApp; + winRedrawScreenProcPtr pwinRedrawScreen; + winRealizeInstalledPaletteProcPtr pwinRealizeInstalledPalette; + winInstallColormapProcPtr pwinInstallColormap; + winStoreColorsProcPtr pwinStoreColors; + winCreateColormapProcPtr pwinCreateColormap; + winDestroyColormapProcPtr pwinDestroyColormap; + winHotKeyAltTabProcPtr pwinHotKeyAltTab; + winCreatePrimarySurfaceProcPtr pwinCreatePrimarySurface; + winReleasePrimarySurfaceProcPtr pwinReleasePrimarySurface; + + winCreateScreenResourcesProc pwinCreateScreenResources; + +#ifdef XWIN_MULTIWINDOW + /* Window Procedures for MultiWindow mode */ + winFinishCreateWindowsWindowProcPtr pwinFinishCreateWindowsWindow; +#endif + + /* Window Procedures for Rootless mode */ + CreateWindowProcPtr CreateWindow; + DestroyWindowProcPtr DestroyWindow; + PositionWindowProcPtr PositionWindow; + ChangeWindowAttributesProcPtr ChangeWindowAttributes; + RealizeWindowProcPtr RealizeWindow; + UnrealizeWindowProcPtr UnrealizeWindow; + ValidateTreeProcPtr ValidateTree; + PostValidateTreeProcPtr PostValidateTree; + WindowExposuresProcPtr WindowExposures; + CopyWindowProcPtr CopyWindow; + ClearToBackgroundProcPtr ClearToBackground; + ClipNotifyProcPtr ClipNotify; + RestackWindowProcPtr RestackWindow; + ReparentWindowProcPtr ReparentWindow; + ResizeWindowProcPtr ResizeWindow; + MoveWindowProcPtr MoveWindow; + SetShapeProcPtr SetShape; + + winCursorRec cursor; + +#ifdef XWIN_NATIVEGDI + RealizeFontPtr RealizeFont; + UnrealizeFontPtr UnrealizeFont; +#endif + +} winPrivScreenRec; + + +#ifdef XWIN_MULTIWINDOWEXTWM +typedef struct { + RootlessWindowPtr pFrame; + HWND hWnd; + int dwWidthBytes; + BITMAPINFOHEADER *pbmihShadow; + HBITMAP hbmpShadow; + HDC hdcShadow; + HDC hdcScreen; + BOOL fResized; + BOOL fRestackingNow; + BOOL fClose; + BOOL fMovingOrSizing; + BOOL fDestroyed;//for debug + char *pfb; +} win32RootlessWindowRec, *win32RootlessWindowPtr; +#endif + + +typedef struct { + pointer value; + XID id; +} WindowIDPairRec, *WindowIDPairPtr; + + +/* + * Extern declares for general global variables + */ + +#include "winglobals.h" + +extern winScreenInfo * g_ScreenInfo; +extern miPointerScreenFuncRec g_winPointerCursorFuncs; +extern DWORD g_dwEvents; +#ifdef HAS_DEVWINDOWS +extern int g_fdMessageQueue; +#endif +extern DevPrivateKeyRec g_iScreenPrivateKeyRec; +#define g_iScreenPrivateKey (&g_iScreenPrivateKeyRec) +extern DevPrivateKeyRec g_iCmapPrivateKeyRec; +#define g_iCmapPrivateKey (&g_iCmapPrivateKeyRec) +extern DevPrivateKeyRec g_iGCPrivateKeyRec; +#define g_iGCPrivateKey (&g_iGCPrivateKeyRec) +extern DevPrivateKeyRec g_iPixmapPrivateKeyRec; +#define g_iPixmapPrivateKey (&g_iPixmapPrivateKeyRec) +extern DevPrivateKeyRec g_iWindowPrivateKeyRec; +#define g_iWindowPrivateKey (&g_iWindowPrivateKeyRec) + +extern unsigned long g_ulServerGeneration; +extern DWORD g_dwEnginesSupported; +extern HINSTANCE g_hInstance; +extern int g_copyROP[]; +extern int g_patternROP[]; +extern const char * g_pszQueryHost; +extern DeviceIntPtr g_pwinPointer; +extern DeviceIntPtr g_pwinKeyboard; + +/* + * Extern declares for dynamically loaded library function pointers + */ + +extern FARPROC g_fpDirectDrawCreate; +extern FARPROC g_fpDirectDrawCreateClipper; +extern FARPROC g_fpTrackMouseEvent; + + +/* + * Screen privates macros + */ + +#define winGetScreenPriv(pScreen) ((winPrivScreenPtr) \ + dixLookupPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey)) + +#define winSetScreenPriv(pScreen,v) \ + dixSetPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey, v) + +#define winScreenPriv(pScreen) \ + winPrivScreenPtr pScreenPriv = winGetScreenPriv(pScreen) + + +/* + * Colormap privates macros + */ + +#define winGetCmapPriv(pCmap) ((winPrivCmapPtr) \ + dixLookupPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey)) + +#define winSetCmapPriv(pCmap,v) \ + dixSetPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey, v) + +#define winCmapPriv(pCmap) \ + winPrivCmapPtr pCmapPriv = winGetCmapPriv(pCmap) + + +/* + * GC privates macros + */ + +#define winGetGCPriv(pGC) ((winPrivGCPtr) \ + dixLookupPrivate(&(pGC)->devPrivates, g_iGCPrivateKey)) + +#define winSetGCPriv(pGC,v) \ + dixSetPrivate(&(pGC)->devPrivates, g_iGCPrivateKey, v) + +#define winGCPriv(pGC) \ + winPrivGCPtr pGCPriv = winGetGCPriv(pGC) + + +/* + * Pixmap privates macros + */ + +#define winGetPixmapPriv(pPixmap) ((winPrivPixmapPtr) \ + dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey)) + +#define winSetPixmapPriv(pPixmap,v) \ + dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey, v) + +#define winPixmapPriv(pPixmap) \ + winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap) + + +/* + * Window privates macros + */ + +#define winGetWindowPriv(pWin) ((winPrivWinPtr) \ + dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey)) + +#define winSetWindowPriv(pWin,v) \ + dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey, v) + +#define winWindowPriv(pWin) \ + winPrivWinPtr pWinPriv = winGetWindowPriv(pWin) + +/* + * wrapper macros + */ +#define _WIN_WRAP(priv, real, mem, func) {\ + priv->mem = real->mem; \ + real->mem = func; \ +} + +#define _WIN_UNWRAP(priv, real, mem) {\ + real->mem = priv->mem; \ +} + +#define WIN_WRAP(mem, func) _WIN_WRAP(pScreenPriv, pScreen, mem, func) + +#define WIN_UNWRAP(mem) _WIN_UNWRAP(pScreenPriv, pScreen, mem) + +/* + * BEGIN DDX and DIX Function Prototypes + */ + + +/* + * winallpriv.c + */ + +Bool +winAllocatePrivates (ScreenPtr pScreen); + +Bool +winInitCmapPrivates (ColormapPtr pCmap, int index); + +Bool +winAllocateCmapPrivates (ColormapPtr pCmap); + + +/* + * winauth.c + */ + +#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) +Bool +winGenerateAuthorization (void); +void winSetAuthorization(void); +#endif + + +/* + * winblock.c + */ + +void +winBlockHandler (int nScreen, + pointer pBlockData, + pointer pTimeout, + pointer pReadMask); + + +#ifdef XWIN_NATIVEGDI +/* + * winclip.c + */ + +RegionPtr +winPixmapToRegionNativeGDI (PixmapPtr pPix); +#endif + + +#ifdef XWIN_CLIPBOARD +/* + * winclipboardinit.c + */ + +Bool +winInitClipboard (void); + +void +winFixClipboardChain (void); +#endif + + +/* + * wincmap.c + */ + +void +winSetColormapFunctions (ScreenPtr pScreen); + +Bool +winCreateDefColormap (ScreenPtr pScreen); + + +/* + * wincreatewnd.c + */ + +Bool +winCreateBoundingWindowFullScreen (ScreenPtr pScreen); + +Bool +winCreateBoundingWindowWindowed (ScreenPtr pScreen); + + +/* + * windialogs.c + */ + +void +winDisplayExitDialog (winPrivScreenPtr pScreenPriv); + +void +winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv); + +void +winDisplayAboutDialog (winPrivScreenPtr pScreenPriv); + + +/* + * winengine.c + */ + +void +winDetectSupportedEngines (void); + +Bool +winSetEngine (ScreenPtr pScreen); + +Bool +winGetDDProcAddresses (void); + +void +winReleaseDDProcAddresses(void); + + +/* + * winerror.c + */ + +#ifdef DDXOSVERRORF +void +OSVenderVErrorF (const char *pszFormat, va_list va_args); +#endif + +void +winMessageBoxF (const char *pszError, UINT uType, ...); + + +#ifdef XWIN_NATIVEGDI +/* + * winfillsp.c + */ + +void +winFillSpansNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + int nSpans, + DDXPointPtr pPoints, + int *pWidths, + int fSorted); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * winfont.c + */ + +Bool +winRealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont); + +Bool +winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * wingc.c + */ + +Bool +winCreateGCNativeGDI (GCPtr pGC); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * wingetsp.c + */ + +void +winGetSpansNativeGDI (DrawablePtr pDrawable, + int wMax, + DDXPointPtr pPoints, + int *pWidths, + int nSpans, + char *pDst); +#endif + + +/* + * winglobals.c + */ + +void +winInitializeGlobals (void); + + +/* + * winkeybd.c + */ + +void +winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode); + +int +winKeybdProc (DeviceIntPtr pDeviceInt, int iState); + +void +winInitializeModeKeyStates (void); + +void +winRestoreModeKeyStates (void); + +Bool +winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam); + +void +winKeybdReleaseKeys (void); + +void +winSendKeyEvent (DWORD dwKey, Bool fDown); + +BOOL +winCheckKeyPressed(WPARAM wParam, LPARAM lParam); + +void +winFixShiftKeys (int iScanCode); + +/* + * winkeyhook.c + */ + +Bool +winInstallKeyboardHookLL (void); + +void +winRemoveKeyboardHookLL (void); + + +/* + * winmisc.c + */ + +#ifdef XWIN_NATIVEGDI +void +winQueryBestSizeNativeGDI (int class, unsigned short *pWidth, + unsigned short *pHeight, ScreenPtr pScreen); +#endif + +CARD8 +winCountBits (DWORD dw); + +Bool +winUpdateFBPointer (ScreenPtr pScreen, void *pbits); + +#ifdef XWIN_NATIVEGDI +BOOL +winPaintBackground (HWND hwnd, COLORREF colorref); +#endif + + +/* + * winmouse.c + */ + +int +winMouseProc (DeviceIntPtr pDeviceInt, int iState); + +int +winMouseWheel (ScreenPtr pScreen, int iDeltaZ); + +void +winMouseButtonsSendEvent (int iEventType, int iButton); + +int +winMouseButtonsHandle (ScreenPtr pScreen, + int iEventType, int iButton, + WPARAM wParam); + +void +winEnqueueMotion(int x, int y); + +#ifdef XWIN_NATIVEGDI +/* + * winnativegdi.c + */ + +HBITMAP +winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth, + BYTE **ppbBits, BITMAPINFO **ppbmi); + +Bool +winSetEngineFunctionsNativeGDI (ScreenPtr pScreen); +#endif + + +#ifdef XWIN_PRIMARYFB +/* + * winpfbddd.c + */ + +Bool +winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * winpixmap.c + */ + +PixmapPtr +winCreatePixmapNativeGDI (ScreenPtr pScreen, int width, int height, int depth, + unsigned usage_hint); + +Bool +winDestroyPixmapNativeGDI (PixmapPtr pPixmap); + +Bool +winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap, + int iWidth, int iHeight, + int iDepth, + int iBitsPerPixel, + int devKind, + pointer pPixData); +#endif + +#ifdef XWIN_NATIVEGDI +/* + * winpolyline.c + */ + +void +winPolyLineNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ppt); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * winpushpxl.c + */ + +void +winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, + int dx, int dy, int xOrg, int yOrg); +#endif + + +/* + * winscrinit.c + */ + +Bool +winScreenInit (int index, + ScreenPtr pScreen, + int argc, char **argv); + +Bool +winFinishScreenInitFB (int index, + ScreenPtr pScreen, + int argc, char **argv); + +#if defined(XWIN_NATIVEGDI) +Bool +winFinishScreenInitNativeGDI (int index, + ScreenPtr pScreen, + int argc, char **argv); +#endif + + +#ifdef XWIN_NATIVEGDI +/* + * winsetsp.c + */ + +void +winSetSpansNativeGDI (DrawablePtr pDrawable, + GCPtr pGC, + char *pSrc, + DDXPointPtr pPoints, + int *pWidth, + int nSpans, + int fSorted); +#endif + + +/* + * winshaddd.c + */ + +Bool +winSetEngineFunctionsShadowDD (ScreenPtr pScreen); + + +/* + * winshadddnl.c + */ + +Bool +winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen); + + +/* + * winshadgdi.c + */ + +Bool +winSetEngineFunctionsShadowGDI (ScreenPtr pScreen); + + +/* + * winwakeup.c + */ + +void +winWakeupHandler (int nScreen, + pointer pWakeupData, + unsigned long ulResult, + pointer pReadmask); + + +/* + * winwindow.c + */ + +#ifdef XWIN_NATIVEGDI +Bool +winCreateWindowNativeGDI (WindowPtr pWin); + +Bool +winDestroyWindowNativeGDI (WindowPtr pWin); + +Bool +winPositionWindowNativeGDI (WindowPtr pWin, int x, int y); + +void +winCopyWindowNativeGDI (WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc); + +Bool +winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask); + +Bool +winUnmapWindowNativeGDI (WindowPtr pWindow); + +Bool +winMapWindowNativeGDI (WindowPtr pWindow); +#endif + +Bool +winCreateWindowRootless (WindowPtr pWindow); + +Bool +winDestroyWindowRootless (WindowPtr pWindow); + +Bool +winPositionWindowRootless (WindowPtr pWindow, int x, int y); + +Bool +winChangeWindowAttributesRootless (WindowPtr pWindow, unsigned long mask); + +Bool +winUnmapWindowRootless (WindowPtr pWindow); + +Bool +winMapWindowRootless (WindowPtr pWindow); + +void +winSetShapeRootless (WindowPtr pWindow, int kind); + + +/* + * winmultiwindowicons.c - Used by both multi-window and Win32Rootless + */ + +HICON +winXIconToHICON (WindowPtr pWin, int iconSize); + +void +winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon); + +#ifdef XWIN_MULTIWINDOW +/* + * winmultiwindowshape.c + */ + +void +winReshapeMultiWindow (WindowPtr pWin); + +void +winSetShapeMultiWindow (WindowPtr pWindow, int kind); + +void +winUpdateRgnMultiWindow (WindowPtr pWindow); +#endif + + +#ifdef XWIN_MULTIWINDOW +/* + * winmultiwindowwindow.c + */ + +Bool +winCreateWindowMultiWindow (WindowPtr pWindow); + +Bool +winDestroyWindowMultiWindow (WindowPtr pWindow); + +Bool +winPositionWindowMultiWindow (WindowPtr pWindow, int x, int y); + +Bool +winChangeWindowAttributesMultiWindow (WindowPtr pWindow, unsigned long mask); + +Bool +winUnmapWindowMultiWindow (WindowPtr pWindow); + +Bool +winMapWindowMultiWindow (WindowPtr pWindow); + +void +winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent); + +void +winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib); + +void +winReorderWindowsMultiWindow (void); + +void +winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w, + unsigned int h, WindowPtr pSib); +void +winMoveWindowMultiWindow (WindowPtr pWin, int x, int y, + WindowPtr pSib, VTKind kind); + +void +winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt, + RegionPtr oldRegion); + +XID +winGetWindowID (WindowPtr pWin); + +int +winAdjustXWindow (WindowPtr pWin, HWND hwnd); +#endif + + +#ifdef XWIN_MULTIWINDOW +/* + * winmultiwindowwndproc.c + */ + +LRESULT CALLBACK +winTopLevelWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); +#endif + + +/* + * wintrayicon.c + */ + +void +winInitNotifyIcon (winPrivScreenPtr pScreenPriv); + +void +winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv); + +LRESULT +winHandleIconMessage (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam, + winPrivScreenPtr pScreenPriv); + + +/* + * winwndproc.c + */ + +LRESULT CALLBACK +winWindowProc (HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam); + + +#ifdef XWIN_MULTIWINDOWEXTWM +/* + * winwin32rootless.c + */ + +Bool +winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen, + int newX, int newY, RegionPtr pShape); + +void +winMWExtWMDestroyFrame (RootlessFrameID wid); + +void +winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY); + +void +winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen, + int newX, int newY, unsigned int newW, unsigned int newH, + unsigned int gravity); + +void +winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid); + +void +winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape); + +void +winMWExtWMUnmapFrame (RootlessFrameID wid); + +void +winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow); + +void +winMWExtWMStopDrawing (RootlessFrameID wid, Bool flush); + +void +winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage); + +void +winMWExtWMDamageRects (RootlessFrameID wid, int count, const BoxRec *rects, + int shift_x, int shift_y); + +void +winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin); + +void +winMWExtWMCopyBytes (unsigned int width, unsigned int height, + const void *src, unsigned int srcRowBytes, + void *dst, unsigned int dstRowBytes); + +void +winMWExtWMCopyWindow (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, + int dx, int dy); +#endif + + +#ifdef XWIN_MULTIWINDOWEXTWM +/* + * winwin32rootlesswindow.c + */ + +void +winMWExtWMReorderWindows (ScreenPtr pScreen); + +void +winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y); + +void +winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h); + +void +winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h); + +void +winMWExtWMUpdateIcon (Window id); + +void +winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv, + winScreenInfoPtr pScreenInfo); + +wBOOL CALLBACK +winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam); + +Bool +winIsInternalWMRunning (winScreenInfoPtr pScreenInfo); + +void +winMWExtWMRestackWindows (ScreenPtr pScreen); +#endif + + +#ifdef XWIN_MULTIWINDOWEXTWM +/* + * winwin32rootlesswndproc.c + */ + +LRESULT CALLBACK +winMWExtWMWindowProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); +#endif + + +/* + * winwindowswm.c + */ + +void +winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg, + Window window, int x, int y, int w, int h); + +void +winWindowsWMExtensionInit (void); + +/* + * wincursor.c + */ + +Bool +winInitCursor (ScreenPtr pScreen); + +/* + * winprocarg.c + */ +void +winInitializeScreens(int maxscreens); + +/* + * winrandr.c + */ +Bool +winRandRInit (ScreenPtr pScreen); +void +winDoRandRScreenSetSize (ScreenPtr pScreen, + CARD16 width, + CARD16 height, + CARD32 mmWidth, + CARD32 mmHeight); + +/* + * END DDX and DIX Function Prototypes + */ + +#endif /* _WIN_H_ */ + diff --git a/xorg-server/hw/xwin/winclipboardxevents.c b/xorg-server/hw/xwin/winclipboardxevents.c index e65717008..b0006a01f 100644 --- a/xorg-server/hw/xwin/winclipboardxevents.c +++ b/xorg-server/hw/xwin/winclipboardxevents.c @@ -1,802 +1,805 @@ -/*
- *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
- *Copyright (C) Colin Harrison 2005-2008
- *
- *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 HAROLD L HUNT II 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 of the copyright holder(s)
- *and author(s) shall not be used in advertising or otherwise to promote
- *the sale, use or other dealings in this Software without prior written
- *authorization from the copyright holder(s) and author(s).
- *
- * Authors: Harold L Hunt II
- * Colin Harrison
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "winclipboard.h"
-#include "misc.h"
-
-
-/*
- * References to external symbols
- */
-
-extern Bool g_fUnicodeSupport;
-
-
-/*
- * Process any pending X events
- */
-
-int
-winClipboardFlushXEvents (HWND hwnd,
- int iWindow,
- Display *pDisplay,
- Bool fUseUnicode)
-{
- static Atom atomLocalProperty;
- static Atom atomCompoundText;
- static Atom atomUTF8String;
- static Atom atomTargets;
- static int generation;
-
- if (generation != serverGeneration)
- {
- generation = serverGeneration;
- atomLocalProperty = XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False);
- atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False);
- atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False);
- atomTargets = XInternAtom (pDisplay, "TARGETS", False);
- }
-
- /* Process all pending events */
- while (XPending (pDisplay))
- {
- XTextProperty xtpText = {0};
- XEvent event;
- XSelectionEvent eventSelection;
- unsigned long ulReturnBytesLeft;
- char *pszReturnData = NULL;
- char *pszGlobalData = NULL;
- int iReturn;
- HGLOBAL hGlobal = NULL;
- XICCEncodingStyle xiccesStyle;
- int iConvertDataLen = 0;
- char *pszConvertData = NULL;
- char *pszTextList[2] = {NULL};
- int iCount;
- char **ppszTextList = NULL;
- wchar_t *pwszUnicodeStr = NULL;
- int iUnicodeLen = 0;
- int iReturnDataLen = 0;
- int i;
- Bool fAbort = FALSE;
- Bool fCloseClipboard = FALSE;
- Bool fSetClipboardData = TRUE;
-
- /* Get the next event - will not block because one is ready */
- XNextEvent (pDisplay, &event);
-
- /* Branch on the event type */
- switch (event.type)
- {
- /*
- * SelectionRequest
- */
-
- case SelectionRequest:
- {
- char *pszAtomName = NULL;
- winDebug("SelectionRequest - target %d\n",
- event.xselectionrequest.target);
-
- pszAtomName = XGetAtomName (pDisplay,
- event.xselectionrequest.target);
- winDebug("SelectionRequest - Target atom name %s\n", pszAtomName);
- XFree (pszAtomName);
- pszAtomName = NULL;
- }
-
- /* Abort if invalid target type */
- if (event.xselectionrequest.target != XA_STRING
- && event.xselectionrequest.target != atomUTF8String
- && event.xselectionrequest.target != atomCompoundText
- && event.xselectionrequest.target != atomTargets)
- {
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
-
- /* Handle targets type of request */
- if (event.xselectionrequest.target == atomTargets)
- {
- Atom atomTargetArr[] = {atomTargets,
- atomCompoundText,
- atomUTF8String,
- XA_STRING};
-
- /* Try to change the property */
- iReturn = XChangeProperty (pDisplay,
- event.xselectionrequest.requestor,
- event.xselectionrequest.property,
- XA_ATOM,
- 32,
- PropModeReplace,
- (unsigned char *) atomTargetArr,
- (sizeof (atomTargetArr)
- / sizeof (atomTargetArr[0])));
- if (iReturn == BadAlloc
- || iReturn == BadAtom
- || iReturn == BadMatch
- || iReturn == BadValue
- || iReturn == BadWindow)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "XChangeProperty failed: %d\n",
- iReturn);
- }
-
- /* Setup selection notify xevent */
- eventSelection.type = SelectionNotify;
- eventSelection.send_event = True;
- eventSelection.display = pDisplay;
- eventSelection.requestor = event.xselectionrequest.requestor;
- eventSelection.selection = event.xselectionrequest.selection;
- eventSelection.target = event.xselectionrequest.target;
- eventSelection.property = event.xselectionrequest.property;
- eventSelection.time = event.xselectionrequest.time;
-
- /*
- * Notify the requesting window that
- * the operation has completed
- */
- iReturn = XSendEvent (pDisplay,
- eventSelection.requestor,
- False,
- 0L,
- (XEvent *) &eventSelection);
- if (iReturn == BadValue || iReturn == BadWindow)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "XSendEvent () failed\n");
- }
- break;
- }
-
- /* Check that clipboard format is available */
- if (fUseUnicode
- && !IsClipboardFormatAvailable (CF_UNICODETEXT))
- {
- static int count; /* Hack to stop acroread spamming the log */
- static HWND lasthwnd; /* I've not seen any other client get here repeatedly? */
- if (hwnd != lasthwnd) count = 0;
- count++;
- if (count < 6) ErrorF ("winClipboardFlushXEvents - CF_UNICODETEXT is not "
- "available from Win32 clipboard. Aborting %d.\n", count);
- lasthwnd = hwnd;
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
- else if (!fUseUnicode
- && !IsClipboardFormatAvailable (CF_TEXT))
- {
- ErrorF ("winClipboardFlushXEvents - CF_TEXT is not "
- "available from Win32 clipboard. Aborting.\n");
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
-
- /* Close clipboard if we have it open already */
- if (GetOpenClipboardWindow () == hwnd)
- {
- CloseClipboard ();
- }
-
- /* Access the clipboard */
- if (!OpenClipboard (hwnd))
- {
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "OpenClipboard () failed: %08lx\n",
- GetLastError ());
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
-
- /* Indicate that clipboard was opened */
- fCloseClipboard = TRUE;
-
- /* Setup the string style */
- if (event.xselectionrequest.target == XA_STRING)
- xiccesStyle = XStringStyle;
-#ifdef X_HAVE_UTF8_STRING
- else if (event.xselectionrequest.target == atomUTF8String)
- xiccesStyle = XUTF8StringStyle;
-#endif
- else if (event.xselectionrequest.target == atomCompoundText)
- xiccesStyle = XCompoundTextStyle;
- else
- xiccesStyle = XStringStyle;
-
- /*
- * FIXME: Can't pass CF_UNICODETEXT on Windows 95/98/Me
- */
-
- /* Get a pointer to the clipboard text, in desired format */
- if (fUseUnicode)
- {
- /* Retrieve clipboard data */
- hGlobal = GetClipboardData (CF_UNICODETEXT);
- }
- else
- {
- /* Retrieve clipboard data */
- hGlobal = GetClipboardData (CF_TEXT);
- }
- if (!hGlobal)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "GetClipboardData () failed: %08lx\n",
- GetLastError ());
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
- pszGlobalData = (char *) GlobalLock (hGlobal);
-
- /* Convert the Unicode string to UTF8 (MBCS) */
- if (fUseUnicode)
- {
- iConvertDataLen = WideCharToMultiByte (CP_UTF8,
- 0,
- (LPCWSTR)pszGlobalData,
- -1,
- NULL,
- 0,
- NULL,
- NULL);
- /* NOTE: iConvertDataLen includes space for null terminator */
- pszConvertData = (char *) malloc (iConvertDataLen);
- WideCharToMultiByte (CP_UTF8,
- 0,
- (LPCWSTR)pszGlobalData,
- -1,
- pszConvertData,
- iConvertDataLen,
- NULL,
- NULL);
- }
- else
- {
- pszConvertData = strdup (pszGlobalData);
- iConvertDataLen = strlen (pszConvertData) + 1;
- }
-
- /* Convert DOS string to UNIX string */
- winClipboardDOStoUNIX (pszConvertData, strlen (pszConvertData));
-
- /* Setup our text list */
- pszTextList[0] = pszConvertData;
- pszTextList[1] = NULL;
-
- /* Initialize the text property */
- xtpText.value = NULL;
- xtpText.nitems = 0;
-
- /* Create the text property from the text list */
- if (fUseUnicode)
- {
-#ifdef X_HAVE_UTF8_STRING
- iReturn = Xutf8TextListToTextProperty (pDisplay,
- pszTextList,
- 1,
- xiccesStyle,
- &xtpText);
-#endif
- }
- else
- {
- iReturn = XmbTextListToTextProperty (pDisplay,
- pszTextList,
- 1,
- xiccesStyle,
- &xtpText);
- }
- if (iReturn == XNoMemory || iReturn == XLocaleNotSupported)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "X*TextListToTextProperty failed: %d\n",
- iReturn);
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
-
- /* Free the converted string */
- free (pszConvertData);
- pszConvertData = NULL;
-
- /* Copy the clipboard text to the requesting window */
- iReturn = XChangeProperty (pDisplay,
- event.xselectionrequest.requestor,
- event.xselectionrequest.property,
- event.xselectionrequest.target,
- 8,
- PropModeReplace,
- xtpText.value,
- xtpText.nitems);
- if (iReturn == BadAlloc || iReturn == BadAtom
- || iReturn == BadMatch || iReturn == BadValue
- || iReturn == BadWindow)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "XChangeProperty failed: %d\n",
- iReturn);
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
-
- /* Release the clipboard data */
- GlobalUnlock (hGlobal);
- pszGlobalData = NULL;
- fCloseClipboard = FALSE;
- CloseClipboard ();
-
- /* Clean up */
- XFree (xtpText.value);
- xtpText.value = NULL;
- xtpText.nitems = 0;
-
- /* Setup selection notify event */
- eventSelection.type = SelectionNotify;
- eventSelection.send_event = True;
- eventSelection.display = pDisplay;
- eventSelection.requestor = event.xselectionrequest.requestor;
- eventSelection.selection = event.xselectionrequest.selection;
- eventSelection.target = event.xselectionrequest.target;
- eventSelection.property = event.xselectionrequest.property;
- eventSelection.time = event.xselectionrequest.time;
-
- /* Notify the requesting window that the operation has completed */
- iReturn = XSendEvent (pDisplay,
- eventSelection.requestor,
- False,
- 0L,
- (XEvent *) &eventSelection);
- if (iReturn == BadValue || iReturn == BadWindow)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "XSendEvent () failed\n");
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionRequest_Done;
- }
-
- winClipboardFlushXEvents_SelectionRequest_Done:
- /* Free allocated resources */
- if (xtpText.value)
- {
- XFree (xtpText.value);
- xtpText.value = NULL;
- xtpText.nitems = 0;
- }
- free(pszConvertData);
- if (hGlobal && pszGlobalData)
- GlobalUnlock (hGlobal);
-
- /*
- * Send a SelectionNotify event to the requesting
- * client when we abort.
- */
- if (fAbort)
- {
- /* Setup selection notify event */
- eventSelection.type = SelectionNotify;
- eventSelection.send_event = True;
- eventSelection.display = pDisplay;
- eventSelection.requestor = event.xselectionrequest.requestor;
- eventSelection.selection = event.xselectionrequest.selection;
- eventSelection.target = event.xselectionrequest.target;
- eventSelection.property = None;
- eventSelection.time = event.xselectionrequest.time;
-
- /* Notify the requesting window that the operation is complete */
- iReturn = XSendEvent (pDisplay,
- eventSelection.requestor,
- False,
- 0L,
- (XEvent *) &eventSelection);
- if (iReturn == BadValue || iReturn == BadWindow)
- {
- /*
- * Should not be a problem if XSendEvent fails because
- * the client may simply have exited.
- */
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "XSendEvent () failed for abort event.\n");
- }
- }
-
- /* Close clipboard if it was opened */
- if (fCloseClipboard)
- {
- fCloseClipboard = FALSE;
- CloseClipboard ();
- }
- break;
-
-
- /*
- * SelectionNotify
- */
-
- case SelectionNotify:
-
- winDebug ("winClipboardFlushXEvents - SelectionNotify\n");
- {
- char *pszAtomName;
- pszAtomName = XGetAtomName (pDisplay,
- event.xselection.selection);
-
- winDebug("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n",
- pszAtomName);
- XFree (pszAtomName);
- }
-
- /*
- * Request conversion of UTF8 and CompoundText targets.
- */
- if (event.xselection.property == None)
- {
- if (event.xselection.target == XA_STRING)
- {
- winDebug ("winClipboardFlushXEvents - SelectionNotify - "
- "XA_STRING\n");
-
- return WIN_XEVENTS_CONVERT;
- }
- else if (event.xselection.target == atomUTF8String)
- {
- winDebug("winClipboardFlushXEvents - SelectionNotify - "
- "Requesting conversion of UTF8 target.\n");
-
- XConvertSelection (pDisplay,
- event.xselection.selection,
- XA_STRING,
- atomLocalProperty,
- iWindow,
- CurrentTime);
-
- /* Process the ConvertSelection event */
- XFlush (pDisplay);
- return WIN_XEVENTS_CONVERT;
- }
-#ifdef X_HAVE_UTF8_STRING
- else if (event.xselection.target == atomCompoundText)
- {
- winDebug("winClipboardFlushXEvents - SelectionNotify - "
- "Requesting conversion of CompoundText target.\n");
-
- XConvertSelection (pDisplay,
- event.xselection.selection,
- atomUTF8String,
- atomLocalProperty,
- iWindow,
- CurrentTime);
-
- /* Process the ConvertSelection event */
- XFlush (pDisplay);
- return WIN_XEVENTS_CONVERT;
- }
-#endif
- else
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
- "Unknown format. Cannot request conversion, "
- "aborting.\n");
- break;
- }
- }
-
- /* Retrieve the size of the stored data */
- iReturn = XGetWindowProperty (pDisplay,
- iWindow,
- atomLocalProperty,
- 0,
- 0, /* Don't get data, just size */
- False,
- AnyPropertyType,
- &xtpText.encoding,
- &xtpText.format,
- &xtpText.nitems,
- &ulReturnBytesLeft,
- &xtpText.value);
- if (iReturn != Success)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
- "XGetWindowProperty () failed, aborting: %d\n",
- iReturn);
- break;
- }
-
- winDebug("SelectionNotify - returned data %d left %d\n",
- xtpText.nitems, ulReturnBytesLeft);
-
- /* Request the selection data */
- iReturn = XGetWindowProperty (pDisplay,
- iWindow,
- atomLocalProperty,
- 0,
- ulReturnBytesLeft,
- False,
- AnyPropertyType,
- &xtpText.encoding,
- &xtpText.format,
- &xtpText.nitems,
- &ulReturnBytesLeft,
- &xtpText.value);
- if (iReturn != Success)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
- "XGetWindowProperty () failed, aborting: %d\n",
- iReturn);
- break;
- }
-
- {
- char *pszAtomName = NULL;
-
- winDebug("SelectionNotify - returned data %d left %d\n",
- xtpText.nitems, ulReturnBytesLeft);
- pszAtomName = XGetAtomName(pDisplay, xtpText.encoding);
- winDebug("Notify atom name %s\n", pszAtomName);
- XFree (pszAtomName);
- pszAtomName = NULL;
- }
-
- if (fUseUnicode)
- {
-#ifdef X_HAVE_UTF8_STRING
- /* Convert the text property to a text list */
- iReturn = Xutf8TextPropertyToTextList (pDisplay,
- &xtpText,
- &ppszTextList,
- &iCount);
-#endif
- }
- else
- {
- iReturn = XmbTextPropertyToTextList (pDisplay,
- &xtpText,
- &ppszTextList,
- &iCount);
- }
- if (iReturn == Success || iReturn > 0)
- {
- /* Conversion succeeded or some unconvertible characters */
- if (ppszTextList != NULL)
- {
- iReturnDataLen = 0;
- for (i = 0; i < iCount; i++)
- {
- iReturnDataLen += strlen(ppszTextList[i]);
- }
- pszReturnData = malloc (iReturnDataLen + 1);
- pszReturnData[0] = '\0';
- for (i = 0; i < iCount; i++)
- {
- strcat (pszReturnData, ppszTextList[i]);
- }
- }
- else
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
- "X*TextPropertyToTextList list_return is NULL.\n");
- pszReturnData = malloc (1);
- pszReturnData[0] = '\0';
- }
- }
- else
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
- "X*TextPropertyToTextList returned: ");
- switch (iReturn)
- {
- case XNoMemory:
- ErrorF ("XNoMemory\n");
- break;
- case XConverterNotFound:
- ErrorF ("XConverterNotFound\n");
- break;
- default:
- ErrorF ("%d", iReturn);
- break;
- }
- pszReturnData = malloc (1);
- pszReturnData[0] = '\0';
- }
-
- /* Free the data returned from XGetWindowProperty */
- if (ppszTextList)
- XFreeStringList (ppszTextList);
- ppszTextList = NULL;
- XFree (xtpText.value);
- xtpText.value = NULL;
- xtpText.nitems = 0;
-
- /* Convert the X clipboard string to DOS format */
- winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData));
-
- if (fUseUnicode)
- {
- /* Find out how much space needed to convert MBCS to Unicode */
- iUnicodeLen = MultiByteToWideChar (CP_UTF8,
- 0,
- pszReturnData,
- -1,
- NULL,
- 0);
-
- /* Allocate memory for the Unicode string */
- pwszUnicodeStr
- = (wchar_t*) malloc (sizeof (wchar_t) * (iUnicodeLen + 1));
- if (!pwszUnicodeStr)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify "
- "malloc failed for pwszUnicodeStr, aborting.\n");
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionNotify_Done;
- }
-
- /* Do the actual conversion */
- MultiByteToWideChar (CP_UTF8,
- 0,
- pszReturnData,
- -1,
- pwszUnicodeStr,
- iUnicodeLen);
-
- /* Allocate global memory for the X clipboard data */
- hGlobal = GlobalAlloc (GMEM_MOVEABLE,
- sizeof (wchar_t) * (iUnicodeLen + 1));
- }
- else
- {
- pszConvertData = strdup (pszReturnData);
- iConvertDataLen = strlen (pszConvertData) + 1;
-
- /* Allocate global memory for the X clipboard data */
- hGlobal = GlobalAlloc (GMEM_MOVEABLE, iConvertDataLen);
- }
-
- free (pszReturnData);
-
- /* Check that global memory was allocated */
- if (!hGlobal)
- {
- ErrorF ("winClipboardFlushXEvents - SelectionNotify "
- "GlobalAlloc failed, aborting: %ld\n",
- GetLastError ());
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionNotify_Done;
- }
-
- /* Obtain a pointer to the global memory */
- pszGlobalData = GlobalLock (hGlobal);
- if (pszGlobalData == NULL)
- {
- ErrorF ("winClipboardFlushXEvents - Could not lock global "
- "memory for clipboard transfer\n");
-
- /* Abort */
- fAbort = TRUE;
- goto winClipboardFlushXEvents_SelectionNotify_Done;
- }
-
- /* Copy the returned string into the global memory */
- if (fUseUnicode)
- {
- memcpy (pszGlobalData,
- pwszUnicodeStr,
- sizeof (wchar_t) * (iUnicodeLen + 1));
- free (pwszUnicodeStr);
- pwszUnicodeStr = NULL;
- }
- else
- {
- strcpy (pszGlobalData, pszConvertData);
- free (pszConvertData);
- pszConvertData = NULL;
- }
-
- /* Release the pointer to the global memory */
- GlobalUnlock (hGlobal);
- pszGlobalData = NULL;
-
- /* Push the selection data to the Windows clipboard */
- if (fUseUnicode)
- SetClipboardData (CF_UNICODETEXT, hGlobal);
- else
- SetClipboardData (CF_TEXT, hGlobal);
-
- /* Flag that SetClipboardData has been called */
- fSetClipboardData = FALSE;
-
- /*
- * NOTE: Do not try to free pszGlobalData, it is owned by
- * Windows after the call to SetClipboardData ().
- */
-
- winClipboardFlushXEvents_SelectionNotify_Done:
- /* Free allocated resources */
- if (ppszTextList)
- XFreeStringList (ppszTextList);
- if (xtpText.value)
- {
- XFree (xtpText.value);
- xtpText.value = NULL;
- xtpText.nitems = 0;
- }
- free(pszConvertData);
- free(pwszUnicodeStr);
- if (hGlobal && pszGlobalData)
- GlobalUnlock (hGlobal);
- if (fSetClipboardData && g_fUnicodeSupport)
- SetClipboardData (CF_UNICODETEXT, NULL);
- if (fSetClipboardData)
- SetClipboardData (CF_TEXT, NULL);
- return WIN_XEVENTS_NOTIFY;
-
- case SelectionClear:
- winDebug("SelectionClear - doing nothing\n");
- break;
-
- case PropertyNotify:
- break;
-
- case MappingNotify:
- break;
-
- default:
- ErrorF ("winClipboardFlushXEvents - unexpected event type %d\n", event.type);
- break;
- }
- }
-
- return WIN_XEVENTS_SUCCESS;
-}
+/* + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. + *Copyright (C) Colin Harrison 2005-2008 + * + *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 HAROLD L HUNT II 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 of the copyright holder(s) + *and author(s) shall not be used in advertising or otherwise to promote + *the sale, use or other dealings in this Software without prior written + *authorization from the copyright holder(s) and author(s). + * + * Authors: Harold L Hunt II + * Colin Harrison + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "winclipboard.h" +#include "misc.h" + + +/* + * References to external symbols + */ + +extern Bool g_fUnicodeSupport; + + +/* + * Process any pending X events + */ + +int +winClipboardFlushXEvents (HWND hwnd, + int iWindow, + Display *pDisplay, + Bool fUseUnicode) +{ + static Atom atomLocalProperty; + static Atom atomCompoundText; + static Atom atomUTF8String; + static Atom atomTargets; + static int generation; + + if (generation != serverGeneration) + { + generation = serverGeneration; + atomLocalProperty = XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False); + atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False); + atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False); + atomTargets = XInternAtom (pDisplay, "TARGETS", False); + } + + /* Process all pending events */ + while (XPending (pDisplay)) + { + XTextProperty xtpText = {0}; + XEvent event; + XSelectionEvent eventSelection; + unsigned long ulReturnBytesLeft; + char *pszReturnData = NULL; + char *pszGlobalData = NULL; + int iReturn; + HGLOBAL hGlobal = NULL; + XICCEncodingStyle xiccesStyle; + int iConvertDataLen = 0; + char *pszConvertData = NULL; + char *pszTextList[2] = {NULL}; + int iCount; + char **ppszTextList = NULL; + wchar_t *pwszUnicodeStr = NULL; + int iUnicodeLen = 0; + int iReturnDataLen = 0; + int i; + Bool fAbort = FALSE; + Bool fCloseClipboard = FALSE; + Bool fSetClipboardData = TRUE; + + /* Get the next event - will not block because one is ready */ + XNextEvent (pDisplay, &event); + + /* Branch on the event type */ + switch (event.type) + { + /* + * SelectionRequest + */ + + case SelectionRequest: + { + char *pszAtomName = NULL; + winDebug("SelectionRequest - target %d\n", + event.xselectionrequest.target); + + pszAtomName = XGetAtomName (pDisplay, + event.xselectionrequest.target); + winDebug("SelectionRequest - Target atom name %s\n", pszAtomName); + XFree (pszAtomName); + pszAtomName = NULL; + } + + /* Abort if invalid target type */ + if (event.xselectionrequest.target != XA_STRING + && event.xselectionrequest.target != atomUTF8String + && event.xselectionrequest.target != atomCompoundText + && event.xselectionrequest.target != atomTargets) + { + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Handle targets type of request */ + if (event.xselectionrequest.target == atomTargets) + { + Atom atomTargetArr[] = {atomTargets, + atomCompoundText, + atomUTF8String, + XA_STRING}; + + /* Try to change the property */ + iReturn = XChangeProperty (pDisplay, + event.xselectionrequest.requestor, + event.xselectionrequest.property, + XA_ATOM, + 32, + PropModeReplace, + (unsigned char *) atomTargetArr, + (sizeof (atomTargetArr) + / sizeof (atomTargetArr[0]))); + if (iReturn == BadAlloc + || iReturn == BadAtom + || iReturn == BadMatch + || iReturn == BadValue + || iReturn == BadWindow) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "XChangeProperty failed: %d\n", + iReturn); + } + + /* Setup selection notify xevent */ + eventSelection.type = SelectionNotify; + eventSelection.send_event = True; + eventSelection.display = pDisplay; + eventSelection.requestor = event.xselectionrequest.requestor; + eventSelection.selection = event.xselectionrequest.selection; + eventSelection.target = event.xselectionrequest.target; + eventSelection.property = event.xselectionrequest.property; + eventSelection.time = event.xselectionrequest.time; + + /* + * Notify the requesting window that + * the operation has completed + */ + iReturn = XSendEvent (pDisplay, + eventSelection.requestor, + False, + 0L, + (XEvent *) &eventSelection); + if (iReturn == BadValue || iReturn == BadWindow) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "XSendEvent () failed\n"); + } + break; + } + + /* Check that clipboard format is available */ + if (fUseUnicode + && !IsClipboardFormatAvailable (CF_UNICODETEXT)) + { + static int count; /* Hack to stop acroread spamming the log */ + static HWND lasthwnd; /* I've not seen any other client get here repeatedly? */ + if (hwnd != lasthwnd) count = 0; + count++; + if (count < 6) ErrorF ("winClipboardFlushXEvents - CF_UNICODETEXT is not " + "available from Win32 clipboard. Aborting %d.\n", count); + lasthwnd = hwnd; + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + else if (!fUseUnicode + && !IsClipboardFormatAvailable (CF_TEXT)) + { + ErrorF ("winClipboardFlushXEvents - CF_TEXT is not " + "available from Win32 clipboard. Aborting.\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Close clipboard if we have it open already */ + if (GetOpenClipboardWindow () == hwnd) + { + CloseClipboard (); + } + + /* Access the clipboard */ + if (!OpenClipboard (hwnd)) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "OpenClipboard () failed: %08lx\n", + GetLastError ()); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Indicate that clipboard was opened */ + fCloseClipboard = TRUE; + + /* Setup the string style */ + if (event.xselectionrequest.target == XA_STRING) + xiccesStyle = XStringStyle; +#ifdef X_HAVE_UTF8_STRING + else if (event.xselectionrequest.target == atomUTF8String) + xiccesStyle = XUTF8StringStyle; +#endif + else if (event.xselectionrequest.target == atomCompoundText) + xiccesStyle = XCompoundTextStyle; + else + xiccesStyle = XStringStyle; + + /* + * FIXME: Can't pass CF_UNICODETEXT on Windows 95/98/Me + */ + + /* Get a pointer to the clipboard text, in desired format */ + if (fUseUnicode) + { + /* Retrieve clipboard data */ + hGlobal = GetClipboardData (CF_UNICODETEXT); + } + else + { + /* Retrieve clipboard data */ + hGlobal = GetClipboardData (CF_TEXT); + } + if (!hGlobal) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "GetClipboardData () failed: %08lx\n", + GetLastError ()); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + pszGlobalData = (char *) GlobalLock (hGlobal); + + /* Convert the Unicode string to UTF8 (MBCS) */ + if (fUseUnicode) + { + iConvertDataLen = WideCharToMultiByte (CP_UTF8, + 0, + (LPCWSTR)pszGlobalData, + -1, + NULL, + 0, + NULL, + NULL); + /* NOTE: iConvertDataLen includes space for null terminator */ + pszConvertData = (char *) malloc (iConvertDataLen); + WideCharToMultiByte (CP_UTF8, + 0, + (LPCWSTR)pszGlobalData, + -1, + pszConvertData, + iConvertDataLen, + NULL, + NULL); + } + else + { + pszConvertData = strdup (pszGlobalData); + iConvertDataLen = strlen (pszConvertData) + 1; + } + + /* Convert DOS string to UNIX string */ + winClipboardDOStoUNIX (pszConvertData, strlen (pszConvertData)); + + /* Setup our text list */ + pszTextList[0] = pszConvertData; + pszTextList[1] = NULL; + + /* Initialize the text property */ + xtpText.value = NULL; + xtpText.nitems = 0; + + /* Create the text property from the text list */ + if (fUseUnicode) + { +#ifdef X_HAVE_UTF8_STRING + iReturn = Xutf8TextListToTextProperty (pDisplay, + pszTextList, + 1, + xiccesStyle, + &xtpText); +#endif + } + else + { + iReturn = XmbTextListToTextProperty (pDisplay, + pszTextList, + 1, + xiccesStyle, + &xtpText); + } + if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "X*TextListToTextProperty failed: %d\n", + iReturn); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Free the converted string */ + free (pszConvertData); + pszConvertData = NULL; + + /* Copy the clipboard text to the requesting window */ + iReturn = XChangeProperty (pDisplay, + event.xselectionrequest.requestor, + event.xselectionrequest.property, + event.xselectionrequest.target, + 8, + PropModeReplace, + xtpText.value, + xtpText.nitems); + if (iReturn == BadAlloc || iReturn == BadAtom + || iReturn == BadMatch || iReturn == BadValue + || iReturn == BadWindow) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "XChangeProperty failed: %d\n", + iReturn); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Release the clipboard data */ + GlobalUnlock (hGlobal); + pszGlobalData = NULL; + fCloseClipboard = FALSE; + CloseClipboard (); + + /* Clean up */ + XFree (xtpText.value); + xtpText.value = NULL; + xtpText.nitems = 0; + + /* Setup selection notify event */ + eventSelection.type = SelectionNotify; + eventSelection.send_event = True; + eventSelection.display = pDisplay; + eventSelection.requestor = event.xselectionrequest.requestor; + eventSelection.selection = event.xselectionrequest.selection; + eventSelection.target = event.xselectionrequest.target; + eventSelection.property = event.xselectionrequest.property; + eventSelection.time = event.xselectionrequest.time; + + /* Notify the requesting window that the operation has completed */ + iReturn = XSendEvent (pDisplay, + eventSelection.requestor, + False, + 0L, + (XEvent *) &eventSelection); + if (iReturn == BadValue || iReturn == BadWindow) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "XSendEvent () failed\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + winClipboardFlushXEvents_SelectionRequest_Done: + /* Free allocated resources */ + if (xtpText.value) + { + XFree (xtpText.value); + xtpText.value = NULL; + xtpText.nitems = 0; + } + free(pszConvertData); + if (hGlobal && pszGlobalData) + GlobalUnlock (hGlobal); + + /* + * Send a SelectionNotify event to the requesting + * client when we abort. + */ + if (fAbort) + { + /* Setup selection notify event */ + eventSelection.type = SelectionNotify; + eventSelection.send_event = True; + eventSelection.display = pDisplay; + eventSelection.requestor = event.xselectionrequest.requestor; + eventSelection.selection = event.xselectionrequest.selection; + eventSelection.target = event.xselectionrequest.target; + eventSelection.property = None; + eventSelection.time = event.xselectionrequest.time; + + /* Notify the requesting window that the operation is complete */ + iReturn = XSendEvent (pDisplay, + eventSelection.requestor, + False, + 0L, + (XEvent *) &eventSelection); + if (iReturn == BadValue || iReturn == BadWindow) + { + /* + * Should not be a problem if XSendEvent fails because + * the client may simply have exited. + */ + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "XSendEvent () failed for abort event.\n"); + } + } + + /* Close clipboard if it was opened */ + if (fCloseClipboard) + { + fCloseClipboard = FALSE; + CloseClipboard (); + } + break; + + + /* + * SelectionNotify + */ + + case SelectionNotify: + + winDebug ("winClipboardFlushXEvents - SelectionNotify\n"); + { + char *pszAtomName; + pszAtomName = XGetAtomName (pDisplay, + event.xselection.selection); + + winDebug("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n", + pszAtomName); + XFree (pszAtomName); + } + + /* + * Request conversion of UTF8 and CompoundText targets. + */ + if (event.xselection.property == None) + { + if (event.xselection.target == XA_STRING) + { + winDebug ("winClipboardFlushXEvents - SelectionNotify - " + "XA_STRING\n"); + + return WIN_XEVENTS_CONVERT; + } + else if (event.xselection.target == atomUTF8String) + { + winDebug("winClipboardFlushXEvents - SelectionNotify - " + "Requesting conversion of UTF8 target.\n"); + + XConvertSelection (pDisplay, + event.xselection.selection, + XA_STRING, + atomLocalProperty, + iWindow, + CurrentTime); + + /* Process the ConvertSelection event */ + XFlush (pDisplay); + return WIN_XEVENTS_CONVERT; + } +#ifdef X_HAVE_UTF8_STRING + else if (event.xselection.target == atomCompoundText) + { + winDebug("winClipboardFlushXEvents - SelectionNotify - " + "Requesting conversion of CompoundText target.\n"); + + XConvertSelection (pDisplay, + event.xselection.selection, + atomUTF8String, + atomLocalProperty, + iWindow, + CurrentTime); + + /* Process the ConvertSelection event */ + XFlush (pDisplay); + return WIN_XEVENTS_CONVERT; + } +#endif + else + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "Unknown format. Cannot request conversion, " + "aborting.\n"); + break; + } + } + + /* Retrieve the size of the stored data */ + iReturn = XGetWindowProperty (pDisplay, + iWindow, + atomLocalProperty, + 0, + 0, /* Don't get data, just size */ + False, + AnyPropertyType, + &xtpText.encoding, + &xtpText.format, + &xtpText.nitems, + &ulReturnBytesLeft, + &xtpText.value); + if (iReturn != Success) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "XGetWindowProperty () failed, aborting: %d\n", + iReturn); + break; + } + + winDebug("SelectionNotify - returned data %d left %d\n", + xtpText.nitems, ulReturnBytesLeft); + + /* Request the selection data */ + iReturn = XGetWindowProperty (pDisplay, + iWindow, + atomLocalProperty, + 0, + ulReturnBytesLeft, + False, + AnyPropertyType, + &xtpText.encoding, + &xtpText.format, + &xtpText.nitems, + &ulReturnBytesLeft, + &xtpText.value); + if (iReturn != Success) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "XGetWindowProperty () failed, aborting: %d\n", + iReturn); + break; + } + + { + char *pszAtomName = NULL; + + winDebug("SelectionNotify - returned data %d left %d\n", + xtpText.nitems, ulReturnBytesLeft); + pszAtomName = XGetAtomName(pDisplay, xtpText.encoding); + winDebug("Notify atom name %s\n", pszAtomName); + XFree (pszAtomName); + pszAtomName = NULL; + } + + if (fUseUnicode) + { +#ifdef X_HAVE_UTF8_STRING + /* Convert the text property to a text list */ + iReturn = Xutf8TextPropertyToTextList (pDisplay, + &xtpText, + &ppszTextList, + &iCount); +#endif + } + else + { + iReturn = XmbTextPropertyToTextList (pDisplay, + &xtpText, + &ppszTextList, + &iCount); + } + if (iReturn == Success || iReturn > 0) + { + /* Conversion succeeded or some unconvertible characters */ + if (ppszTextList != NULL) + { + iReturnDataLen = 0; + for (i = 0; i < iCount; i++) + { + iReturnDataLen += strlen(ppszTextList[i]); + } + pszReturnData = malloc (iReturnDataLen + 1); + pszReturnData[0] = '\0'; + for (i = 0; i < iCount; i++) + { + strcat (pszReturnData, ppszTextList[i]); + } + } + else + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "X*TextPropertyToTextList list_return is NULL.\n"); + pszReturnData = malloc (1); + pszReturnData[0] = '\0'; + } + } + else + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "X*TextPropertyToTextList returned: "); + switch (iReturn) + { + case XNoMemory: + ErrorF ("XNoMemory\n"); + break; + case XLocaleNotSupported: + ErrorF ("XLocaleNotSupported\n"); + break; + case XConverterNotFound: + ErrorF ("XConverterNotFound\n"); + break; + default: + ErrorF ("%d\n", iReturn); + break; + } + pszReturnData = malloc (1); + pszReturnData[0] = '\0'; + } + + /* Free the data returned from XGetWindowProperty */ + if (ppszTextList) + XFreeStringList (ppszTextList); + ppszTextList = NULL; + XFree (xtpText.value); + xtpText.value = NULL; + xtpText.nitems = 0; + + /* Convert the X clipboard string to DOS format */ + winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData)); + + if (fUseUnicode) + { + /* Find out how much space needed to convert MBCS to Unicode */ + iUnicodeLen = MultiByteToWideChar (CP_UTF8, + 0, + pszReturnData, + -1, + NULL, + 0); + + /* Allocate memory for the Unicode string */ + pwszUnicodeStr + = (wchar_t*) malloc (sizeof (wchar_t) * (iUnicodeLen + 1)); + if (!pwszUnicodeStr) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify " + "malloc failed for pwszUnicodeStr, aborting.\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionNotify_Done; + } + + /* Do the actual conversion */ + MultiByteToWideChar (CP_UTF8, + 0, + pszReturnData, + -1, + pwszUnicodeStr, + iUnicodeLen); + + /* Allocate global memory for the X clipboard data */ + hGlobal = GlobalAlloc (GMEM_MOVEABLE, + sizeof (wchar_t) * (iUnicodeLen + 1)); + } + else + { + pszConvertData = strdup (pszReturnData); + iConvertDataLen = strlen (pszConvertData) + 1; + + /* Allocate global memory for the X clipboard data */ + hGlobal = GlobalAlloc (GMEM_MOVEABLE, iConvertDataLen); + } + + free (pszReturnData); + + /* Check that global memory was allocated */ + if (!hGlobal) + { + ErrorF ("winClipboardFlushXEvents - SelectionNotify " + "GlobalAlloc failed, aborting: %ld\n", + GetLastError ()); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionNotify_Done; + } + + /* Obtain a pointer to the global memory */ + pszGlobalData = GlobalLock (hGlobal); + if (pszGlobalData == NULL) + { + ErrorF ("winClipboardFlushXEvents - Could not lock global " + "memory for clipboard transfer\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionNotify_Done; + } + + /* Copy the returned string into the global memory */ + if (fUseUnicode) + { + memcpy (pszGlobalData, + pwszUnicodeStr, + sizeof (wchar_t) * (iUnicodeLen + 1)); + free (pwszUnicodeStr); + pwszUnicodeStr = NULL; + } + else + { + strcpy (pszGlobalData, pszConvertData); + free (pszConvertData); + pszConvertData = NULL; + } + + /* Release the pointer to the global memory */ + GlobalUnlock (hGlobal); + pszGlobalData = NULL; + + /* Push the selection data to the Windows clipboard */ + if (fUseUnicode) + SetClipboardData (CF_UNICODETEXT, hGlobal); + else + SetClipboardData (CF_TEXT, hGlobal); + + /* Flag that SetClipboardData has been called */ + fSetClipboardData = FALSE; + + /* + * NOTE: Do not try to free pszGlobalData, it is owned by + * Windows after the call to SetClipboardData (). + */ + + winClipboardFlushXEvents_SelectionNotify_Done: + /* Free allocated resources */ + if (ppszTextList) + XFreeStringList (ppszTextList); + if (xtpText.value) + { + XFree (xtpText.value); + xtpText.value = NULL; + xtpText.nitems = 0; + } + free(pszConvertData); + free(pwszUnicodeStr); + if (hGlobal && pszGlobalData) + GlobalUnlock (hGlobal); + if (fSetClipboardData && g_fUnicodeSupport) + SetClipboardData (CF_UNICODETEXT, NULL); + if (fSetClipboardData) + SetClipboardData (CF_TEXT, NULL); + return WIN_XEVENTS_NOTIFY; + + case SelectionClear: + winDebug("SelectionClear - doing nothing\n"); + break; + + case PropertyNotify: + break; + + case MappingNotify: + break; + + default: + ErrorF ("winClipboardFlushXEvents - unexpected event type %d\n", event.type); + break; + } + } + + return WIN_XEVENTS_SUCCESS; +} diff --git a/xorg-server/hw/xwin/winmonitors.c b/xorg-server/hw/xwin/winmonitors.c index 63af803d0..a9d46f90e 100644 --- a/xorg-server/hw/xwin/winmonitors.c +++ b/xorg-server/hw/xwin/winmonitors.c @@ -53,7 +53,7 @@ wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _d return TRUE; } -typedef wBOOL (*ENUMDISPLAYMONITORSPROC)(HDC,LPCRECT,MONITORENUMPROC,LPARAM); +typedef WINAPI wBOOL (*ENUMDISPLAYMONITORSPROC)(HDC,LPCRECT,MONITORENUMPROC,LPARAM); ENUMDISPLAYMONITORSPROC _EnumDisplayMonitors; wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data); diff --git a/xorg-server/hw/xwin/winmultiwindowicons.c b/xorg-server/hw/xwin/winmultiwindowicons.c index 6af9636ea..763cb7e08 100644 --- a/xorg-server/hw/xwin/winmultiwindowicons.c +++ b/xorg-server/hw/xwin/winmultiwindowicons.c @@ -1,642 +1,641 @@ -/*
- *Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from the XFree86 Project.
- *
- * Authors: Earle F. Philhower, III
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include "dixevents.h"
-#include "winmultiwindowclass.h"
-#include "winprefs.h"
-
-#include "propertyst.h"
-
-#include "propertyst.h"
-#include "windowstr.h"
-
-
-/*
- * Prototypes for local functions
- */
-
-static void
-winScaleXBitmapToWindows (int iconSize, int effBPP,
- PixmapPtr pixmap, unsigned char *image);
-
-
-/*
- * Scale an X icon bitmap into a Windoze icon bitmap
- */
-
-static void
-winScaleXBitmapToWindows (int iconSize,
- int effBPP,
- PixmapPtr pixmap,
- unsigned char *image)
-{
- int row, column, effXBPP, effXDepth;
- unsigned char *outPtr;
- char *iconData = 0;
- int stride, xStride;
- float factX, factY;
- int posX, posY;
- unsigned char *ptr;
- unsigned int zero;
- unsigned int color;
-
- effXBPP = BitsPerPixel(pixmap->drawable.depth);
- effXDepth = pixmap->drawable.depth;
-
- if (pixmap->drawable.bitsPerPixel == 15)
- effXBPP = 16;
-
- if (pixmap->drawable.depth == 15)
- effXDepth = 16;
-
- /* Need 16-bit aligned rows for DDBitmaps */
- stride = ((iconSize * effBPP + 15) & (~15)) / 8;
- xStride = PixmapBytePad (pixmap->drawable.width, pixmap->drawable.depth);
- if (stride == 0 || xStride == 0)
- {
- ErrorF ("winScaleXBitmapToWindows - stride or xStride is zero. "
- "Bailing.\n");
- return;
- }
-
- /* Allocate memory for icon data */
- iconData = malloc (xStride * pixmap->drawable.height);
- if (!iconData)
- {
- ErrorF ("winScaleXBitmapToWindows - malloc failed for iconData. "
- "Bailing.\n");
- return;
- }
-
- /* Get icon data */
- miGetImage ((DrawablePtr) &(pixmap->drawable), 0, 0,
- pixmap->drawable.width, pixmap->drawable.height,
- ZPixmap, 0xffffffff, iconData);
-
- /* Keep aspect ratio */
- factX = ((float)pixmap->drawable.width) / ((float)iconSize);
- factY = ((float)pixmap->drawable.height) / ((float)iconSize);
- if (factX > factY)
- factY = factX;
- else
- factX = factY;
-
- /* Out-of-bounds, fill icon with zero */
- zero = 0;
-
- for (row = 0; row < iconSize; row++)
- {
- outPtr = image + stride * row;
- for (column = 0; column < iconSize; column++)
- {
- posX = factX * column;
- posY = factY * row;
-
- ptr = (unsigned char*) iconData + posY*xStride;
- if (effXBPP == 1)
- {
- ptr += posX / 8;
-
- /* Out of X icon bounds, leave space blank */
- if (posX >= pixmap->drawable.width
- || posY >= pixmap->drawable.height)
- ptr = (unsigned char *) &zero;
-
- if ((*ptr) & (1 << (posX & 7)))
- switch (effBPP)
- {
- case 32:
- *(outPtr++) = 0;
- case 24:
- *(outPtr++) = 0;
- case 16:
- *(outPtr++) = 0;
- case 8:
- *(outPtr++) = 0;
- break;
- case 1:
- outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
- break;
- }
- else
- switch (effBPP)
- {
- case 32:
- *(outPtr++) = 255;
- *(outPtr++) = 255;
- *(outPtr++) = 255;
- *(outPtr++) = 0;
- break;
- case 24:
- *(outPtr++) = 255;
- case 16:
- *(outPtr++) = 255;
- case 8:
- *(outPtr++) = 255;
- break;
- case 1:
- outPtr[column / 8] |= (1 << (7 - (column & 7)));
- break;
- }
- }
- else if (effXDepth == 24 || effXDepth == 32)
- {
- ptr += posX * (effXBPP / 8);
-
- /* Out of X icon bounds, leave space blank */
- if (posX >= pixmap->drawable.width
- || posY >= pixmap->drawable.height)
- ptr = (unsigned char *) &zero;
- color = (((*ptr) << 16)
- + ((*(ptr + 1)) << 8)
- + ((*(ptr + 2)) << 0));
- switch (effBPP)
- {
- case 32:
- *(outPtr++) = *(ptr++); /* b */
- *(outPtr++) = *(ptr++); /* g */
- *(outPtr++) = *(ptr++); /* r */
- *(outPtr++) = (effXDepth == 32) ? *(ptr++) : 0x0; /* alpha */
- break;
- case 24:
- *(outPtr++) = *(ptr++);
- *(outPtr++) = *(ptr++);
- *(outPtr++) = *(ptr++);
- break;
- case 16:
- color = ((((*ptr) >> 2) << 10)
- + (((*(ptr + 1)) >> 2) << 5)
- + (((*(ptr + 2)) >> 2)));
- *(outPtr++) = (color >> 8);
- *(outPtr++) = (color & 255);
- break;
- case 8:
- color = (((*ptr))) + (((*(ptr + 1)))) + (((*(ptr + 2))));
- color /= 3;
- *(outPtr++) = color;
- break;
- case 1:
- if (color)
- outPtr[column / 8] |= (1 << (7 - (column & 7)));
- else
- outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
- }
- }
- else if (effXDepth == 16)
- {
- ptr += posX * (effXBPP / 8);
-
- /* Out of X icon bounds, leave space blank */
- if (posX >= pixmap->drawable.width
- || posY >= pixmap->drawable.height)
- ptr = (unsigned char *) &zero;
- color = ((*ptr) << 8) + (*(ptr + 1));
- switch (effBPP)
- {
- case 32:
- *(outPtr++) = (color & 31) << 2;
- *(outPtr++) = ((color >> 5) & 31) << 2;
- *(outPtr++) = ((color >> 10) & 31) << 2;
- *(outPtr++) = 0; /* resvd */
- break;
- case 24:
- *(outPtr++) = (color & 31) << 2;
- *(outPtr++) = ((color >> 5) & 31) << 2;
- *(outPtr++) = ((color >> 10) & 31) << 2;
- break;
- case 16:
- *(outPtr++) = *(ptr++);
- *(outPtr++) = *(ptr++);
- break;
- case 8:
- *(outPtr++) = (((color & 31)
- + ((color >> 5) & 31)
- + ((color >> 10) & 31)) / 3) << 2;
- break;
- case 1:
- if (color)
- outPtr[column / 8] |= (1 << (7 - (column & 7)));
- else
- outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
- break;
- } /* end switch(effbpp) */
- } /* end if effxbpp==16) */
- } /* end for column */
- } /* end for row */
- free (iconData);
-}
-
-static HICON
-NetWMToWinIconAlpha(uint32_t *icon)
-{
- int width = icon[0];
- int height = icon[1];
- uint32_t *pixels = &icon[2];
- HICON result;
- HDC hdc = GetDC(NULL);
- uint32_t *DIB_pixels;
- ICONINFO ii = {TRUE};
- BITMAPV4HEADER bmh = {sizeof(bmh)};
-
- /* Define an ARGB pixel format used for Color+Alpha icons */
- bmh.bV4Width = width;
- bmh.bV4Height = -height; /* Invert the image */
- bmh.bV4Planes = 1;
- bmh.bV4BitCount = 32;
- bmh.bV4V4Compression = BI_BITFIELDS;
- bmh.bV4AlphaMask = 0xFF000000;
- bmh.bV4RedMask = 0x00FF0000;
- bmh.bV4GreenMask = 0x0000FF00;
- bmh.bV4BlueMask = 0x000000FF;
-
- ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh,
- DIB_RGB_COLORS, (void**)&DIB_pixels, NULL, 0);
- ReleaseDC(NULL, hdc);
- ii.hbmMask = CreateBitmap(width, height, 1, 1, NULL);
- memcpy(DIB_pixels, pixels, height*width*4);
-
- /* CreateIconIndirect() traditionally required DDBitmaps */
- /* Systems from WinXP accept 32-bit ARGB DIBitmaps with full 8-bit alpha support */
- /* The icon is created with a DIB + empty DDB mask (an MS example does the same) */
- result = CreateIconIndirect(&ii);
-
- DeleteObject(ii.hbmColor);
- DeleteObject(ii.hbmMask);
-
- winDebug("NetWMToWinIconAlpha - %d x %d = %p\n", icon[0], icon[1], result);
- return result;
-}
-
-static HICON
-NetWMToWinIconThreshold(uint32_t *icon)
-{
- int width = icon[0];
- int height = icon[1];
- uint32_t *pixels = &icon[2];
- int row, col;
- HICON result;
- ICONINFO ii = {TRUE};
-
- HDC hdc = GetDC(NULL);
- HDC xorDC = CreateCompatibleDC(hdc);
- HDC andDC = CreateCompatibleDC(hdc);
- ii.hbmColor = CreateCompatibleBitmap(hdc, width, height);
- ii.hbmMask = CreateCompatibleBitmap(hdc, width, height);
- ReleaseDC(NULL, hdc);
- SelectObject(xorDC, ii.hbmColor);
- SelectObject(andDC, ii.hbmMask);
-
- for (row = 0; row < height; row++) {
- for (col = 0; col < width; col++) {
- if ((*pixels & 0xFF000000) > 31<<24) { /* 31 alpha threshold, i.e. opaque above, transparent below */
- SetPixelV(xorDC, col, row, RGB(((char*)pixels)[2], ((char*)pixels)[1],
- ((char*)pixels)[0]));
- SetPixelV(andDC, col, row, RGB(0, 0, 0)); /* black mask */
- }
- else {
- SetPixelV(xorDC, col, row, RGB(0, 0, 0));
- SetPixelV(andDC, col, row, RGB(255, 255, 255)); /* white mask */
- }
- pixels++;
- }
- }
- DeleteDC(xorDC);
- DeleteDC(andDC);
-
- result = CreateIconIndirect(&ii);
-
- DeleteObject(ii.hbmColor);
- DeleteObject(ii.hbmMask );
-
- winDebug("NetWMToWinIconThreshold - %d x %d = %p\n", icon[0], icon[1], result);
- return result;
-}
-
-static HICON
-NetWMToWinIcon(int bpp, uint32_t *icon)
-{
- static Bool hasIconAlphaChannel = FALSE;
- static BOOL versionChecked = FALSE;
-
- if (!versionChecked)
- {
- OSVERSIONINFOEX osvi = {0};
- ULONGLONG dwlConditionMask = 0;
-
- osvi.dwOSVersionInfoSize = sizeof (osvi);
- osvi.dwMajorVersion = 5;
- osvi.dwMinorVersion = 1;
-
- /* Windows versions later than XP have icon alpha channel suport, 2000 does not */
- VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
- VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
- hasIconAlphaChannel = VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask);
- versionChecked = TRUE;
-
- ErrorF("OS has icon alpha channel support: %s\n", hasIconAlphaChannel ? "yes" : "no");
- }
-
- if (hasIconAlphaChannel && (bpp==32))
- return NetWMToWinIconAlpha(icon);
- else
- return NetWMToWinIconThreshold(icon);
-}
-
-static pointer
-GetWindowProp(WindowPtr pWin, Atom name, long int *size_return)
-{
- struct _Window *pwin;
- struct _Property *prop;
-
- if (!pWin || !name) {
- ErrorF ("GetWindowProp - pWin or name was NULL\n");
- return 0;
- }
- pwin = (struct _Window*) pWin;
- if (!pwin->optional) return NULL;
- for (prop = (struct _Property *) pwin->optional->userProps;
- prop;
- prop=prop->next){
- if (prop->propertyName == name) {
- *size_return=prop->size;
- return prop->data;
- }
- }
- return NULL;
-}
-
-/*
- * Attempt to create a custom icon from the WM_HINTS bitmaps
- */
-
-HICON
-winXIconToHICON (WindowPtr pWin, int iconSize)
-{
- unsigned char *mask, *image, *imageMask;
- unsigned char *dst, *src;
- PixmapPtr iconPtr;
- PixmapPtr maskPtr;
- int planes, bpp, effBPP, stride, maskStride, i;
- int biggest_size = 0;
- HDC hDC;
- ICONINFO ii;
- WinXWMHints hints;
- HICON hIcon = NULL;
- uint32_t *biggest_icon = NULL;
-
- /* Try to get _NET_WM_ICON icons first */
- static Atom _XA_NET_WM_ICON;
- static int generation;
- uint32_t *icon, *icon_data = NULL;
- long int size=0;
-
- hDC = GetDC (GetDesktopWindow ());
- planes = GetDeviceCaps (hDC, PLANES);
- bpp = GetDeviceCaps (hDC, BITSPIXEL);
- ReleaseDC (GetDesktopWindow (), hDC);
-
- if (generation != serverGeneration) {
- generation = serverGeneration;
- _XA_NET_WM_ICON = MakeAtom("_NET_WM_ICON", 12, TRUE);
- }
-
- if (_XA_NET_WM_ICON) icon_data = GetWindowProp(pWin, _XA_NET_WM_ICON, &size);
- if (icon_data)
- {
- for(icon = icon_data;
- icon < &icon_data[size] && *icon;
- icon = &icon[icon[0]*icon[1]+2])
- {
- if (icon[0]==iconSize && icon[1]==iconSize)
- return NetWMToWinIcon(bpp, icon);
- /* Find the biggest icon and let Windows scale the size */
- else if (biggest_size < icon[0])
- {
- biggest_icon = icon;
- biggest_size = icon[0];
- }
- }
- if (biggest_icon)
- return NetWMToWinIcon(bpp, biggest_icon);
- }
- winDebug("winXIconToHICON - pWin %x: no suitable NetIcon\n",(int)pWin, iconSize);
-
- winMultiWindowGetWMHints (pWin, &hints);
- if (!hints.icon_pixmap) return NULL;
-
- dixLookupResourceByType((pointer) &iconPtr, hints.icon_pixmap, RT_PIXMAP,
- NullClient, DixUnknownAccess);
-
- if (!iconPtr) return NULL;
-
- /* 15 BPP is really 16BPP as far as we care */
- if (bpp == 15)
- effBPP = 16;
- else
- effBPP = bpp;
-
- /* Need 16-bit aligned rows for DDBitmaps */
- stride = ((iconSize * effBPP + 15) & (~15)) / 8;
-
- /* Mask is 1-bit deep */
- maskStride = ((iconSize * 1 + 15) & (~15)) / 8;
-
- image = malloc (stride * iconSize);
- imageMask = malloc (stride * iconSize);
- /* Default to a completely black mask */
- mask = calloc (maskStride, iconSize);
-
- winScaleXBitmapToWindows (iconSize, effBPP, iconPtr, image);
- dixLookupResourceByType((pointer) &maskPtr, hints.icon_mask, RT_PIXMAP,
- NullClient, DixUnknownAccess);
-
- if (maskPtr)
- {
- winScaleXBitmapToWindows (iconSize, 1, maskPtr, mask);
-
- winScaleXBitmapToWindows (iconSize, effBPP, maskPtr, imageMask);
-
- /* Now we need to set all bits of the icon which are not masked */
- /* on to 0 because Color is really an XOR, not an OR function */
- dst = image;
- src = imageMask;
-
- for (i = 0; i < (stride * iconSize); i++)
- if ((*(src++)))
- *(dst++) = 0;
- else
- dst++;
- }
-
- ii.fIcon = TRUE;
- ii.xHotspot = 0; /* ignored */
- ii.yHotspot = 0; /* ignored */
-
- /* Create Win32 mask from pixmap shape */
- ii.hbmMask = CreateBitmap (iconSize, iconSize, planes, 1, mask);
-
- /* Create Win32 bitmap from pixmap */
- ii.hbmColor = CreateBitmap (iconSize, iconSize, planes, bpp, image);
-
- /* Merge Win32 mask and bitmap into icon */
- hIcon = CreateIconIndirect (&ii);
-
- /* Release Win32 mask and bitmap */
- DeleteObject (ii.hbmMask);
- DeleteObject (ii.hbmColor);
-
- /* Free X mask and bitmap */
- free (mask);
- free (image);
- free (imageMask);
-
- return hIcon;
-}
-
-
-
-/*
- * Change the Windows window icon
- */
-
-#ifdef XWIN_MULTIWINDOW
-void
-winUpdateIcon (Window id)
-{
- WindowPtr pWin;
- HICON hIcon, hIconSmall=NULL, hIconOld;
-
- dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess);
- if (pWin)
- {
- winWindowPriv(pWin);
- if (pWinPriv->hWnd) {
- hIcon = winOverrideIcon ((unsigned long)pWin);
- if (!hIcon) {
- hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
- if (!hIcon) {
- hIcon = g_hIconX;
- hIconSmall = g_hSmallIconX;
- } else {
- /* Leave undefined if not found */
- hIconSmall = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON));
- }
- }
-
- /* Set the large icon */
- hIconOld = (HICON) SendMessage (pWinPriv->hWnd,
- WM_SETICON, ICON_BIG, (LPARAM) hIcon);
-
- /* Delete the icon if its not the default */
- winDestroyIcon(hIconOld);
-
- /* Same for the small icon */
- hIconOld = (HICON) SendMessage (pWinPriv->hWnd,
- WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall);
- winDestroyIcon(hIconOld);
- }
- }
-}
-
-void winInitGlobalIcons (void)
-{
- int sm_cx = GetSystemMetrics(SM_CXICON);
- int sm_cxsm = GetSystemMetrics(SM_CXSMICON);
- /* Load default X icon in case it's not ready yet */
- if (!g_hIconX)
- {
- g_hIconX = winOverrideDefaultIcon(sm_cx);
- g_hSmallIconX = winOverrideDefaultIcon(sm_cxsm);
- }
-
- if (!g_hIconX)
- {
- g_hIconX = (HICON)LoadImage (g_hInstance,
- MAKEINTRESOURCE(IDI_XWIN),
- IMAGE_ICON,
- GetSystemMetrics(SM_CXICON),
- GetSystemMetrics(SM_CYICON),
- 0);
- g_hSmallIconX = (HICON)LoadImage (g_hInstance,
- MAKEINTRESOURCE(IDI_XWIN),
- IMAGE_ICON,
- GetSystemMetrics(SM_CXSMICON),
- GetSystemMetrics(SM_CYSMICON),
- LR_DEFAULTSIZE);
- }
-}
-
-void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon)
-{
- HICON hIcon, hSmallIcon;
-
- winInitGlobalIcons();
-
- /* Try and get the icon from WM_HINTS */
- hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
- hSmallIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON));
-
- /* If we got the small, but not the large one swap them */
- if (!hIcon && hSmallIcon)
- {
- hIcon = hSmallIcon;
- hSmallIcon = NULL;
- }
-
- /* Use default X icon if no icon loaded from WM_HINTS */
- if (!hIcon) {
- hIcon = g_hIconX;
- hSmallIcon = g_hSmallIconX;
- }
-
- if (pIcon)
- *pIcon = hIcon;
- else
- winDestroyIcon(hIcon);
- if (pSmallIcon)
- *pSmallIcon = hSmallIcon;
- else
- winDestroyIcon(hSmallIcon);
-}
-
-void winDestroyIcon(HICON hIcon)
-{
- /* Delete the icon if its not the default */
- if (hIcon &&
- hIcon != g_hIconX &&
- hIcon != g_hSmallIconX &&
- !winIconIsOverride((unsigned long)hIcon))
- DestroyIcon (hIcon);
-}
-#endif
+/* + *Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Earle F. Philhower, III + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" +#include "winprefs.h" + +#include "propertyst.h" +#include "windowstr.h" + + +/* + * Prototypes for local functions + */ + +static void +winScaleXBitmapToWindows (int iconSize, int effBPP, + PixmapPtr pixmap, unsigned char *image); + + +/* + * Scale an X icon bitmap into a Windoze icon bitmap + */ + +static void +winScaleXBitmapToWindows (int iconSize, + int effBPP, + PixmapPtr pixmap, + unsigned char *image) +{ + int row, column, effXBPP, effXDepth; + unsigned char *outPtr; + char *iconData = 0; + int stride, xStride; + float factX, factY; + int posX, posY; + unsigned char *ptr; + unsigned int zero; + unsigned int color; + + effXBPP = BitsPerPixel(pixmap->drawable.depth); + effXDepth = pixmap->drawable.depth; + + if (pixmap->drawable.bitsPerPixel == 15) + effXBPP = 16; + + if (pixmap->drawable.depth == 15) + effXDepth = 16; + + /* Need 16-bit aligned rows for DDBitmaps */ + stride = ((iconSize * effBPP + 15) & (~15)) / 8; + xStride = PixmapBytePad (pixmap->drawable.width, pixmap->drawable.depth); + if (stride == 0 || xStride == 0) + { + ErrorF ("winScaleXBitmapToWindows - stride or xStride is zero. " + "Bailing.\n"); + return; + } + + /* Allocate memory for icon data */ + iconData = malloc (xStride * pixmap->drawable.height); + if (!iconData) + { + ErrorF ("winScaleXBitmapToWindows - malloc failed for iconData. " + "Bailing.\n"); + return; + } + + /* Get icon data */ + miGetImage ((DrawablePtr) &(pixmap->drawable), 0, 0, + pixmap->drawable.width, pixmap->drawable.height, + ZPixmap, 0xffffffff, iconData); + + /* Keep aspect ratio */ + factX = ((float)pixmap->drawable.width) / ((float)iconSize); + factY = ((float)pixmap->drawable.height) / ((float)iconSize); + if (factX > factY) + factY = factX; + else + factX = factY; + + /* Out-of-bounds, fill icon with zero */ + zero = 0; + + for (row = 0; row < iconSize; row++) + { + outPtr = image + stride * row; + for (column = 0; column < iconSize; column++) + { + posX = factX * column; + posY = factY * row; + + ptr = (unsigned char*) iconData + posY*xStride; + if (effXBPP == 1) + { + ptr += posX / 8; + + /* Out of X icon bounds, leave space blank */ + if (posX >= pixmap->drawable.width + || posY >= pixmap->drawable.height) + ptr = (unsigned char *) &zero; + + if ((*ptr) & (1 << (posX & 7))) + switch (effBPP) + { + case 32: + *(outPtr++) = 0; + case 24: + *(outPtr++) = 0; + case 16: + *(outPtr++) = 0; + case 8: + *(outPtr++) = 0; + break; + case 1: + outPtr[column / 8] &= ~(1 << (7 - (column & 7))); + break; + } + else + switch (effBPP) + { + case 32: + *(outPtr++) = 255; + *(outPtr++) = 255; + *(outPtr++) = 255; + *(outPtr++) = 0; + break; + case 24: + *(outPtr++) = 255; + case 16: + *(outPtr++) = 255; + case 8: + *(outPtr++) = 255; + break; + case 1: + outPtr[column / 8] |= (1 << (7 - (column & 7))); + break; + } + } + else if (effXDepth == 24 || effXDepth == 32) + { + ptr += posX * (effXBPP / 8); + + /* Out of X icon bounds, leave space blank */ + if (posX >= pixmap->drawable.width + || posY >= pixmap->drawable.height) + ptr = (unsigned char *) &zero; + color = (((*ptr) << 16) + + ((*(ptr + 1)) << 8) + + ((*(ptr + 2)) << 0)); + switch (effBPP) + { + case 32: + *(outPtr++) = *(ptr++); /* b */ + *(outPtr++) = *(ptr++); /* g */ + *(outPtr++) = *(ptr++); /* r */ + *(outPtr++) = (effXDepth == 32) ? *(ptr++) : 0x0; /* alpha */ + break; + case 24: + *(outPtr++) = *(ptr++); + *(outPtr++) = *(ptr++); + *(outPtr++) = *(ptr++); + break; + case 16: + color = ((((*ptr) >> 2) << 10) + + (((*(ptr + 1)) >> 2) << 5) + + (((*(ptr + 2)) >> 2))); + *(outPtr++) = (color >> 8); + *(outPtr++) = (color & 255); + break; + case 8: + color = (((*ptr))) + (((*(ptr + 1)))) + (((*(ptr + 2)))); + color /= 3; + *(outPtr++) = color; + break; + case 1: + if (color) + outPtr[column / 8] |= (1 << (7 - (column & 7))); + else + outPtr[column / 8] &= ~(1 << (7 - (column & 7))); + } + } + else if (effXDepth == 16) + { + ptr += posX * (effXBPP / 8); + + /* Out of X icon bounds, leave space blank */ + if (posX >= pixmap->drawable.width + || posY >= pixmap->drawable.height) + ptr = (unsigned char *) &zero; + color = ((*ptr) << 8) + (*(ptr + 1)); + switch (effBPP) + { + case 32: + *(outPtr++) = (color & 31) << 2; + *(outPtr++) = ((color >> 5) & 31) << 2; + *(outPtr++) = ((color >> 10) & 31) << 2; + *(outPtr++) = 0; /* resvd */ + break; + case 24: + *(outPtr++) = (color & 31) << 2; + *(outPtr++) = ((color >> 5) & 31) << 2; + *(outPtr++) = ((color >> 10) & 31) << 2; + break; + case 16: + *(outPtr++) = *(ptr++); + *(outPtr++) = *(ptr++); + break; + case 8: + *(outPtr++) = (((color & 31) + + ((color >> 5) & 31) + + ((color >> 10) & 31)) / 3) << 2; + break; + case 1: + if (color) + outPtr[column / 8] |= (1 << (7 - (column & 7))); + else + outPtr[column / 8] &= ~(1 << (7 - (column & 7))); + break; + } /* end switch(effbpp) */ + } /* end if effxbpp==16) */ + } /* end for column */ + } /* end for row */ + free (iconData); +} + +static HICON +NetWMToWinIconAlpha(uint32_t *icon) +{ + int width = icon[0]; + int height = icon[1]; + uint32_t *pixels = &icon[2]; + HICON result; + HDC hdc = GetDC(NULL); + uint32_t *DIB_pixels; + ICONINFO ii = {TRUE}; + BITMAPV4HEADER bmh = {sizeof(bmh)}; + + /* Define an ARGB pixel format used for Color+Alpha icons */ + bmh.bV4Width = width; + bmh.bV4Height = -height; /* Invert the image */ + bmh.bV4Planes = 1; + bmh.bV4BitCount = 32; + bmh.bV4V4Compression = BI_BITFIELDS; + bmh.bV4AlphaMask = 0xFF000000; + bmh.bV4RedMask = 0x00FF0000; + bmh.bV4GreenMask = 0x0000FF00; + bmh.bV4BlueMask = 0x000000FF; + + ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh, + DIB_RGB_COLORS, (void**)&DIB_pixels, NULL, 0); + ReleaseDC(NULL, hdc); + ii.hbmMask = CreateBitmap(width, height, 1, 1, NULL); + memcpy(DIB_pixels, pixels, height*width*4); + + /* CreateIconIndirect() traditionally required DDBitmaps */ + /* Systems from WinXP accept 32-bit ARGB DIBitmaps with full 8-bit alpha support */ + /* The icon is created with a DIB + empty DDB mask (an MS example does the same) */ + result = CreateIconIndirect(&ii); + + DeleteObject(ii.hbmColor); + DeleteObject(ii.hbmMask); + + winDebug("NetWMToWinIconAlpha - %d x %d = %p\n", icon[0], icon[1], result); + return result; +} + +static HICON +NetWMToWinIconThreshold(uint32_t *icon) +{ + int width = icon[0]; + int height = icon[1]; + uint32_t *pixels = &icon[2]; + int row, col; + HICON result; + ICONINFO ii = {TRUE}; + + HDC hdc = GetDC(NULL); + HDC xorDC = CreateCompatibleDC(hdc); + HDC andDC = CreateCompatibleDC(hdc); + ii.hbmColor = CreateCompatibleBitmap(hdc, width, height); + ii.hbmMask = CreateCompatibleBitmap(hdc, width, height); + ReleaseDC(NULL, hdc); + SelectObject(xorDC, ii.hbmColor); + SelectObject(andDC, ii.hbmMask); + + for (row = 0; row < height; row++) { + for (col = 0; col < width; col++) { + if ((*pixels & 0xFF000000) > 31<<24) { /* 31 alpha threshold, i.e. opaque above, transparent below */ + SetPixelV(xorDC, col, row, RGB(((char*)pixels)[2], ((char*)pixels)[1], + ((char*)pixels)[0])); + SetPixelV(andDC, col, row, RGB(0, 0, 0)); /* black mask */ + } + else { + SetPixelV(xorDC, col, row, RGB(0, 0, 0)); + SetPixelV(andDC, col, row, RGB(255, 255, 255)); /* white mask */ + } + pixels++; + } + } + DeleteDC(xorDC); + DeleteDC(andDC); + + result = CreateIconIndirect(&ii); + + DeleteObject(ii.hbmColor); + DeleteObject(ii.hbmMask ); + + winDebug("NetWMToWinIconThreshold - %d x %d = %p\n", icon[0], icon[1], result); + return result; +} + +static HICON +NetWMToWinIcon(int bpp, uint32_t *icon) +{ + static Bool hasIconAlphaChannel = FALSE; + static BOOL versionChecked = FALSE; + + if (!versionChecked) + { + OSVERSIONINFOEX osvi = {0}; + ULONGLONG dwlConditionMask = 0; + + osvi.dwOSVersionInfoSize = sizeof (osvi); + osvi.dwMajorVersion = 5; + osvi.dwMinorVersion = 1; + + /* Windows versions later than XP have icon alpha channel suport, 2000 does not */ + VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); + hasIconAlphaChannel = VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask); + versionChecked = TRUE; + + ErrorF("OS has icon alpha channel support: %s\n", hasIconAlphaChannel ? "yes" : "no"); + } + + if (hasIconAlphaChannel && (bpp==32)) + return NetWMToWinIconAlpha(icon); + else + return NetWMToWinIconThreshold(icon); +} + +static pointer +GetWindowProp(WindowPtr pWin, Atom name, long int *size_return) +{ + struct _Window *pwin; + struct _Property *prop; + + if (!pWin || !name) { + ErrorF ("GetWindowProp - pWin or name was NULL\n"); + return 0; + } + pwin = (struct _Window*) pWin; + if (!pwin->optional) return NULL; + for (prop = (struct _Property *) pwin->optional->userProps; + prop; + prop=prop->next){ + if (prop->propertyName == name) { + *size_return=prop->size; + return prop->data; + } + } + return NULL; +} + +/* + * Attempt to create a custom icon from the WM_HINTS bitmaps + */ + +HICON +winXIconToHICON (WindowPtr pWin, int iconSize) +{ + unsigned char *mask, *image, *imageMask; + unsigned char *dst, *src; + PixmapPtr iconPtr; + PixmapPtr maskPtr; + int planes, bpp, effBPP, stride, maskStride, i; + int biggest_size = 0; + HDC hDC; + ICONINFO ii; + WinXWMHints hints; + HICON hIcon = NULL; + uint32_t *biggest_icon = NULL; + + /* Try to get _NET_WM_ICON icons first */ + static Atom _XA_NET_WM_ICON; + static int generation; + uint32_t *icon, *icon_data = NULL; + long int size=0; + + hDC = GetDC (GetDesktopWindow ()); + planes = GetDeviceCaps (hDC, PLANES); + bpp = GetDeviceCaps (hDC, BITSPIXEL); + ReleaseDC (GetDesktopWindow (), hDC); + + if (generation != serverGeneration) { + generation = serverGeneration; + _XA_NET_WM_ICON = MakeAtom("_NET_WM_ICON", 12, TRUE); + } + + if (_XA_NET_WM_ICON) icon_data = GetWindowProp(pWin, _XA_NET_WM_ICON, &size); + if (icon_data) + { + for(icon = icon_data; + icon < &icon_data[size] && *icon; + icon = &icon[icon[0]*icon[1]+2]) + { + if (icon[0]==iconSize && icon[1]==iconSize) + return NetWMToWinIcon(bpp, icon); + /* Find the biggest icon and let Windows scale the size */ + else if (biggest_size < icon[0]) + { + biggest_icon = icon; + biggest_size = icon[0]; + } + } + if (biggest_icon) + return NetWMToWinIcon(bpp, biggest_icon); + } + winDebug("winXIconToHICON - pWin %x: no suitable NetIcon\n",(int)pWin, iconSize); + + winMultiWindowGetWMHints (pWin, &hints); + if (!hints.icon_pixmap) return NULL; + + dixLookupResourceByType((pointer) &iconPtr, hints.icon_pixmap, RT_PIXMAP, + NullClient, DixUnknownAccess); + + if (!iconPtr) return NULL; + + /* 15 BPP is really 16BPP as far as we care */ + if (bpp == 15) + effBPP = 16; + else + effBPP = bpp; + + /* Need 16-bit aligned rows for DDBitmaps */ + stride = ((iconSize * effBPP + 15) & (~15)) / 8; + + /* Mask is 1-bit deep */ + maskStride = ((iconSize * 1 + 15) & (~15)) / 8; + + image = malloc (stride * iconSize); + imageMask = malloc (stride * iconSize); + /* Default to a completely black mask */ + mask = calloc (maskStride, iconSize); + + winScaleXBitmapToWindows (iconSize, effBPP, iconPtr, image); + dixLookupResourceByType((pointer) &maskPtr, hints.icon_mask, RT_PIXMAP, + NullClient, DixUnknownAccess); + + if (maskPtr) + { + winScaleXBitmapToWindows (iconSize, 1, maskPtr, mask); + + winScaleXBitmapToWindows (iconSize, effBPP, maskPtr, imageMask); + + /* Now we need to set all bits of the icon which are not masked */ + /* on to 0 because Color is really an XOR, not an OR function */ + dst = image; + src = imageMask; + + for (i = 0; i < (stride * iconSize); i++) + if ((*(src++))) + *(dst++) = 0; + else + dst++; + } + + ii.fIcon = TRUE; + ii.xHotspot = 0; /* ignored */ + ii.yHotspot = 0; /* ignored */ + + /* Create Win32 mask from pixmap shape */ + ii.hbmMask = CreateBitmap (iconSize, iconSize, planes, 1, mask); + + /* Create Win32 bitmap from pixmap */ + ii.hbmColor = CreateBitmap (iconSize, iconSize, planes, bpp, image); + + /* Merge Win32 mask and bitmap into icon */ + hIcon = CreateIconIndirect (&ii); + + /* Release Win32 mask and bitmap */ + DeleteObject (ii.hbmMask); + DeleteObject (ii.hbmColor); + + /* Free X mask and bitmap */ + free (mask); + free (image); + free (imageMask); + + return hIcon; +} + + + +/* + * Change the Windows window icon + */ + +#ifdef XWIN_MULTIWINDOW +void +winUpdateIcon (Window id) +{ + WindowPtr pWin; + HICON hIcon, hIconSmall=NULL, hIconOld; + + dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess); + if (pWin) + { + winWindowPriv(pWin); + if (pWinPriv->hWnd) { + hIcon = winOverrideIcon ((unsigned long)pWin); + if (!hIcon) { + hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); + if (!hIcon) { + hIcon = g_hIconX; + hIconSmall = g_hSmallIconX; + } else { + /* Leave undefined if not found */ + hIconSmall = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON)); + } + } + + /* Set the large icon */ + hIconOld = (HICON) SendMessage (pWinPriv->hWnd, + WM_SETICON, ICON_BIG, (LPARAM) hIcon); + + /* Delete the icon if its not the default */ + winDestroyIcon(hIconOld); + + /* Same for the small icon */ + hIconOld = (HICON) SendMessage (pWinPriv->hWnd, + WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall); + winDestroyIcon(hIconOld); + } + } +} + +void winInitGlobalIcons (void) +{ + int sm_cx = GetSystemMetrics(SM_CXICON); + int sm_cxsm = GetSystemMetrics(SM_CXSMICON); + /* Load default X icon in case it's not ready yet */ + if (!g_hIconX) + { + g_hIconX = winOverrideDefaultIcon(sm_cx); + g_hSmallIconX = winOverrideDefaultIcon(sm_cxsm); + } + + if (!g_hIconX) + { + g_hIconX = (HICON)LoadImage (g_hInstance, + MAKEINTRESOURCE(IDI_XWIN), + IMAGE_ICON, + GetSystemMetrics(SM_CXICON), + GetSystemMetrics(SM_CYICON), + 0); + g_hSmallIconX = (HICON)LoadImage (g_hInstance, + MAKEINTRESOURCE(IDI_XWIN), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + LR_DEFAULTSIZE); + } +} + +void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon) +{ + HICON hIcon, hSmallIcon; + + winInitGlobalIcons(); + + /* Try and get the icon from WM_HINTS */ + hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); + hSmallIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON)); + + /* If we got the small, but not the large one swap them */ + if (!hIcon && hSmallIcon) + { + hIcon = hSmallIcon; + hSmallIcon = NULL; + } + + /* Use default X icon if no icon loaded from WM_HINTS */ + if (!hIcon) { + hIcon = g_hIconX; + hSmallIcon = g_hSmallIconX; + } + + if (pIcon) + *pIcon = hIcon; + else + winDestroyIcon(hIcon); + + if (pSmallIcon) + *pSmallIcon = hSmallIcon; + else + winDestroyIcon(hSmallIcon); +} + +void winDestroyIcon(HICON hIcon) +{ + /* Delete the icon if its not one of the application defaults or an override */ + if (hIcon && + hIcon != g_hIconX && + hIcon != g_hSmallIconX && + !winIconIsOverride((unsigned long)hIcon)) + DestroyIcon (hIcon); +} +#endif diff --git a/xorg-server/hw/xwin/winmultiwindowwindow.c b/xorg-server/hw/xwin/winmultiwindowwindow.c index 93434fceb..21b818b89 100644 --- a/xorg-server/hw/xwin/winmultiwindowwindow.c +++ b/xorg-server/hw/xwin/winmultiwindowwindow.c @@ -1,992 +1,1008 @@ -/*
- *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- *Copyright (C) Colin Harrison 2005-2008
- *
- *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 XFREE86 PROJECT 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 of the XFree86 Project
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from the XFree86 Project.
- *
- * Authors: Kensuke Matsuzaki
- * Earle F. Philhower, III
- * Harold L Hunt II
- * Colin Harrison
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include "dixevents.h"
-#include "winmultiwindowclass.h"
-
-/*
- * Prototypes for local functions
- */
-
-void
-winCreateWindowsWindow (WindowPtr pWin);
-
-static void
-winDestroyWindowsWindow (WindowPtr pWin);
-
-static void
-winUpdateWindowsWindow (WindowPtr pWin);
-
-static void
-winFindWindow (pointer value, XID id, pointer cdata);
-
-static
-void winInitMultiWindowClass(void)
-{
- static wATOM atomXWinClass=0;
- WNDCLASSEX wcx;
-
- if (atomXWinClass==0)
- {
- /* Setup our window class */
- wcx.cbSize=sizeof(WNDCLASSEX);
- wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0);
- wcx.lpfnWndProc = winTopLevelWindowProc;
- wcx.cbClsExtra = 0;
- wcx.cbWndExtra = 0;
- wcx.hInstance = g_hInstance;
- wcx.hIcon = g_hIconX;
- wcx.hCursor = 0;
- wcx.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
- wcx.lpszMenuName = NULL;
- wcx.lpszClassName = WINDOW_CLASS_X;
- wcx.hIconSm = g_hSmallIconX;
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X);
-#endif
-
- atomXWinClass = RegisterClassEx (&wcx);
- }
-}
-
-/*
- * CreateWindow - See Porting Layer Definition - p. 37
- */
-
-Bool
-winCreateWindowMultiWindow (WindowPtr pWin)
-{
- Bool fResult = TRUE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG
- winTrace ("winCreateWindowMultiWindow - pWin: %p\n", pWin);
-#endif
-
- WIN_UNWRAP(CreateWindow);
- fResult = (*pScreen->CreateWindow) (pWin);
- WIN_WRAP(CreateWindow, winCreateWindowMultiWindow);
-
- /* Initialize some privates values */
- pWinPriv->hRgn = NULL;
- pWinPriv->hWnd = NULL;
- pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen);
- pWinPriv->fXKilled = FALSE;
-
- return fResult;
-}
-
-
-/*
- * DestroyWindow - See Porting Layer Definition - p. 37
- */
-
-Bool
-winDestroyWindowMultiWindow (WindowPtr pWin)
-{
- Bool fResult = TRUE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winDestroyWindowMultiWindow - pWin: %p\n", pWin);
-#endif
-
- WIN_UNWRAP(DestroyWindow);
- fResult = (*pScreen->DestroyWindow)(pWin);
- WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow);
-
- /* Flag that the window has been destroyed */
- pWinPriv->fXKilled = TRUE;
-
- /* Kill the MS Windows window associated with this window */
- winDestroyWindowsWindow (pWin);
-
- return fResult;
-}
-
-
-/*
- * PositionWindow - See Porting Layer Definition - p. 37
- *
- * This function adjusts the position and size of Windows window
- * with respect to the underlying X window. This is the inverse
- * of winAdjustXWindow, which adjusts X window to Windows window.
- */
-
-Bool
-winPositionWindowMultiWindow (WindowPtr pWin, int x, int y)
-{
- Bool fResult = TRUE;
- int iX, iY, iWidth, iHeight;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
- HWND hWnd = pWinPriv->hWnd;
- RECT rcNew;
- RECT rcOld;
-#if CYGMULTIWINDOW_DEBUG
- RECT rcClient;
- RECT *lpRc;
-#endif
- DWORD dwExStyle;
- DWORD dwStyle;
-
-#if CYGMULTIWINDOW_DEBUG
- winTrace ("winPositionWindowMultiWindow - pWin: %p\n", pWin);
-#endif
-
- WIN_UNWRAP(PositionWindow);
- fResult = (*pScreen->PositionWindow)(pWin, x, y);
- WIN_WRAP(PositionWindow, winPositionWindowMultiWindow);
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n",
- x, y);
-#endif
-
- /* Bail out if the Windows window handle is bad */
- if (!hWnd)
- {
-#if CYGWINDOWING_DEBUG
- ErrorF ("\timmediately return since hWnd is NULL\n");
-#endif
- return fResult;
- }
-
- /* Get the Windows window style and extended style */
- dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE);
- dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE);
-
- /* Get the X and Y location of the X window */
- iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
- iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
-
- /* Get the height and width of the X window */
- iWidth = pWin->drawable.width;
- iHeight = pWin->drawable.height;
-
- /* Store the origin, height, and width in a rectangle structure */
- SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
-
-#if CYGMULTIWINDOW_DEBUG
- lpRc = &rcNew;
- ErrorF ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n",
- GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
-#endif
-
- /*
- * Calculate the required size of the Windows window rectangle,
- * given the size of the Windows window client area.
- */
- AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle);
-
- /* Get a rectangle describing the old Windows window */
- GetWindowRect (hWnd, &rcOld);
-
-#if CYGMULTIWINDOW_DEBUG
- /* Get a rectangle describing the Windows window client area */
- GetClientRect (hWnd, &rcClient);
-
- lpRc = &rcNew;
- ErrorF ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n",
- GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
-
- lpRc = &rcOld;
- ErrorF ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n",
- GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
-
- lpRc = &rcClient;
- ErrorF ("(%d ms)rcClient (%d, %d)-(%d, %d)\n",
- GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
-#endif
-
- /* Check if the old rectangle and new rectangle are the same */
- if (!EqualRect (&rcNew, &rcOld))
- {
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winPositionWindowMultiWindow - Need to move\n");
-#endif
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("\tMoveWindow to (%ld, %ld) - %ldx%ld\n", rcNew.left, rcNew.top,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
-#endif
- /* Change the position and dimensions of the Windows window */
- MoveWindow (hWnd,
- rcNew.left, rcNew.top,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
- TRUE);
- }
- else
- {
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winPositionWindowMultiWindow - Not need to move\n");
-#endif
- }
-
- return fResult;
-}
-
-
-/*
- * ChangeWindowAttributes - See Porting Layer Definition - p. 37
- */
-
-Bool
-winChangeWindowAttributesMultiWindow (WindowPtr pWin, unsigned long mask)
-{
- Bool fResult = TRUE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin);
-#endif
-
- WIN_UNWRAP(ChangeWindowAttributes);
- fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask);
- WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow);
-
- /*
- * NOTE: We do not currently need to do anything here.
- */
-
- return fResult;
-}
-
-
-/*
- * UnmapWindow - See Porting Layer Definition - p. 37
- * Also referred to as UnrealizeWindow
- */
-
-Bool
-winUnmapWindowMultiWindow (WindowPtr pWin)
-{
- Bool fResult = TRUE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin);
-#endif
-
- WIN_UNWRAP(UnrealizeWindow);
- fResult = (*pScreen->UnrealizeWindow)(pWin);
- WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow);
-
- /* Flag that the window has been killed */
- pWinPriv->fXKilled = TRUE;
-
- /* Destroy the Windows window associated with this X window */
- winDestroyWindowsWindow (pWin);
-
- return fResult;
-}
-
-
-/*
- * MapWindow - See Porting Layer Definition - p. 37
- * Also referred to as RealizeWindow
- */
-
-Bool
-winMapWindowMultiWindow (WindowPtr pWin)
-{
- Bool fResult = TRUE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin);
-#endif
-
- WIN_UNWRAP(RealizeWindow);
- fResult = (*pScreen->RealizeWindow)(pWin);
- WIN_WRAP(RealizeWindow, winMapWindowMultiWindow);
-
- /* Flag that this window has not been destroyed */
- pWinPriv->fXKilled = FALSE;
-
- /* Refresh/redisplay the Windows window associated with this X window */
- winUpdateWindowsWindow (pWin);
-
- /* Update the Windows window's shape */
- winReshapeMultiWindow (pWin);
- winUpdateRgnMultiWindow (pWin);
-
- return fResult;
-}
-
-
-/*
- * ReparentWindow - See Porting Layer Definition - p. 42
- */
-
-void
-winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin);
-#endif
-
- WIN_UNWRAP(ReparentWindow);
- if (pScreen->ReparentWindow)
- (*pScreen->ReparentWindow)(pWin, pPriorParent);
- WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow);
-
- /* Update the Windows window associated with this X window */
- winUpdateWindowsWindow (pWin);
-}
-
-
-/*
- * RestackWindow - Shuffle the z-order of a window
- */
-
-void
-winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib)
-{
-#if 0
- WindowPtr pPrevWin;
- UINT uFlags;
- HWND hInsertAfter;
- HWND hWnd = NULL;
-#endif
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
-#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
- winTrace ("winRestackMultiWindow - %08x\n", pWin);
-#endif
-
- WIN_UNWRAP(RestackWindow);
- if (pScreen->RestackWindow)
- (*pScreen->RestackWindow)(pWin, pOldNextSib);
- WIN_WRAP(RestackWindow, winRestackWindowMultiWindow);
-
-#if 1
- /*
- * Calling winReorderWindowsMultiWindow here means our window manager
- * (i.e. Windows Explorer) has initiative to determine Z order.
- */
- if (pWin->nextSib != pOldNextSib)
- winReorderWindowsMultiWindow ();
-#else
- /* Bail out if no window privates or window handle is invalid */
- if (!pWinPriv || !pWinPriv->hWnd)
- return;
-
- /* Get a pointer to our previous sibling window */
- pPrevWin = pWin->prevSib;
-
- /*
- * Look for a sibling window with
- * valid privates and window handle
- */
- while (pPrevWin
- && !winGetWindowPriv(pPrevWin)
- && !winGetWindowPriv(pPrevWin)->hWnd)
- pPrevWin = pPrevWin->prevSib;
-
- /* Check if we found a valid sibling */
- if (pPrevWin)
- {
- /* Valid sibling - get handle to insert window after */
- hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd;
- uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
-
- hWnd = GetNextWindow (pWinPriv->hWnd, GW_HWNDPREV);
-
- do
- {
- if (GetProp (hWnd, WIN_WINDOW_PROP))
- {
- if (hWnd == winGetWindowPriv(pPrevWin)->hWnd)
- {
- uFlags |= SWP_NOZORDER;
- }
- break;
- }
- hWnd = GetNextWindow (hWnd, GW_HWNDPREV);
- }
- while (hWnd);
- }
- else
- {
- /* No valid sibling - make this window the top window */
- hInsertAfter = HWND_TOP;
- uFlags = SWP_NOMOVE | SWP_NOSIZE;
- }
-
- /* Perform the restacking operation in Windows */
- SetWindowPos (pWinPriv->hWnd,
- hInsertAfter,
- 0, 0,
- 0, 0,
- uFlags);
-#endif
-}
-
-
-/*
- * winCreateWindowsWindow - Create a Windows window associated with an X window
- */
-
-void
-winCreateWindowsWindow (WindowPtr pWin)
-{
- int iX, iY;
- int iWidth;
- int iHeight;
- HWND hWnd;
- HWND hFore = NULL;
- winWindowPriv(pWin);
- HICON hIcon;
- HICON hIconSmall;
- winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv;
- WinXSizeHints hints;
- WindowPtr pDaddy;
-
- winInitMultiWindowClass();
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin);
-#endif
-
- iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
- iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
-
- iWidth = pWin->drawable.width;
- iHeight = pWin->drawable.height;
-
- /* ensure window actually ends up somewhere visible */
- if (iX > GetSystemMetrics (SM_CXVIRTUALSCREEN))
- iX = CW_USEDEFAULT;
-
- if (iY > GetSystemMetrics (SM_CYVIRTUALSCREEN))
- iY = CW_USEDEFAULT;
-
- if (winMultiWindowGetTransientFor (pWin, &pDaddy))
- {
- if (pDaddy)
- {
- hFore = GetForegroundWindow();
- if (hFore && (pDaddy != (WindowPtr)GetProp(hFore, WIN_WID_PROP))) hFore = NULL;
- }
- }
- else
- {
- /* Default positions if none specified */
- if (!winMultiWindowGetWMNormalHints(pWin, &hints))
- hints.flags = 0;
- if (!(hints.flags & (USPosition|PPosition)) &&
- !pWin->overrideRedirect)
- {
- iX = CW_USEDEFAULT;
- iY = CW_USEDEFAULT;
- }
- }
-
- /* Create the window */
- /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */
- /* CW_USEDEFAULT, change back to popup after creation */
- hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */
- WINDOW_CLASS_X, /* Class name */
- WINDOW_TITLE_X, /* Window name */
- WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
- iX, /* Horizontal position */
- iY, /* Vertical position */
- iWidth, /* Right edge */
- iHeight, /* Bottom edge */
- hFore, /* Null or Parent window if transient*/
- (HMENU) NULL, /* No menu */
- GetModuleHandle (NULL), /* Instance handle */
- pWin); /* ScreenPrivates */
- if (hWnd == NULL)
- {
- ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
- (int) GetLastError ());
- }
- pWinPriv->hWnd = hWnd;
-
- /* Set application or .XWinrc defined Icons */
- winSelectIcons(pWin, &hIcon, &hIconSmall);
- if (hIcon) SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
- if (hIconSmall) SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall);
-
- /* Change style back to popup, already placed... */
- SetWindowLongPtr(hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
- SetWindowPos (hWnd, 0, 0, 0, 0, 0,
- SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
- /* Make sure it gets the proper system menu for a WS_POPUP, too */
- GetSystemMenu (hWnd, TRUE);
-
- /* Cause any .XWinrc menus to be added in main WNDPROC */
- PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0);
-
- SetProp (hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin));
-
- /* Flag that this Windows window handles its own activation */
- SetProp (hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
-
- /* Call engine-specific create window procedure */
- (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin);
-}
-
-
-Bool winInDestroyWindowsWindow = FALSE;
-/*
- * winDestroyWindowsWindow - Destroy a Windows window associated
- * with an X window
- */
-static void
-winDestroyWindowsWindow (WindowPtr pWin)
-{
- MSG msg;
- winWindowPriv(pWin);
- BOOL oldstate = winInDestroyWindowsWindow;
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winDestroyWindowsWindow\n");
-#endif
-
- /* Bail out if the Windows window handle is invalid */
- if (pWinPriv->hWnd == NULL)
- return;
-
- winInDestroyWindowsWindow = TRUE;
-
- SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, NULL);
- /* Destroy the Windows window */
- DestroyWindow (pWinPriv->hWnd);
-
- /* Null our handle to the Window so referencing it will cause an error */
- pWinPriv->hWnd = NULL;
-
- /* Process all messages on our queue */
- while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
- {
- if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg))
- {
- DispatchMessage (&msg);
- }
- }
-
- winInDestroyWindowsWindow = oldstate;
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("-winDestroyWindowsWindow\n");
-#endif
-}
-
-
-/*
- * winUpdateWindowsWindow - Redisplay/redraw a Windows window
- * associated with an X window
- */
-
-static void
-winUpdateWindowsWindow (WindowPtr pWin)
-{
- winWindowPriv(pWin);
- HWND hWnd = pWinPriv->hWnd;
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winUpdateWindowsWindow\n");
-#endif
-
- /* Check if the Windows window's parents have been destroyed */
- if (pWin->parent != NULL
- && pWin->parent->parent == NULL
- && pWin->mapped)
- {
- /* Create the Windows window if it has been destroyed */
- if (hWnd == NULL)
- {
- winCreateWindowsWindow (pWin);
- assert (pWinPriv->hWnd != NULL);
- }
-
- /* Display the window without activating it */
- ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
-
- /* Send first paint message */
- UpdateWindow (pWinPriv->hWnd);
- }
- else if (hWnd != NULL)
- {
- /* Destroy the Windows window if its parents are destroyed */
- winDestroyWindowsWindow (pWin);
- assert (pWinPriv->hWnd == NULL);
- }
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("-winUpdateWindowsWindow\n");
-#endif
-}
-
-
-/*
- * winGetWindowID -
- */
-
-XID
-winGetWindowID (WindowPtr pWin)
-{
- WindowIDPairRec wi = {pWin, 0};
- ClientPtr c = wClient(pWin);
-
- /* */
- FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winGetWindowID - Window ID: %d\n", wi.id);
-#endif
-
- return wi.id;
-}
-
-
-/*
- * winFindWindow -
- */
-
-static void
-winFindWindow (pointer value, XID id, pointer cdata)
-{
- WindowIDPairPtr wi = (WindowIDPairPtr)cdata;
-
- if (value == wi->value)
- {
- wi->id = id;
- }
-}
-
-
-/*
- * winReorderWindowsMultiWindow -
- */
-
-void
-winReorderWindowsMultiWindow (void)
-{
- HWND hwnd = NULL;
- WindowPtr pWin = NULL;
- WindowPtr pWinSib = NULL;
- XID vlist[2];
- static Bool fRestacking = FALSE; /* Avoid recusive calls to this function */
- DWORD dwCurrentProcessID = GetCurrentProcessId ();
- DWORD dwWindowProcessID = 0;
-
-#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG
- winTrace ("winReorderWindowsMultiWindow\n");
-#endif
-
- if (fRestacking)
- {
- /* It is a recusive call so immediately exit */
-#if CYGWINDOWING_DEBUG
- ErrorF ("winReorderWindowsMultiWindow - "
- "exit because fRestacking == TRUE\n");
-#endif
- return;
- }
- fRestacking = TRUE;
-
- /* Loop through top level Window windows, descending in Z order */
- for ( hwnd = GetTopWindow (NULL);
- hwnd;
- hwnd = GetNextWindow (hwnd, GW_HWNDNEXT) )
- {
- /* Don't take care of other Cygwin/X process's windows */
- GetWindowThreadProcessId (hwnd, &dwWindowProcessID);
-
- if ( GetProp (hwnd, WIN_WINDOW_PROP)
- && (dwWindowProcessID == dwCurrentProcessID)
- && !IsIconic (hwnd) ) /* ignore minimized windows */
- {
- pWinSib = pWin;
- pWin = GetProp (hwnd, WIN_WINDOW_PROP);
-
- if (!pWinSib)
- { /* 1st window - raise to the top */
- vlist[0] = Above;
-
- ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin));
- }
- else
- { /* 2nd or deeper windows - just below the previous one */
- vlist[0] = winGetWindowID (pWinSib);
- vlist[1] = Below;
-
- ConfigureWindow (pWin, CWSibling | CWStackMode,
- vlist, wClient(pWin));
- }
- }
- }
-
- fRestacking = FALSE;
-}
-
-
-/*
- * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE
- */
-
-void
-winMinimizeWindow (Window id)
-{
- WindowPtr pWin;
- winPrivWinPtr pWinPriv;
-#ifdef XWIN_MULTIWINDOWEXTWM
- win32RootlessWindowPtr pRLWinPriv;
-#endif
- HWND hWnd;
- ScreenPtr pScreen = NULL;
- winPrivScreenPtr pScreenPriv = NULL;
- winScreenInfo *pScreenInfo = NULL;
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("winMinimizeWindow\n");
-#endif
-
- dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess);
- if (!pWin)
- {
- ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__);
- return;
- }
-
- pScreen = pWin->drawable.pScreen;
- if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
- if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
-
-#ifdef XWIN_MULTIWINDOWEXTWM
- if (pScreenPriv && pScreenInfo->fInternalWM)
- {
- pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
- hWnd = pRLWinPriv->hWnd;
- }
- else
-#else
- if (pScreenPriv)
-#endif
- {
- pWinPriv = winGetWindowPriv (pWin);
- hWnd = pWinPriv->hWnd;
- }
-
- ShowWindow (hWnd, SW_MINIMIZE);
-}
-
-
-/*
- * CopyWindow - See Porting Layer Definition - p. 39
- */
-void
-winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt,
- RegionPtr oldRegion)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("CopyWindowMultiWindow\n");
-#endif
- WIN_UNWRAP(CopyWindow);
- (*pScreen->CopyWindow)(pWin, oldpt, oldRegion);
- WIN_WRAP(CopyWindow, winCopyWindowMultiWindow);
-}
-
-
-/*
- * MoveWindow - See Porting Layer Definition - p. 42
- */
-void
-winMoveWindowMultiWindow (WindowPtr pWin, int x, int y,
- WindowPtr pSib, VTKind kind)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("MoveWindowMultiWindow to (%d, %d)\n", x, y);
-#endif
-
- WIN_UNWRAP(MoveWindow);
- (*pScreen->MoveWindow)(pWin, x, y, pSib, kind);
- WIN_WRAP(MoveWindow, winMoveWindowMultiWindow);
-}
-
-
-/*
- * ResizeWindow - See Porting Layer Definition - p. 42
- */
-void
-winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w,
- unsigned int h, WindowPtr pSib)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h);
-#endif
- WIN_UNWRAP(ResizeWindow);
- (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
- WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow);
-}
-
-
-/*
- * winAdjustXWindow
- *
- * Move and resize X window with respect to corresponding Windows window.
- * This is called from WM_MOVE/WM_SIZE handlers when the user performs
- * any windowing operation (move, resize, minimize, maximize, restore).
- *
- * The functionality is the inverse of winPositionWindowMultiWindow, which
- * adjusts Windows window with respect to X window.
- */
-int
-winAdjustXWindow (WindowPtr pWin, HWND hwnd)
-{
- RECT rcDraw; /* Rect made from pWin->drawable to be adjusted */
- RECT rcWin; /* The source: WindowRect from hwnd */
- DrawablePtr pDraw;
- XID vlist[4];
- LONG dX, dY, dW, dH, x, y;
- DWORD dwStyle, dwExStyle;
-
-#define WIDTH(rc) (rc.right - rc.left)
-#define HEIGHT(rc) (rc.bottom - rc.top)
-
-#if CYGWINDOWING_DEBUG
- ErrorF ("winAdjustXWindow\n");
-#endif
-
- if (IsIconic (hwnd))
- {
-#if CYGWINDOWING_DEBUG
- ErrorF ("\timmediately return because the window is iconized\n");
-#endif
- /*
- * If the Windows window is minimized, its WindowRect has
- * meaningless values so we don't adjust X window to it.
- */
- vlist[0] = 0;
- vlist[1] = 0;
- return ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin));
- }
-
- pDraw = &pWin->drawable;
-
- /* Calculate the window rect from the drawable */
- x = pDraw->x + GetSystemMetrics (SM_XVIRTUALSCREEN);
- y = pDraw->y + GetSystemMetrics (SM_YVIRTUALSCREEN);
- SetRect (&rcDraw, x, y, x + pDraw->width, y + pDraw->height);
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n",
- rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
- rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
-#endif
- dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE);
- dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE);
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tWindowStyle: %08x %08x\n", dwStyle, dwExStyle);
-#endif
- AdjustWindowRectEx (&rcDraw, dwStyle, FALSE, dwExStyle);
-
- /* The source of adjust */
- GetWindowRect (hwnd, &rcWin);
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
- rcWin.left, rcWin.top, rcWin.right, rcWin.bottom,
- rcWin.right - rcWin.left, rcWin.bottom - rcWin.top);
- winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n",
- rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
- rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
-#endif
-
- if (EqualRect (&rcDraw, &rcWin)) {
- /* Bail if no adjust is needed */
-#if CYGWINDOWING_DEBUG
- ErrorF ("\treturn because already adjusted\n");
-#endif
- return 0;
- }
-
- /* Calculate delta values */
- dX = rcWin.left - rcDraw.left;
- dY = rcWin.top - rcDraw.top;
- dW = WIDTH(rcWin) - WIDTH(rcDraw);
- dH = HEIGHT(rcWin) - HEIGHT(rcDraw);
-
- /*
- * Adjust.
- * We may only need to move (vlist[0] and [1]), or only resize
- * ([2] and [3]) but currently we set all the parameters and leave
- * the decision to ConfigureWindow. The reason is code simplicity.
- */
- vlist[0] = pDraw->x + dX - wBorderWidth(pWin);
- vlist[1] = pDraw->y + dY - wBorderWidth(pWin);
- vlist[2] = pDraw->width + dW;
- vlist[3] = pDraw->height + dH;
-#if CYGWINDOWING_DEBUG
- ErrorF ("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist[0], vlist[1],
- vlist[2], vlist[3]);
-#endif
- return ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight,
- vlist, wClient(pWin));
-
-#undef WIDTH
-#undef HEIGHT
-}
-
+/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + *Copyright (C) Colin Harrison 2005-2008 + * + *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 XFREE86 PROJECT 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 of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Kensuke Matsuzaki + * Earle F. Philhower, III + * Harold L Hunt II + * Colin Harrison + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include "dixevents.h" +#include "winmultiwindowclass.h" + +/* + * Prototypes for local functions + */ + +void +winCreateWindowsWindow (WindowPtr pWin); + +static void +winDestroyWindowsWindow (WindowPtr pWin); + +static void +winUpdateWindowsWindow (WindowPtr pWin); + +static void +winFindWindow (pointer value, XID id, pointer cdata); + +static +void winInitMultiWindowClass(void) +{ + static wATOM atomXWinClass=0; + WNDCLASSEX wcx; + + if (atomXWinClass==0) + { + /* Setup our window class */ + wcx.cbSize=sizeof(WNDCLASSEX); + wcx.style = CS_HREDRAW | CS_VREDRAW | (g_fNativeGl ? CS_OWNDC : 0); + wcx.lpfnWndProc = winTopLevelWindowProc; + wcx.cbClsExtra = 0; + wcx.cbWndExtra = 0; + wcx.hInstance = g_hInstance; + wcx.hIcon = g_hIconX; + wcx.hCursor = 0; + wcx.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); + wcx.lpszMenuName = NULL; + wcx.lpszClassName = WINDOW_CLASS_X; + wcx.hIconSm = g_hSmallIconX; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X); +#endif + + atomXWinClass = RegisterClassEx (&wcx); + } +} + +/* + * CreateWindow - See Porting Layer Definition - p. 37 + */ + +Bool +winCreateWindowMultiWindow (WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + winTrace ("winCreateWindowMultiWindow - pWin: %p\n", pWin); +#endif + + WIN_UNWRAP(CreateWindow); + fResult = (*pScreen->CreateWindow) (pWin); + WIN_WRAP(CreateWindow, winCreateWindowMultiWindow); + + /* Initialize some privates values */ + pWinPriv->hRgn = NULL; + pWinPriv->hWnd = NULL; + pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen); + pWinPriv->fXKilled = FALSE; + + return fResult; +} + + +/* + * DestroyWindow - See Porting Layer Definition - p. 37 + */ + +Bool +winDestroyWindowMultiWindow (WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowMultiWindow - pWin: %p\n", pWin); +#endif + + WIN_UNWRAP(DestroyWindow); + fResult = (*pScreen->DestroyWindow)(pWin); + WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow); + + /* Flag that the window has been destroyed */ + pWinPriv->fXKilled = TRUE; + + /* Kill the MS Windows window associated with this window */ + winDestroyWindowsWindow (pWin); + + return fResult; +} + + +/* + * PositionWindow - See Porting Layer Definition - p. 37 + * + * This function adjusts the position and size of Windows window + * with respect to the underlying X window. This is the inverse + * of winAdjustXWindow, which adjusts X window to Windows window. + */ + +Bool +winPositionWindowMultiWindow (WindowPtr pWin, int x, int y) +{ + Bool fResult = TRUE; + int iX, iY, iWidth, iHeight; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + + HWND hWnd = pWinPriv->hWnd; + RECT rcNew; + RECT rcOld; +#if CYGMULTIWINDOW_DEBUG + RECT rcClient; + RECT *lpRc; +#endif + DWORD dwExStyle; + DWORD dwStyle; + +#if CYGMULTIWINDOW_DEBUG + winTrace ("winPositionWindowMultiWindow - pWin: %p\n", pWin); +#endif + + WIN_UNWRAP(PositionWindow); + fResult = (*pScreen->PositionWindow)(pWin, x, y); + WIN_WRAP(PositionWindow, winPositionWindowMultiWindow); + +#if CYGWINDOWING_DEBUG + ErrorF ("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n", + x, y); +#endif + + /* Bail out if the Windows window handle is bad */ + if (!hWnd) + { +#if CYGWINDOWING_DEBUG + ErrorF ("\timmediately return since hWnd is NULL\n"); +#endif + return fResult; + } + + /* Get the Windows window style and extended style */ + dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE); + + /* Get the X and Y location of the X window */ + iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Get the height and width of the X window */ + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); + +#if CYGMULTIWINDOW_DEBUG + lpRc = &rcNew; + ErrorF ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n", + GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); +#endif + + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); + + /* Get a rectangle describing the old Windows window */ + GetWindowRect (hWnd, &rcOld); + +#if CYGMULTIWINDOW_DEBUG + /* Get a rectangle describing the Windows window client area */ + GetClientRect (hWnd, &rcClient); + + lpRc = &rcNew; + ErrorF ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n", + GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); + + lpRc = &rcOld; + ErrorF ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n", + GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); + + lpRc = &rcClient; + ErrorF ("(%d ms)rcClient (%d, %d)-(%d, %d)\n", + GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); +#endif + + /* Check if the old rectangle and new rectangle are the same */ + if (!EqualRect (&rcNew, &rcOld)) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winPositionWindowMultiWindow - Need to move\n"); +#endif + +#if CYGWINDOWING_DEBUG + ErrorF ("\tMoveWindow to (%ld, %ld) - %ldx%ld\n", rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + /* Change the position and dimensions of the Windows window */ + MoveWindow (hWnd, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + TRUE); + } + else + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winPositionWindowMultiWindow - Not need to move\n"); +#endif + } + + return fResult; +} + + +/* + * ChangeWindowAttributes - See Porting Layer Definition - p. 37 + */ + +Bool +winChangeWindowAttributesMultiWindow (WindowPtr pWin, unsigned long mask) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin); +#endif + + WIN_UNWRAP(ChangeWindowAttributes); + fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask); + WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow); + + /* + * NOTE: We do not currently need to do anything here. + */ + + return fResult; +} + + +/* + * UnmapWindow - See Porting Layer Definition - p. 37 + * Also referred to as UnrealizeWindow + */ + +Bool +winUnmapWindowMultiWindow (WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin); +#endif + + WIN_UNWRAP(UnrealizeWindow); + fResult = (*pScreen->UnrealizeWindow)(pWin); + WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow); + + /* Flag that the window has been killed */ + pWinPriv->fXKilled = TRUE; + + /* Destroy the Windows window associated with this X window */ + winDestroyWindowsWindow (pWin); + + return fResult; +} + + +/* + * MapWindow - See Porting Layer Definition - p. 37 + * Also referred to as RealizeWindow + */ + +Bool +winMapWindowMultiWindow (WindowPtr pWin) +{ + Bool fResult = TRUE; + ScreenPtr pScreen = pWin->drawable.pScreen; + winWindowPriv(pWin); + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin); +#endif + + WIN_UNWRAP(RealizeWindow); + fResult = (*pScreen->RealizeWindow)(pWin); + WIN_WRAP(RealizeWindow, winMapWindowMultiWindow); + + /* Flag that this window has not been destroyed */ + pWinPriv->fXKilled = FALSE; + + /* Refresh/redisplay the Windows window associated with this X window */ + winUpdateWindowsWindow (pWin); + + /* Update the Windows window's shape */ + winReshapeMultiWindow (pWin); + winUpdateRgnMultiWindow (pWin); + + return fResult; +} + + +/* + * ReparentWindow - See Porting Layer Definition - p. 42 + */ + +void +winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin); +#endif + + WIN_UNWRAP(ReparentWindow); + if (pScreen->ReparentWindow) + (*pScreen->ReparentWindow)(pWin, pPriorParent); + WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow); + + /* Update the Windows window associated with this X window */ + winUpdateWindowsWindow (pWin); +} + + +/* + * RestackWindow - Shuffle the z-order of a window + */ + +void +winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) +{ +#if 0 + WindowPtr pPrevWin; + UINT uFlags; + HWND hInsertAfter; + HWND hWnd = NULL; +#endif + ScreenPtr pScreen = pWin->drawable.pScreen; + winScreenPriv(pScreen); + +#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG + winTrace ("winRestackMultiWindow - %08x\n", pWin); +#endif + + WIN_UNWRAP(RestackWindow); + if (pScreen->RestackWindow) + (*pScreen->RestackWindow)(pWin, pOldNextSib); + WIN_WRAP(RestackWindow, winRestackWindowMultiWindow); + +#if 1 + /* + * Calling winReorderWindowsMultiWindow here means our window manager + * (i.e. Windows Explorer) has initiative to determine Z order. + */ + if (pWin->nextSib != pOldNextSib) + winReorderWindowsMultiWindow (); +#else + /* Bail out if no window privates or window handle is invalid */ + if (!pWinPriv || !pWinPriv->hWnd) + return; + + /* Get a pointer to our previous sibling window */ + pPrevWin = pWin->prevSib; + + /* + * Look for a sibling window with + * valid privates and window handle + */ + while (pPrevWin + && !winGetWindowPriv(pPrevWin) + && !winGetWindowPriv(pPrevWin)->hWnd) + pPrevWin = pPrevWin->prevSib; + + /* Check if we found a valid sibling */ + if (pPrevWin) + { + /* Valid sibling - get handle to insert window after */ + hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd; + uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; + + hWnd = GetNextWindow (pWinPriv->hWnd, GW_HWNDPREV); + + do + { + if (GetProp (hWnd, WIN_WINDOW_PROP)) + { + if (hWnd == winGetWindowPriv(pPrevWin)->hWnd) + { + uFlags |= SWP_NOZORDER; + } + break; + } + hWnd = GetNextWindow (hWnd, GW_HWNDPREV); + } + while (hWnd); + } + else + { + /* No valid sibling - make this window the top window */ + hInsertAfter = HWND_TOP; + uFlags = SWP_NOMOVE | SWP_NOSIZE; + } + + /* Perform the restacking operation in Windows */ + SetWindowPos (pWinPriv->hWnd, + hInsertAfter, + 0, 0, + 0, 0, + uFlags); +#endif +} + + +/* + * winCreateWindowsWindow - Create a Windows window associated with an X window + */ + +void +winCreateWindowsWindow (WindowPtr pWin) +{ + int iX, iY; + int iWidth; + int iHeight; + HWND hWnd; + HWND hFore = NULL; + winWindowPriv(pWin); + HICON hIcon; + HICON hIconSmall; + winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv; + WinXSizeHints hints; + WindowPtr pDaddy; + + winInitMultiWindowClass(); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin); +#endif + + iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); + + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; + + /* If it's an InputOutput window, and so is going to end up being made visible, + make sure the window actually ends up somewhere where it will be visible */ + if (pWin->drawable.class != InputOnly) + { + if ((iX < GetSystemMetrics (SM_XVIRTUALSCREEN)) || (iX > GetSystemMetrics (SM_CXVIRTUALSCREEN))) + iX = CW_USEDEFAULT; + + if ((iY < GetSystemMetrics (SM_YVIRTUALSCREEN)) || (iY > GetSystemMetrics (SM_CYVIRTUALSCREEN))) + iY = CW_USEDEFAULT; + } + + if (winMultiWindowGetTransientFor (pWin, &pDaddy)) + { + if (pDaddy) + { + hFore = GetForegroundWindow(); + if (hFore && (pDaddy != (WindowPtr)GetProp(hFore, WIN_WID_PROP))) hFore = NULL; + } + } + else + { + /* Default positions if none specified */ + if (!winMultiWindowGetWMNormalHints(pWin, &hints)) + hints.flags = 0; + if (!(hints.flags & (USPosition|PPosition)) && + !pWin->overrideRedirect) + { + iX = CW_USEDEFAULT; + iY = CW_USEDEFAULT; + } + } + + /* Create the window */ + /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */ + /* CW_USEDEFAULT, change back to popup after creation */ + hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ + WINDOW_CLASS_X, /* Class name */ + WINDOW_TITLE_X, /* Window name */ + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + iX, /* Horizontal position */ + iY, /* Vertical position */ + iWidth, /* Right edge */ + iHeight, /* Bottom edge */ + hFore, /* Null or Parent window if transient*/ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL), /* Instance handle */ + pWin); /* ScreenPrivates */ + if (hWnd == NULL) + { + ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n", + (int) GetLastError ()); + } + pWinPriv->hWnd = hWnd; + + /* Set application or .XWinrc defined Icons */ + winSelectIcons(pWin, &hIcon, &hIconSmall); + if (hIcon) SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon); + if (hIconSmall) SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall); + + /* Change style back to popup, already placed... */ + SetWindowLongPtr(hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + SetWindowPos (hWnd, 0, 0, 0, 0, 0, + SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + /* Make sure it gets the proper system menu for a WS_POPUP, too */ + GetSystemMenu (hWnd, TRUE); + + /* Cause any .XWinrc menus to be added in main WNDPROC */ + PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0); + + SetProp (hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin)); + + /* Flag that this Windows window handles its own activation */ + SetProp (hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0); + + /* Call engine-specific create window procedure */ + (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin); +} + + +Bool winInDestroyWindowsWindow = FALSE; +/* + * winDestroyWindowsWindow - Destroy a Windows window associated + * with an X window + */ +static void +winDestroyWindowsWindow (WindowPtr pWin) +{ + MSG msg; + winWindowPriv(pWin); + BOOL oldstate = winInDestroyWindowsWindow; + HICON hIcon; + HICON hIconSm; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winDestroyWindowsWindow\n"); +#endif + + /* Bail out if the Windows window handle is invalid */ + if (pWinPriv->hWnd == NULL) + return; + + winInDestroyWindowsWindow = TRUE; + + /* Store the info we need to destroy after this window is gone */ + hIcon = (HICON)SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_BIG, 0); + hIconSm = (HICON)SendMessage(pWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0); + + SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, NULL); + + /* Destroy the Windows window */ + DestroyWindow (pWinPriv->hWnd); + + /* Null our handle to the Window so referencing it will cause an error */ + pWinPriv->hWnd = NULL; + + /* Destroy any icons we created for this window */ + winDestroyIcon(hIcon); + winDestroyIcon(hIconSm); + + /* Process all messages on our queue */ + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg)) + { + DispatchMessage (&msg); + } + } + + winInDestroyWindowsWindow = oldstate; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("-winDestroyWindowsWindow\n"); +#endif +} + + +/* + * winUpdateWindowsWindow - Redisplay/redraw a Windows window + * associated with an X window + */ + +static void +winUpdateWindowsWindow (WindowPtr pWin) +{ + winWindowPriv(pWin); + HWND hWnd = pWinPriv->hWnd; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winUpdateWindowsWindow\n"); +#endif + + /* Check if the Windows window's parents have been destroyed */ + if (pWin->parent != NULL + && pWin->parent->parent == NULL + && pWin->mapped) + { + /* Create the Windows window if it has been destroyed */ + if (hWnd == NULL) + { + winCreateWindowsWindow (pWin); + assert (pWinPriv->hWnd != NULL); + } + + /* Display the window without activating it */ + if (pWin->drawable.class != InputOnly) + ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE); + + /* Send first paint message */ + UpdateWindow (pWinPriv->hWnd); + } + else if (hWnd != NULL) + { + /* Destroy the Windows window if its parents are destroyed */ + winDestroyWindowsWindow (pWin); + assert (pWinPriv->hWnd == NULL); + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("-winUpdateWindowsWindow\n"); +#endif +} + + +/* + * winGetWindowID - + */ + +XID +winGetWindowID (WindowPtr pWin) +{ + WindowIDPairRec wi = {pWin, 0}; + ClientPtr c = wClient(pWin); + + /* */ + FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winGetWindowID - Window ID: %d\n", wi.id); +#endif + + return wi.id; +} + + +/* + * winFindWindow - + */ + +static void +winFindWindow (pointer value, XID id, pointer cdata) +{ + WindowIDPairPtr wi = (WindowIDPairPtr)cdata; + + if (value == wi->value) + { + wi->id = id; + } +} + + +/* + * winReorderWindowsMultiWindow - + */ + +void +winReorderWindowsMultiWindow (void) +{ + HWND hwnd = NULL; + WindowPtr pWin = NULL; + WindowPtr pWinSib = NULL; + XID vlist[2]; + static Bool fRestacking = FALSE; /* Avoid recusive calls to this function */ + DWORD dwCurrentProcessID = GetCurrentProcessId (); + DWORD dwWindowProcessID = 0; + +#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG + winTrace ("winReorderWindowsMultiWindow\n"); +#endif + + if (fRestacking) + { + /* It is a recusive call so immediately exit */ +#if CYGWINDOWING_DEBUG + ErrorF ("winReorderWindowsMultiWindow - " + "exit because fRestacking == TRUE\n"); +#endif + return; + } + fRestacking = TRUE; + + /* Loop through top level Window windows, descending in Z order */ + for ( hwnd = GetTopWindow (NULL); + hwnd; + hwnd = GetNextWindow (hwnd, GW_HWNDNEXT) ) + { + /* Don't take care of other Cygwin/X process's windows */ + GetWindowThreadProcessId (hwnd, &dwWindowProcessID); + + if ( GetProp (hwnd, WIN_WINDOW_PROP) + && (dwWindowProcessID == dwCurrentProcessID) + && !IsIconic (hwnd) ) /* ignore minimized windows */ + { + pWinSib = pWin; + pWin = GetProp (hwnd, WIN_WINDOW_PROP); + + if (!pWinSib) + { /* 1st window - raise to the top */ + vlist[0] = Above; + + ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin)); + } + else + { /* 2nd or deeper windows - just below the previous one */ + vlist[0] = winGetWindowID (pWinSib); + vlist[1] = Below; + + ConfigureWindow (pWin, CWSibling | CWStackMode, + vlist, wClient(pWin)); + } + } + } + + fRestacking = FALSE; +} + + +/* + * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE + */ + +void +winMinimizeWindow (Window id) +{ + WindowPtr pWin; + winPrivWinPtr pWinPriv; +#ifdef XWIN_MULTIWINDOWEXTWM + win32RootlessWindowPtr pRLWinPriv; +#endif + HWND hWnd; + ScreenPtr pScreen = NULL; + winPrivScreenPtr pScreenPriv = NULL; + winScreenInfo *pScreenInfo = NULL; + +#if CYGWINDOWING_DEBUG + ErrorF ("winMinimizeWindow\n"); +#endif + + dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess); + if (!pWin) + { + ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__); + return; + } + + pScreen = pWin->drawable.pScreen; + if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + +#ifdef XWIN_MULTIWINDOWEXTWM + if (pScreenPriv && pScreenInfo->fInternalWM) + { + pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); + hWnd = pRLWinPriv->hWnd; + } + else +#else + if (pScreenPriv) +#endif + { + pWinPriv = winGetWindowPriv (pWin); + hWnd = pWinPriv->hWnd; + } + + ShowWindow (hWnd, SW_MINIMIZE); +} + + +/* + * CopyWindow - See Porting Layer Definition - p. 39 + */ +void +winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt, + RegionPtr oldRegion) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winScreenPriv(pScreen); + +#if CYGWINDOWING_DEBUG + ErrorF ("CopyWindowMultiWindow\n"); +#endif + WIN_UNWRAP(CopyWindow); + (*pScreen->CopyWindow)(pWin, oldpt, oldRegion); + WIN_WRAP(CopyWindow, winCopyWindowMultiWindow); +} + + +/* + * MoveWindow - See Porting Layer Definition - p. 42 + */ +void +winMoveWindowMultiWindow (WindowPtr pWin, int x, int y, + WindowPtr pSib, VTKind kind) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winScreenPriv(pScreen); + +#if CYGWINDOWING_DEBUG + ErrorF ("MoveWindowMultiWindow to (%d, %d)\n", x, y); +#endif + + WIN_UNWRAP(MoveWindow); + (*pScreen->MoveWindow)(pWin, x, y, pSib, kind); + WIN_WRAP(MoveWindow, winMoveWindowMultiWindow); +} + + +/* + * ResizeWindow - See Porting Layer Definition - p. 42 + */ +void +winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w, + unsigned int h, WindowPtr pSib) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + winScreenPriv(pScreen); + +#if CYGWINDOWING_DEBUG + ErrorF ("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h); +#endif + WIN_UNWRAP(ResizeWindow); + (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib); + WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow); +} + + +/* + * winAdjustXWindow + * + * Move and resize X window with respect to corresponding Windows window. + * This is called from WM_MOVE/WM_SIZE handlers when the user performs + * any windowing operation (move, resize, minimize, maximize, restore). + * + * The functionality is the inverse of winPositionWindowMultiWindow, which + * adjusts Windows window with respect to X window. + */ +int +winAdjustXWindow (WindowPtr pWin, HWND hwnd) +{ + RECT rcDraw; /* Rect made from pWin->drawable to be adjusted */ + RECT rcWin; /* The source: WindowRect from hwnd */ + DrawablePtr pDraw; + XID vlist[4]; + LONG dX, dY, dW, dH, x, y; + DWORD dwStyle, dwExStyle; + +#define WIDTH(rc) (rc.right - rc.left) +#define HEIGHT(rc) (rc.bottom - rc.top) + +#if CYGWINDOWING_DEBUG + ErrorF ("winAdjustXWindow\n"); +#endif + + if (IsIconic (hwnd)) + { +#if CYGWINDOWING_DEBUG + ErrorF ("\timmediately return because the window is iconized\n"); +#endif + /* + * If the Windows window is minimized, its WindowRect has + * meaningless values so we don't adjust X window to it. + */ + vlist[0] = 0; + vlist[1] = 0; + return ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin)); + } + + pDraw = &pWin->drawable; + + /* Calculate the window rect from the drawable */ + x = pDraw->x + GetSystemMetrics (SM_XVIRTUALSCREEN); + y = pDraw->y + GetSystemMetrics (SM_YVIRTUALSCREEN); + SetRect (&rcDraw, x, y, x + pDraw->width, y + pDraw->height); +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n", + rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom, + rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top); +#endif + dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE); +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tWindowStyle: %08x %08x\n", dwStyle, dwExStyle); +#endif + AdjustWindowRectEx (&rcDraw, dwStyle, FALSE, dwExStyle); + + /* The source of adjust */ + GetWindowRect (hwnd, &rcWin); +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n", + rcWin.left, rcWin.top, rcWin.right, rcWin.bottom, + rcWin.right - rcWin.left, rcWin.bottom - rcWin.top); + winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n", + rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom, + rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top); +#endif + + if (EqualRect (&rcDraw, &rcWin)) { + /* Bail if no adjust is needed */ +#if CYGWINDOWING_DEBUG + ErrorF ("\treturn because already adjusted\n"); +#endif + return 0; + } + + /* Calculate delta values */ + dX = rcWin.left - rcDraw.left; + dY = rcWin.top - rcDraw.top; + dW = WIDTH(rcWin) - WIDTH(rcDraw); + dH = HEIGHT(rcWin) - HEIGHT(rcDraw); + + /* + * Adjust. + * We may only need to move (vlist[0] and [1]), or only resize + * ([2] and [3]) but currently we set all the parameters and leave + * the decision to ConfigureWindow. The reason is code simplicity. + */ + vlist[0] = pDraw->x + dX - wBorderWidth(pWin); + vlist[1] = pDraw->y + dY - wBorderWidth(pWin); + vlist[2] = pDraw->width + dW; + vlist[3] = pDraw->height + dH; +#if CYGWINDOWING_DEBUG + ErrorF ("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist[0], vlist[1], + vlist[2], vlist[3]); +#endif + return ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight, + vlist, wClient(pWin)); + +#undef WIDTH +#undef HEIGHT +} + diff --git a/xorg-server/hw/xwin/winmultiwindowwm.c b/xorg-server/hw/xwin/winmultiwindowwm.c index 28685a729..67a58a076 100644 --- a/xorg-server/hw/xwin/winmultiwindowwm.c +++ b/xorg-server/hw/xwin/winmultiwindowwm.c @@ -1,1745 +1,1787 @@ -/*
- *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- *Copyright (C) Colin Harrison 2005-2009
- *
- *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 XFREE86 PROJECT 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 of the XFree86 Project
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from the XFree86 Project.
- *
- * Authors: Kensuke Matsuzaki
- * Colin Harrison
- */
-
-/* X headers */
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#ifdef __CYGWIN__
-#include <sys/select.h>
-#endif
-#include <fcntl.h>
-#include <setjmp.h>
-#define HANDLE void *
-#include <pthread.h>
-#undef HANDLE
-#include <X11/X.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <X11/Xlocale.h>
-#include <X11/Xproto.h>
-#include <X11/Xutil.h>
-#include <X11/cursorfont.h>
-#include <X11/Xwindows.h>
-
-/* Local headers */
-#include "objbase.h"
-#include "ddraw.h"
-#include "winwindow.h"
-#include "winprefs.h"
-#include "window.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-#include <X11/extensions/windowswmstr.h>
-#else
-/* We need the native HWND atom for intWM, so for consistency use the
- same name as extWM would if we were building with enabled... */
-#define WINDOWSWM_NATIVE_HWND "_WINDOWSWM_NATIVE_HWND"
-#endif
-
-extern void winDebug(const char *format, ...);
-extern void winReshapeMultiWindow(WindowPtr pWin);
-extern void winUpdateRgnMultiWindow(WindowPtr pWin);
-
-#ifndef CYGDEBUG
-#define CYGDEBUG NO
-#endif
-
-/*
- * Constant defines
- */
-
-#define WIN_CONNECT_RETRIES 5
-#define WIN_CONNECT_DELAY 5
-#ifdef HAS_DEVWINDOWS
-# define WIN_MSG_QUEUE_FNAME "/dev/windows"
-#endif
-#define WIN_JMP_OKAY 0
-#define WIN_JMP_ERROR_IO 2
-
-/*
- * Local structures
- */
-
-typedef struct _WMMsgNodeRec {
- winWMMessageRec msg;
- struct _WMMsgNodeRec *pNext;
-} WMMsgNodeRec, *WMMsgNodePtr;
-
-typedef struct _WMMsgQueueRec {
- struct _WMMsgNodeRec *pHead;
- struct _WMMsgNodeRec *pTail;
- pthread_mutex_t pmMutex;
- pthread_cond_t pcNotEmpty;
- int nQueueSize;
-} WMMsgQueueRec, *WMMsgQueuePtr;
-
-typedef struct _WMInfo {
- Display *pDisplay;
- WMMsgQueueRec wmMsgQueue;
- Atom atmWmProtos;
- Atom atmWmDelete;
- Atom atmPrivMap;
- Bool fAllowOtherWM;
-} WMInfoRec, *WMInfoPtr;
-
-typedef struct _WMProcArgRec {
- DWORD dwScreen;
- WMInfoPtr pWMInfo;
- pthread_mutex_t *ppmServerStarted;
-} WMProcArgRec, *WMProcArgPtr;
-
-typedef struct _XMsgProcArgRec {
- Display *pDisplay;
- DWORD dwScreen;
- WMInfoPtr pWMInfo;
- pthread_mutex_t *ppmServerStarted;
- HWND hwndScreen;
-} XMsgProcArgRec, *XMsgProcArgPtr;
-
-
-/*
- * References to external symbols
- */
-
-extern char *display;
-extern void ErrorF (const char* /*f*/, ...);
-
-/*
- * Prototypes for local functions
- */
-
-static void
-PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode);
-
-static WMMsgNodePtr
-PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo);
-
-static Bool
-InitQueue (WMMsgQueuePtr pQueue);
-
-static void
-GetWindowName (Display * pDpy, Window iWin, wchar_t **ppName);
-
-static int
-SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData);
-
-static void
-UpdateName (WMInfoPtr pWMInfo, Window iWindow);
-
-static void*
-winMultiWindowWMProc (void* pArg);
-
-static int
-winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr);
-
-static int
-winMultiWindowWMIOErrorHandler (Display *pDisplay);
-
-static void *
-winMultiWindowXMsgProc (void *pArg);
-
-static int
-winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr);
-
-static int
-winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay);
-
-static int
-winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr);
-
-static void
-winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg);
-
-#if 0
-static void
-PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction);
-#endif
-
-static Bool
-CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen, Bool fAllowOtherWM);
-
-static void
-winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle);
-
-void
-winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle);
-
-/*
- * Local globals
- */
-
-static jmp_buf g_jmpWMEntry;
-static jmp_buf g_jmpXMsgProcEntry;
-static Bool g_shutdown = FALSE;
-static Bool redirectError = FALSE;
-static Bool g_fAnotherWMRunning = FALSE;
-
-/*
- * PushMessage - Push a message onto the queue
- */
-
-static void
-PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode)
-{
-
- /* Lock the queue mutex */
- pthread_mutex_lock (&pQueue->pmMutex);
-
- pNode->pNext = NULL;
-
- if (pQueue->pTail != NULL)
- {
- pQueue->pTail->pNext = pNode;
- }
- pQueue->pTail = pNode;
-
- if (pQueue->pHead == NULL)
- {
- pQueue->pHead = pNode;
- }
-
-
-#if 0
- switch (pNode->msg.msg)
- {
- case WM_WM_MOVE:
- ErrorF ("\tWM_WM_MOVE\n");
- break;
- case WM_WM_SIZE:
- ErrorF ("\tWM_WM_SIZE\n");
- break;
- case WM_WM_RAISE:
- ErrorF ("\tWM_WM_RAISE\n");
- break;
- case WM_WM_LOWER:
- ErrorF ("\tWM_WM_LOWER\n");
- break;
- case WM_WM_MAP:
- ErrorF ("\tWM_WM_MAP\n");
- break;
- case WM_WM_MAP2:
- ErrorF ("\tWM_WM_MAP2\n");
- break;
- case WM_WM_MAP3:
- ErrorF ("\tWM_WM_MAP3\n");
- break;
- case WM_WM_UNMAP:
- ErrorF ("\tWM_WM_UNMAP\n");
- break;
- case WM_WM_KILL:
- ErrorF ("\tWM_WM_KILL\n");
- break;
- case WM_WM_ACTIVATE:
- ErrorF ("\tWM_WM_ACTIVATE\n");
- break;
- default:
- ErrorF ("\tUnknown Message.\n");
- break;
- }
-#endif
-
- /* Increase the count of elements in the queue by one */
- ++(pQueue->nQueueSize);
-
- /* Release the queue mutex */
- pthread_mutex_unlock (&pQueue->pmMutex);
-
- /* Signal that the queue is not empty */
- pthread_cond_signal (&pQueue->pcNotEmpty);
-}
-
-
-#if CYGMULTIWINDOW_DEBUG
-/*
- * QueueSize - Return the size of the queue
- */
-
-static int
-QueueSize (WMMsgQueuePtr pQueue)
-{
- WMMsgNodePtr pNode;
- int nSize = 0;
-
- /* Loop through all elements in the queue */
- for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext)
- ++nSize;
-
- return nSize;
-}
-#endif
-
-
-/*
- * PopMessage - Pop a message from the queue
- */
-
-static WMMsgNodePtr
-PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo)
-{
- WMMsgNodePtr pNode;
-
- /* Lock the queue mutex */
- pthread_mutex_lock (&pQueue->pmMutex);
-
- /* Wait for --- */
- while (pQueue->pHead == NULL)
- {
- pthread_cond_wait (&pQueue->pcNotEmpty, &pQueue->pmMutex);
- }
-
- pNode = pQueue->pHead;
- if (pQueue->pHead != NULL)
- {
- pQueue->pHead = pQueue->pHead->pNext;
- }
-
- if (pQueue->pTail == pNode)
- {
- pQueue->pTail = NULL;
- }
-
- /* Drop the number of elements in the queue by one */
- --(pQueue->nQueueSize);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("Queue Size %d %d\n", pQueue->nQueueSize, QueueSize(pQueue));
-#endif
-
- /* Release the queue mutex */
- pthread_mutex_unlock (&pQueue->pmMutex);
-
- return pNode;
-}
-
-
-#if 0
-/*
- * HaveMessage -
- */
-
-static Bool
-HaveMessage (WMMsgQueuePtr pQueue, UINT msg, Window iWindow)
-{
- WMMsgNodePtr pNode;
-
- for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext)
- {
- if (pNode->msg.msg==msg && pNode->msg.iWindow==iWindow)
- return True;
- }
-
- return False;
-}
-#endif
-
-
-/*
- * InitQueue - Initialize the Window Manager message queue
- */
-
-static
-Bool
-InitQueue (WMMsgQueuePtr pQueue)
-{
- /* Check if the pQueue pointer is NULL */
- if (pQueue == NULL)
- {
- ErrorF ("InitQueue - pQueue is NULL. Exiting.\n");
- return FALSE;
- }
-
- /* Set the head and tail to NULL */
- pQueue->pHead = NULL;
- pQueue->pTail = NULL;
-
- /* There are no elements initially */
- pQueue->nQueueSize = 0;
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("InitQueue - Queue Size %d %d\n", pQueue->nQueueSize,
- QueueSize(pQueue));
-#endif
-
- ErrorF ("InitQueue - Calling pthread_mutex_init\n");
-
- /* Create synchronization objects */
- pthread_mutex_init (&pQueue->pmMutex, NULL);
-
- ErrorF ("InitQueue - pthread_mutex_init returned\n");
- ErrorF ("InitQueue - Calling pthread_cond_init\n");
-
- pthread_cond_init (&pQueue->pcNotEmpty, NULL);
-
- ErrorF ("InitQueue - pthread_cond_init returned\n");
-
- return TRUE;
-}
-
-
-/*
- * GetWindowName - Retrieve the title of an X Window
- */
-
-static void
-GetWindowName (Display *pDisplay, Window iWin, wchar_t **ppName)
-{
- int nResult, nNum;
- char **ppList;
- char *pszReturnData;
- int iLen, i;
- XTextProperty xtpName;
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("GetWindowName\n");
-#endif
-
- /* Intialize ppName to NULL */
- *ppName = NULL;
-
- /* Try to get --- */
- nResult = XGetWMName (pDisplay, iWin, &xtpName);
- if (!nResult || !xtpName.value || !xtpName.nitems)
- {
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("GetWindowName - XGetWMName failed. No name.\n");
-#endif
- return;
- }
-
- if (Xutf8TextPropertyToTextList (pDisplay, &xtpName, &ppList, &nNum) >= Success && nNum > 0 && *ppList)
- {
- iLen = 0;
- for (i = 0; i < nNum; i++) iLen += strlen(ppList[i]);
- pszReturnData = (char *) malloc (iLen + 1);
- pszReturnData[0] = '\0';
- for (i = 0; i < nNum; i++) strcat (pszReturnData, ppList[i]);
- if (ppList) XFreeStringList (ppList);
- }
- else
- {
- pszReturnData = (char *) malloc (1);
- pszReturnData[0] = '\0';
- }
- iLen = MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, NULL, 0);
- *ppName = (wchar_t*)malloc(sizeof(wchar_t)*(iLen + 1));
- MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, *ppName, iLen);
- XFree (xtpName.value);
- free (pszReturnData);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("GetWindowName - Returning\n");
-#endif
-}
-
-
-/*
- * Send a message to the X server from the WM thread
- */
-
-static int
-SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData)
-{
- XEvent e;
-
- /* Prepare the X event structure */
- e.type = ClientMessage;
- e.xclient.window = iWin;
- e.xclient.message_type = atmType;
- e.xclient.format = 32;
- e.xclient.data.l[0] = nData;
- e.xclient.data.l[1] = CurrentTime;
-
- /* Send the event to X */
- return XSendEvent (pDisplay, iWin, False, NoEventMask, &e);
-}
-
-
-/*
- * Updates the name of a HWND according to its X WM_NAME property
- */
-
-static void
-UpdateName (WMInfoPtr pWMInfo, Window iWindow)
-{
- wchar_t *pszName;
- Atom atmType;
- int fmtRet;
- unsigned long items, remain;
- HWND *retHwnd, hWnd;
- XWindowAttributes attr;
-
- hWnd = 0;
-
- /* See if we can get the cached HWND for this window... */
- if (XGetWindowProperty (pWMInfo->pDisplay,
- iWindow,
- pWMInfo->atmPrivMap,
- 0,
- 1,
- False,
- XA_INTEGER,//pWMInfo->atmPrivMap,
- &atmType,
- &fmtRet,
- &items,
- &remain,
- (unsigned char **) &retHwnd) == Success)
- {
- if (retHwnd)
- {
- hWnd = *retHwnd;
- XFree (retHwnd);
- }
- }
-
- /* Some sanity checks */
- if (!hWnd) return;
- if (!IsWindow (hWnd)) return;
-
- /* Set the Windows window name */
- GetWindowName (pWMInfo->pDisplay, iWindow, &pszName);
- if (pszName)
- {
- /* Get the window attributes */
- XGetWindowAttributes (pWMInfo->pDisplay,
- iWindow,
- &attr);
- if (!attr.override_redirect)
- {
- SetWindowTextW (hWnd, pszName);
- winUpdateIcon (iWindow);
- }
-
- free (pszName);
- }
-}
-
-
-#if 0
-/*
- * Fix up any differences between the X11 and Win32 window stacks
- * starting at the window passed in
- */
-static void
-PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction)
-{
- Atom atmType;
- int fmtRet;
- unsigned long items, remain;
- HWND hWnd, *retHwnd;
- DWORD myWinProcID, winProcID;
- Window xWindow;
- WINDOWPLACEMENT wndPlace;
-
- hWnd = NULL;
- /* See if we can get the cached HWND for this window... */
- if (XGetWindowProperty (pWMInfo->pDisplay,
- iWindow,
- pWMInfo->atmPrivMap,
- 0,
- 1,
- False,
- XA_INTEGER,//pWMInfo->atmPrivMap,
- &atmType,
- &fmtRet,
- &items,
- &remain,
- (unsigned char **) &retHwnd) == Success)
- {
- if (retHwnd)
- {
- hWnd = *retHwnd;
- XFree (retHwnd);
- }
- }
-
- if (!hWnd) return;
-
- GetWindowThreadProcessId (hWnd, &myWinProcID);
- hWnd = GetNextWindow (hWnd, direction);
-
- while (hWnd) {
- GetWindowThreadProcessId (hWnd, &winProcID);
- if (winProcID == myWinProcID)
- {
- wndPlace.length = sizeof(WINDOWPLACEMENT);
- GetWindowPlacement (hWnd, &wndPlace);
- if ( !(wndPlace.showCmd==SW_HIDE ||
- wndPlace.showCmd==SW_MINIMIZE) )
- {
- xWindow = (Window)GetProp (hWnd, WIN_WID_PROP);
- if (xWindow)
- {
- if (direction==GW_HWNDPREV)
- XRaiseWindow (pWMInfo->pDisplay, xWindow);
- else
- XLowerWindow (pWMInfo->pDisplay, xWindow);
- }
- }
- }
- hWnd = GetNextWindow(hWnd, direction);
- }
-}
-#endif /* PreserveWin32Stack */
-
-
-/*
- * winMultiWindowWMProc
- */
-
-static void *
-winMultiWindowWMProc (void *pArg)
-{
- WMProcArgPtr pProcArg = (WMProcArgPtr)pArg;
- WMInfoPtr pWMInfo = pProcArg->pWMInfo;
-
- /* Initialize the Window Manager */
- winInitMultiWindowWM (pWMInfo, pProcArg);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winMultiWindowWMProc ()\n");
-#endif
-
- /* Loop until we explicitly break out */
- for (;;)
- {
- WMMsgNodePtr pNode;
-
- if(g_fAnotherWMRunning)/* Another Window manager exists. */
- {
- Sleep (1000);
- continue;
- }
-
- /* Pop a message off of our queue */
- pNode = PopMessage (&pWMInfo->wmMsgQueue, pWMInfo);
- if (pNode == NULL)
- {
- /* Bail if PopMessage returns without a message */
- /* NOTE: Remember that PopMessage is a blocking function. */
- ErrorF ("winMultiWindowWMProc - Queue is Empty? Exiting.\n");
- pthread_exit (NULL);
- }
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winMultiWindowWMProc - %d ms MSG: %d ID: %d\n",
- GetTickCount (), (int)pNode->msg.msg, (int)pNode->msg.dwID);
-#endif
-
- /* Branch on the message type */
- switch (pNode->msg.msg)
- {
-#if 0
- case WM_WM_MOVE:
- ErrorF ("\tWM_WM_MOVE\n");
- break;
-
- case WM_WM_SIZE:
- ErrorF ("\tWM_WM_SIZE\n");
- break;
-#endif
-
- case WM_WM_RAISE:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("\tWM_WM_RAISE\n");
-#endif
- /* Raise the window */
- XRaiseWindow (pWMInfo->pDisplay, pNode->msg.iWindow);
-#if 0
- PreserveWin32Stack (pWMInfo, pNode->msg.iWindow, GW_HWNDPREV);
-#endif
- break;
-
- case WM_WM_LOWER:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("\tWM_WM_LOWER\n");
-#endif
-
- /* Lower the window */
- XLowerWindow (pWMInfo->pDisplay, pNode->msg.iWindow);
- break;
-
- case WM_WM_MAP:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("\tWM_WM_MAP\n");
-#endif
- /* Put a note as to the HWND associated with this Window */
- XChangeProperty (pWMInfo->pDisplay,
- pNode->msg.iWindow,
- pWMInfo->atmPrivMap,
- XA_INTEGER,//pWMInfo->atmPrivMap,
- 32,
- PropModeReplace,
- (unsigned char *) &(pNode->msg.hwndWindow),
- 1);
- UpdateName (pWMInfo, pNode->msg.iWindow);
- winUpdateIcon (pNode->msg.iWindow);
- break;
-
- case WM_WM_MAP2:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("\tWM_WM_MAP2\n");
-#endif
- XChangeProperty (pWMInfo->pDisplay,
- pNode->msg.iWindow,
- pWMInfo->atmPrivMap,
- XA_INTEGER,//pWMInfo->atmPrivMap,
- 32,
- PropModeReplace,
- (unsigned char *) &(pNode->msg.hwndWindow),
- 1);
- break;
-
- case WM_WM_MAP3:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("\tWM_WM_MAP3\n");
-#endif
- /* Put a note as to the HWND associated with this Window */
- XChangeProperty (pWMInfo->pDisplay,
- pNode->msg.iWindow,
- pWMInfo->atmPrivMap,
- XA_INTEGER,//pWMInfo->atmPrivMap,
- 32,
- PropModeReplace,
- (unsigned char *) &(pNode->msg.hwndWindow),
- 1);
- UpdateName (pWMInfo, pNode->msg.iWindow);
- winUpdateIcon (pNode->msg.iWindow);
- {
- HWND zstyle = HWND_NOTOPMOST;
- winApplyHints (pWMInfo->pDisplay, pNode->msg.iWindow, pNode->msg.hwndWindow, &zstyle);
- winUpdateWindowPosition (pNode->msg.hwndWindow, TRUE, &zstyle);
- }
- break;
-
- case WM_WM_UNMAP:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("\tWM_WM_UNMAP\n");
-#endif
-
- /* Unmap the window */
- XUnmapWindow (pWMInfo->pDisplay, pNode->msg.iWindow);
- break;
-
- case WM_WM_KILL:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("\tWM_WM_KILL\n");
-#endif
- {
- int i, n, found = 0;
- Atom *protocols;
-
- /* --- */
- if (XGetWMProtocols (pWMInfo->pDisplay,
- pNode->msg.iWindow,
- &protocols,
- &n))
- {
- for (i = 0; i < n; ++i)
- if (protocols[i] == pWMInfo->atmWmDelete)
- ++found;
-
- XFree (protocols);
- }
-
- /* --- */
- if (found)
- SendXMessage (pWMInfo->pDisplay,
- pNode->msg.iWindow,
- pWMInfo->atmWmProtos,
- pWMInfo->atmWmDelete);
- else
- XKillClient (pWMInfo->pDisplay,
- pNode->msg.iWindow);
- }
- break;
-
- case WM_WM_ACTIVATE:
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("\tWM_WM_ACTIVATE\n");
-#endif
-
- /* Set the input focus */
- XSetInputFocus (pWMInfo->pDisplay,
- pNode->msg.iWindow,
- RevertToPointerRoot,
- CurrentTime);
- break;
-
- case WM_WM_NAME_EVENT:
- UpdateName (pWMInfo, pNode->msg.iWindow);
- break;
-
- case WM_WM_HINTS_EVENT:
- winUpdateIcon (pNode->msg.iWindow);
- break;
-
- case WM_WM_CHANGE_STATE:
- /* Minimize the window in Windows */
- winMinimizeWindow (pNode->msg.iWindow);
- break;
-
- default:
- ErrorF ("winMultiWindowWMProc - Unknown Message. Exiting.\n");
- pthread_exit (NULL);
- break;
- }
-
- /* Free the retrieved message */
- free (pNode);
-
- /* Flush any pending events on our display */
- XFlush (pWMInfo->pDisplay);
- }
-
- /* Free the condition variable */
- pthread_cond_destroy (&pWMInfo->wmMsgQueue.pcNotEmpty);
-
- /* Free the mutex variable */
- pthread_mutex_destroy (&pWMInfo->wmMsgQueue.pmMutex);
-
- /* Free the passed-in argument */
- free (pProcArg);
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF("-winMultiWindowWMProc ()\n");
-#endif
- return NULL;
-}
-
-
-/*
- * X message procedure
- */
-
-static void *
-winMultiWindowXMsgProc (void *pArg)
-{
- winWMMessageRec msg;
- XMsgProcArgPtr pProcArg = (XMsgProcArgPtr) pArg;
- char pszDisplay[512];
- int iRetries;
- XEvent event;
- Atom atmWmName;
- Atom atmWmHints;
- Atom atmWmChange;
- int iReturn;
- XIconSize *xis;
-
- ErrorF ("winMultiWindowXMsgProc - Hello\n");
-
- /* Check that argument pointer is not invalid */
- if (pProcArg == NULL)
- {
- ErrorF ("winMultiWindowXMsgProc - pProcArg is NULL. Exiting.\n");
- pthread_exit (NULL);
- }
-
- ErrorF ("winMultiWindowXMsgProc - Calling pthread_mutex_lock ()\n");
-
- /* Grab the server started mutex - pause until we get it */
- iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted);
- if (iReturn != 0)
- {
- ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () failed: %d. "
- "Exiting.\n",
- iReturn);
- pthread_exit (NULL);
- }
-
- ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n");
-
- /* Allow multiple threads to access Xlib */
- if (XInitThreads () == 0)
- {
- ErrorF ("winMultiWindowXMsgProc - XInitThreads () failed. Exiting.\n");
- pthread_exit (NULL);
- }
-
- /* See if X supports the current locale */
- if (XSupportsLocale () == False)
- {
- ErrorF ("winMultiWindowXMsgProc - Warning: locale not supported by X\n");
- }
-
- /* Release the server started mutex */
- pthread_mutex_unlock (pProcArg->ppmServerStarted);
-
- ErrorF ("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n");
-
- /* Set jump point for IO Error exits */
- iReturn = setjmp (g_jmpXMsgProcEntry);
-
- /* Check if we should continue operations */
- if (iReturn != WIN_JMP_ERROR_IO
- && iReturn != WIN_JMP_OKAY)
- {
- /* setjmp returned an unknown value, exit */
- ErrorF ("winInitMultiWindowXMsgProc - setjmp returned: %d. Exiting.\n",
- iReturn);
- pthread_exit (NULL);
- }
- else if (iReturn == WIN_JMP_ERROR_IO)
- {
- ErrorF ("winInitMultiWindowXMsgProc - Caught IO Error. Exiting.\n");
- pthread_exit (NULL);
- }
-
- /* Install our error handler */
- XSetErrorHandler (winMultiWindowXMsgProcErrorHandler);
- XSetIOErrorHandler (winMultiWindowXMsgProcIOErrorHandler);
-
- /* Setup the display connection string x */
- snprintf (pszDisplay,
- 512, "127.0.0.1:%s.%d", display, (int)pProcArg->dwScreen);
-
- /* Print the display connection string */
- ErrorF ("winMultiWindowXMsgProc - DISPLAY=%s\n", pszDisplay);
-
- /* Use our generated cookie for authentication */
- winSetAuthorization();
-
- /* Initialize retry count */
- iRetries = 0;
-
- /* Open the X display */
- do
- {
- /* Try to open the display */
- pProcArg->pDisplay = XOpenDisplay (pszDisplay);
- if (pProcArg->pDisplay == NULL)
- {
- ErrorF ("winMultiWindowXMsgProc - Could not open display, try: %d, "
- "sleeping: %d\n",
- iRetries + 1, WIN_CONNECT_DELAY);
- ++iRetries;
- sleep (WIN_CONNECT_DELAY);
- continue;
- }
- else
- break;
- }
- while (pProcArg->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES);
-
- /* Make sure that the display opened */
- if (pProcArg->pDisplay == NULL)
- {
- ErrorF ("winMultiWindowXMsgProc - Failed opening the display. "
- "Exiting.\n");
- pthread_exit (NULL);
- }
-
- ErrorF ("winMultiWindowXMsgProc - XOpenDisplay () returned and "
- "successfully opened the display.\n");
-
- /* Check if another window manager is already running */
- g_fAnotherWMRunning = CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen, pProcArg->pWMInfo->fAllowOtherWM);
-
- if (g_fAnotherWMRunning && !pProcArg->pWMInfo->fAllowOtherWM)
- {
- ErrorF ("winMultiWindowXMsgProc - "
- "another window manager is running. Exiting.\n");
- pthread_exit (NULL);
- }
-
- /* Set up the supported icon sizes */
- xis = XAllocIconSize ();
- if (xis)
- {
- xis->min_width = xis->min_height = 16;
- xis->max_width = xis->max_height = 48;
- xis->width_inc = xis->height_inc = 16;
- XSetIconSizes (pProcArg->pDisplay,
- RootWindow (pProcArg->pDisplay, pProcArg->dwScreen),
- xis,
- 1);
- XFree (xis);
- }
-
- atmWmName = XInternAtom (pProcArg->pDisplay,
- "WM_NAME",
- False);
- atmWmHints = XInternAtom (pProcArg->pDisplay,
- "WM_HINTS",
- False);
- atmWmChange = XInternAtom (pProcArg->pDisplay,
- "WM_CHANGE_STATE",
- False);
-
- /*
- iiimxcf had a bug until 2009-04-27, assuming that the
- WM_STATE atom exists, causing clients to fail with
- a BadAtom X error if it doesn't.
-
- Since this is on in the default Solaris 10 install,
- workaround this by making sure it does exist...
- */
- XInternAtom(pProcArg->pDisplay, "WM_STATE", 0);
-
- /* Loop until we explicitly break out */
- while (1)
- {
- if (g_shutdown)
- break;
-
- if (pProcArg->pWMInfo->fAllowOtherWM && !XPending (pProcArg->pDisplay))
- {
- if (CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen, TRUE))
- {
- if (!g_fAnotherWMRunning)
- {
- g_fAnotherWMRunning = TRUE;
- SendMessage(*(HWND*)pProcArg->hwndScreen, WM_UNMANAGE, 0, 0);
- }
- }
- else
- {
- if (g_fAnotherWMRunning)
- {
- g_fAnotherWMRunning = FALSE;
- SendMessage(*(HWND*)pProcArg->hwndScreen, WM_MANAGE, 0, 0);
- }
- }
- Sleep (500);
- continue;
- }
-
- /* Fetch next event */
- XNextEvent (pProcArg->pDisplay, &event);
-
- /* Branch on event type */
- if (event.type == CreateNotify)
- {
- XWindowAttributes attr;
-
- XSelectInput (pProcArg->pDisplay,
- event.xcreatewindow.window,
- PropertyChangeMask);
-
- /* Get the window attributes */
- XGetWindowAttributes (pProcArg->pDisplay,
- event.xcreatewindow.window,
- &attr);
-
- if (!attr.override_redirect)
- XSetWindowBorderWidth(pProcArg->pDisplay,
- event.xcreatewindow.window,
- 0);
- }
- else if (event.type == MapNotify)
- {
- /* Fake a reparentNotify event as SWT/Motif expects a
- Window Manager to reparent a top-level window when
- it is mapped and waits until they do.
-
- We don't actually need to reparent, as the frame is
- a native window, not an X window
-
- We do this on MapNotify, not MapRequest like a real
- Window Manager would, so we don't have do get involved
- in actually mapping the window via it's (non-existent)
- parent...
-
- See sourceware bugzilla #9848
- */
-
- XWindowAttributes attr;
- Window root;
- Window parent;
- Window *children;
- unsigned int nchildren;
-
- if (XGetWindowAttributes(event.xmap.display,
- event.xmap.window,
- &attr) &&
- XQueryTree(event.xmap.display,
- event.xmap.window,
- &root, &parent, &children, &nchildren))
- {
- if (children) XFree(children);
-
- /*
- It's a top-level window if the parent window is a root window
- Only non-override_redirect windows can get reparented
- */
- if ((attr.root == parent) && !event.xmap.override_redirect)
- {
- XEvent event_send;
-
- event_send.type = ReparentNotify;
- event_send.xreparent.event = event.xmap.window;
- event_send.xreparent.window = event.xmap.window;
- event_send.xreparent.parent = parent;
- event_send.xreparent.x = attr.x;
- event_send.xreparent.y = attr.y;
-
- XSendEvent(event.xmap.display,
- event.xmap.window,
- True, StructureNotifyMask,
- &event_send);
- }
- }
- }
- else if (event.type == PropertyNotify
- && event.xproperty.atom == atmWmName)
- {
- memset (&msg, 0, sizeof (msg));
-
- msg.msg = WM_WM_NAME_EVENT;
- msg.iWindow = event.xproperty.window;
-
- /* Other fields ignored */
- winSendMessageToWM (pProcArg->pWMInfo, &msg);
- }
- else if (event.type == PropertyNotify
- && event.xproperty.atom == atmWmHints)
- {
- memset (&msg, 0, sizeof (msg));
-
- msg.msg = WM_WM_HINTS_EVENT;
- msg.iWindow = event.xproperty.window;
-
- /* Other fields ignored */
- winSendMessageToWM (pProcArg->pWMInfo, &msg);
- }
- else if (event.type == ClientMessage
- && event.xclient.message_type == atmWmChange
- && event.xclient.data.l[0] == IconicState)
- {
- ErrorF ("winMultiWindowXMsgProc - WM_CHANGE_STATE - IconicState\n");
-
- memset (&msg, 0, sizeof (msg));
-
- msg.msg = WM_WM_CHANGE_STATE;
- msg.iWindow = event.xclient.window;
-
- winSendMessageToWM (pProcArg->pWMInfo, &msg);
- }
- }
-
- XCloseDisplay (pProcArg->pDisplay);
- pthread_exit (NULL);
- return NULL;
-}
-
-
-/*
- * winInitWM - Entry point for the X server to spawn
- * the Window Manager thread. Called from
- * winscrinit.c/winFinishScreenInitFB ().
- */
-
-Bool
-winInitWM (void **ppWMInfo,
- pthread_t *ptWMProc,
- pthread_t *ptXMsgProc,
- pthread_mutex_t *ppmServerStarted,
- int dwScreen,
- HWND hwndScreen,
- BOOL allowOtherWM)
-{
- WMProcArgPtr pArg = (WMProcArgPtr) malloc (sizeof(WMProcArgRec));
- WMInfoPtr pWMInfo = (WMInfoPtr) malloc (sizeof(WMInfoRec));
- XMsgProcArgPtr pXMsgArg = (XMsgProcArgPtr) malloc (sizeof(XMsgProcArgRec));
-
- /* Bail if the input parameters are bad */
- if (pArg == NULL || pWMInfo == NULL)
- {
- ErrorF ("winInitWM - malloc failed.\n");
- return FALSE;
- }
-
- /* Zero the allocated memory */
- ZeroMemory (pArg, sizeof (WMProcArgRec));
- ZeroMemory (pWMInfo, sizeof (WMInfoRec));
- ZeroMemory (pXMsgArg, sizeof (XMsgProcArgRec));
-
- /* Set a return pointer to the Window Manager info structure */
- *ppWMInfo = pWMInfo;
- pWMInfo->fAllowOtherWM = allowOtherWM;
-
- /* Setup the argument structure for the thread function */
- pArg->dwScreen = dwScreen;
- pArg->pWMInfo = pWMInfo;
- pArg->ppmServerStarted = ppmServerStarted;
-
- /* Intialize the message queue */
- if (!InitQueue (&pWMInfo->wmMsgQueue))
- {
- ErrorF ("winInitWM - InitQueue () failed.\n");
- return FALSE;
- }
-
- /* Spawn a thread for the Window Manager */
- if (pthread_create (ptWMProc, NULL, winMultiWindowWMProc, pArg))
- {
- /* Bail if thread creation failed */
- ErrorF ("winInitWM - pthread_create failed for Window Manager.\n");
- return FALSE;
- }
-
- /* Spawn the XNextEvent thread, will send messages to WM */
- pXMsgArg->dwScreen = dwScreen;
- pXMsgArg->pWMInfo = pWMInfo;
- pXMsgArg->ppmServerStarted = ppmServerStarted;
- pXMsgArg->hwndScreen = hwndScreen;
- if (pthread_create (ptXMsgProc, NULL, winMultiWindowXMsgProc, pXMsgArg))
- {
- /* Bail if thread creation failed */
- ErrorF ("winInitWM - pthread_create failed on XMSG.\n");
- return FALSE;
- }
-
-#if CYGDEBUG || YES
- winDebug ("winInitWM - Returning.\n");
-#endif
-
- return TRUE;
-}
-
-
-/*
- * Window manager thread - setup
- */
-
-static void
-winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
-{
- int iRetries = 0;
- char pszDisplay[512];
- int iReturn;
-
- ErrorF ("winInitMultiWindowWM - Hello\n");
-
- /* Check that argument pointer is not invalid */
- if (pProcArg == NULL)
- {
- ErrorF ("winInitMultiWindowWM - pProcArg is NULL. Exiting.\n");
- pthread_exit (NULL);
- }
-
- ErrorF ("winInitMultiWindowWM - Calling pthread_mutex_lock ()\n");
-
- /* Grab our garbage mutex to satisfy pthread_cond_wait */
- iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted);
- if (iReturn != 0)
- {
- ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () failed: %d. "
- "Exiting.\n",
- iReturn);
- pthread_exit (NULL);
- }
-
- ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () returned.\n");
-
- /* Allow multiple threads to access Xlib */
- if (XInitThreads () == 0)
- {
- ErrorF ("winInitMultiWindowWM - XInitThreads () failed. Exiting.\n");
- pthread_exit (NULL);
- }
-
- /* See if X supports the current locale */
- if (XSupportsLocale () == False)
- {
- ErrorF ("winInitMultiWindowWM - Warning: Locale not supported by X.\n");
- }
-
- /* Release the server started mutex */
- pthread_mutex_unlock (pProcArg->ppmServerStarted);
-
- ErrorF ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n");
-
- /* Set jump point for IO Error exits */
- iReturn = setjmp (g_jmpWMEntry);
-
- /* Check if we should continue operations */
- if (iReturn != WIN_JMP_ERROR_IO
- && iReturn != WIN_JMP_OKAY)
- {
- /* setjmp returned an unknown value, exit */
- ErrorF ("winInitMultiWindowWM - setjmp returned: %d. Exiting.\n",
- iReturn);
- pthread_exit (NULL);
- }
- else if (iReturn == WIN_JMP_ERROR_IO)
- {
- ErrorF ("winInitMultiWindowWM - Caught IO Error. Exiting.\n");
- pthread_exit (NULL);
- }
-
- /* Install our error handler */
- XSetErrorHandler (winMultiWindowWMErrorHandler);
- XSetIOErrorHandler (winMultiWindowWMIOErrorHandler);
-
- /* Setup the display connection string x */
- snprintf (pszDisplay,
- 512,
- "127.0.0.1:%s.%d",
- display,
- (int) pProcArg->dwScreen);
-
- /* Print the display connection string */
- ErrorF ("winInitMultiWindowWM - DISPLAY=%s\n", pszDisplay);
-
- /* Use our generated cookie for authentication */
- winSetAuthorization();
-
- /* Open the X display */
- do
- {
- /* Try to open the display */
- pWMInfo->pDisplay = XOpenDisplay (pszDisplay);
- if (pWMInfo->pDisplay == NULL)
- {
- ErrorF ("winInitMultiWindowWM - Could not open display, try: %d, "
- "sleeping: %d\n",
- iRetries + 1, WIN_CONNECT_DELAY);
- ++iRetries;
- sleep (WIN_CONNECT_DELAY);
- continue;
- }
- else
- break;
- }
- while (pWMInfo->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES);
-
- /* Make sure that the display opened */
- if (pWMInfo->pDisplay == NULL)
- {
- ErrorF ("winInitMultiWindowWM - Failed opening the display. "
- "Exiting.\n");
- pthread_exit (NULL);
- }
-
- ErrorF ("winInitMultiWindowWM - XOpenDisplay () returned and "
- "successfully opened the display.\n");
-
-
- /* Create some atoms */
- pWMInfo->atmWmProtos = XInternAtom (pWMInfo->pDisplay,
- "WM_PROTOCOLS",
- False);
- pWMInfo->atmWmDelete = XInternAtom (pWMInfo->pDisplay,
- "WM_DELETE_WINDOW",
- False);
-
- pWMInfo->atmPrivMap = XInternAtom (pWMInfo->pDisplay,
- WINDOWSWM_NATIVE_HWND,
- False);
-
-
- if (1) {
- Cursor cursor = XCreateFontCursor (pWMInfo->pDisplay, XC_left_ptr);
- if (cursor)
- {
- XDefineCursor (pWMInfo->pDisplay, DefaultRootWindow(pWMInfo->pDisplay), cursor);
- XFreeCursor (pWMInfo->pDisplay, cursor);
- }
- }
-}
-
-
-/*
- * winSendMessageToWM - Send a message from the X thread to the WM thread
- */
-
-void
-winSendMessageToWM (void *pWMInfo, winWMMessagePtr pMsg)
-{
- WMMsgNodePtr pNode;
-
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winSendMessageToWM ()\n");
-#endif
-
- pNode = (WMMsgNodePtr)malloc(sizeof(WMMsgNodeRec));
- if (pNode != NULL)
- {
- memcpy (&pNode->msg, pMsg, sizeof(winWMMessageRec));
- PushMessage (&((WMInfoPtr)pWMInfo)->wmMsgQueue, pNode);
- }
-}
-
-
-/*
- * Window manager error handler
- */
-
-static int
-winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr)
-{
- char pszErrorMsg[100];
-
- if (pErr->request_code == X_ChangeWindowAttributes
- && pErr->error_code == BadAccess)
- {
- ErrorF ("winMultiWindowWMErrorHandler - ChangeWindowAttributes "
- "BadAccess.\n");
- return 0;
- }
-
- XGetErrorText (pDisplay,
- pErr->error_code,
- pszErrorMsg,
- sizeof (pszErrorMsg));
- ErrorF ("winMultiWindowWMErrorHandler - ERROR: %s\n", pszErrorMsg);
-
- return 0;
-}
-
-
-/*
- * Window manager IO error handler
- */
-
-static int
-winMultiWindowWMIOErrorHandler (Display *pDisplay)
-{
- ErrorF ("winMultiWindowWMIOErrorHandler!\n\n");
-
- if (g_shutdown)
- pthread_exit(NULL);
-
- /* Restart at the main entry point */
- longjmp (g_jmpWMEntry, WIN_JMP_ERROR_IO);
-
- return 0;
-}
-
-
-/*
- * X message procedure error handler
- */
-
-static int
-winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr)
-{
- char pszErrorMsg[100];
-
- XGetErrorText (pDisplay,
- pErr->error_code,
- pszErrorMsg,
- sizeof (pszErrorMsg));
-#if CYGMULTIWINDOW_DEBUG
- ErrorF ("winMultiWindowXMsgProcErrorHandler - ERROR: %s\n", pszErrorMsg);
-#endif
-
- return 0;
-}
-
-
-/*
- * X message procedure IO error handler
- */
-
-static int
-winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay)
-{
- ErrorF ("winMultiWindowXMsgProcIOErrorHandler!\n\n");
-
- /* Restart at the main entry point */
- longjmp (g_jmpXMsgProcEntry, WIN_JMP_ERROR_IO);
-
- return 0;
-}
-
-
-/*
- * Catch RedirectError to detect other window manager running
- */
-
-static int
-winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr)
-{
- redirectError = TRUE;
- return 0;
-}
-
-
-/*
- * Check if another window manager is running
- */
-
-static Bool
-CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen, Bool fAllowOtherWM)
-{
- /*
- Try to select the events which only one client at a time is allowed to select.
- If this causes an error, another window manager is already running...
- */
- redirectError = FALSE;
- XSetErrorHandler (winRedirectErrorHandler);
- XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen),
- ResizeRedirectMask | SubstructureRedirectMask | ButtonPressMask);
- XSync (pDisplay, 0);
- XSetErrorHandler (winMultiWindowXMsgProcErrorHandler);
-
- /*
- Side effect: select the events we are actually interested in...
-
- If other WMs are not allowed, also select one of the events which only one client
- at a time is allowed to select, so other window managers won't start...
- */
- XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen),
- SubstructureNotifyMask | ( !fAllowOtherWM ? ButtonPressMask : 0));
- XSync (pDisplay, 0);
- return redirectError;
-}
-
-/*
- * Notify the MWM thread we're exiting and not to reconnect
- */
-
-void
-winDeinitMultiWindowWM (void)
-{
- ErrorF ("winDeinitMultiWindowWM - Noting shutdown in progress\n");
- g_shutdown = TRUE;
-}
-
-/* Windows window styles */
-#define HINT_NOFRAME (1l<<0)
-#define HINT_BORDER (1L<<1)
-#define HINT_SIZEBOX (1l<<2)
-#define HINT_CAPTION (1l<<3)
-#define HINT_NOMAXIMIZE (1L<<4)
-/* These two are used on their own */
-#define HINT_MAX (1L<<0)
-#define HINT_MIN (1L<<1)
-
-static void
-winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle)
-{
- static Atom windowState, motif_wm_hints, windowType;
- static Atom hiddenState, fullscreenState, belowState, aboveState;
- static Atom dockWindow;
- static int generation;
- Atom type, *pAtom = NULL;
- int format;
- unsigned long hint = 0, maxmin = 0, style, nitems = 0 , left = 0;
- WindowPtr pWin = GetProp (hWnd, WIN_WINDOW_PROP);
- MwmHints *mwm_hint = NULL;
-
- if (!hWnd) return;
- if (!IsWindow (hWnd)) return;
-
- if (generation != serverGeneration) {
- generation = serverGeneration;
- windowState = XInternAtom(pDisplay, "_NET_WM_STATE", False);
- motif_wm_hints = XInternAtom(pDisplay, "_MOTIF_WM_HINTS", False);
- windowType = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE", False);
- hiddenState = XInternAtom(pDisplay, "_NET_WM_STATE_HIDDEN", False);
- fullscreenState = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", False);
- belowState = XInternAtom(pDisplay, "_NET_WM_STATE_BELOW", False);
- aboveState = XInternAtom(pDisplay, "_NET_WM_STATE_ABOVE", False);
- dockWindow = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False);
- }
-
- if (XGetWindowProperty(pDisplay, iWindow, windowState, 0L,
- 1L, False, XA_ATOM, &type, &format,
- &nitems, &left, (unsigned char **)&pAtom) == Success)
- {
- if (pAtom && nitems == 1)
- {
- if (*pAtom == hiddenState) maxmin |= HINT_MIN;
- else if (*pAtom == fullscreenState) maxmin |= HINT_MAX;
- if (*pAtom == belowState) *zstyle = HWND_BOTTOM;
- else if (*pAtom == aboveState) *zstyle = HWND_TOPMOST;
- }
- if (pAtom) XFree(pAtom);
- }
-
- nitems = left = 0;
- if (XGetWindowProperty(pDisplay, iWindow, motif_wm_hints, 0L,
- PropMwmHintsElements, False, motif_wm_hints, &type, &format,
- &nitems, &left, (unsigned char **)&mwm_hint) == Success)
- {
- if (mwm_hint && nitems == PropMwmHintsElements && (mwm_hint->flags & MwmHintsDecorations))
- {
- if (!mwm_hint->decorations) hint |= HINT_NOFRAME;
- else if (!(mwm_hint->decorations & MwmDecorAll))
- {
- if (mwm_hint->decorations & MwmDecorBorder) hint |= HINT_BORDER;
- if (mwm_hint->decorations & MwmDecorHandle) hint |= HINT_SIZEBOX;
- if (mwm_hint->decorations & MwmDecorTitle) hint |= HINT_CAPTION;
- }
- }
- if (mwm_hint) XFree(mwm_hint);
- }
-
- nitems = left = 0;
- pAtom = NULL;
- if (XGetWindowProperty(pDisplay, iWindow, windowType, 0L,
- 1L, False, XA_ATOM, &type, &format,
- &nitems, &left, (unsigned char **)&pAtom) == Success)
- {
- if (pAtom && nitems == 1)
- {
- if (*pAtom == dockWindow)
- {
- hint = (hint & ~HINT_NOFRAME) | HINT_SIZEBOX; /* Xming puts a sizebox on dock windows */
- *zstyle = HWND_TOPMOST;
- }
- }
- if (pAtom) XFree(pAtom);
- }
-
- {
- XSizeHints *normal_hint = XAllocSizeHints();
- long supplied;
- if (normal_hint && (XGetWMNormalHints(pDisplay, iWindow, normal_hint, &supplied) == Success))
- {
- if (normal_hint->flags & PMaxSize)
- {
- /* Not maximizable if a maximum size is specified */
- hint |= HINT_NOMAXIMIZE;
-
- if (normal_hint->flags & PMinSize)
- {
- /*
- If both minimum size and maximum size are specified and are the same,
- don't bother with a resizing frame
- */
- if ((normal_hint->min_width == normal_hint->max_width)
- && (normal_hint->min_height == normal_hint->max_height))
- hint = (hint & ~HINT_SIZEBOX);
- }
- }
- }
- XFree(normal_hint);
- }
-
- /* Override hint settings from above with settings from config file */
- style = winOverrideStyle((unsigned long)pWin);
- if (style & STYLE_TOPMOST) *zstyle = HWND_TOPMOST;
- else if (style & STYLE_MAXIMIZE) maxmin = (hint & ~HINT_MIN) | HINT_MAX;
- else if (style & STYLE_MINIMIZE) maxmin = (hint & ~HINT_MAX) | HINT_MIN;
- else if (style & STYLE_BOTTOM) *zstyle = HWND_BOTTOM;
-
- if (maxmin & HINT_MAX) SendMessage(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
- else if (maxmin & HINT_MIN) SendMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
-
- if (style & STYLE_NOTITLE)
- hint = (hint & ~HINT_NOFRAME & ~HINT_BORDER & ~HINT_CAPTION) | HINT_SIZEBOX;
- else if (style & STYLE_OUTLINE)
- hint = (hint & ~HINT_NOFRAME & ~HINT_SIZEBOX & ~HINT_CAPTION) | HINT_BORDER;
- else if (style & STYLE_NOFRAME)
- hint = (hint & ~HINT_BORDER & ~HINT_CAPTION & ~HINT_SIZEBOX) | HINT_NOFRAME;
-
- /* Now apply styles to window */
- style = GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION & ~WS_SIZEBOX; /* Just in case */
- if (!style) return;
-
- if (!hint) /* All on */
- style = style | WS_CAPTION | WS_SIZEBOX;
- else if (hint & HINT_NOFRAME) /* All off */
- style = style & ~WS_CAPTION & ~WS_SIZEBOX;
- else style = style | ((hint & HINT_BORDER) ? WS_BORDER : 0) |
- ((hint & HINT_SIZEBOX) ? WS_SIZEBOX : 0) |
- ((hint & HINT_CAPTION) ? WS_CAPTION : 0);
-
- if (hint & HINT_NOMAXIMIZE)
- style = style & ~WS_MAXIMIZEBOX;
-
- SetWindowLongPtr (hWnd, GWL_STYLE, style);
-}
-
-void
-winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle)
-{
- int iX, iY, iWidth, iHeight;
- int iDx, iDy;
- RECT rcNew;
- WindowPtr pWin = GetProp (hWnd, WIN_WINDOW_PROP);
- DrawablePtr pDraw = NULL;
-
- if (!pWin) return;
- pDraw = &pWin->drawable;
- if (!pDraw) return;
-
- /* Get the X and Y location of the X window */
- iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
- iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
-
- /* Get the height and width of the X window */
- iWidth = pWin->drawable.width;
- iHeight = pWin->drawable.height;
-
- /* Setup a rectangle with the X window position and size */
- SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
-
-#if 0
- ErrorF ("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n",
- rcNew.left, rcNew.top,
- rcNew.right, rcNew.bottom);
-#endif
-
- AdjustWindowRectEx (&rcNew, GetWindowLongPtr (hWnd, GWL_STYLE), FALSE, WS_EX_APPWINDOW);
-
- /* Don't allow window decoration to disappear off to top-left as a result of this adjustment */
- if (rcNew.left < GetSystemMetrics(SM_XVIRTUALSCREEN))
- {
- iDx = GetSystemMetrics(SM_XVIRTUALSCREEN) - rcNew.left;
- rcNew.left += iDx;
- rcNew.right += iDx;
- }
-
- if (rcNew.top < GetSystemMetrics(SM_YVIRTUALSCREEN))
- {
- iDy = GetSystemMetrics(SM_YVIRTUALSCREEN) - rcNew.top;
- rcNew.top += iDy;
- rcNew.bottom += iDy;
- }
-
-#if 0
- ErrorF ("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n",
- rcNew.left, rcNew.top,
- rcNew.right, rcNew.bottom);
-#endif
-
- /* Position the Windows window */
- SetWindowPos (hWnd, *zstyle, rcNew.left, rcNew.top,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
- 0);
-
- if (reshape)
- {
- winReshapeMultiWindow(pWin);
- winUpdateRgnMultiWindow(pWin);
- }
-}
+/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + *Copyright (C) Colin Harrison 2005-2009 + * + *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 XFREE86 PROJECT 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 of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Kensuke Matsuzaki + * Colin Harrison + */ + +/* X headers */ +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#ifdef __CYGWIN__ +#include <sys/select.h> +#endif +#include <fcntl.h> +#include <setjmp.h> +#define HANDLE void * +#include <pthread.h> +#undef HANDLE +#include <X11/X.h> +#include <X11/Xatom.h> +#include <X11/Xlib.h> +#include <X11/Xlocale.h> +#include <X11/Xproto.h> +#include <X11/Xutil.h> +#include <X11/cursorfont.h> +#include <X11/Xwindows.h> + +/* Local headers */ +#include "objbase.h" +#include "ddraw.h" +#include "winwindow.h" +#include "winprefs.h" +#include "window.h" +#include "pixmapstr.h" +#include "windowstr.h" + +#ifdef XWIN_MULTIWINDOWEXTWM +#include <X11/extensions/windowswmstr.h> +#else +/* We need the native HWND atom for intWM, so for consistency use the + same name as extWM would if we were building with enabled... */ +#define WINDOWSWM_NATIVE_HWND "_WINDOWSWM_NATIVE_HWND" +#endif + +extern void winDebug(const char *format, ...); +extern void winReshapeMultiWindow(WindowPtr pWin); +extern void winUpdateRgnMultiWindow(WindowPtr pWin); + +#ifndef CYGDEBUG +#define CYGDEBUG NO +#endif + +/* + * Constant defines + */ + +#define WIN_CONNECT_RETRIES 5 +#define WIN_CONNECT_DELAY 5 +#ifdef HAS_DEVWINDOWS +# define WIN_MSG_QUEUE_FNAME "/dev/windows" +#endif +#define WIN_JMP_OKAY 0 +#define WIN_JMP_ERROR_IO 2 + +/* + * Local structures + */ + +typedef struct _WMMsgNodeRec { + winWMMessageRec msg; + struct _WMMsgNodeRec *pNext; +} WMMsgNodeRec, *WMMsgNodePtr; + +typedef struct _WMMsgQueueRec { + struct _WMMsgNodeRec *pHead; + struct _WMMsgNodeRec *pTail; + pthread_mutex_t pmMutex; + pthread_cond_t pcNotEmpty; + int nQueueSize; +} WMMsgQueueRec, *WMMsgQueuePtr; + +typedef struct _WMInfo { + Display *pDisplay; + WMMsgQueueRec wmMsgQueue; + Atom atmWmProtos; + Atom atmWmDelete; + Atom atmPrivMap; + Bool fAllowOtherWM; +} WMInfoRec, *WMInfoPtr; + +typedef struct _WMProcArgRec { + DWORD dwScreen; + WMInfoPtr pWMInfo; + pthread_mutex_t *ppmServerStarted; +} WMProcArgRec, *WMProcArgPtr; + +typedef struct _XMsgProcArgRec { + Display *pDisplay; + DWORD dwScreen; + WMInfoPtr pWMInfo; + pthread_mutex_t *ppmServerStarted; + HWND hwndScreen; +} XMsgProcArgRec, *XMsgProcArgPtr; + + +/* + * References to external symbols + */ + +extern char *display; +extern void ErrorF (const char* /*f*/, ...); + +/* + * Prototypes for local functions + */ + +static void +PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode); + +static WMMsgNodePtr +PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo); + +static Bool +InitQueue (WMMsgQueuePtr pQueue); + +static void +GetWindowName (Display * pDpy, Window iWin, wchar_t **ppName); + +static int +SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData); + +static void +UpdateName (WMInfoPtr pWMInfo, Window iWindow); + +static void* +winMultiWindowWMProc (void* pArg); + +static int +winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static int +winMultiWindowWMIOErrorHandler (Display *pDisplay); + +static void * +winMultiWindowXMsgProc (void *pArg); + +static int +winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static int +winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay); + +static int +winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr); + +static void +winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg); + +#if 0 +static void +PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction); +#endif + +static Bool +CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen, Bool fAllowOtherWM); + +static void +winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle); + +void +winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle); + +/* + * Local globals + */ + +static jmp_buf g_jmpWMEntry; +static jmp_buf g_jmpXMsgProcEntry; +static Bool g_shutdown = FALSE; +static Bool redirectError = FALSE; +static Bool g_fAnotherWMRunning = FALSE; + +/* + * PushMessage - Push a message onto the queue + */ + +static void +PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode) +{ + + /* Lock the queue mutex */ + pthread_mutex_lock (&pQueue->pmMutex); + + pNode->pNext = NULL; + + if (pQueue->pTail != NULL) + { + pQueue->pTail->pNext = pNode; + } + pQueue->pTail = pNode; + + if (pQueue->pHead == NULL) + { + pQueue->pHead = pNode; + } + + +#if 0 + switch (pNode->msg.msg) + { + case WM_WM_MOVE: + ErrorF ("\tWM_WM_MOVE\n"); + break; + case WM_WM_SIZE: + ErrorF ("\tWM_WM_SIZE\n"); + break; + case WM_WM_RAISE: + ErrorF ("\tWM_WM_RAISE\n"); + break; + case WM_WM_LOWER: + ErrorF ("\tWM_WM_LOWER\n"); + break; + case WM_WM_MAP: + ErrorF ("\tWM_WM_MAP\n"); + break; + case WM_WM_MAP2: + ErrorF ("\tWM_WM_MAP2\n"); + break; + case WM_WM_MAP3: + ErrorF ("\tWM_WM_MAP3\n"); + break; + case WM_WM_UNMAP: + ErrorF ("\tWM_WM_UNMAP\n"); + break; + case WM_WM_KILL: + ErrorF ("\tWM_WM_KILL\n"); + break; + case WM_WM_ACTIVATE: + ErrorF ("\tWM_WM_ACTIVATE\n"); + break; + default: + ErrorF ("\tUnknown Message.\n"); + break; + } +#endif + + /* Increase the count of elements in the queue by one */ + ++(pQueue->nQueueSize); + + /* Release the queue mutex */ + pthread_mutex_unlock (&pQueue->pmMutex); + + /* Signal that the queue is not empty */ + pthread_cond_signal (&pQueue->pcNotEmpty); +} + + +#if CYGMULTIWINDOW_DEBUG +/* + * QueueSize - Return the size of the queue + */ + +static int +QueueSize (WMMsgQueuePtr pQueue) +{ + WMMsgNodePtr pNode; + int nSize = 0; + + /* Loop through all elements in the queue */ + for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext) + ++nSize; + + return nSize; +} +#endif + + +/* + * PopMessage - Pop a message from the queue + */ + +static WMMsgNodePtr +PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo) +{ + WMMsgNodePtr pNode; + + /* Lock the queue mutex */ + pthread_mutex_lock (&pQueue->pmMutex); + + /* Wait for --- */ + while (pQueue->pHead == NULL) + { + pthread_cond_wait (&pQueue->pcNotEmpty, &pQueue->pmMutex); + } + + pNode = pQueue->pHead; + if (pQueue->pHead != NULL) + { + pQueue->pHead = pQueue->pHead->pNext; + } + + if (pQueue->pTail == pNode) + { + pQueue->pTail = NULL; + } + + /* Drop the number of elements in the queue by one */ + --(pQueue->nQueueSize); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("Queue Size %d %d\n", pQueue->nQueueSize, QueueSize(pQueue)); +#endif + + /* Release the queue mutex */ + pthread_mutex_unlock (&pQueue->pmMutex); + + return pNode; +} + + +#if 0 +/* + * HaveMessage - + */ + +static Bool +HaveMessage (WMMsgQueuePtr pQueue, UINT msg, Window iWindow) +{ + WMMsgNodePtr pNode; + + for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext) + { + if (pNode->msg.msg==msg && pNode->msg.iWindow==iWindow) + return True; + } + + return False; +} +#endif + + +/* + * InitQueue - Initialize the Window Manager message queue + */ + +static +Bool +InitQueue (WMMsgQueuePtr pQueue) +{ + /* Check if the pQueue pointer is NULL */ + if (pQueue == NULL) + { + ErrorF ("InitQueue - pQueue is NULL. Exiting.\n"); + return FALSE; + } + + /* Set the head and tail to NULL */ + pQueue->pHead = NULL; + pQueue->pTail = NULL; + + /* There are no elements initially */ + pQueue->nQueueSize = 0; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("InitQueue - Queue Size %d %d\n", pQueue->nQueueSize, + QueueSize(pQueue)); +#endif + + ErrorF ("InitQueue - Calling pthread_mutex_init\n"); + + /* Create synchronization objects */ + pthread_mutex_init (&pQueue->pmMutex, NULL); + + ErrorF ("InitQueue - pthread_mutex_init returned\n"); + ErrorF ("InitQueue - Calling pthread_cond_init\n"); + + pthread_cond_init (&pQueue->pcNotEmpty, NULL); + + ErrorF ("InitQueue - pthread_cond_init returned\n"); + + return TRUE; +} + + +/* + * GetWindowName - Retrieve the title of an X Window + */ + +static void +GetWindowName (Display *pDisplay, Window iWin, wchar_t **ppName) +{ + int nResult, nNum; + char **ppList; + char *pszReturnData; + int iLen, i; + XTextProperty xtpName; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("GetWindowName\n"); +#endif + + /* Intialize ppName to NULL */ + *ppName = NULL; + + /* Try to get --- */ + nResult = XGetWMName (pDisplay, iWin, &xtpName); + if (!nResult || !xtpName.value || !xtpName.nitems) + { +#if CYGMULTIWINDOW_DEBUG + ErrorF ("GetWindowName - XGetWMName failed. No name.\n"); +#endif + return; + } + + if (Xutf8TextPropertyToTextList (pDisplay, &xtpName, &ppList, &nNum) >= Success && nNum > 0 && *ppList) + { + iLen = 0; + for (i = 0; i < nNum; i++) iLen += strlen(ppList[i]); + pszReturnData = (char *) malloc (iLen + 1); + pszReturnData[0] = '\0'; + for (i = 0; i < nNum; i++) strcat (pszReturnData, ppList[i]); + if (ppList) XFreeStringList (ppList); + } + else + { + pszReturnData = (char *) malloc (1); + pszReturnData[0] = '\0'; + } + iLen = MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, NULL, 0); + *ppName = (wchar_t*)malloc(sizeof(wchar_t)*(iLen + 1)); + MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, *ppName, iLen); + XFree (xtpName.value); + free (pszReturnData); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("GetWindowName - Returning\n"); +#endif +} + + +/* + * Send a message to the X server from the WM thread + */ + +static int +SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData) +{ + XEvent e; + + /* Prepare the X event structure */ + e.type = ClientMessage; + e.xclient.window = iWin; + e.xclient.message_type = atmType; + e.xclient.format = 32; + e.xclient.data.l[0] = nData; + e.xclient.data.l[1] = CurrentTime; + + /* Send the event to X */ + return XSendEvent (pDisplay, iWin, False, NoEventMask, &e); +} + + +/* + * Updates the name of a HWND according to its X WM_NAME property + */ + +static void +UpdateName (WMInfoPtr pWMInfo, Window iWindow) +{ + wchar_t *pszName; + Atom atmType; + int fmtRet; + unsigned long items, remain; + HWND *retHwnd, hWnd; + XWindowAttributes attr; + + hWnd = 0; + + /* See if we can get the cached HWND for this window... */ + if (XGetWindowProperty (pWMInfo->pDisplay, + iWindow, + pWMInfo->atmPrivMap, + 0, + 1, + False, + XA_INTEGER,//pWMInfo->atmPrivMap, + &atmType, + &fmtRet, + &items, + &remain, + (unsigned char **) &retHwnd) == Success) + { + if (retHwnd) + { + hWnd = *retHwnd; + XFree (retHwnd); + } + } + + /* Some sanity checks */ + if (!hWnd) return; + if (!IsWindow (hWnd)) return; + + /* Set the Windows window name */ + GetWindowName (pWMInfo->pDisplay, iWindow, &pszName); + if (pszName) + { + /* Get the window attributes */ + XGetWindowAttributes (pWMInfo->pDisplay, + iWindow, + &attr); + if (!attr.override_redirect) + { + SetWindowTextW (hWnd, pszName); + winUpdateIcon (iWindow); + } + + free (pszName); + } +} + + +#if 0 +/* + * Fix up any differences between the X11 and Win32 window stacks + * starting at the window passed in + */ +static void +PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction) +{ + Atom atmType; + int fmtRet; + unsigned long items, remain; + HWND hWnd, *retHwnd; + DWORD myWinProcID, winProcID; + Window xWindow; + WINDOWPLACEMENT wndPlace; + + hWnd = NULL; + /* See if we can get the cached HWND for this window... */ + if (XGetWindowProperty (pWMInfo->pDisplay, + iWindow, + pWMInfo->atmPrivMap, + 0, + 1, + False, + XA_INTEGER,//pWMInfo->atmPrivMap, + &atmType, + &fmtRet, + &items, + &remain, + (unsigned char **) &retHwnd) == Success) + { + if (retHwnd) + { + hWnd = *retHwnd; + XFree (retHwnd); + } + } + + if (!hWnd) return; + + GetWindowThreadProcessId (hWnd, &myWinProcID); + hWnd = GetNextWindow (hWnd, direction); + + while (hWnd) { + GetWindowThreadProcessId (hWnd, &winProcID); + if (winProcID == myWinProcID) + { + wndPlace.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement (hWnd, &wndPlace); + if ( !(wndPlace.showCmd==SW_HIDE || + wndPlace.showCmd==SW_MINIMIZE) ) + { + xWindow = (Window)GetProp (hWnd, WIN_WID_PROP); + if (xWindow) + { + if (direction==GW_HWNDPREV) + XRaiseWindow (pWMInfo->pDisplay, xWindow); + else + XLowerWindow (pWMInfo->pDisplay, xWindow); + } + } + } + hWnd = GetNextWindow(hWnd, direction); + } +} +#endif /* PreserveWin32Stack */ + + +/* + * winMultiWindowWMProc + */ + +static void * +winMultiWindowWMProc (void *pArg) +{ + WMProcArgPtr pProcArg = (WMProcArgPtr)pArg; + WMInfoPtr pWMInfo = pProcArg->pWMInfo; + + /* Initialize the Window Manager */ + winInitMultiWindowWM (pWMInfo, pProcArg); + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winMultiWindowWMProc ()\n"); +#endif + + /* Loop until we explicitly break out */ + for (;;) + { + WMMsgNodePtr pNode; + + if(g_fAnotherWMRunning)/* Another Window manager exists. */ + { + Sleep (1000); + continue; + } + + /* Pop a message off of our queue */ + pNode = PopMessage (&pWMInfo->wmMsgQueue, pWMInfo); + if (pNode == NULL) + { + /* Bail if PopMessage returns without a message */ + /* NOTE: Remember that PopMessage is a blocking function. */ + ErrorF ("winMultiWindowWMProc - Queue is Empty? Exiting.\n"); + pthread_exit (NULL); + } + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winMultiWindowWMProc - %d ms MSG: %d ID: %d\n", + GetTickCount (), (int)pNode->msg.msg, (int)pNode->msg.dwID); +#endif + + /* Branch on the message type */ + switch (pNode->msg.msg) + { +#if 0 + case WM_WM_MOVE: + ErrorF ("\tWM_WM_MOVE\n"); + break; + + case WM_WM_SIZE: + ErrorF ("\tWM_WM_SIZE\n"); + break; +#endif + + case WM_WM_RAISE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_RAISE\n"); +#endif + /* Raise the window */ + XRaiseWindow (pWMInfo->pDisplay, pNode->msg.iWindow); +#if 0 + PreserveWin32Stack (pWMInfo, pNode->msg.iWindow, GW_HWNDPREV); +#endif + break; + + case WM_WM_LOWER: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_LOWER\n"); +#endif + + /* Lower the window */ + XLowerWindow (pWMInfo->pDisplay, pNode->msg.iWindow); + break; + + case WM_WM_MAP: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_MAP\n"); +#endif + /* Put a note as to the HWND associated with this Window */ + XChangeProperty (pWMInfo->pDisplay, + pNode->msg.iWindow, + pWMInfo->atmPrivMap, + XA_INTEGER,//pWMInfo->atmPrivMap, + 32, + PropModeReplace, + (unsigned char *) &(pNode->msg.hwndWindow), + 1); + UpdateName (pWMInfo, pNode->msg.iWindow); + winUpdateIcon (pNode->msg.iWindow); + break; + + case WM_WM_MAP2: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_MAP2\n"); +#endif + XChangeProperty (pWMInfo->pDisplay, + pNode->msg.iWindow, + pWMInfo->atmPrivMap, + XA_INTEGER,//pWMInfo->atmPrivMap, + 32, + PropModeReplace, + (unsigned char *) &(pNode->msg.hwndWindow), + 1); + break; + + case WM_WM_MAP3: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_MAP3\n"); +#endif + /* Put a note as to the HWND associated with this Window */ + XChangeProperty (pWMInfo->pDisplay, + pNode->msg.iWindow, + pWMInfo->atmPrivMap, + XA_INTEGER,//pWMInfo->atmPrivMap, + 32, + PropModeReplace, + (unsigned char *) &(pNode->msg.hwndWindow), + 1); + UpdateName (pWMInfo, pNode->msg.iWindow); + winUpdateIcon (pNode->msg.iWindow); + { + HWND zstyle = HWND_NOTOPMOST; + winApplyHints (pWMInfo->pDisplay, pNode->msg.iWindow, pNode->msg.hwndWindow, &zstyle); + winUpdateWindowPosition (pNode->msg.hwndWindow, TRUE, &zstyle); + } + break; + + case WM_WM_UNMAP: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_UNMAP\n"); +#endif + + /* Unmap the window */ + XUnmapWindow (pWMInfo->pDisplay, pNode->msg.iWindow); + break; + + case WM_WM_KILL: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_KILL\n"); +#endif + { + int i, n, found = 0; + Atom *protocols; + + /* --- */ + if (XGetWMProtocols (pWMInfo->pDisplay, + pNode->msg.iWindow, + &protocols, + &n)) + { + for (i = 0; i < n; ++i) + if (protocols[i] == pWMInfo->atmWmDelete) + ++found; + + XFree (protocols); + } + + /* --- */ + if (found) + SendXMessage (pWMInfo->pDisplay, + pNode->msg.iWindow, + pWMInfo->atmWmProtos, + pWMInfo->atmWmDelete); + else + XKillClient (pWMInfo->pDisplay, + pNode->msg.iWindow); + } + break; + + case WM_WM_ACTIVATE: +#if CYGMULTIWINDOW_DEBUG + ErrorF ("\tWM_WM_ACTIVATE\n"); +#endif + + /* Set the input focus */ + XSetInputFocus (pWMInfo->pDisplay, + pNode->msg.iWindow, + RevertToPointerRoot, + CurrentTime); + break; + + case WM_WM_NAME_EVENT: + UpdateName (pWMInfo, pNode->msg.iWindow); + break; + + case WM_WM_HINTS_EVENT: + winUpdateIcon (pNode->msg.iWindow); + break; + + case WM_WM_CHANGE_STATE: + /* Minimize the window in Windows */ + winMinimizeWindow (pNode->msg.iWindow); + break; + + default: + ErrorF ("winMultiWindowWMProc - Unknown Message. Exiting.\n"); + pthread_exit (NULL); + break; + } + + /* Free the retrieved message */ + free (pNode); + + /* Flush any pending events on our display */ + XFlush (pWMInfo->pDisplay); + } + + /* Free the condition variable */ + pthread_cond_destroy (&pWMInfo->wmMsgQueue.pcNotEmpty); + + /* Free the mutex variable */ + pthread_mutex_destroy (&pWMInfo->wmMsgQueue.pmMutex); + + /* Free the passed-in argument */ + free (pProcArg); + +#if CYGMULTIWINDOW_DEBUG + ErrorF("-winMultiWindowWMProc ()\n"); +#endif + return NULL; +} + + +/* + * X message procedure + */ + +static void * +winMultiWindowXMsgProc (void *pArg) +{ + winWMMessageRec msg; + XMsgProcArgPtr pProcArg = (XMsgProcArgPtr) pArg; + char pszDisplay[512]; + int iRetries; + XEvent event; + Atom atmWmName; + Atom atmWmHints; + Atom atmWmChange; + int iReturn; + XIconSize *xis; + + ErrorF ("winMultiWindowXMsgProc - Hello\n"); + + /* Check that argument pointer is not invalid */ + if (pProcArg == NULL) + { + ErrorF ("winMultiWindowXMsgProc - pProcArg is NULL. Exiting.\n"); + pthread_exit (NULL); + } + + ErrorF ("winMultiWindowXMsgProc - Calling pthread_mutex_lock ()\n"); + + /* Grab the server started mutex - pause until we get it */ + iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted); + if (iReturn != 0) + { + ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () failed: %d. " + "Exiting.\n", + iReturn); + pthread_exit (NULL); + } + + ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n"); + + /* Allow multiple threads to access Xlib */ + if (XInitThreads () == 0) + { + ErrorF ("winMultiWindowXMsgProc - XInitThreads () failed. Exiting.\n"); + pthread_exit (NULL); + } + + /* See if X supports the current locale */ + if (XSupportsLocale () == False) + { + ErrorF ("winMultiWindowXMsgProc - Warning: locale not supported by X\n"); + } + + /* Release the server started mutex */ + pthread_mutex_unlock (pProcArg->ppmServerStarted); + + ErrorF ("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n"); + + /* Set jump point for IO Error exits */ + iReturn = setjmp (g_jmpXMsgProcEntry); + + /* Check if we should continue operations */ + if (iReturn != WIN_JMP_ERROR_IO + && iReturn != WIN_JMP_OKAY) + { + /* setjmp returned an unknown value, exit */ + ErrorF ("winInitMultiWindowXMsgProc - setjmp returned: %d. Exiting.\n", + iReturn); + pthread_exit (NULL); + } + else if (iReturn == WIN_JMP_ERROR_IO) + { + ErrorF ("winInitMultiWindowXMsgProc - Caught IO Error. Exiting.\n"); + pthread_exit (NULL); + } + + /* Install our error handler */ + XSetErrorHandler (winMultiWindowXMsgProcErrorHandler); + XSetIOErrorHandler (winMultiWindowXMsgProcIOErrorHandler); + + /* Setup the display connection string x */ + snprintf (pszDisplay, + 512, "127.0.0.1:%s.%d", display, (int)pProcArg->dwScreen); + + /* Print the display connection string */ + ErrorF ("winMultiWindowXMsgProc - DISPLAY=%s\n", pszDisplay); + + /* Use our generated cookie for authentication */ + winSetAuthorization(); + + /* Initialize retry count */ + iRetries = 0; + + /* Open the X display */ + do + { + /* Try to open the display */ + pProcArg->pDisplay = XOpenDisplay (pszDisplay); + if (pProcArg->pDisplay == NULL) + { + ErrorF ("winMultiWindowXMsgProc - Could not open display, try: %d, " + "sleeping: %d\n", + iRetries + 1, WIN_CONNECT_DELAY); + ++iRetries; + sleep (WIN_CONNECT_DELAY); + continue; + } + else + break; + } + while (pProcArg->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); + + /* Make sure that the display opened */ + if (pProcArg->pDisplay == NULL) + { + ErrorF ("winMultiWindowXMsgProc - Failed opening the display. " + "Exiting.\n"); + pthread_exit (NULL); + } + + ErrorF ("winMultiWindowXMsgProc - XOpenDisplay () returned and " + "successfully opened the display.\n"); + + /* Check if another window manager is already running */ + g_fAnotherWMRunning = CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen, pProcArg->pWMInfo->fAllowOtherWM); + + if (g_fAnotherWMRunning && !pProcArg->pWMInfo->fAllowOtherWM) + { + ErrorF ("winMultiWindowXMsgProc - " + "another window manager is running. Exiting.\n"); + pthread_exit (NULL); + } + + /* Set up the supported icon sizes */ + xis = XAllocIconSize (); + if (xis) + { + xis->min_width = xis->min_height = 16; + xis->max_width = xis->max_height = 48; + xis->width_inc = xis->height_inc = 16; + XSetIconSizes (pProcArg->pDisplay, + RootWindow (pProcArg->pDisplay, pProcArg->dwScreen), + xis, + 1); + XFree (xis); + } + + atmWmName = XInternAtom (pProcArg->pDisplay, + "WM_NAME", + False); + atmWmHints = XInternAtom (pProcArg->pDisplay, + "WM_HINTS", + False); + atmWmChange = XInternAtom (pProcArg->pDisplay, + "WM_CHANGE_STATE", + False); + + /* + iiimxcf had a bug until 2009-04-27, assuming that the + WM_STATE atom exists, causing clients to fail with + a BadAtom X error if it doesn't. + + Since this is on in the default Solaris 10 install, + workaround this by making sure it does exist... + */ + XInternAtom(pProcArg->pDisplay, "WM_STATE", 0); + + /* Loop until we explicitly break out */ + while (1) + { + if (g_shutdown) + break; + + if (pProcArg->pWMInfo->fAllowOtherWM && !XPending (pProcArg->pDisplay)) + { + if (CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen, TRUE)) + { + if (!g_fAnotherWMRunning) + { + g_fAnotherWMRunning = TRUE; + SendMessage(*(HWND*)pProcArg->hwndScreen, WM_UNMANAGE, 0, 0); + } + } + else + { + if (g_fAnotherWMRunning) + { + g_fAnotherWMRunning = FALSE; + SendMessage(*(HWND*)pProcArg->hwndScreen, WM_MANAGE, 0, 0); + } + } + Sleep (500); + continue; + } + + /* Fetch next event */ + XNextEvent (pProcArg->pDisplay, &event); + + /* Branch on event type */ + if (event.type == CreateNotify) + { + XWindowAttributes attr; + + XSelectInput (pProcArg->pDisplay, + event.xcreatewindow.window, + PropertyChangeMask); + + /* Get the window attributes */ + XGetWindowAttributes (pProcArg->pDisplay, + event.xcreatewindow.window, + &attr); + + if (!attr.override_redirect) + XSetWindowBorderWidth(pProcArg->pDisplay, + event.xcreatewindow.window, + 0); + } + else if (event.type == MapNotify) + { + /* Fake a reparentNotify event as SWT/Motif expects a + Window Manager to reparent a top-level window when + it is mapped and waits until they do. + + We don't actually need to reparent, as the frame is + a native window, not an X window + + We do this on MapNotify, not MapRequest like a real + Window Manager would, so we don't have do get involved + in actually mapping the window via it's (non-existent) + parent... + + See sourceware bugzilla #9848 + */ + + XWindowAttributes attr; + Window root; + Window parent; + Window *children; + unsigned int nchildren; + + if (XGetWindowAttributes(event.xmap.display, + event.xmap.window, + &attr) && + XQueryTree(event.xmap.display, + event.xmap.window, + &root, &parent, &children, &nchildren)) + { + if (children) XFree(children); + + /* + It's a top-level window if the parent window is a root window + Only non-override_redirect windows can get reparented + */ + if ((attr.root == parent) && !event.xmap.override_redirect) + { + XEvent event_send; + + event_send.type = ReparentNotify; + event_send.xreparent.event = event.xmap.window; + event_send.xreparent.window = event.xmap.window; + event_send.xreparent.parent = parent; + event_send.xreparent.x = attr.x; + event_send.xreparent.y = attr.y; + + XSendEvent(event.xmap.display, + event.xmap.window, + True, StructureNotifyMask, + &event_send); + } + } + } + else if (event.type == ConfigureNotify) + { + if (!event.xconfigure.send_event) + { + /* + Java applications using AWT on JRE 1.6.0 break with non-reparenting WMs AWT + doesn't explicitly know about (See sun bug #6434227) + + XDecoratedPeer.handleConfigureNotifyEvent() only processes non-synthetic + ConfigureNotify events to update window location if it's identified the + WM as a non-reparenting WM it knows about (compiz or lookingglass) + + Rather than tell all sorts of lies to get XWM to recognize us as one of + those, simply send a synthetic ConfigureNotify for every non-synthetic one + */ + XEvent event_send = event; + event_send.xconfigure.send_event = TRUE; + event_send.xconfigure.event = event.xconfigure.window; + XSendEvent(event.xconfigure.display, + event.xconfigure.window, + True, StructureNotifyMask, + &event_send); + } + } + else if (event.type == PropertyNotify + && event.xproperty.atom == atmWmName) + { + memset (&msg, 0, sizeof (msg)); + + msg.msg = WM_WM_NAME_EVENT; + msg.iWindow = event.xproperty.window; + + /* Other fields ignored */ + winSendMessageToWM (pProcArg->pWMInfo, &msg); + } + else if (event.type == PropertyNotify + && event.xproperty.atom == atmWmHints) + { + memset (&msg, 0, sizeof (msg)); + + msg.msg = WM_WM_HINTS_EVENT; + msg.iWindow = event.xproperty.window; + + /* Other fields ignored */ + winSendMessageToWM (pProcArg->pWMInfo, &msg); + } + else if (event.type == ClientMessage + && event.xclient.message_type == atmWmChange + && event.xclient.data.l[0] == IconicState) + { + ErrorF ("winMultiWindowXMsgProc - WM_CHANGE_STATE - IconicState\n"); + + memset (&msg, 0, sizeof (msg)); + + msg.msg = WM_WM_CHANGE_STATE; + msg.iWindow = event.xclient.window; + + winSendMessageToWM (pProcArg->pWMInfo, &msg); + } + } + + XCloseDisplay (pProcArg->pDisplay); + pthread_exit (NULL); + return NULL; +} + + +/* + * winInitWM - Entry point for the X server to spawn + * the Window Manager thread. Called from + * winscrinit.c/winFinishScreenInitFB (). + */ + +Bool +winInitWM (void **ppWMInfo, + pthread_t *ptWMProc, + pthread_t *ptXMsgProc, + pthread_mutex_t *ppmServerStarted, + int dwScreen, + HWND hwndScreen, + BOOL allowOtherWM) +{ + WMProcArgPtr pArg = (WMProcArgPtr) malloc (sizeof(WMProcArgRec)); + WMInfoPtr pWMInfo = (WMInfoPtr) malloc (sizeof(WMInfoRec)); + XMsgProcArgPtr pXMsgArg = (XMsgProcArgPtr) malloc (sizeof(XMsgProcArgRec)); + + /* Bail if the input parameters are bad */ + if (pArg == NULL || pWMInfo == NULL) + { + ErrorF ("winInitWM - malloc failed.\n"); + return FALSE; + } + + /* Zero the allocated memory */ + ZeroMemory (pArg, sizeof (WMProcArgRec)); + ZeroMemory (pWMInfo, sizeof (WMInfoRec)); + ZeroMemory (pXMsgArg, sizeof (XMsgProcArgRec)); + + /* Set a return pointer to the Window Manager info structure */ + *ppWMInfo = pWMInfo; + pWMInfo->fAllowOtherWM = allowOtherWM; + + /* Setup the argument structure for the thread function */ + pArg->dwScreen = dwScreen; + pArg->pWMInfo = pWMInfo; + pArg->ppmServerStarted = ppmServerStarted; + + /* Intialize the message queue */ + if (!InitQueue (&pWMInfo->wmMsgQueue)) + { + ErrorF ("winInitWM - InitQueue () failed.\n"); + return FALSE; + } + + /* Spawn a thread for the Window Manager */ + if (pthread_create (ptWMProc, NULL, winMultiWindowWMProc, pArg)) + { + /* Bail if thread creation failed */ + ErrorF ("winInitWM - pthread_create failed for Window Manager.\n"); + return FALSE; + } + + /* Spawn the XNextEvent thread, will send messages to WM */ + pXMsgArg->dwScreen = dwScreen; + pXMsgArg->pWMInfo = pWMInfo; + pXMsgArg->ppmServerStarted = ppmServerStarted; + pXMsgArg->hwndScreen = hwndScreen; + if (pthread_create (ptXMsgProc, NULL, winMultiWindowXMsgProc, pXMsgArg)) + { + /* Bail if thread creation failed */ + ErrorF ("winInitWM - pthread_create failed on XMSG.\n"); + return FALSE; + } + +#if CYGDEBUG || YES + winDebug ("winInitWM - Returning.\n"); +#endif + + return TRUE; +} + + +/* + * Window manager thread - setup + */ + +static void +winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg) +{ + int iRetries = 0; + char pszDisplay[512]; + int iReturn; + + ErrorF ("winInitMultiWindowWM - Hello\n"); + + /* Check that argument pointer is not invalid */ + if (pProcArg == NULL) + { + ErrorF ("winInitMultiWindowWM - pProcArg is NULL. Exiting.\n"); + pthread_exit (NULL); + } + + ErrorF ("winInitMultiWindowWM - Calling pthread_mutex_lock ()\n"); + + /* Grab our garbage mutex to satisfy pthread_cond_wait */ + iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted); + if (iReturn != 0) + { + ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () failed: %d. " + "Exiting.\n", + iReturn); + pthread_exit (NULL); + } + + ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () returned.\n"); + + /* Allow multiple threads to access Xlib */ + if (XInitThreads () == 0) + { + ErrorF ("winInitMultiWindowWM - XInitThreads () failed. Exiting.\n"); + pthread_exit (NULL); + } + + /* See if X supports the current locale */ + if (XSupportsLocale () == False) + { + ErrorF ("winInitMultiWindowWM - Warning: Locale not supported by X.\n"); + } + + /* Release the server started mutex */ + pthread_mutex_unlock (pProcArg->ppmServerStarted); + + ErrorF ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n"); + + /* Set jump point for IO Error exits */ + iReturn = setjmp (g_jmpWMEntry); + + /* Check if we should continue operations */ + if (iReturn != WIN_JMP_ERROR_IO + && iReturn != WIN_JMP_OKAY) + { + /* setjmp returned an unknown value, exit */ + ErrorF ("winInitMultiWindowWM - setjmp returned: %d. Exiting.\n", + iReturn); + pthread_exit (NULL); + } + else if (iReturn == WIN_JMP_ERROR_IO) + { + ErrorF ("winInitMultiWindowWM - Caught IO Error. Exiting.\n"); + pthread_exit (NULL); + } + + /* Install our error handler */ + XSetErrorHandler (winMultiWindowWMErrorHandler); + XSetIOErrorHandler (winMultiWindowWMIOErrorHandler); + + /* Setup the display connection string x */ + snprintf (pszDisplay, + 512, + "127.0.0.1:%s.%d", + display, + (int) pProcArg->dwScreen); + + /* Print the display connection string */ + ErrorF ("winInitMultiWindowWM - DISPLAY=%s\n", pszDisplay); + + /* Use our generated cookie for authentication */ + winSetAuthorization(); + + /* Open the X display */ + do + { + /* Try to open the display */ + pWMInfo->pDisplay = XOpenDisplay (pszDisplay); + if (pWMInfo->pDisplay == NULL) + { + ErrorF ("winInitMultiWindowWM - Could not open display, try: %d, " + "sleeping: %d\n", + iRetries + 1, WIN_CONNECT_DELAY); + ++iRetries; + sleep (WIN_CONNECT_DELAY); + continue; + } + else + break; + } + while (pWMInfo->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); + + /* Make sure that the display opened */ + if (pWMInfo->pDisplay == NULL) + { + ErrorF ("winInitMultiWindowWM - Failed opening the display. " + "Exiting.\n"); + pthread_exit (NULL); + } + + ErrorF ("winInitMultiWindowWM - XOpenDisplay () returned and " + "successfully opened the display.\n"); + + + /* Create some atoms */ + pWMInfo->atmWmProtos = XInternAtom (pWMInfo->pDisplay, + "WM_PROTOCOLS", + False); + pWMInfo->atmWmDelete = XInternAtom (pWMInfo->pDisplay, + "WM_DELETE_WINDOW", + False); + + pWMInfo->atmPrivMap = XInternAtom (pWMInfo->pDisplay, + WINDOWSWM_NATIVE_HWND, + False); + + + if (1) { + Cursor cursor = XCreateFontCursor (pWMInfo->pDisplay, XC_left_ptr); + if (cursor) + { + XDefineCursor (pWMInfo->pDisplay, DefaultRootWindow(pWMInfo->pDisplay), cursor); + XFreeCursor (pWMInfo->pDisplay, cursor); + } + } +} + + +/* + * winSendMessageToWM - Send a message from the X thread to the WM thread + */ + +void +winSendMessageToWM (void *pWMInfo, winWMMessagePtr pMsg) +{ + WMMsgNodePtr pNode; + +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winSendMessageToWM ()\n"); +#endif + + pNode = (WMMsgNodePtr)malloc(sizeof(WMMsgNodeRec)); + if (pNode != NULL) + { + memcpy (&pNode->msg, pMsg, sizeof(winWMMessageRec)); + PushMessage (&((WMInfoPtr)pWMInfo)->wmMsgQueue, pNode); + } +} + + +/* + * Window manager error handler + */ + +static int +winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + char pszErrorMsg[100]; + + if (pErr->request_code == X_ChangeWindowAttributes + && pErr->error_code == BadAccess) + { + ErrorF ("winMultiWindowWMErrorHandler - ChangeWindowAttributes " + "BadAccess.\n"); + return 0; + } + + XGetErrorText (pDisplay, + pErr->error_code, + pszErrorMsg, + sizeof (pszErrorMsg)); + ErrorF ("winMultiWindowWMErrorHandler - ERROR: %s\n", pszErrorMsg); + + return 0; +} + + +/* + * Window manager IO error handler + */ + +static int +winMultiWindowWMIOErrorHandler (Display *pDisplay) +{ + ErrorF ("winMultiWindowWMIOErrorHandler!\n\n"); + + if (g_shutdown) + pthread_exit(NULL); + + /* Restart at the main entry point */ + longjmp (g_jmpWMEntry, WIN_JMP_ERROR_IO); + + return 0; +} + + +/* + * X message procedure error handler + */ + +static int +winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + char pszErrorMsg[100]; + + XGetErrorText (pDisplay, + pErr->error_code, + pszErrorMsg, + sizeof (pszErrorMsg)); +#if CYGMULTIWINDOW_DEBUG + ErrorF ("winMultiWindowXMsgProcErrorHandler - ERROR: %s\n", pszErrorMsg); +#endif + + return 0; +} + + +/* + * X message procedure IO error handler + */ + +static int +winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay) +{ + ErrorF ("winMultiWindowXMsgProcIOErrorHandler!\n\n"); + + /* Restart at the main entry point */ + longjmp (g_jmpXMsgProcEntry, WIN_JMP_ERROR_IO); + + return 0; +} + + +/* + * Catch RedirectError to detect other window manager running + */ + +static int +winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr) +{ + redirectError = TRUE; + return 0; +} + + +/* + * Check if another window manager is running + */ + +static Bool +CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen, Bool fAllowOtherWM) +{ + /* + Try to select the events which only one client at a time is allowed to select. + If this causes an error, another window manager is already running... + */ + redirectError = FALSE; + XSetErrorHandler (winRedirectErrorHandler); + XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen), + ResizeRedirectMask | SubstructureRedirectMask | ButtonPressMask); + XSync (pDisplay, 0); + XSetErrorHandler (winMultiWindowXMsgProcErrorHandler); + + /* + Side effect: select the events we are actually interested in... + + If other WMs are not allowed, also select one of the events which only one client + at a time is allowed to select, so other window managers won't start... + */ + XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen), + SubstructureNotifyMask | ( !fAllowOtherWM ? ButtonPressMask : 0)); + XSync (pDisplay, 0); + return redirectError; +} + +/* + * Notify the MWM thread we're exiting and not to reconnect + */ + +void +winDeinitMultiWindowWM (void) +{ + ErrorF ("winDeinitMultiWindowWM - Noting shutdown in progress\n"); + g_shutdown = TRUE; +} + +/* Windows window styles */ +#define HINT_NOFRAME (1l<<0) +#define HINT_BORDER (1L<<1) +#define HINT_SIZEBOX (1l<<2) +#define HINT_CAPTION (1l<<3) +#define HINT_NOMAXIMIZE (1L<<4) +/* These two are used on their own */ +#define HINT_MAX (1L<<0) +#define HINT_MIN (1L<<1) + +static void +winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle) +{ + static Atom windowState, motif_wm_hints, windowType; + static Atom hiddenState, fullscreenState, belowState, aboveState; + static Atom dockWindow; + static int generation; + Atom type, *pAtom = NULL; + int format; + unsigned long hint = 0, maxmin = 0, style, nitems = 0 , left = 0; + MwmHints *mwm_hint = NULL; + + if (!hWnd) return; + if (!IsWindow (hWnd)) return; + + if (generation != serverGeneration) { + generation = serverGeneration; + windowState = XInternAtom(pDisplay, "_NET_WM_STATE", False); + motif_wm_hints = XInternAtom(pDisplay, "_MOTIF_WM_HINTS", False); + windowType = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE", False); + hiddenState = XInternAtom(pDisplay, "_NET_WM_STATE_HIDDEN", False); + fullscreenState = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", False); + belowState = XInternAtom(pDisplay, "_NET_WM_STATE_BELOW", False); + aboveState = XInternAtom(pDisplay, "_NET_WM_STATE_ABOVE", False); + dockWindow = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False); + } + + if (XGetWindowProperty(pDisplay, iWindow, windowState, 0L, + 1L, False, XA_ATOM, &type, &format, + &nitems, &left, (unsigned char **)&pAtom) == Success) + { + if (pAtom && nitems == 1) + { + if (*pAtom == hiddenState) maxmin |= HINT_MIN; + else if (*pAtom == fullscreenState) maxmin |= HINT_MAX; + if (*pAtom == belowState) *zstyle = HWND_BOTTOM; + else if (*pAtom == aboveState) *zstyle = HWND_TOPMOST; + } + if (pAtom) XFree(pAtom); + } + + nitems = left = 0; + if (XGetWindowProperty(pDisplay, iWindow, motif_wm_hints, 0L, + PropMwmHintsElements, False, motif_wm_hints, &type, &format, + &nitems, &left, (unsigned char **)&mwm_hint) == Success) + { + if (mwm_hint && nitems == PropMwmHintsElements && (mwm_hint->flags & MwmHintsDecorations)) + { + if (!mwm_hint->decorations) hint |= HINT_NOFRAME; + else if (!(mwm_hint->decorations & MwmDecorAll)) + { + if (mwm_hint->decorations & MwmDecorBorder) hint |= HINT_BORDER; + if (mwm_hint->decorations & MwmDecorHandle) hint |= HINT_SIZEBOX; + if (mwm_hint->decorations & MwmDecorTitle) hint |= HINT_CAPTION; + } + } + if (mwm_hint) XFree(mwm_hint); + } + + nitems = left = 0; + pAtom = NULL; + if (XGetWindowProperty(pDisplay, iWindow, windowType, 0L, + 1L, False, XA_ATOM, &type, &format, + &nitems, &left, (unsigned char **)&pAtom) == Success) + { + if (pAtom && nitems == 1) + { + if (*pAtom == dockWindow) + { + hint = (hint & ~HINT_NOFRAME) | HINT_SIZEBOX; /* Xming puts a sizebox on dock windows */ + *zstyle = HWND_TOPMOST; + } + } + if (pAtom) XFree(pAtom); + } + + { + XSizeHints *normal_hint = XAllocSizeHints(); + long supplied; + if (normal_hint && (XGetWMNormalHints(pDisplay, iWindow, normal_hint, &supplied) == Success)) + { + if (normal_hint->flags & PMaxSize) + { + /* Not maximizable if a maximum size is specified */ + hint |= HINT_NOMAXIMIZE; + + if (normal_hint->flags & PMinSize) + { + /* + If both minimum size and maximum size are specified and are the same, + don't bother with a resizing frame + */ + if ((normal_hint->min_width == normal_hint->max_width) + && (normal_hint->min_height == normal_hint->max_height)) + hint = (hint & ~HINT_SIZEBOX); + } + } + } + XFree(normal_hint); + } + + /* Override hint settings from above with settings from config file */ + { + XClassHint class_hint = {0,0}; + char *window_name = 0; + + if (XGetClassHint(pDisplay, iWindow, &class_hint)) + { + XFetchName(pDisplay, iWindow, &window_name); + + style = winOverrideStyle(class_hint.res_name, class_hint.res_class, window_name); + + if (class_hint.res_name) XFree(class_hint.res_name); + if (class_hint.res_class) XFree(class_hint.res_class); + if (window_name) XFree(window_name); + } + else + { + style = STYLE_NONE; + } + } + + if (style & STYLE_TOPMOST) *zstyle = HWND_TOPMOST; + else if (style & STYLE_MAXIMIZE) maxmin = (hint & ~HINT_MIN) | HINT_MAX; + else if (style & STYLE_MINIMIZE) maxmin = (hint & ~HINT_MAX) | HINT_MIN; + else if (style & STYLE_BOTTOM) *zstyle = HWND_BOTTOM; + + if (maxmin & HINT_MAX) SendMessage(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0); + else if (maxmin & HINT_MIN) SendMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); + + if (style & STYLE_NOTITLE) + hint = (hint & ~HINT_NOFRAME & ~HINT_BORDER & ~HINT_CAPTION) | HINT_SIZEBOX; + else if (style & STYLE_OUTLINE) + hint = (hint & ~HINT_NOFRAME & ~HINT_SIZEBOX & ~HINT_CAPTION) | HINT_BORDER; + else if (style & STYLE_NOFRAME) + hint = (hint & ~HINT_BORDER & ~HINT_CAPTION & ~HINT_SIZEBOX) | HINT_NOFRAME; + + /* Now apply styles to window */ + style = GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION & ~WS_SIZEBOX; /* Just in case */ + if (!style) return; + + if (!hint) /* All on */ + style = style | WS_CAPTION | WS_SIZEBOX; + else if (hint & HINT_NOFRAME) /* All off */ + style = style & ~WS_CAPTION & ~WS_SIZEBOX; + else style = style | ((hint & HINT_BORDER) ? WS_BORDER : 0) | + ((hint & HINT_SIZEBOX) ? WS_SIZEBOX : 0) | + ((hint & HINT_CAPTION) ? WS_CAPTION : 0); + + if (hint & HINT_NOMAXIMIZE) + style = style & ~WS_MAXIMIZEBOX; + + SetWindowLongPtr (hWnd, GWL_STYLE, style); +} + +void +winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle) +{ + int iX, iY, iWidth, iHeight; + int iDx, iDy; + RECT rcNew; + WindowPtr pWin = GetProp (hWnd, WIN_WINDOW_PROP); + DrawablePtr pDraw = NULL; + + if (!pWin) return; + pDraw = &pWin->drawable; + if (!pDraw) return; + + /* Get the X and Y location of the X window */ + iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Get the height and width of the X window */ + iWidth = pWin->drawable.width; + iHeight = pWin->drawable.height; + + /* Setup a rectangle with the X window position and size */ + SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); + +#if 0 + ErrorF ("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n", + rcNew.left, rcNew.top, + rcNew.right, rcNew.bottom); +#endif + + AdjustWindowRectEx (&rcNew, GetWindowLongPtr (hWnd, GWL_STYLE), FALSE, WS_EX_APPWINDOW); + + /* Don't allow window decoration to disappear off to top-left as a result of this adjustment */ + if (rcNew.left < GetSystemMetrics(SM_XVIRTUALSCREEN)) + { + iDx = GetSystemMetrics(SM_XVIRTUALSCREEN) - rcNew.left; + rcNew.left += iDx; + rcNew.right += iDx; + } + + if (rcNew.top < GetSystemMetrics(SM_YVIRTUALSCREEN)) + { + iDy = GetSystemMetrics(SM_YVIRTUALSCREEN) - rcNew.top; + rcNew.top += iDy; + rcNew.bottom += iDy; + } + +#if 0 + ErrorF ("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n", + rcNew.left, rcNew.top, + rcNew.right, rcNew.bottom); +#endif + + /* Position the Windows window */ + SetWindowPos (hWnd, *zstyle, rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + 0); + + if (reshape) + { + winReshapeMultiWindow(pWin); + winUpdateRgnMultiWindow(pWin); + } +} diff --git a/xorg-server/hw/xwin/winpfbdd.c b/xorg-server/hw/xwin/winpfbdd.c index c0bca71e3..a3990208d 100644 --- a/xorg-server/hw/xwin/winpfbdd.c +++ b/xorg-server/hw/xwin/winpfbdd.c @@ -294,7 +294,8 @@ winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen) /* Call the wrapped CloseScreen procedure */ WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + if (pScreen->CloseScreen) + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); /* Delete the window property */ RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); diff --git a/xorg-server/hw/xwin/winprefs.c b/xorg-server/hw/xwin/winprefs.c index 073c9ec62..d941c5169 100644 --- a/xorg-server/hw/xwin/winprefs.c +++ b/xorg-server/hw/xwin/winprefs.c @@ -1,852 +1,832 @@ -/*
- * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- * Copyright (C) Colin Harrison 2005-2008
- *
- * 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 XFREE86 PROJECT 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 of the XFree86 Project
- * shall not be used in advertising or otherwise to promote the sale, use
- * or other dealings in this Software without prior written authorization
- * from the XFree86 Project.
- *
- * Authors: Earle F. Philhower, III
- * Colin Harrison
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef __CYGWIN__
-#include <sys/resource.h>
-#endif
-#include "win.h"
-
-#include <X11/Xwindows.h>
-#include <shellapi.h>
-
-#include "winprefs.h"
-#include "winmultiwindowclass.h"
-
-/* Where will the custom menu commands start counting from? */
-#define STARTMENUID WM_USER
-
-extern const char *winGetBaseDir(void);
-
-/* From winmultiwindowflex.l, the real parser */
-extern void parse_file (FILE *fp);
-
-
-/* Currently in use command ID, incremented each new menu item created */
-static int g_cmdid = STARTMENUID;
-
-
-/* Defined in DIX */
-extern char *display;
-
-/* Local function to handle comma-ified icon names */
-static HICON
-LoadImageComma (char *fname, int sx, int sy, int flags);
-
-
-/*
- * Creates or appends a menu from a MENUPARSED structure
- */
-static HMENU
-MakeMenu (char *name,
- HMENU editMenu,
- int editItem)
-{
- int i;
- int item;
- MENUPARSED *m;
- HMENU hmenu, hsub;
-
- for (i=0; i<pref.menuItems; i++)
- {
- if (!strcmp(name, pref.menu[i].menuName))
- break;
- }
-
- /* Didn't find a match, bummer */
- if (i==pref.menuItems)
- {
- ErrorF("MakeMenu: Can't find menu %s\n", name);
- return NULL;
- }
-
- m = &(pref.menu[i]);
-
- if (editMenu)
- {
- hmenu = editMenu;
- item = editItem;
- }
- else
- {
- hmenu = CreatePopupMenu();
- if (!hmenu)
- {
- ErrorF("MakeMenu: Unable to CreatePopupMenu() %s\n", name);
- return NULL;
- }
- item = 0;
- }
-
- /* Add the menu items */
- for (i=0; i<m->menuItems; i++)
- {
- /* Only assign IDs one time... */
- if ( m->menuItem[i].commandID == 0 )
- m->menuItem[i].commandID = g_cmdid++;
-
- switch (m->menuItem[i].cmd)
- {
- case CMD_EXEC:
- case CMD_ALWAYSONTOP:
- case CMD_RELOAD:
- InsertMenu (hmenu,
- item,
- MF_BYPOSITION|MF_ENABLED|MF_STRING,
- m->menuItem[i].commandID,
- m->menuItem[i].text);
- break;
-
- case CMD_SEPARATOR:
- InsertMenu (hmenu,
- item,
- MF_BYPOSITION|MF_SEPARATOR,
- 0,
- NULL);
- break;
-
- case CMD_MENU:
- /* Recursive! */
- hsub = MakeMenu (m->menuItem[i].param, 0, 0);
- if (hsub)
- InsertMenu (hmenu,
- item,
- MF_BYPOSITION|MF_POPUP|MF_ENABLED|MF_STRING,
- (UINT_PTR)hsub,
- m->menuItem[i].text);
- break;
- }
-
- /* If item==-1 (means to add at end of menu) don't increment) */
- if (item>=0)
- item++;
- }
-
- return hmenu;
-}
-
-
-#ifdef XWIN_MULTIWINDOW
-/*
- * Callback routine that is executed once per window class.
- * Removes or creates custom window settings depending on LPARAM
- */
-static wBOOL CALLBACK
-ReloadEnumWindowsProc (HWND hwnd, LPARAM lParam)
-{
- HICON hicon;
- Window wid;
-
- if (!hwnd) {
- ErrorF("ReloadEnumWindowsProc: hwnd==NULL!\n");
- return FALSE;
- }
-
- /* It's our baby, either clean or dirty it */
- if (lParam==FALSE)
- {
- /* Reset the window's icon to undefined. */
- hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_BIG, 0);
-
- /* If the old icon is generated on-the-fly, get rid of it, will regen */
- winDestroyIcon (hicon);
-
- /* Same for the small icon */
- hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_SMALL, 0);
- winDestroyIcon (hicon);
-
- /* Remove any menu additions; bRevert=TRUE destroys any modified menus */
- GetSystemMenu (hwnd, TRUE);
-
- /* This window is now clean of our taint (but with undefined icons) */
- }
- else
- {
- /* winUpdateIcon() will set the icon default, dynamic, or from xwinrc */
- wid = (Window)GetProp (hwnd, WIN_WID_PROP);
- if (wid)
- winUpdateIcon (wid);
-
- /* Update the system menu for this window */
- SetupSysMenu ((unsigned long)hwnd);
-
- /* That was easy... */
- }
-
- return TRUE;
-}
-#endif
-
-
-/*
- * Removes any custom icons in classes, custom menus, etc.
- * Frees all members in pref structure.
- * Reloads the preferences file.
- * Set custom icons and menus again.
- */
-static void
-ReloadPrefs (void)
-{
- int i;
-
-#ifdef XWIN_MULTIWINDOW
- /* First, iterate over all windows, deleting their icons and custom menus.
- * This is really only needed because winDestroyIcon() will try to
- * destroy the old global icons, which will have changed.
- * It is probably better to set a windows USER_DATA to flag locally defined
- * icons, and use that to accurately know when to destroy old icons.
- */
- EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, FALSE);
-#endif
-
- /* Now, free/clear all info from our prefs structure */
- for (i=0; i<pref.menuItems; i++)
- free (pref.menu[i].menuItem);
- free (pref.menu);
- pref.menu = NULL;
- pref.menuItems = 0;
-
- pref.rootMenuName[0] = 0;
-
- free (pref.sysMenu);
- pref.sysMenuItems = 0;
-
- pref.defaultSysMenuName[0] = 0;
- pref.defaultSysMenuPos = 0;
-
- pref.iconDirectory[0] = 0;
- pref.defaultIconName[0] = 0;
- pref.trayIconName[0] = 0;
-
- for (i=0; i<pref.iconItems; i++)
- if (pref.icon[i].hicon)
- DestroyIcon ((HICON)pref.icon[i].hicon);
- free (pref.icon);
- pref.icon = NULL;
- pref.iconItems = 0;
-
- /* Free global default X icon */
- if (g_hIconX)
- DestroyIcon (g_hIconX);
- if (g_hSmallIconX)
- DestroyIcon (g_hSmallIconX);
-
- /* Reset the custom command IDs */
- g_cmdid = STARTMENUID;
-
- /* Load the updated resource file */
- LoadPreferences();
-
- g_hIconX = NULL;
- g_hSmallIconX = NULL;
-
-#ifdef XWIN_MULTIWINDOW
- winInitGlobalIcons();
-#endif
-
-#ifdef XWIN_MULTIWINDOW
- /* Rebuild the icons and menus */
- EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, TRUE);
-#endif
-
- /* Whew, done */
-}
-
-/*
- * Check/uncheck the ALWAYSONTOP items in this menu
- */
-void
-HandleCustomWM_INITMENU(unsigned long hwndIn,
- unsigned long hmenuIn)
-{
- HWND hwnd;
- HMENU hmenu;
- DWORD dwExStyle;
- int i, j;
-
- hwnd = (HWND)hwndIn;
- hmenu = (HMENU)hmenuIn;
- if (!hwnd || !hmenu)
- return;
-
- if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)
- dwExStyle = MF_BYCOMMAND | MF_CHECKED;
- else
- dwExStyle = MF_BYCOMMAND | MF_UNCHECKED;
-
- for (i=0; i<pref.menuItems; i++)
- for (j=0; j<pref.menu[i].menuItems; j++)
- if (pref.menu[i].menuItem[j].cmd==CMD_ALWAYSONTOP)
- CheckMenuItem (hmenu, pref.menu[i].menuItem[j].commandID, dwExStyle );
-
-}
-
-/*
- * Searches for the custom WM_COMMAND command ID and performs action.
- * Return TRUE if command is proccessed, FALSE otherwise.
- */
-Bool
-HandleCustomWM_COMMAND (unsigned long hwndIn,
- int command)
-{
- HWND hwnd;
- int i, j;
- MENUPARSED *m;
- DWORD dwExStyle;
-
- hwnd = (HWND)hwndIn;
-
- if (!command)
- return FALSE;
-
- for (i=0; i<pref.menuItems; i++)
- {
- m = &(pref.menu[i]);
- for (j=0; j<m->menuItems; j++)
- {
- if (command==m->menuItem[j].commandID)
- {
- /* Match! */
- switch(m->menuItem[j].cmd)
- {
-#ifdef __CYGWIN__
- case CMD_EXEC:
- if (fork()==0)
- {
- struct rlimit rl;
- unsigned long i;
-
- /* Close any open descriptors except for STD* */
- getrlimit (RLIMIT_NOFILE, &rl);
- for (i = STDERR_FILENO+1; i < rl.rlim_cur; i++)
- close(i);
-
- /* Disassociate any TTYs */
- setsid();
-
- execl ("/bin/sh",
- "/bin/sh",
- "-c",
- m->menuItem[j].param,
- NULL);
- exit (0);
- }
- else
- return TRUE;
- break;
-#else
- case CMD_EXEC:
- {
- /* Start process without console window */
- STARTUPINFO start;
- PROCESS_INFORMATION child;
-
- memset (&start, 0, sizeof (start));
- start.cb = sizeof (start);
- start.dwFlags = STARTF_USESHOWWINDOW;
- start.wShowWindow = SW_HIDE;
-
- memset (&child, 0, sizeof (child));
-
- if (CreateProcess (NULL, m->menuItem[j].param, NULL, NULL, FALSE, 0,
- NULL, NULL, &start, &child))
- {
- CloseHandle (child.hThread);
- CloseHandle (child.hProcess);
- }
- else
- MessageBox(NULL, m->menuItem[j].param, "Mingrc Exec Command Error!", MB_OK | MB_ICONEXCLAMATION);
- }
- return TRUE;
-#endif
- case CMD_ALWAYSONTOP:
- if (!hwnd)
- return FALSE;
-
- /* Get extended window style */
- dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
-
- /* Handle topmost windows */
- if (dwExStyle & WS_EX_TOPMOST)
- SetWindowPos (hwnd,
- HWND_NOTOPMOST,
- 0, 0,
- 0, 0,
- SWP_NOSIZE | SWP_NOMOVE);
- else
- SetWindowPos (hwnd,
- HWND_TOPMOST,
- 0, 0,
- 0, 0,
- SWP_NOSIZE | SWP_NOMOVE);
-#if XWIN_MULTIWINDOW
- /* Reflect the changed Z order */
- winReorderWindowsMultiWindow ();
-#endif
- return TRUE;
-
- case CMD_RELOAD:
- ReloadPrefs();
- return TRUE;
-
- default:
- return FALSE;
- }
- } /* match */
- } /* for j */
- } /* for i */
-
- return FALSE;
-}
-
-
-#ifdef XWIN_MULTIWINDOW
-/*
- * Add the default or a custom menu depending on the class match
- */
-void
-SetupSysMenu (unsigned long hwndIn)
-{
- HWND hwnd;
- HMENU sys;
- int i;
- WindowPtr pWin;
- char *res_name, *res_class;
-
- hwnd = (HWND)hwndIn;
- if (!hwnd)
- return;
-
- pWin = GetProp (hwnd, WIN_WINDOW_PROP);
-
- sys = GetSystemMenu (hwnd, FALSE);
- if (!sys)
- return;
-
- if (pWin)
- {
- /* First see if there's a class match... */
- if (winMultiWindowGetClassHint (pWin, &res_name, &res_class))
- {
- for (i=0; i<pref.sysMenuItems; i++)
- {
- if (!strcmp(pref.sysMenu[i].match, res_name) ||
- !strcmp(pref.sysMenu[i].match, res_class) )
- {
- free(res_name);
- free(res_class);
-
- MakeMenu (pref.sysMenu[i].menuName, sys,
- pref.sysMenu[i].menuPos==AT_START?0:-1);
- return;
- }
- }
-
- /* No match, just free alloc'd strings */
- free(res_name);
- free(res_class);
- } /* Found wm_class */
- } /* if pwin */
-
- /* Fallback to system default */
- if (pref.defaultSysMenuName[0])
- {
- if (pref.defaultSysMenuPos==AT_START)
- MakeMenu (pref.defaultSysMenuName, sys, 0);
- else
- MakeMenu (pref.defaultSysMenuName, sys, -1);
- }
-}
-#endif
-
-
-/*
- * Possibly add a menu to the toolbar icon
- */
-void
-SetupRootMenu (unsigned long hmenuRoot)
-{
- HMENU root;
-
- root = (HMENU)hmenuRoot;
- if (!root)
- return;
-
- if (pref.rootMenuName[0])
- {
- MakeMenu(pref.rootMenuName, root, 0);
- }
-}
-
-
-/*
- * Check for and return an overridden default ICON specified in the prefs
- */
-HICON
-winOverrideDefaultIcon(int size)
-{
- HICON hicon;
-
- if (pref.defaultIconName[0])
- {
- hicon = LoadImageComma (pref.defaultIconName, size, size, 0);
- if (hicon==NULL)
- ErrorF ("winOverrideDefaultIcon: LoadImageComma(%s) failed\n",
- pref.defaultIconName);
-
- return hicon;
- }
-
- return 0;
-}
-
-
-/*
- * Return the HICON to use in the taskbar notification area
- */
-HICON
-winTaskbarIcon(void)
-{
- HICON hicon;
-
- hicon = 0;
- /* First try and load an overridden, if success then return it */
- if (pref.trayIconName[0])
- {
- hicon = LoadImageComma (pref.trayIconName,
- GetSystemMetrics (SM_CXSMICON),
- GetSystemMetrics (SM_CYSMICON),
- 0 );
- }
-
- /* Otherwise return the default */
- if (!hicon)
- hicon = (HICON) LoadImage (g_hInstance,
- MAKEINTRESOURCE(IDI_XWIN),
- IMAGE_ICON,
- GetSystemMetrics (SM_CXSMICON),
- GetSystemMetrics (SM_CYSMICON),
- 0);
-
- return hicon;
-}
-
-
-/*
- * Parse a filename to extract an icon:
- * If fname is exactly ",nnn" then extract icon from our resource
- * else if it is "file,nnn" then extract icon nnn from that file
- * else try to load it as an .ico file and if that fails return NULL
- */
-static HICON
-LoadImageComma (char *fname, int sx, int sy, int flags)
-{
- HICON hicon;
- int index;
- char file[PATH_MAX+NAME_MAX+2];
-
- /* Some input error checking */
- if (!fname || !fname[0])
- return NULL;
-
- index = 0;
- hicon = NULL;
-
- if (fname[0]==',')
- {
- /* It's the XWIN.EXE resource they want */
- index = atoi (fname+1);
- hicon = LoadImage (g_hInstance,
- MAKEINTRESOURCE(index),
- IMAGE_ICON,
- sx,
- sy,
- flags);
- }
- else
- {
- file[0] = 0;
- /* Prepend path if not given a "X:\" filename */
- if ( !(fname[0] && fname[1]==':' && fname[2]=='\\') )
- {
- strcpy (file, pref.iconDirectory);
- if (pref.iconDirectory[0])
- if (fname[strlen(fname)-1]!='\\')
- strcat (file, "\\");
- }
- strcat (file, fname);
-
- if (strrchr (file, ','))
- {
- /* Specified as <fname>,<index> */
-
- *(strrchr (file, ',')) = 0; /* End string at comma */
- index = atoi (strrchr (fname, ',') + 1);
- hicon = ExtractIcon (g_hInstance, file, index);
- }
- else
- {
- /* Just an .ico file... */
-
- hicon = (HICON)LoadImage (NULL,
- file,
- IMAGE_ICON,
- sx,
- sy,
- LR_LOADFROMFILE|flags);
- }
- }
- return hicon;
-}
-
-/*
- * Check for a match of the window class to one specified in the
- * ICONS{} section in the prefs file, and load the icon from a file
- */
-HICON
-winOverrideIcon (unsigned long longWin)
-{
- WindowPtr pWin = (WindowPtr) longWin;
- char *res_name, *res_class;
- int i;
- HICON hicon;
- char *wmName;
-
- if (pWin==NULL)
- return 0;
-
- /* If we can't find the class, we can't override from default! */
- if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class))
- return 0;
-
- winMultiWindowGetWMName (pWin, &wmName);
-
- for (i=0; i<pref.iconItems; i++) {
- if (!strcmp(pref.icon[i].match, res_name) ||
- !strcmp(pref.icon[i].match, res_class) ||
- (wmName && strstr(wmName, pref.icon[i].match)))
- {
- free (res_name);
- free (res_class);
- free(wmName);
-
- if (pref.icon[i].hicon)
- return pref.icon[i].hicon;
-
- hicon = LoadImageComma (pref.icon[i].iconFile, 0, 0, LR_DEFAULTSIZE);
- if (hicon==NULL)
- ErrorF ("winOverrideIcon: LoadImageComma(%s) failed\n",
- pref.icon[i].iconFile);
-
- pref.icon[i].hicon = hicon;
- return hicon;
- }
- }
-
- /* Didn't find the icon, fail gracefully */
- free (res_name);
- free (res_class);
- free(wmName);
-
- return 0;
-}
-
-
-/*
- * Should we free this icon or leave it in memory (is it part of our
- * ICONS{} overrides)?
- */
-int
-winIconIsOverride(unsigned hiconIn)
-{
- HICON hicon;
- int i;
-
- hicon = (HICON)hiconIn;
-
- if (!hicon)
- return 0;
-
- for (i=0; i<pref.iconItems; i++)
- if ((HICON)pref.icon[i].hicon == hicon)
- return 1;
-
- return 0;
-}
-
-
-
-/*
- * Try and open ~/.XWinrc and system.XWinrc
- * Load it into prefs structure for use by other functions
- */
-void
-LoadPreferences (void)
-{
- char *home;
- char fname[PATH_MAX+NAME_MAX+2];
- FILE *prefFile;
- char szDisplay[512];
- char *szEnvDisplay;
- int i, j;
- char param[PARAM_MAX+1];
- char *srcParam, *dstParam;
-
- /* First, clear all preference settings */
- memset (&pref, 0, sizeof(pref));
- prefFile = NULL;
-
- /* Now try and find a ~/.xwinrc file */
- home = getenv ("HOME");
- if (home)
- {
- strcpy (fname, home);
- if (fname[strlen(fname)-1]!='/')
- strcat (fname, "/");
- strcat (fname, ".XWinrc");
-
- prefFile = fopen (fname, "r");
- if (prefFile)
- ErrorF ("winPrefsLoadPreferences: %s\n", fname);
- }
-
- /* No home file found, check system default */
- if (!prefFile)
- {
- char buffer[MAX_PATH];
-#ifdef RELOCATE_PROJECTROOT
- snprintf(buffer, sizeof(buffer), "%s\\system.XWinrc", winGetBaseDir());
-#else
- strncpy(buffer, SYSCONFDIR"/X11/system.XWinrc", sizeof(buffer));
-#endif
- buffer[sizeof(buffer)-1] = 0;
- prefFile = fopen (buffer, "r");
- if (prefFile)
- ErrorF ("winPrefsLoadPreferences: %s\n", buffer);
- }
-
- /* If we could open it, then read the settings and close it */
- if (prefFile)
- {
- parse_file (prefFile);
- fclose (prefFile);
- }
-
- /* Setup a DISPLAY environment variable, need to allocate on heap */
- /* because putenv doesn't copy the argument... */
- snprintf (szDisplay, 512, "DISPLAY=127.0.0.1:%s.0", display);
- szEnvDisplay = (char *)(malloc (strlen(szDisplay)+1));
- if (szEnvDisplay)
- {
- strcpy (szEnvDisplay, szDisplay);
- putenv (szEnvDisplay);
- }
-
- /* Replace any "%display%" in menu commands with display string */
- snprintf (szDisplay, 512, "127.0.0.1:%s.0", display);
- for (i=0; i<pref.menuItems; i++)
- {
- for (j=0; j<pref.menu[i].menuItems; j++)
- {
- if (pref.menu[i].menuItem[j].cmd==CMD_EXEC)
- {
- srcParam = pref.menu[i].menuItem[j].param;
- dstParam = param;
- while (*srcParam) {
- if (!strncmp(srcParam, "%display%", 9))
- {
- memcpy (dstParam, szDisplay, strlen(szDisplay));
- dstParam += strlen(szDisplay);
- srcParam += 9;
- }
- else
- {
- *dstParam = *srcParam;
- dstParam++;
- srcParam++;
- }
- }
- *dstParam = 0;
- strcpy (pref.menu[i].menuItem[j].param, param);
- } /* cmd==cmd_exec */
- } /* for all menuitems */
- } /* for all menus */
-
-}
-
-
-/*
- * Check for a match of the window class to one specified in the
- * STYLES{} section in the prefs file, and return the style type
- */
-unsigned long
-winOverrideStyle (unsigned long longpWin)
-{
- WindowPtr pWin = (WindowPtr) longpWin;
- char *res_name, *res_class;
- int i;
- char *wmName;
-
- if (pWin==NULL)
- return STYLE_NONE;
-
- /* If we can't find the class, we can't override from default! */
- if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class))
- return STYLE_NONE;
-
- winMultiWindowGetWMName (pWin, &wmName);
-
- for (i=0; i<pref.styleItems; i++) {
- if (!strcmp(pref.style[i].match, res_name) ||
- !strcmp(pref.style[i].match, res_class) ||
- (wmName && strstr(wmName, pref.style[i].match)))
- {
- free (res_name);
- free (res_class);
- free(wmName);
-
- if (pref.style[i].type)
- return pref.style[i].type;
- }
- }
-
- /* Didn't find the style, fail gracefully */
- free (res_name);
- free (res_class);
- free(wmName);
-
- return STYLE_NONE;
-}
+/* + * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * Copyright (C) Colin Harrison 2005-2008 + * + * 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 XFREE86 PROJECT 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 of the XFree86 Project + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from the XFree86 Project. + * + * Authors: Earle F. Philhower, III + * Colin Harrison + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#ifdef __CYGWIN__ +#include <sys/resource.h> +#endif +#include "win.h" + +#include <X11/Xwindows.h> +#include <shellapi.h> + +#include "winprefs.h" +#include "winmultiwindowclass.h" + +/* Where will the custom menu commands start counting from? */ +#define STARTMENUID WM_USER + +extern const char *winGetBaseDir(void); + +/* From winmultiwindowflex.l, the real parser */ +extern void parse_file (FILE *fp); + + +/* Currently in use command ID, incremented each new menu item created */ +static int g_cmdid = STARTMENUID; + + +/* Defined in DIX */ +extern char *display; + +/* Local function to handle comma-ified icon names */ +static HICON +LoadImageComma (char *fname, int sx, int sy, int flags); + + +/* + * Creates or appends a menu from a MENUPARSED structure + */ +static HMENU +MakeMenu (char *name, + HMENU editMenu, + int editItem) +{ + int i; + int item; + MENUPARSED *m; + HMENU hmenu, hsub; + + for (i=0; i<pref.menuItems; i++) + { + if (!strcmp(name, pref.menu[i].menuName)) + break; + } + + /* Didn't find a match, bummer */ + if (i==pref.menuItems) + { + ErrorF("MakeMenu: Can't find menu %s\n", name); + return NULL; + } + + m = &(pref.menu[i]); + + if (editMenu) + { + hmenu = editMenu; + item = editItem; + } + else + { + hmenu = CreatePopupMenu(); + if (!hmenu) + { + ErrorF("MakeMenu: Unable to CreatePopupMenu() %s\n", name); + return NULL; + } + item = 0; + } + + /* Add the menu items */ + for (i=0; i<m->menuItems; i++) + { + /* Only assign IDs one time... */ + if ( m->menuItem[i].commandID == 0 ) + m->menuItem[i].commandID = g_cmdid++; + + switch (m->menuItem[i].cmd) + { + case CMD_EXEC: + case CMD_ALWAYSONTOP: + case CMD_RELOAD: + InsertMenu (hmenu, + item, + MF_BYPOSITION|MF_ENABLED|MF_STRING, + m->menuItem[i].commandID, + m->menuItem[i].text); + break; + + case CMD_SEPARATOR: + InsertMenu (hmenu, + item, + MF_BYPOSITION|MF_SEPARATOR, + 0, + NULL); + break; + + case CMD_MENU: + /* Recursive! */ + hsub = MakeMenu (m->menuItem[i].param, 0, 0); + if (hsub) + InsertMenu (hmenu, + item, + MF_BYPOSITION|MF_POPUP|MF_ENABLED|MF_STRING, + (UINT_PTR)hsub, + m->menuItem[i].text); + break; + } + + /* If item==-1 (means to add at end of menu) don't increment) */ + if (item>=0) + item++; + } + + return hmenu; +} + + +#ifdef XWIN_MULTIWINDOW +/* + * Callback routine that is executed once per window class. + * Removes or creates custom window settings depending on LPARAM + */ +static wBOOL CALLBACK +ReloadEnumWindowsProc (HWND hwnd, LPARAM lParam) +{ + HICON hicon; + Window wid; + + if (!hwnd) { + ErrorF("ReloadEnumWindowsProc: hwnd==NULL!\n"); + return FALSE; + } + + /* It's our baby, either clean or dirty it */ + if (lParam==FALSE) + { + /* Reset the window's icon to undefined. */ + hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_BIG, 0); + + /* If the old icon is generated on-the-fly, get rid of it, will regen */ + winDestroyIcon (hicon); + + /* Same for the small icon */ + hicon = (HICON)SendMessage(hwnd, WM_SETICON, ICON_SMALL, 0); + winDestroyIcon (hicon); + + /* Remove any menu additions; bRevert=TRUE destroys any modified menus */ + GetSystemMenu (hwnd, TRUE); + + /* This window is now clean of our taint (but with undefined icons) */ + } + else + { + /* winUpdateIcon() will set the icon default, dynamic, or from xwinrc */ + wid = (Window)GetProp (hwnd, WIN_WID_PROP); + if (wid) + winUpdateIcon (wid); + + /* Update the system menu for this window */ + SetupSysMenu ((unsigned long)hwnd); + + /* That was easy... */ + } + + return TRUE; +} +#endif + + +/* + * Removes any custom icons in classes, custom menus, etc. + * Frees all members in pref structure. + * Reloads the preferences file. + * Set custom icons and menus again. + */ +static void +ReloadPrefs (void) +{ + int i; + +#ifdef XWIN_MULTIWINDOW + /* First, iterate over all windows, deleting their icons and custom menus. + * This is really only needed because winDestroyIcon() will try to + * destroy the old global icons, which will have changed. + * It is probably better to set a windows USER_DATA to flag locally defined + * icons, and use that to accurately know when to destroy old icons. + */ + EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, FALSE); +#endif + + /* Now, free/clear all info from our prefs structure */ + for (i=0; i<pref.menuItems; i++) + free (pref.menu[i].menuItem); + free (pref.menu); + pref.menu = NULL; + pref.menuItems = 0; + + pref.rootMenuName[0] = 0; + + free (pref.sysMenu); + pref.sysMenuItems = 0; + + pref.defaultSysMenuName[0] = 0; + pref.defaultSysMenuPos = 0; + + pref.iconDirectory[0] = 0; + pref.defaultIconName[0] = 0; + pref.trayIconName[0] = 0; + + for (i=0; i<pref.iconItems; i++) + if (pref.icon[i].hicon) + DestroyIcon ((HICON)pref.icon[i].hicon); + free (pref.icon); + pref.icon = NULL; + pref.iconItems = 0; + + /* Free global default X icon */ + if (g_hIconX) + DestroyIcon (g_hIconX); + if (g_hSmallIconX) + DestroyIcon (g_hSmallIconX); + + /* Reset the custom command IDs */ + g_cmdid = STARTMENUID; + + /* Load the updated resource file */ + LoadPreferences(); + + g_hIconX = NULL; + g_hSmallIconX = NULL; + +#ifdef XWIN_MULTIWINDOW + winInitGlobalIcons(); +#endif + +#ifdef XWIN_MULTIWINDOW + /* Rebuild the icons and menus */ + EnumThreadWindows (g_dwCurrentThreadID, ReloadEnumWindowsProc, TRUE); +#endif + + /* Whew, done */ +} + +/* + * Check/uncheck the ALWAYSONTOP items in this menu + */ +void +HandleCustomWM_INITMENU(unsigned long hwndIn, + unsigned long hmenuIn) +{ + HWND hwnd; + HMENU hmenu; + DWORD dwExStyle; + int i, j; + + hwnd = (HWND)hwndIn; + hmenu = (HMENU)hmenuIn; + if (!hwnd || !hmenu) + return; + + if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) + dwExStyle = MF_BYCOMMAND | MF_CHECKED; + else + dwExStyle = MF_BYCOMMAND | MF_UNCHECKED; + + for (i=0; i<pref.menuItems; i++) + for (j=0; j<pref.menu[i].menuItems; j++) + if (pref.menu[i].menuItem[j].cmd==CMD_ALWAYSONTOP) + CheckMenuItem (hmenu, pref.menu[i].menuItem[j].commandID, dwExStyle ); + +} + +/* + * Searches for the custom WM_COMMAND command ID and performs action. + * Return TRUE if command is proccessed, FALSE otherwise. + */ +Bool +HandleCustomWM_COMMAND (unsigned long hwndIn, + int command) +{ + HWND hwnd; + int i, j; + MENUPARSED *m; + DWORD dwExStyle; + + hwnd = (HWND)hwndIn; + + if (!command) + return FALSE; + + for (i=0; i<pref.menuItems; i++) + { + m = &(pref.menu[i]); + for (j=0; j<m->menuItems; j++) + { + if (command==m->menuItem[j].commandID) + { + /* Match! */ + switch(m->menuItem[j].cmd) + { +#ifdef __CYGWIN__ + case CMD_EXEC: + if (fork()==0) + { + struct rlimit rl; + unsigned long i; + + /* Close any open descriptors except for STD* */ + getrlimit (RLIMIT_NOFILE, &rl); + for (i = STDERR_FILENO+1; i < rl.rlim_cur; i++) + close(i); + + /* Disassociate any TTYs */ + setsid(); + + execl ("/bin/sh", + "/bin/sh", + "-c", + m->menuItem[j].param, + NULL); + exit (0); + } + else + return TRUE; + break; +#else + case CMD_EXEC: + { + /* Start process without console window */ + STARTUPINFO start; + PROCESS_INFORMATION child; + + memset (&start, 0, sizeof (start)); + start.cb = sizeof (start); + start.dwFlags = STARTF_USESHOWWINDOW; + start.wShowWindow = SW_HIDE; + + memset (&child, 0, sizeof (child)); + + if (CreateProcess (NULL, m->menuItem[j].param, NULL, NULL, FALSE, 0, + NULL, NULL, &start, &child)) + { + CloseHandle (child.hThread); + CloseHandle (child.hProcess); + } + else + MessageBox(NULL, m->menuItem[j].param, "Mingrc Exec Command Error!", MB_OK | MB_ICONEXCLAMATION); + } + return TRUE; +#endif + case CMD_ALWAYSONTOP: + if (!hwnd) + return FALSE; + + /* Get extended window style */ + dwExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); + + /* Handle topmost windows */ + if (dwExStyle & WS_EX_TOPMOST) + SetWindowPos (hwnd, + HWND_NOTOPMOST, + 0, 0, + 0, 0, + SWP_NOSIZE | SWP_NOMOVE); + else + SetWindowPos (hwnd, + HWND_TOPMOST, + 0, 0, + 0, 0, + SWP_NOSIZE | SWP_NOMOVE); +#if XWIN_MULTIWINDOW + /* Reflect the changed Z order */ + winReorderWindowsMultiWindow (); +#endif + return TRUE; + + case CMD_RELOAD: + ReloadPrefs(); + return TRUE; + + default: + return FALSE; + } + } /* match */ + } /* for j */ + } /* for i */ + + return FALSE; +} + + +#ifdef XWIN_MULTIWINDOW +/* + * Add the default or a custom menu depending on the class match + */ +void +SetupSysMenu (unsigned long hwndIn) +{ + HWND hwnd; + HMENU sys; + int i; + WindowPtr pWin; + char *res_name, *res_class; + + hwnd = (HWND)hwndIn; + if (!hwnd) + return; + + pWin = GetProp (hwnd, WIN_WINDOW_PROP); + + sys = GetSystemMenu (hwnd, FALSE); + if (!sys) + return; + + if (pWin) + { + /* First see if there's a class match... */ + if (winMultiWindowGetClassHint (pWin, &res_name, &res_class)) + { + for (i=0; i<pref.sysMenuItems; i++) + { + if (!strcmp(pref.sysMenu[i].match, res_name) || + !strcmp(pref.sysMenu[i].match, res_class) ) + { + free(res_name); + free(res_class); + + MakeMenu (pref.sysMenu[i].menuName, sys, + pref.sysMenu[i].menuPos==AT_START?0:-1); + return; + } + } + + /* No match, just free alloc'd strings */ + free(res_name); + free(res_class); + } /* Found wm_class */ + } /* if pwin */ + + /* Fallback to system default */ + if (pref.defaultSysMenuName[0]) + { + if (pref.defaultSysMenuPos==AT_START) + MakeMenu (pref.defaultSysMenuName, sys, 0); + else + MakeMenu (pref.defaultSysMenuName, sys, -1); + } +} +#endif + + +/* + * Possibly add a menu to the toolbar icon + */ +void +SetupRootMenu (unsigned long hmenuRoot) +{ + HMENU root; + + root = (HMENU)hmenuRoot; + if (!root) + return; + + if (pref.rootMenuName[0]) + { + MakeMenu(pref.rootMenuName, root, 0); + } +} + + +/* + * Check for and return an overridden default ICON specified in the prefs + */ +HICON +winOverrideDefaultIcon(int size) +{ + HICON hicon; + + if (pref.defaultIconName[0]) + { + hicon = LoadImageComma (pref.defaultIconName, size, size, 0); + if (hicon==NULL) + ErrorF ("winOverrideDefaultIcon: LoadImageComma(%s) failed\n", + pref.defaultIconName); + + return hicon; + } + + return 0; +} + + +/* + * Return the HICON to use in the taskbar notification area + */ +HICON +winTaskbarIcon(void) +{ + HICON hicon; + + hicon = 0; + /* First try and load an overridden, if success then return it */ + if (pref.trayIconName[0]) + { + hicon = LoadImageComma (pref.trayIconName, + GetSystemMetrics (SM_CXSMICON), + GetSystemMetrics (SM_CYSMICON), + 0 ); + } + + /* Otherwise return the default */ + if (!hicon) + hicon = (HICON) LoadImage (g_hInstance, + MAKEINTRESOURCE(IDI_XWIN), + IMAGE_ICON, + GetSystemMetrics (SM_CXSMICON), + GetSystemMetrics (SM_CYSMICON), + 0); + + return hicon; +} + + +/* + * Parse a filename to extract an icon: + * If fname is exactly ",nnn" then extract icon from our resource + * else if it is "file,nnn" then extract icon nnn from that file + * else try to load it as an .ico file and if that fails return NULL + */ +static HICON +LoadImageComma (char *fname, int sx, int sy, int flags) +{ + HICON hicon; + int index; + char file[PATH_MAX+NAME_MAX+2]; + + /* Some input error checking */ + if (!fname || !fname[0]) + return NULL; + + index = 0; + hicon = NULL; + + if (fname[0]==',') + { + /* It's the XWIN.EXE resource they want */ + index = atoi (fname+1); + hicon = LoadImage (g_hInstance, + MAKEINTRESOURCE(index), + IMAGE_ICON, + sx, + sy, + flags); + } + else + { + file[0] = 0; + /* Prepend path if not given a "X:\" filename */ + if ( !(fname[0] && fname[1]==':' && fname[2]=='\\') ) + { + strcpy (file, pref.iconDirectory); + if (pref.iconDirectory[0]) + if (fname[strlen(fname)-1]!='\\') + strcat (file, "\\"); + } + strcat (file, fname); + + if (strrchr (file, ',')) + { + /* Specified as <fname>,<index> */ + + *(strrchr (file, ',')) = 0; /* End string at comma */ + index = atoi (strrchr (fname, ',') + 1); + hicon = ExtractIcon (g_hInstance, file, index); + } + else + { + /* Just an .ico file... */ + + hicon = (HICON)LoadImage (NULL, + file, + IMAGE_ICON, + sx, + sy, + LR_LOADFROMFILE|flags); + } + } + return hicon; +} + +/* + * Check for a match of the window class to one specified in the + * ICONS{} section in the prefs file, and load the icon from a file + */ +HICON +winOverrideIcon (unsigned long longWin) +{ + WindowPtr pWin = (WindowPtr) longWin; + char *res_name, *res_class; + int i; + HICON hicon; + char *wmName; + + if (pWin==NULL) + return 0; + + /* If we can't find the class, we can't override from default! */ + if (!winMultiWindowGetClassHint (pWin, &res_name, &res_class)) + return 0; + + winMultiWindowGetWMName (pWin, &wmName); + + for (i=0; i<pref.iconItems; i++) { + if (!strcmp(pref.icon[i].match, res_name) || + !strcmp(pref.icon[i].match, res_class) || + (wmName && strstr(wmName, pref.icon[i].match))) + { + free (res_name); + free (res_class); + free(wmName); + + if (pref.icon[i].hicon) + return pref.icon[i].hicon; + + hicon = LoadImageComma (pref.icon[i].iconFile, 0, 0, LR_DEFAULTSIZE); + if (hicon==NULL) + ErrorF ("winOverrideIcon: LoadImageComma(%s) failed\n", + pref.icon[i].iconFile); + + pref.icon[i].hicon = hicon; + return hicon; + } + } + + /* Didn't find the icon, fail gracefully */ + free (res_name); + free (res_class); + free(wmName); + + return 0; +} + + +/* + * Should we free this icon or leave it in memory (is it part of our + * ICONS{} overrides)? + */ +int +winIconIsOverride(unsigned hiconIn) +{ + HICON hicon; + int i; + + hicon = (HICON)hiconIn; + + if (!hicon) + return 0; + + for (i=0; i<pref.iconItems; i++) + if ((HICON)pref.icon[i].hicon == hicon) + return 1; + + return 0; +} + + + +/* + * Try and open ~/.XWinrc and system.XWinrc + * Load it into prefs structure for use by other functions + */ +void +LoadPreferences (void) +{ + char *home; + char fname[PATH_MAX+NAME_MAX+2]; + FILE *prefFile; + char szDisplay[512]; + char *szEnvDisplay; + int i, j; + char param[PARAM_MAX+1]; + char *srcParam, *dstParam; + + /* First, clear all preference settings */ + memset (&pref, 0, sizeof(pref)); + prefFile = NULL; + + /* Now try and find a ~/.xwinrc file */ + home = getenv ("HOME"); + if (home) + { + strcpy (fname, home); + if (fname[strlen(fname)-1]!='/') + strcat (fname, "/"); + strcat (fname, ".XWinrc"); + + prefFile = fopen (fname, "r"); + if (prefFile) + ErrorF ("winPrefsLoadPreferences: %s\n", fname); + } + + /* No home file found, check system default */ + if (!prefFile) + { + char buffer[MAX_PATH]; +#ifdef RELOCATE_PROJECTROOT + snprintf(buffer, sizeof(buffer), "%s\\system.XWinrc", winGetBaseDir()); +#else + strncpy(buffer, SYSCONFDIR"/X11/system.XWinrc", sizeof(buffer)); +#endif + buffer[sizeof(buffer)-1] = 0; + prefFile = fopen (buffer, "r"); + if (prefFile) + ErrorF ("winPrefsLoadPreferences: %s\n", buffer); + } + + /* If we could open it, then read the settings and close it */ + if (prefFile) + { + parse_file (prefFile); + fclose (prefFile); + } + + /* Setup a DISPLAY environment variable, need to allocate on heap */ + /* because putenv doesn't copy the argument... */ + snprintf (szDisplay, 512, "DISPLAY=127.0.0.1:%s.0", display); + szEnvDisplay = (char *)(malloc (strlen(szDisplay)+1)); + if (szEnvDisplay) + { + strcpy (szEnvDisplay, szDisplay); + putenv (szEnvDisplay); + } + + /* Replace any "%display%" in menu commands with display string */ + snprintf (szDisplay, 512, "127.0.0.1:%s.0", display); + for (i=0; i<pref.menuItems; i++) + { + for (j=0; j<pref.menu[i].menuItems; j++) + { + if (pref.menu[i].menuItem[j].cmd==CMD_EXEC) + { + srcParam = pref.menu[i].menuItem[j].param; + dstParam = param; + while (*srcParam) { + if (!strncmp(srcParam, "%display%", 9)) + { + memcpy (dstParam, szDisplay, strlen(szDisplay)); + dstParam += strlen(szDisplay); + srcParam += 9; + } + else + { + *dstParam = *srcParam; + dstParam++; + srcParam++; + } + } + *dstParam = 0; + strcpy (pref.menu[i].menuItem[j].param, param); + } /* cmd==cmd_exec */ + } /* for all menuitems */ + } /* for all menus */ + +} + + +/* + * Check for a match of the window class to one specified in the + * STYLES{} section in the prefs file, and return the style type + */ +unsigned long +winOverrideStyle (char *res_name, char *res_class, char *wmName) +{ + int i; + + for (i=0; i<pref.styleItems; i++) { + if ((res_name && !strcmp(pref.style[i].match, res_name)) || + (res_class && !strcmp(pref.style[i].match, res_class)) || + (wmName && strstr(wmName, pref.style[i].match))) + { + if (pref.style[i].type) + return pref.style[i].type; + } + } + + /* Didn't find the style, fail gracefully */ + return STYLE_NONE; +} diff --git a/xorg-server/hw/xwin/winprefs.h b/xorg-server/hw/xwin/winprefs.h index 276b9724d..ecd0a3fbd 100644 --- a/xorg-server/hw/xwin/winprefs.h +++ b/xorg-server/hw/xwin/winprefs.h @@ -1,190 +1,190 @@ -#if !defined(WINPREFS_H)
-#define WINPREFS_H
-/*
- * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- * Copyright (C) Colin Harrison 2005-2008
- *
- * 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 XFREE86 PROJECT 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 of the XFree86 Project
- * shall not be used in advertising or otherwise to promote the sale, use
- * or other dealings in this Software without prior written authorization
- * from the XFree86 Project.
- *
- * Authors: Earle F. Philhower, III
- * Colin Harrison
- */
-
-/* Need Bool */
-#include <X11/Xdefs.h>
-/* Need TRUE */
-#include "misc.h"
-
-/* Need to know how long paths can be... */
-#include <limits.h>
-/* Xwindows redefines PATH_MAX to at least 1024 */
-#include <X11/Xwindows.h>
-
-#ifndef NAME_MAX
-#define NAME_MAX PATH_MAX
-#endif
-#define MENU_MAX 128 /* Maximum string length of a menu name or item */
-#define PARAM_MAX (4*PATH_MAX) /* Maximum length of a parameter to a MENU */
-
-
-/* Supported commands in a MENU {} statement */
-typedef enum MENUCOMMANDTYPE
-{
- CMD_EXEC, /* /bin/sh -c the parameter */
- CMD_MENU, /* Display a popup menu named param */
- CMD_SEPARATOR, /* Menu separator */
- CMD_ALWAYSONTOP, /* Toggle always-on-top mode */
- CMD_RELOAD /* Reparse the .XWINRC file */
-} MENUCOMMANDTYPE;
-
-#define STYLE_NONE (0L) /* Dummy the first entry */
-#define STYLE_NOTITLE (1L) /* Force window style no titlebar */
-#define STYLE_OUTLINE (1L<<1) /* Force window style just thin-line border */
-#define STYLE_NOFRAME (1L<<2) /* Force window style no frame */
-#define STYLE_TOPMOST (1L<<3) /* Open a window always-on-top */
-#define STYLE_MAXIMIZE (1L<<4) /* Open a window maximized */
-#define STYLE_MINIMIZE (1L<<5) /* Open a window minimized */
-#define STYLE_BOTTOM (1L<<6) /* Open a window at the bottom of the Z order */
-
-/* Where to place a system menu */
-typedef enum MENUPOSITION
-{
- AT_START, /* Place menu at the top of the system menu */
- AT_END /* Put it at the bottom of the menu (default) */
-} MENUPOSITION;
-
-/* Menu item definitions */
-typedef struct MENUITEM
-{
- char text[MENU_MAX+1]; /* To be displayed in menu */
- MENUCOMMANDTYPE cmd; /* What should it do? */
- char param[PARAM_MAX+1]; /* Any parameters? */
- unsigned long commandID; /* Windows WM_COMMAND ID assigned at runtime */
-} MENUITEM;
-
-/* A completely read in menu... */
-typedef struct MENUPARSED
-{
- char menuName[MENU_MAX+1]; /* What's it called in the text? */
- MENUITEM *menuItem; /* Array of items */
- int menuItems; /* How big's the array? */
-} MENUPARSED;
-
-/* To map between a window and a system menu to add for it */
-typedef struct SYSMENUITEM
-{
- char match[MENU_MAX+1]; /* String to look for to apply this sysmenu */
- char menuName[MENU_MAX+1]; /* Which menu to show? Used to set *menu */
- MENUPOSITION menuPos; /* Where to place it (ignored in root) */
-} SYSMENUITEM;
-
-/* To redefine icons for certain window types */
-typedef struct ICONITEM
-{
- char match[MENU_MAX+1]; /* What string to search for? */
- char iconFile[PATH_MAX+NAME_MAX+2]; /* Icon location, WIN32 path */
- HICON hicon; /* LoadImage() result */
-} ICONITEM;
-
-/* To redefine styles for certain window types */
-typedef struct STYLEITEM
-{
- char match[MENU_MAX+1]; /* What string to search for? */
- unsigned long type; /* What should it do? */
-} STYLEITEM;
-
-typedef struct WINPREFS
-{
- /* Menu information */
- MENUPARSED *menu; /* Array of created menus */
- int menuItems; /* How big? */
-
- /* Taskbar menu settings */
- char rootMenuName[MENU_MAX+1]; /* Menu for taskbar icon */
-
- /* System menu addition menus */
- SYSMENUITEM *sysMenu;
- int sysMenuItems;
-
- /* Which menu to add to unmatched windows? */
- char defaultSysMenuName[MENU_MAX+1];
- MENUPOSITION defaultSysMenuPos; /* Where to place it */
-
- /* Icon information */
- char iconDirectory[PATH_MAX+1]; /* Where do the .icos lie? (Win32 path) */
- char defaultIconName[NAME_MAX+1]; /* Replacement for x.ico */
- char trayIconName[NAME_MAX+1]; /* Replacement for tray icon */
-
- ICONITEM *icon;
- int iconItems;
-
- STYLEITEM *style;
- int styleItems;
-
- /* Force exit flag */
- Bool fForceExit;
-
- /* Silent exit flag */
- Bool fSilentExit;
-
-} WINPREFS;
-
-/* The global pref settings structure loaded by the winprefyacc.y parser */
-extern WINPREFS pref;
-
-
-/* Functions */
-void
-LoadPreferences(void);
-
-void
-SetupRootMenu (unsigned long hmenuRoot);
-
-void
-SetupSysMenu (unsigned long hwndIn);
-
-void
-HandleCustomWM_INITMENU(unsigned long hwndIn,
- unsigned long hmenuIn);
-
-Bool
-HandleCustomWM_COMMAND (unsigned long hwndIn,
- int command);
-
-int
-winIconIsOverride (unsigned hiconIn);
-
-HICON
-winOverrideIcon (unsigned long longpWin);
-
-unsigned long
-winOverrideStyle (unsigned long longpWin);
-
-HICON
-winTaskbarIcon(void);
-
-HICON
-winOverrideDefaultIcon(int size);
-#endif
+#if !defined(WINPREFS_H) +#define WINPREFS_H +/* + * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * Copyright (C) Colin Harrison 2005-2008 + * + * 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 XFREE86 PROJECT 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 of the XFree86 Project + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from the XFree86 Project. + * + * Authors: Earle F. Philhower, III + * Colin Harrison + */ + +/* Need Bool */ +#include <X11/Xdefs.h> +/* Need TRUE */ +#include "misc.h" + +/* Need to know how long paths can be... */ +#include <limits.h> +/* Xwindows redefines PATH_MAX to at least 1024 */ +#include <X11/Xwindows.h> + +#ifndef NAME_MAX +#define NAME_MAX PATH_MAX +#endif +#define MENU_MAX 128 /* Maximum string length of a menu name or item */ +#define PARAM_MAX (4*PATH_MAX) /* Maximum length of a parameter to a MENU */ + + +/* Supported commands in a MENU {} statement */ +typedef enum MENUCOMMANDTYPE +{ + CMD_EXEC, /* /bin/sh -c the parameter */ + CMD_MENU, /* Display a popup menu named param */ + CMD_SEPARATOR, /* Menu separator */ + CMD_ALWAYSONTOP, /* Toggle always-on-top mode */ + CMD_RELOAD /* Reparse the .XWINRC file */ +} MENUCOMMANDTYPE; + +#define STYLE_NONE (0L) /* Dummy the first entry */ +#define STYLE_NOTITLE (1L) /* Force window style no titlebar */ +#define STYLE_OUTLINE (1L<<1) /* Force window style just thin-line border */ +#define STYLE_NOFRAME (1L<<2) /* Force window style no frame */ +#define STYLE_TOPMOST (1L<<3) /* Open a window always-on-top */ +#define STYLE_MAXIMIZE (1L<<4) /* Open a window maximized */ +#define STYLE_MINIMIZE (1L<<5) /* Open a window minimized */ +#define STYLE_BOTTOM (1L<<6) /* Open a window at the bottom of the Z order */ + +/* Where to place a system menu */ +typedef enum MENUPOSITION +{ + AT_START, /* Place menu at the top of the system menu */ + AT_END /* Put it at the bottom of the menu (default) */ +} MENUPOSITION; + +/* Menu item definitions */ +typedef struct MENUITEM +{ + char text[MENU_MAX+1]; /* To be displayed in menu */ + MENUCOMMANDTYPE cmd; /* What should it do? */ + char param[PARAM_MAX+1]; /* Any parameters? */ + unsigned long commandID; /* Windows WM_COMMAND ID assigned at runtime */ +} MENUITEM; + +/* A completely read in menu... */ +typedef struct MENUPARSED +{ + char menuName[MENU_MAX+1]; /* What's it called in the text? */ + MENUITEM *menuItem; /* Array of items */ + int menuItems; /* How big's the array? */ +} MENUPARSED; + +/* To map between a window and a system menu to add for it */ +typedef struct SYSMENUITEM +{ + char match[MENU_MAX+1]; /* String to look for to apply this sysmenu */ + char menuName[MENU_MAX+1]; /* Which menu to show? Used to set *menu */ + MENUPOSITION menuPos; /* Where to place it (ignored in root) */ +} SYSMENUITEM; + +/* To redefine icons for certain window types */ +typedef struct ICONITEM +{ + char match[MENU_MAX+1]; /* What string to search for? */ + char iconFile[PATH_MAX+NAME_MAX+2]; /* Icon location, WIN32 path */ + HICON hicon; /* LoadImage() result */ +} ICONITEM; + +/* To redefine styles for certain window types */ +typedef struct STYLEITEM +{ + char match[MENU_MAX+1]; /* What string to search for? */ + unsigned long type; /* What should it do? */ +} STYLEITEM; + +typedef struct WINPREFS +{ + /* Menu information */ + MENUPARSED *menu; /* Array of created menus */ + int menuItems; /* How big? */ + + /* Taskbar menu settings */ + char rootMenuName[MENU_MAX+1]; /* Menu for taskbar icon */ + + /* System menu addition menus */ + SYSMENUITEM *sysMenu; + int sysMenuItems; + + /* Which menu to add to unmatched windows? */ + char defaultSysMenuName[MENU_MAX+1]; + MENUPOSITION defaultSysMenuPos; /* Where to place it */ + + /* Icon information */ + char iconDirectory[PATH_MAX+1]; /* Where do the .icos lie? (Win32 path) */ + char defaultIconName[NAME_MAX+1]; /* Replacement for x.ico */ + char trayIconName[NAME_MAX+1]; /* Replacement for tray icon */ + + ICONITEM *icon; + int iconItems; + + STYLEITEM *style; + int styleItems; + + /* Force exit flag */ + Bool fForceExit; + + /* Silent exit flag */ + Bool fSilentExit; + +} WINPREFS; + +/* The global pref settings structure loaded by the winprefyacc.y parser */ +extern WINPREFS pref; + + +/* Functions */ +void +LoadPreferences(void); + +void +SetupRootMenu (unsigned long hmenuRoot); + +void +SetupSysMenu (unsigned long hwndIn); + +void +HandleCustomWM_INITMENU(unsigned long hwndIn, + unsigned long hmenuIn); + +Bool +HandleCustomWM_COMMAND (unsigned long hwndIn, + int command); + +int +winIconIsOverride (unsigned hiconIn); + +HICON +winOverrideIcon (unsigned long longpWin); + +unsigned long +winOverrideStyle (char *res_name, char *res_class, char *wmName); + +HICON +winTaskbarIcon(void); + +HICON +winOverrideDefaultIcon(int size); +#endif diff --git a/xorg-server/hw/xwin/winscrinit.c b/xorg-server/hw/xwin/winscrinit.c index 691237e6f..983ff5730 100644 --- a/xorg-server/hw/xwin/winscrinit.c +++ b/xorg-server/hw/xwin/winscrinit.c @@ -220,6 +220,10 @@ winScreenInit (int index, if (!((*pScreenPriv->pwinFinishScreenInit) (index, pScreen, argc, argv))) { ErrorF ("winScreenInit - winFinishScreenInit () failed\n"); + + /* call the engine dependent screen close procedure to clean up from a failure */ + pScreenPriv->pwinCloseScreen(index, pScreen); + return FALSE; } diff --git a/xorg-server/hw/xwin/winshaddd.c b/xorg-server/hw/xwin/winshaddd.c index 00d7a379f..6dad2782f 100644 --- a/xorg-server/hw/xwin/winshaddd.c +++ b/xorg-server/hw/xwin/winshaddd.c @@ -728,7 +728,8 @@ winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen) /* Call the wrapped CloseScreen procedure */ WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + if (pScreen->CloseScreen) + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); winFreeFBShadowDD(pScreen); diff --git a/xorg-server/hw/xwin/winshadddnl.c b/xorg-server/hw/xwin/winshadddnl.c index 0a0b4ae13..63d48adb6 100644 --- a/xorg-server/hw/xwin/winshadddnl.c +++ b/xorg-server/hw/xwin/winshadddnl.c @@ -802,7 +802,8 @@ winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen) /* Call the wrapped CloseScreen procedure */ WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + if (pScreen->CloseScreen) + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); winFreeFBShadowDDNL(pScreen); diff --git a/xorg-server/hw/xwin/winshadgdi.c b/xorg-server/hw/xwin/winshadgdi.c index 499037656..1e7cb006c 100644 --- a/xorg-server/hw/xwin/winshadgdi.c +++ b/xorg-server/hw/xwin/winshadgdi.c @@ -636,7 +636,8 @@ winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen) /* Call the wrapped CloseScreen procedure */ WIN_UNWRAP(CloseScreen); - fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); + if (pScreen->CloseScreen) + fReturn = (*pScreen->CloseScreen) (nIndex, pScreen); /* Delete the window property */ RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); diff --git a/xorg-server/hw/xwin/winvideo.c b/xorg-server/hw/xwin/winvideo.c index 998a3face..ed205448d 100644 --- a/xorg-server/hw/xwin/winvideo.c +++ b/xorg-server/hw/xwin/winvideo.c @@ -1,210 +1,208 @@ -/*
- *Copyright (C) 2003-2004 Harold L Hunt II 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 HAROLD L HUNT II 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 of Harold L Hunt II
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from Harold L Hunt II.
- *
- * Authors: Harold L Hunt II
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvproto.h>
-
-void
-winInitVideo (ScreenPtr pScreen);
-
-/*
- * winInitVideo - Initialize support for the X Video (Xv) Extension.
- */
-
-void
-winInitVideo (ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-
- if (pScreenInfo->dwBPP > 8)
- {
-
- }
-
-
-}
-
-
-
-
-
-
-
-#if 0
-#include "../xfree86/common/xf86.h"
-#include "../Xext/xvdix.h"
-#include "../xfree86/common/xf86xv.h"
-#include <X11/extensions/Xv.h>
-#endif
-
-#include "win.h"
-
-
-
-#if 0
-/* client libraries expect an encoding */
-static XF86VideoEncodingRec DummyEncoding[1] =
-{
- {
- 0,
- "XV_IMAGE",
- IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
- {1, 1}
- }
-};
-
-#define NUM_FORMATS 3
-
-static XF86VideoFormatRec Formats[NUM_FORMATS] =
-{
- {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
-};
-
-#define NUM_ATTRIBUTES 3
-
-static XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
-{
- {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
- {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
- {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
-};
-
-#define NUM_IMAGES 4
-
-static XF86ImageRec Images[NUM_IMAGES] =
-{
- XVIMAGE_YUY2,
- XVIMAGE_YV12,
- XVIMAGE_I420,
- XVIMAGE_UYVY
-};
-
-
-
-/*
- * winInitVideo - Initialize support for the X Video (Xv) Extension.
- */
-
-void
-winInitVideo (ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
- XF86VideoAdaptorPtr newAdaptor = NULL;
-
- if (pScreenInfo->dwBPP > 8)
- {
- newAdaptor = I810SetupImageVideo (pScreen);
- I810InitOffscreenImages (pScreen);
- }
-
- xf86XVScreenInit (pScreen, adaptors, 1);
-}
-
-
-static XF86VideoAdaptorPtr
-winSetupImageVideo (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-#if 0
- I810Ptr pI810 = I810PTR(pScrn);
-#endif
- XF86VideoAdaptorPtr adapt;
-
- if (!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec))))
- return NULL;
-
- adapt->type = XvWindowMask | XvInputMask | XvImageMask;
- adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
- adapt->name = PROJECT_NAME " Video Overlay";
- adapt->nEncodings = 1;
- adapt->pEncodings = DummyEncoding;
- adapt->nFormats = NUM_FORMATS;
- adapt->pFormats = Formats;
- adapt->nPorts = 1;
- adapt->pPortPrivates = NULL;
-
- adapt->pPortPrivates[0].ptr = NULL;
- adapt->pAttributes = Attributes;
- adapt->nImages = NUM_IMAGES;
- adapt->nAttributes = NUM_ATTRIBUTES;
- adapt->pImages = Images;
- adapt->PutVideo = NULL;
- adapt->PutStill = NULL;
- adapt->GetVideo = NULL;
- adapt->GetStill = NULL;
-#if 0
- adapt->StopVideo = I810StopVideo;
- adapt->SetPortAttribute = I810SetPortAttribute;
- adapt->GetPortAttribute = I810GetPortAttribute;
- adapt->QueryBestSize = I810QueryBestSize;
- adapt->PutImage = I810PutImage;
- adapt->QueryImageAttributes = I810QueryImageAttributes;
-#endif
-
-#if 0
- pPriv->colorKey = pI810->colorKey & ((1 << pScrn->depth) - 1);
-#endif
- pPriv->videoStatus = 0;
- pPriv->brightness = 0;
- pPriv->contrast = 64;
- pPriv->linear = NULL;
- pPriv->currentBuf = 0;
-
-#if 0
- /* gotta uninit this someplace */
- RegionNull(&pPriv->clip);
-#endif
-
-#if 0
- pI810->adaptor = adapt;
-
- pI810->BlockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = I810BlockHandler;
-#endif
-
-#if 0
- xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
- xvContrast = MAKE_ATOM("XV_CONTRAST");
- xvColorKey = MAKE_ATOM("XV_COLORKEY");
-#endif
-
-#if 0
- I810ResetVideo(pScrn);
-#endif
-
- return adapt;
-}
-#endif
+/* + *Copyright (C) 2003-2004 Harold L Hunt II 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 HAROLD L HUNT II 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 of Harold L Hunt II + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from Harold L Hunt II. + * + * Authors: Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include <X11/extensions/Xv.h> +#include <X11/extensions/Xvproto.h> + +void +winInitVideo (ScreenPtr pScreen); + +/* + * winInitVideo - Initialize support for the X Video (Xv) Extension. + */ + +void +winInitVideo (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + + if (pScreenInfo->dwBPP > 8) + { + + } + + +} + + + + + + + +#if 0 +#include "../xfree86/common/xf86.h" +#include "../Xext/xvdix.h" +#include "../xfree86/common/xf86xv.h" +#include <X11/extensions/Xv.h> +#endif + + + +#if 0 +/* client libraries expect an encoding */ +static XF86VideoEncodingRec DummyEncoding[1] = +{ + { + 0, + "XV_IMAGE", + IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + {1, 1} + } +}; + +#define NUM_FORMATS 3 + +static XF86VideoFormatRec Formats[NUM_FORMATS] = +{ + {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +}; + +#define NUM_ATTRIBUTES 3 + +static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = +{ + {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, + {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, + {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"} +}; + +#define NUM_IMAGES 4 + +static XF86ImageRec Images[NUM_IMAGES] = +{ + XVIMAGE_YUY2, + XVIMAGE_YV12, + XVIMAGE_I420, + XVIMAGE_UYVY +}; + + + +/* + * winInitVideo - Initialize support for the X Video (Xv) Extension. + */ + +void +winInitVideo (ScreenPtr pScreen) +{ + winScreenPriv(pScreen); + winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; + XF86VideoAdaptorPtr newAdaptor = NULL; + + if (pScreenInfo->dwBPP > 8) + { + newAdaptor = I810SetupImageVideo (pScreen); + I810InitOffscreenImages (pScreen); + } + + xf86XVScreenInit (pScreen, adaptors, 1); +} + + +static XF86VideoAdaptorPtr +winSetupImageVideo (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +#if 0 + I810Ptr pI810 = I810PTR(pScrn); +#endif + XF86VideoAdaptorPtr adapt; + + if (!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = PROJECT_NAME " Video Overlay"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = NULL; + + adapt->pPortPrivates[0].ptr = NULL; + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; +#if 0 + adapt->StopVideo = I810StopVideo; + adapt->SetPortAttribute = I810SetPortAttribute; + adapt->GetPortAttribute = I810GetPortAttribute; + adapt->QueryBestSize = I810QueryBestSize; + adapt->PutImage = I810PutImage; + adapt->QueryImageAttributes = I810QueryImageAttributes; +#endif + +#if 0 + pPriv->colorKey = pI810->colorKey & ((1 << pScrn->depth) - 1); +#endif + pPriv->videoStatus = 0; + pPriv->brightness = 0; + pPriv->contrast = 64; + pPriv->linear = NULL; + pPriv->currentBuf = 0; + +#if 0 + /* gotta uninit this someplace */ + RegionNull(&pPriv->clip); +#endif + +#if 0 + pI810->adaptor = adapt; + + pI810->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = I810BlockHandler; +#endif + +#if 0 + xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); + xvContrast = MAKE_ATOM("XV_CONTRAST"); + xvColorKey = MAKE_ATOM("XV_COLORKEY"); +#endif + +#if 0 + I810ResetVideo(pScrn); +#endif + + return adapt; +} +#endif diff --git a/xorg-server/hw/xwin/winwin32rootless.c b/xorg-server/hw/xwin/winwin32rootless.c index 5049e40b5..8f9917a7b 100644 --- a/xorg-server/hw/xwin/winwin32rootless.c +++ b/xorg-server/hw/xwin/winwin32rootless.c @@ -1,1070 +1,1070 @@ -/*
- *Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from the XFree86 Project.
- *
- * Authors: Kensuke Matsuzaki
- * Earle F. Philhower, III
- * Harold L Hunt II
- */
-/*
- * Look at hw/darwin/quartz/xpr/xprFrame.c and hw/darwin/quartz/cr/crFrame.c
- */
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include <winuser.h>
-#define _WINDOWSWM_SERVER_
-#include <X11/extensions/windowswmstr.h>
-#include "dixevents.h"
-#include "winmultiwindowclass.h"
-#include <X11/Xatom.h>
-
-
-/*
- * Constant defines
- */
-
-#ifndef ULW_COLORKEY
-#define ULW_COLORKEY 0x00000001
-#endif
-#ifndef ULW_ALPHA
-#define ULW_ALPHA 0x00000002
-#endif
-#ifndef ULW_OPAQUE
-#define ULW_OPAQUE 0x00000004
-#endif
-#define AC_SRC_ALPHA 0x01
-
-/*
- * Local function
- */
-
-DEFINE_ATOM_HELPER(AtmWindowsWmNativeHwnd, WINDOWSWM_NATIVE_HWND)
-static void
-winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame);
-
-/*
- * Global variables
- */
-
-Bool g_fNoConfigureWindow = FALSE;
-
-/*
- * Internal function to get the DIB format that is compatible with the screen
- * Fixme: Share code with winshadgdi.c
- */
-
-static
-Bool
-winMWExtWMQueryDIBFormat (win32RootlessWindowPtr pRLWinPriv, BITMAPINFOHEADER *pbmih)
-{
- HBITMAP hbmp;
-#if CYGMULTIWINDOW_DEBUG
- LPDWORD pdw = NULL;
-#endif
-
- /* Create a memory bitmap compatible with the screen */
- hbmp = CreateCompatibleBitmap (pRLWinPriv->hdcScreen, 1, 1);
- if (hbmp == NULL)
- {
- ErrorF ("winMWExtWMQueryDIBFormat - CreateCompatibleBitmap failed\n");
- return FALSE;
- }
-
- /* Initialize our bitmap info header */
- ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD));
- pbmih->biSize = sizeof (BITMAPINFOHEADER);
-
- /* Get the biBitCount */
- if (!GetDIBits (pRLWinPriv->hdcScreen,
- hbmp,
- 0, 1,
- NULL,
- (BITMAPINFO*) pbmih,
- DIB_RGB_COLORS))
- {
- ErrorF ("winMWExtWMQueryDIBFormat - First call to GetDIBits failed\n");
- DeleteObject (hbmp);
- return FALSE;
- }
-
-#if CYGMULTIWINDOW_DEBUG
- /* Get a pointer to bitfields */
- pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER));
-
- winDebug ("winMWExtWMQueryDIBFormat - First call masks: %08x %08x %08x\n",
- (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]);
-#endif
-
- /* Get optimal color table, or the optimal bitfields */
- if (!GetDIBits (pRLWinPriv->hdcScreen,
- hbmp,
- 0, 1,
- NULL,
- (BITMAPINFO*)pbmih,
- DIB_RGB_COLORS))
- {
- ErrorF ("winMWExtWMQueryDIBFormat - Second call to GetDIBits "
- "failed\n");
- DeleteObject (hbmp);
- return FALSE;
- }
-
- /* Free memory */
- DeleteObject (hbmp);
-
- return TRUE;
-}
-
-static HRGN
-winMWExtWMCreateRgnFromRegion (RegionPtr pShape)
-{
- int nRects;
- BoxPtr pRects, pEnd;
- HRGN hRgn, hRgnRect;
-
- if (pShape == NULL) return NULL;
-
- nRects = RegionNumRects(pShape);
- pRects = RegionRects(pShape);
-
- hRgn = CreateRectRgn (0, 0, 0, 0);
- if (hRgn == NULL)
- {
- ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) "
- "failed: %d\n",
- 0, 0, 0, 0, (int) GetLastError ());
- }
-
- /* Loop through all rectangles in the X region */
- for (pEnd = pRects + nRects; pRects < pEnd; pRects++)
- {
- /* Create a Windows region for the X rectangle */
- hRgnRect = CreateRectRgn (pRects->x1,
- pRects->y1,
- pRects->x2,
- pRects->y2);
- if (hRgnRect == NULL)
- {
- ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) "
- "failed: %d\n",
- pRects->x1,
- pRects->y1,
- pRects->x2,
- pRects->y2,
- (int) GetLastError ());
- }
-
- /* Merge the Windows region with the accumulated region */
- if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR)
- {
- ErrorF ("winReshape - CombineRgn () failed: %d\n",
- (int) GetLastError ());
- }
-
- /* Delete the temporary Windows region */
- DeleteObject (hRgnRect);
- }
-
- return hRgn;
-}
-
-static void
-InitWin32RootlessEngine (win32RootlessWindowPtr pRLWinPriv)
-{
- pRLWinPriv->hdcScreen = GetDC (pRLWinPriv->hWnd);
- pRLWinPriv->hdcShadow = CreateCompatibleDC (pRLWinPriv->hdcScreen);
- pRLWinPriv->hbmpShadow = NULL;
-
- /* Allocate bitmap info header */
- pRLWinPriv->pbmihShadow = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER)
- + 256 * sizeof (RGBQUAD));
- if (pRLWinPriv->pbmihShadow == NULL)
- {
- ErrorF ("InitWin32RootlessEngine - malloc () failed\n");
- return;
- }
-
- /* Query the screen format */
- winMWExtWMQueryDIBFormat (pRLWinPriv,
- pRLWinPriv->pbmihShadow);
-}
-
-Bool
-winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen,
- int newX, int newY, RegionPtr pShape)
-{
-#define CLASS_NAME_LENGTH 512
- Bool fResult = TRUE;
- win32RootlessWindowPtr pRLWinPriv;
- WNDCLASSEX wc;
- char pszClass[CLASS_NAME_LENGTH], pszWindowID[12];
- HICON hIcon;
- HICON hIconSmall;
- char *res_name, *res_class, *res_role;
- static int s_iWindowID = 0;
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMCreateFrame %d %d - %d %d\n",
- newX, newY, pFrame->width, pFrame->height);
-#endif
-
- pRLWinPriv = (win32RootlessWindowPtr) malloc (sizeof (win32RootlessWindowRec));
- pRLWinPriv->pFrame = pFrame;
- pRLWinPriv->pfb = NULL;
- pRLWinPriv->hbmpShadow = NULL;
- pRLWinPriv->hdcShadow = NULL;
- pRLWinPriv->hdcScreen = NULL;
- pRLWinPriv->pbmihShadow = NULL;
- pRLWinPriv->fResized = TRUE;
- pRLWinPriv->fClose = FALSE;
- pRLWinPriv->fRestackingNow = FALSE;
- pRLWinPriv->fDestroyed = FALSE;
- pRLWinPriv->fMovingOrSizing = FALSE;
-
- // Store the implementation private frame ID
- pFrame->wid = (RootlessFrameID) pRLWinPriv;
-
- winSelectIcons(pFrame->win, &hIcon, &hIconSmall);
-
- /* Set standard class name prefix so we can identify window easily */
- strncpy (pszClass, WINDOW_CLASS_X, sizeof(pszClass));
-
- if (winMultiWindowGetClassHint (pFrame->win, &res_name, &res_class))
- {
- strncat (pszClass, "-", 1);
- strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass));
- strncat (pszClass, "-", 1);
- strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass));
-
- /* Check if a window class is provided by the WM_WINDOW_ROLE property,
- * if not use the WM_CLASS information.
- * For further information see:
- * http://tronche.com/gui/x/icccm/sec-5.html
- */
- if (winMultiWindowGetWindowRole (pFrame->win, &res_role) )
- {
- strcat (pszClass, "-");
- strcat (pszClass, res_role);
- free (res_role);
- }
-
- free (res_name);
- free (res_class);
- }
-
- /* Add incrementing window ID to make unique class name */
- snprintf (pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++);
- pszWindowID[sizeof(pszWindowID)-1] = 0;
- strcat (pszClass, pszWindowID);
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winCreateWindowsWindow - Creating class: %s\n", pszClass);
-#endif
-
- /* Setup our window class */
- wc.cbSize = sizeof(wc);
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = winMWExtWMWindowProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = g_hInstance;
- wc.hIcon = hIcon;
- wc.hIconSm = hIconSmall;
- wc.hCursor = 0;
- wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = pszClass;
- RegisterClassEx (&wc);
-
- /* Create the window */
- g_fNoConfigureWindow = TRUE;
- pRLWinPriv->hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */
- pszClass, /* Class name */
- WINDOW_TITLE_X, /* Window name */
- WS_POPUP | WS_CLIPCHILDREN,
- newX, /* Horizontal position */
- newY, /* Vertical position */
- pFrame->width, /* Right edge */
- pFrame->height, /* Bottom edge */
- (HWND) NULL, /* No parent or owner window */
- (HMENU) NULL, /* No menu */
- GetModuleHandle (NULL), /* Instance handle */
- pRLWinPriv); /* ScreenPrivates */
- if (pRLWinPriv->hWnd == NULL)
- {
- ErrorF ("winMWExtWMCreateFrame - CreateWindowExA () failed: %d\n",
- (int) GetLastError ());
- fResult = FALSE;
- }
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMCreateFrame - ShowWindow\n");
-#endif
-
- //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE);
- g_fNoConfigureWindow = FALSE;
-
- if (pShape != NULL)
- {
- winMWExtWMReshapeFrame (pFrame->wid, pShape);
- }
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMCreateFrame - (%08x) %08x\n",
- (int) pFrame->wid, (int) pRLWinPriv->hWnd);
-#if 0
- {
- WindowPtr pWin2 = NULL;
- win32RootlessWindowPtr pRLWinPriv2 = NULL;
-
- /* Check if the Windows window property for our X window pointer is valid */
- if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL)
- {
- pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE);
- }
- winDebug ("winMWExtWMCreateFrame2 (%08x) %08x\n",
- pRLWinPriv2, pRLWinPriv2->hWnd);
- if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd)
- {
- winDebug ("Error param missmatch\n");
- }
- }
-#endif
-#endif
-
- winMWExtWMSetNativeProperty (pFrame);
-
- return fResult;
-}
-
-void
-winMWExtWMDestroyFrame (RootlessFrameID wid)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- HICON hiconClass;
- HICON hiconSmClass;
- HMODULE hInstance;
- int iReturn;
- char pszClass[CLASS_NAME_LENGTH];
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMDestroyFrame (%08x) %08x\n",
- (int) pRLWinPriv, (int) pRLWinPriv->hWnd);
-#if 0
- {
- WindowPtr pWin2 = NULL;
- win32RootlessWindowPtr pRLWinPriv2 = NULL;
-
- /* Check if the Windows window property for our X window pointer is valid */
- if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL)
- {
- pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE);
- }
- winDebug ("winMWExtWMDestroyFrame2 (%08x) %08x\n",
- pRLWinPriv2, pRLWinPriv2->hWnd);
- if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd)
- {
- winDebug ("Error param missmatch\n");
- *(int*)0 = 1;//raise exseption
- }
- }
-#endif
-#endif
-
- /* Store the info we need to destroy after this window is gone */
- hInstance = (HINSTANCE) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HMODULE);
- hiconClass = (HICON) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HICON);
- hiconSmClass = (HICON) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HICONSM);
- iReturn = GetClassName (pRLWinPriv->hWnd, pszClass, CLASS_NAME_LENGTH);
-
- pRLWinPriv->fClose = TRUE;
- pRLWinPriv->fDestroyed = TRUE;
-
- /* Destroy the Windows window */
- DestroyWindow (pRLWinPriv->hWnd);
-
- /* Only if we were able to get the name */
- if (iReturn)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMDestroyFrame - Unregistering %s: ", pszClass);
-#endif
- iReturn = UnregisterClass (pszClass, hInstance);
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMDestroyFramew - %d Deleting Icon: ", iReturn);
-#endif
-
- winDestroyIcon(hiconClass);
- winDestroyIcon(hiconSmClass);
- }
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMDestroyFrame - done\n");
-#endif
-}
-
-void
-winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int iNewX, int iNewY)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- RECT rcNew;
- DWORD dwExStyle;
- DWORD dwStyle;
- int iX, iY, iWidth, iHeight;
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMMoveFrame (%08x) (%d %d)\n", (int) pRLWinPriv, iNewX, iNewY);
-#endif
-
- /* Get the Windows window style and extended style */
- dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE);
- dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE);
-
- /* Get the X and Y location of the X window */
- iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN);
- iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN);
-
- /* Get the height and width of the X window */
- iWidth = pRLWinPriv->pFrame->width;
- iHeight = pRLWinPriv->pFrame->height;
-
- /* Store the origin, height, and width in a rectangle structure */
- SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
-
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tWindow {%d, %d, %d, %d}, {%d, %d}\n",
- rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
-#endif
- /*
- * Calculate the required size of the Windows window rectangle,
- * given the size of the Windows window client area.
- */
- AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle);
-
-#ifdef CYGMULTIWINDOW_DEBUG
- winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n",
- rcNew.left, rcNew.top, rcNew.right, rcNew.bottom,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
-#endif
- g_fNoConfigureWindow = TRUE;
- SetWindowPos (pRLWinPriv->hWnd, NULL, rcNew.left, rcNew.top, 0, 0,
- SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
- g_fNoConfigureWindow = FALSE;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMMoveFrame (%08x) done\n", (int) pRLWinPriv);
-#endif
-}
-
-void
-winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen,
- int iNewX, int iNewY,
- unsigned int uiNewWidth, unsigned int uiNewHeight,
- unsigned int uiGravity)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- RECT rcNew;
- RECT rcOld;
- DWORD dwExStyle;
- DWORD dwStyle;
- int iX, iY;
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMResizeFrame (%08x) (%d %d)-(%d %d)\n",
- (int) pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight);
-#endif
-
- pRLWinPriv->fResized = TRUE;
-
- /* Get the Windows window style and extended style */
- dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE);
- dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE);
-
- /* Get the X and Y location of the X window */
- iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN);
- iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN);
-
- /* Store the origin, height, and width in a rectangle structure */
- SetRect (&rcNew, iX, iY, iX + uiNewWidth, iY + uiNewHeight);
-
- /*
- * Calculate the required size of the Windows window rectangle,
- * given the size of the Windows window client area.
- */
- AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle);
-
- /* Get a rectangle describing the old Windows window */
- GetWindowRect (pRLWinPriv->hWnd, &rcOld);
-
- /* Check if the old rectangle and new rectangle are the same */
- if (!EqualRect (&rcNew, &rcOld))
- {
-
- g_fNoConfigureWindow = TRUE;
- MoveWindow (pRLWinPriv->hWnd,
- rcNew.left, rcNew.top,
- rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
- TRUE);
- g_fNoConfigureWindow = FALSE;
- }
-}
-
-void
-winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- win32RootlessWindowPtr pRLNextWinPriv = (win32RootlessWindowPtr) nextWid;
- winScreenPriv(pRLWinPriv->pFrame->win->drawable.pScreen);
- winScreenInfo *pScreenInfo = NULL;
- DWORD dwCurrentProcessID = GetCurrentProcessId ();
- DWORD dwWindowProcessID = 0;
- HWND hWnd;
- Bool fFirst = TRUE;
- Bool fNeedRestack = TRUE;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMRestackFrame (%08x)\n", (int) pRLWinPriv);
-#endif
-
- if (pScreenPriv->fRestacking) return;
-
- if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
-
- pRLWinPriv->fRestackingNow = TRUE;
-
- /* Show window */
- if(!IsWindowVisible (pRLWinPriv->hWnd))
- ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE);
-
- if (pRLNextWinPriv == NULL)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("Win %08x is top\n", pRLWinPriv);
-#endif
- pScreenPriv->widTop = wid;
- SetWindowPos (pRLWinPriv->hWnd, HWND_TOP,
- 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
- }
- else if (winIsInternalWMRunning(pScreenInfo))
- {
- /* using mulwinidow wm */
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("Win %08x is not top\n", pRLWinPriv);
-#endif
- for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDPREV);
- fNeedRestack && hWnd != NULL;
- hWnd = GetNextWindow (hWnd, GW_HWNDPREV))
- {
- GetWindowThreadProcessId (hWnd, &dwWindowProcessID);
-
- if ((dwWindowProcessID == dwCurrentProcessID)
- && GetProp (hWnd, WIN_WINDOW_PROP))
- {
- if (hWnd == pRLNextWinPriv->hWnd)
- {
- /* Enable interleave X window and Windows window */
- if (!fFirst)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("raise: Insert after Win %08x\n", pRLNextWinPriv);
-#endif
- SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
- 0, 0, 0, 0,
- SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
- }
- else
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("No change\n");
-#endif
- }
- fNeedRestack = FALSE;
- break;
- }
- if (fFirst) fFirst = FALSE;
- }
- }
-
- for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDNEXT);
- fNeedRestack && hWnd != NULL;
- hWnd = GetNextWindow (hWnd, GW_HWNDNEXT))
- {
- GetWindowThreadProcessId (hWnd, &dwWindowProcessID);
-
- if ((dwWindowProcessID == dwCurrentProcessID)
- && GetProp (hWnd, WIN_WINDOW_PROP))
- {
- if (hWnd == pRLNextWinPriv->hWnd)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("lower: Insert after Win %08x\n", pRLNextWinPriv);
-#endif
- SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
- 0, 0, 0, 0,
- SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
- fNeedRestack = FALSE;
- break;
- }
- }
- }
- }
- else
- {
- /* using general wm like twm, wmaker etc.
- Interleave X window and Windows window will cause problem. */
- SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd,
- 0, 0, 0, 0,
- SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
-#if 0
-#endif
- }
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMRestackFrame - done (%08x)\n", (int) pRLWinPriv);
-#endif
-
- pRLWinPriv->fRestackingNow = FALSE;
-}
-
-void
-winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- HRGN hRgn, hRgnWindow, hRgnClient;
- RECT rcWindow, rcClient;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMReshapeFrame (%08x)\n", (int) pRLWinPriv);
-#endif
-
- hRgn = winMWExtWMCreateRgnFromRegion (pShape);
-
- /* Create region for non-client area */
- GetWindowRect (pRLWinPriv->hWnd, &rcWindow);
- GetClientRect (pRLWinPriv->hWnd, &rcClient);
- MapWindowPoints (pRLWinPriv->hWnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);
- OffsetRgn (hRgn, rcClient.left - rcWindow.left, rcClient.top - rcWindow.top);
- OffsetRect (&rcClient, -rcWindow.left, -rcWindow.top);
- OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
- hRgnWindow = CreateRectRgnIndirect (&rcWindow);
- hRgnClient = CreateRectRgnIndirect (&rcClient);
- CombineRgn (hRgnWindow, hRgnWindow, hRgnClient, RGN_DIFF);
- CombineRgn (hRgn, hRgnWindow, hRgn, RGN_OR);
-
-
- SetWindowRgn (pRLWinPriv->hWnd, hRgn, TRUE);
-
- DeleteObject (hRgnWindow);
- DeleteObject (hRgnClient);
-}
-
-void
-winMWExtWMUnmapFrame (RootlessFrameID wid)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMUnmapFrame (%08x)\n", (int) pRLWinPriv);
-#endif
-
- g_fNoConfigureWindow = TRUE;
- //ShowWindow (pRLWinPriv->hWnd, SW_MINIMIZE);
- ShowWindow (pRLWinPriv->hWnd, SW_HIDE);
- g_fNoConfigureWindow = FALSE;
-}
-
-/*
- * Fixme: Code sharing with winshadgdi.c and other engine support
- */
-void
-winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- winPrivScreenPtr pScreenPriv = NULL;
- winScreenInfo *pScreenInfo = NULL;
- ScreenPtr pScreen = NULL;
- DIBSECTION dibsection;
- Bool fReturn = TRUE;
- HDC hdcNew;
- HBITMAP hbmpNew;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMStartDrawing (%08x) %08x\n", (int) pRLWinPriv, pRLWinPriv->fDestroyed);
-#endif
-
- if (!pRLWinPriv->fDestroyed)
- {
- pScreen = pRLWinPriv->pFrame->win->drawable.pScreen;
- if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
- if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\tpScreenPriv %08X\n", (int) pScreenPriv);
- winDebug ("\tpScreenInfo %08X\n", (int) pScreenInfo);
- winDebug ("\t(%d, %d)\n", (int)pRLWinPriv->pFrame->width,
- (int) pRLWinPriv->pFrame->height);
-#endif
- if (pRLWinPriv->hdcScreen == NULL)
- {
- InitWin32RootlessEngine (pRLWinPriv);
- }
-
- if (pRLWinPriv->fResized)
- {
- /* width * bpp must be multiple of 4 to match 32bit alignment */
- int stridesize;
- int misalignment;
-
- pRLWinPriv->pbmihShadow->biWidth = pRLWinPriv->pFrame->width;
- pRLWinPriv->pbmihShadow->biHeight = -pRLWinPriv->pFrame->height;
-
- stridesize = pRLWinPriv->pFrame->width * (pScreenInfo->dwBPP >> 3);
- misalignment = stridesize & 3;
- if (misalignment != 0)
- {
- stridesize += 4 - misalignment;
- pRLWinPriv->pbmihShadow->biWidth = stridesize / (pScreenInfo->dwBPP >> 3);
- winDebug("\tresizing to %d (was %d)\n",
- pRLWinPriv->pbmihShadow->biWidth, pRLWinPriv->pFrame->width);
- }
-
- hdcNew = CreateCompatibleDC (pRLWinPriv->hdcScreen);
- /* Create a DI shadow bitmap with a bit pointer */
- hbmpNew = CreateDIBSection (pRLWinPriv->hdcScreen,
- (BITMAPINFO *) pRLWinPriv->pbmihShadow,
- DIB_RGB_COLORS,
- (VOID**) &pRLWinPriv->pfb,
- NULL,
- 0);
- if (hbmpNew == NULL || pRLWinPriv->pfb == NULL)
- {
- ErrorF ("winMWExtWMStartDrawing - CreateDIBSection failed\n");
- //return FALSE;
- }
- else
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMStartDrawing - Shadow buffer allocated\n");
-#endif
- }
-
- /* Get information about the bitmap that was allocated */
- GetObject (hbmpNew, sizeof (dibsection), &dibsection);
-
-#if CYGMULTIWINDOW_DEBUG
- /* Print information about bitmap allocated */
- winDebug ("winMWExtWMStartDrawing - Dibsection width: %d height: %d "
- "depth: %d size image: %d\n",
- (unsigned int)dibsection.dsBmih.biWidth,
- (unsigned int)dibsection.dsBmih.biHeight,
- (unsigned int)dibsection.dsBmih.biBitCount,
- (unsigned int)dibsection.dsBmih.biSizeImage);
-#endif
-
- /* Select the shadow bitmap into the shadow DC */
- SelectObject (hdcNew, hbmpNew);
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMStartDrawing - Attempting a shadow blit\n");
-#endif
-
- /* Blit from the old shadow to the new shadow */
- fReturn = BitBlt (hdcNew,
- 0, 0,
- pRLWinPriv->pFrame->width, pRLWinPriv->pFrame->height,
- pRLWinPriv->hdcShadow,
- 0, 0,
- SRCCOPY);
- if (fReturn)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMStartDrawing - Shadow blit success\n");
-#endif
- }
- else
- {
- ErrorF ("winMWExtWMStartDrawing - Shadow blit failure\n");
- }
-
- /* Look for height weirdness */
- if (dibsection.dsBmih.biHeight < 0)
- {
- /* FIXME: Figure out why biHeight is sometimes negative */
- ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - "
- "biHeight still negative: %d\n",
- (int) dibsection.dsBmih.biHeight);
- ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - "
- "Flipping biHeight sign\n");
- dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight;
- }
-
- pRLWinPriv->dwWidthBytes = dibsection.dsBm.bmWidthBytes;
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMStartDrawing - bytesPerRow: %d\n",
- (unsigned int)dibsection.dsBm.bmWidthBytes);
-#endif
-
- /* Free the old shadow bitmap */
- DeleteObject (pRLWinPriv->hdcShadow);
- DeleteObject (pRLWinPriv->hbmpShadow);
-
- pRLWinPriv->hdcShadow = hdcNew;
- pRLWinPriv->hbmpShadow = hbmpNew;
-
- pRLWinPriv->fResized = FALSE;
-#if CYGMULTIWINDOW_DEBUG && FALSE
- winDebug ("winMWExtWMStartDrawing - 0x%08x %d\n",
- (unsigned int)pRLWinPriv->pfb,
- (unsigned int)dibsection.dsBm.bmWidthBytes);
-#endif
- }
- }
- else
- {
- ErrorF ("winMWExtWMStartDrawing - Already window was destroyed \n");
- }
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMStartDrawing - done (0x%08x) 0x%08x %d\n",
- (int) pRLWinPriv,
- (unsigned int)pRLWinPriv->pfb, (unsigned int)pRLWinPriv->dwWidthBytes);
-#endif
- *pixelData = pRLWinPriv->pfb;
- *bytesPerRow = pRLWinPriv->dwWidthBytes;
-}
-
-void
-winMWExtWMStopDrawing (RootlessFrameID wid, Bool fFlush)
-{
-#if 0
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- BLENDFUNCTION bfBlend;
- SIZE szWin;
- POINT ptSrc;
-#if CYGMULTIWINDOW_DEBUG || TRUE
- winDebug ("winMWExtWMStopDrawing (%08x)\n", pRLWinPriv);
-#endif
- szWin.cx = pRLWinPriv->dwWidth;
- szWin.cy = pRLWinPriv->dwHeight;
- ptSrc.x = 0;
- ptSrc.y = 0;
- bfBlend.BlendOp = AC_SRC_OVER;
- bfBlend.BlendFlags = 0;
- bfBlend.SourceConstantAlpha = 255;
- bfBlend.AlphaFormat = AC_SRC_ALPHA;
-
- if (!UpdateLayeredWindow (pRLWinPriv->hWnd,
- NULL, NULL, &szWin,
- pRLWinPriv->hdcShadow, &ptSrc,
- 0, &bfBlend, ULW_ALPHA))
- {
- ErrorF ("winMWExtWMStopDrawing - UpdateLayeredWindow failed\n");
- }
-#endif
-}
-
-void
-winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
-#if 0
- BLENDFUNCTION bfBlend;
- SIZE szWin;
- POINT ptSrc;
-#endif
-#if CYGMULTIWINDOW_DEBUG && 0
- winDebug ("winMWExtWMUpdateRegion (%08x)\n", pRLWinPriv);
-#endif
-#if 0
- szWin.cx = pRLWinPriv->dwWidth;
- szWin.cy = pRLWinPriv->dwHeight;
- ptSrc.x = 0;
- ptSrc.y = 0;
- bfBlend.BlendOp = AC_SRC_OVER;
- bfBlend.BlendFlags = 0;
- bfBlend.SourceConstantAlpha = 255;
- bfBlend.AlphaFormat = AC_SRC_ALPHA;
-
- if (!UpdateLayeredWindow (pRLWinPriv->hWnd,
- NULL, NULL, &szWin,
- pRLWinPriv->hdcShadow, &ptSrc,
- 0, &bfBlend, ULW_ALPHA))
- {
- LPVOID lpMsgBuf;
-
- /* Display a fancy error message */
- FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError (),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf,
- 0, NULL);
-
- ErrorF ("winMWExtWMUpdateRegion - UpdateLayeredWindow failed: %s\n",
- (LPSTR)lpMsgBuf);
- LocalFree (lpMsgBuf);
- }
-#endif
- if (!g_fNoConfigureWindow) UpdateWindow (pRLWinPriv->hWnd);
-}
-
-void
-winMWExtWMDamageRects (RootlessFrameID wid, int nCount, const BoxRec *pRects,
- int shift_x, int shift_y)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- const BoxRec *pEnd;
-#if CYGMULTIWINDOW_DEBUG && 0
- winDebug ("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n",
- pRLWinPriv, nCount, pRects, shift_x, shift_y);
-#endif
-
- for (pEnd = pRects + nCount; pRects < pEnd; pRects++) {
- RECT rcDmg;
- rcDmg.left = pRects->x1 + shift_x;
- rcDmg.top = pRects->y1 + shift_y;
- rcDmg.right = pRects->x2 + shift_x;
- rcDmg.bottom = pRects->y2 + shift_y;
-
- InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE);
- }
-}
-
-void
-winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMRootlessSwitchWindow (%08x) %08x\n",
- (int) pRLWinPriv, (int) pRLWinPriv->hWnd);
-#endif
- pRLWinPriv->pFrame = pFrame;
- pRLWinPriv->fResized = TRUE;
-
- /* Set the window extended style flags */
- SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
-
- /* Set the window standard style flags */
- SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE,
- WS_POPUP | WS_CLIPCHILDREN);
-
- DeleteProperty (serverClient, oldWin, AtmWindowsWmNativeHwnd ());
- winMWExtWMSetNativeProperty (pFrame);
-#if CYGMULTIWINDOW_DEBUG
-#if 0
- {
- WindowPtr pWin2 = NULL;
- win32RootlessWindowPtr pRLWinPriv2 = NULL;
-
- /* Check if the Windows window property for our X window pointer is valid */
- if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL)
- {
- pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE);
- }
- winDebug ("winMWExtWMSwitchFrame2 (%08x) %08x\n",
- pRLWinPriv2, pRLWinPriv2->hWnd);
- if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd)
- {
- winDebug ("Error param missmatch\n");
- }
- }
-#endif
-#endif
-}
-
-void
-winMWExtWMCopyBytes (unsigned int width, unsigned int height,
- const void *src, unsigned int srcRowBytes,
- void *dst, unsigned int dstRowBytes)
-{
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMCopyBytes - Not implemented\n");
-#endif
-}
-
-void
-winMWExtWMCopyWindow (RootlessFrameID wid, int nDstRects, const BoxRec *pDstRects,
- int nDx, int nDy)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid;
- const BoxRec *pEnd;
- RECT rcDmg;
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMCopyWindow (%08x, %d, %08x, %d, %d)\n",
- (int) pRLWinPriv, nDstRects, (int) pDstRects, nDx, nDy);
-#endif
-
- for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("BitBlt (%d, %d, %d, %d) (%d, %d)\n",
- pDstRects->x1, pDstRects->y1,
- pDstRects->x2 - pDstRects->x1,
- pDstRects->y2 - pDstRects->y1,
- pDstRects->x1 + nDx,
- pDstRects->y1 + nDy);
-#endif
-
- if (!BitBlt (pRLWinPriv->hdcShadow,
- pDstRects->x1, pDstRects->y1,
- pDstRects->x2 - pDstRects->x1,
- pDstRects->y2 - pDstRects->y1,
- pRLWinPriv->hdcShadow,
- pDstRects->x1 + nDx, pDstRects->y1 + nDy,
- SRCCOPY))
- {
- ErrorF ("winMWExtWMCopyWindow - BitBlt failed.\n");
- }
-
- rcDmg.left = pDstRects->x1;
- rcDmg.top = pDstRects->y1;
- rcDmg.right = pDstRects->x2;
- rcDmg.bottom = pDstRects->y2;
-
- InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE);
- }
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMCopyWindow - done\n");
-#endif
-}
-
-
-/*
- * winMWExtWMSetNativeProperty
- */
-
-static void
-winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame)
-{
- win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid;
- long lData;
-
- /* FIXME: move this to WindowsWM extension */
-
- lData = (long) pRLWinPriv->hWnd;
- dixChangeWindowProperty(serverClient, pFrame->win, AtmWindowsWmNativeHwnd(),
- XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE);
-}
+/* + *Copyright (C) 1994-2000 The XFree86 Project, 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 XFREE86 PROJECT 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 of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: Kensuke Matsuzaki + * Earle F. Philhower, III + * Harold L Hunt II + */ +/* + * Look at hw/darwin/quartz/xpr/xprFrame.c and hw/darwin/quartz/cr/crFrame.c + */ +#ifdef HAVE_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" +#include <winuser.h> +#define _WINDOWSWM_SERVER_ +#include <X11/extensions/windowswmstr.h> +#include "dixevents.h" +#include "winmultiwindowclass.h" +#include <X11/Xatom.h> + + +/* + * Constant defines + */ + +#ifndef ULW_COLORKEY +#define ULW_COLORKEY 0x00000001 +#endif +#ifndef ULW_ALPHA +#define ULW_ALPHA 0x00000002 +#endif +#ifndef ULW_OPAQUE +#define ULW_OPAQUE 0x00000004 +#endif +#define AC_SRC_ALPHA 0x01 + +/* + * Local function + */ + +DEFINE_ATOM_HELPER(AtmWindowsWmNativeHwnd, WINDOWSWM_NATIVE_HWND) +static void +winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame); + +/* + * Global variables + */ + +Bool g_fNoConfigureWindow = FALSE; + +/* + * Internal function to get the DIB format that is compatible with the screen + * Fixme: Share code with winshadgdi.c + */ + +static +Bool +winMWExtWMQueryDIBFormat (win32RootlessWindowPtr pRLWinPriv, BITMAPINFOHEADER *pbmih) +{ + HBITMAP hbmp; +#if CYGMULTIWINDOW_DEBUG + LPDWORD pdw = NULL; +#endif + + /* Create a memory bitmap compatible with the screen */ + hbmp = CreateCompatibleBitmap (pRLWinPriv->hdcScreen, 1, 1); + if (hbmp == NULL) + { + ErrorF ("winMWExtWMQueryDIBFormat - CreateCompatibleBitmap failed\n"); + return FALSE; + } + + /* Initialize our bitmap info header */ + ZeroMemory (pbmih, sizeof (BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD)); + pbmih->biSize = sizeof (BITMAPINFOHEADER); + + /* Get the biBitCount */ + if (!GetDIBits (pRLWinPriv->hdcScreen, + hbmp, + 0, 1, + NULL, + (BITMAPINFO*) pbmih, + DIB_RGB_COLORS)) + { + ErrorF ("winMWExtWMQueryDIBFormat - First call to GetDIBits failed\n"); + DeleteObject (hbmp); + return FALSE; + } + +#if CYGMULTIWINDOW_DEBUG + /* Get a pointer to bitfields */ + pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); + + winDebug ("winMWExtWMQueryDIBFormat - First call masks: %08x %08x %08x\n", + (unsigned int)pdw[0], (unsigned int)pdw[1], (unsigned int)pdw[2]); +#endif + + /* Get optimal color table, or the optimal bitfields */ + if (!GetDIBits (pRLWinPriv->hdcScreen, + hbmp, + 0, 1, + NULL, + (BITMAPINFO*)pbmih, + DIB_RGB_COLORS)) + { + ErrorF ("winMWExtWMQueryDIBFormat - Second call to GetDIBits " + "failed\n"); + DeleteObject (hbmp); + return FALSE; + } + + /* Free memory */ + DeleteObject (hbmp); + + return TRUE; +} + +static HRGN +winMWExtWMCreateRgnFromRegion (RegionPtr pShape) +{ + int nRects; + BoxPtr pRects, pEnd; + HRGN hRgn, hRgnRect; + + if (pShape == NULL) return NULL; + + nRects = RegionNumRects(pShape); + pRects = RegionRects(pShape); + + hRgn = CreateRectRgn (0, 0, 0, 0); + if (hRgn == NULL) + { + ErrorF ("winReshape - Initial CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n", + 0, 0, 0, 0, (int) GetLastError ()); + } + + /* Loop through all rectangles in the X region */ + for (pEnd = pRects + nRects; pRects < pEnd; pRects++) + { + /* Create a Windows region for the X rectangle */ + hRgnRect = CreateRectRgn (pRects->x1, + pRects->y1, + pRects->x2, + pRects->y2); + if (hRgnRect == NULL) + { + ErrorF ("winReshape - Loop CreateRectRgn (%d, %d, %d, %d) " + "failed: %d\n", + pRects->x1, + pRects->y1, + pRects->x2, + pRects->y2, + (int) GetLastError ()); + } + + /* Merge the Windows region with the accumulated region */ + if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR) + { + ErrorF ("winReshape - CombineRgn () failed: %d\n", + (int) GetLastError ()); + } + + /* Delete the temporary Windows region */ + DeleteObject (hRgnRect); + } + + return hRgn; +} + +static void +InitWin32RootlessEngine (win32RootlessWindowPtr pRLWinPriv) +{ + pRLWinPriv->hdcScreen = GetDC (pRLWinPriv->hWnd); + pRLWinPriv->hdcShadow = CreateCompatibleDC (pRLWinPriv->hdcScreen); + pRLWinPriv->hbmpShadow = NULL; + + /* Allocate bitmap info header */ + pRLWinPriv->pbmihShadow = (BITMAPINFOHEADER*) malloc (sizeof (BITMAPINFOHEADER) + + 256 * sizeof (RGBQUAD)); + if (pRLWinPriv->pbmihShadow == NULL) + { + ErrorF ("InitWin32RootlessEngine - malloc () failed\n"); + return; + } + + /* Query the screen format */ + winMWExtWMQueryDIBFormat (pRLWinPriv, + pRLWinPriv->pbmihShadow); +} + +Bool +winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen, + int newX, int newY, RegionPtr pShape) +{ +#define CLASS_NAME_LENGTH 512 + Bool fResult = TRUE; + win32RootlessWindowPtr pRLWinPriv; + WNDCLASSEX wc; + char pszClass[CLASS_NAME_LENGTH], pszWindowID[12]; + HICON hIcon; + HICON hIconSmall; + char *res_name, *res_class, *res_role; + static int s_iWindowID = 0; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCreateFrame %d %d - %d %d\n", + newX, newY, pFrame->width, pFrame->height); +#endif + + pRLWinPriv = (win32RootlessWindowPtr) malloc (sizeof (win32RootlessWindowRec)); + pRLWinPriv->pFrame = pFrame; + pRLWinPriv->pfb = NULL; + pRLWinPriv->hbmpShadow = NULL; + pRLWinPriv->hdcShadow = NULL; + pRLWinPriv->hdcScreen = NULL; + pRLWinPriv->pbmihShadow = NULL; + pRLWinPriv->fResized = TRUE; + pRLWinPriv->fClose = FALSE; + pRLWinPriv->fRestackingNow = FALSE; + pRLWinPriv->fDestroyed = FALSE; + pRLWinPriv->fMovingOrSizing = FALSE; + + // Store the implementation private frame ID + pFrame->wid = (RootlessFrameID) pRLWinPriv; + + winSelectIcons(pFrame->win, &hIcon, &hIconSmall); + + /* Set standard class name prefix so we can identify window easily */ + strncpy (pszClass, WINDOW_CLASS_X, sizeof(pszClass)); + + if (winMultiWindowGetClassHint (pFrame->win, &res_name, &res_class)) + { + strncat (pszClass, "-", 1); + strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass)); + strncat (pszClass, "-", 1); + strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass)); + + /* Check if a window class is provided by the WM_WINDOW_ROLE property, + * if not use the WM_CLASS information. + * For further information see: + * http://tronche.com/gui/x/icccm/sec-5.html + */ + if (winMultiWindowGetWindowRole (pFrame->win, &res_role) ) + { + strcat (pszClass, "-"); + strcat (pszClass, res_role); + free (res_role); + } + + free (res_name); + free (res_class); + } + + /* Add incrementing window ID to make unique class name */ + snprintf (pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++); + pszWindowID[sizeof(pszWindowID)-1] = 0; + strcat (pszClass, pszWindowID); + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winCreateWindowsWindow - Creating class: %s\n", pszClass); +#endif + + /* Setup our window class */ + wc.cbSize = sizeof(wc); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = winMWExtWMWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_hInstance; + wc.hIcon = hIcon; + wc.hIconSm = hIconSmall; + wc.hCursor = 0; + wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = pszClass; + RegisterClassEx (&wc); + + /* Create the window */ + g_fNoConfigureWindow = TRUE; + pRLWinPriv->hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ + pszClass, /* Class name */ + WINDOW_TITLE_X, /* Window name */ + WS_POPUP | WS_CLIPCHILDREN, + newX, /* Horizontal position */ + newY, /* Vertical position */ + pFrame->width, /* Right edge */ + pFrame->height, /* Bottom edge */ + (HWND) NULL, /* No parent or owner window */ + (HMENU) NULL, /* No menu */ + GetModuleHandle (NULL), /* Instance handle */ + pRLWinPriv); /* ScreenPrivates */ + if (pRLWinPriv->hWnd == NULL) + { + ErrorF ("winMWExtWMCreateFrame - CreateWindowExA () failed: %d\n", + (int) GetLastError ()); + fResult = FALSE; + } + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCreateFrame - ShowWindow\n"); +#endif + + //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE); + g_fNoConfigureWindow = FALSE; + + if (pShape != NULL) + { + winMWExtWMReshapeFrame (pFrame->wid, pShape); + } + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCreateFrame - (%08x) %08x\n", + (int) pFrame->wid, (int) pRLWinPriv->hWnd); +#if 0 + { + WindowPtr pWin2 = NULL; + win32RootlessWindowPtr pRLWinPriv2 = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) + { + pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); + } + winDebug ("winMWExtWMCreateFrame2 (%08x) %08x\n", + pRLWinPriv2, pRLWinPriv2->hWnd); + if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) + { + winDebug ("Error param missmatch\n"); + } + } +#endif +#endif + + winMWExtWMSetNativeProperty (pFrame); + + return fResult; +} + +void +winMWExtWMDestroyFrame (RootlessFrameID wid) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + HICON hIcon; + HICON hIconSm; + HMODULE hInstance; + int iReturn; + char pszClass[CLASS_NAME_LENGTH]; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMDestroyFrame (%08x) %08x\n", + (int) pRLWinPriv, (int) pRLWinPriv->hWnd); +#if 0 + { + WindowPtr pWin2 = NULL; + win32RootlessWindowPtr pRLWinPriv2 = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) + { + pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); + } + winDebug ("winMWExtWMDestroyFrame2 (%08x) %08x\n", + pRLWinPriv2, pRLWinPriv2->hWnd); + if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) + { + winDebug ("Error param missmatch\n"); + *(int*)0 = 1;//raise exseption + } + } +#endif +#endif + + /* Store the info we need to destroy after this window is gone */ + hInstance = (HINSTANCE) GetClassLongPtr (pRLWinPriv->hWnd, GCLP_HMODULE); + hIcon = (HICON)SendMessage(pRLWinPriv->hWnd, WM_GETICON, ICON_BIG, 0); + hIconSm = (HICON)SendMessage(pRLWinPriv->hWnd, WM_GETICON, ICON_SMALL, 0); + iReturn = GetClassName (pRLWinPriv->hWnd, pszClass, CLASS_NAME_LENGTH); + + pRLWinPriv->fClose = TRUE; + pRLWinPriv->fDestroyed = TRUE; + + /* Destroy the Windows window */ + DestroyWindow (pRLWinPriv->hWnd); + + /* Only if we were able to get the name */ + if (iReturn) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMDestroyFrame - Unregistering %s: ", pszClass); +#endif + iReturn = UnregisterClass (pszClass, hInstance); + } + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMDestroyFramew - Deleting Icon\n"); +#endif + + winDestroyIcon(hIcon); + winDestroyIcon(hIconSm); + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMDestroyFrame - done\n"); +#endif +} + +void +winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int iNewX, int iNewY) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + RECT rcNew; + DWORD dwExStyle; + DWORD dwStyle; + int iX, iY, iWidth, iHeight; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMMoveFrame (%08x) (%d %d)\n", (int) pRLWinPriv, iNewX, iNewY); +#endif + + /* Get the Windows window style and extended style */ + dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); + + /* Get the X and Y location of the X window */ + iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Get the height and width of the X window */ + iWidth = pRLWinPriv->pFrame->width; + iHeight = pRLWinPriv->pFrame->height; + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); + +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tWindow {%d, %d, %d, %d}, {%d, %d}\n", + rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); + +#ifdef CYGMULTIWINDOW_DEBUG + winDebug("\tAdjusted {%d, %d, %d, %d}, {%d, %d}\n", + rcNew.left, rcNew.top, rcNew.right, rcNew.bottom, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); +#endif + g_fNoConfigureWindow = TRUE; + SetWindowPos (pRLWinPriv->hWnd, NULL, rcNew.left, rcNew.top, 0, 0, + SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); + g_fNoConfigureWindow = FALSE; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMMoveFrame (%08x) done\n", (int) pRLWinPriv); +#endif +} + +void +winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen, + int iNewX, int iNewY, + unsigned int uiNewWidth, unsigned int uiNewHeight, + unsigned int uiGravity) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + RECT rcNew; + RECT rcOld; + DWORD dwExStyle; + DWORD dwStyle; + int iX, iY; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMResizeFrame (%08x) (%d %d)-(%d %d)\n", + (int) pRLWinPriv, iNewX, iNewY, uiNewWidth, uiNewHeight); +#endif + + pRLWinPriv->fResized = TRUE; + + /* Get the Windows window style and extended style */ + dwExStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE); + dwStyle = GetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE); + + /* Get the X and Y location of the X window */ + iX = iNewX + GetSystemMetrics (SM_XVIRTUALSCREEN); + iY = iNewY + GetSystemMetrics (SM_YVIRTUALSCREEN); + + /* Store the origin, height, and width in a rectangle structure */ + SetRect (&rcNew, iX, iY, iX + uiNewWidth, iY + uiNewHeight); + + /* + * Calculate the required size of the Windows window rectangle, + * given the size of the Windows window client area. + */ + AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); + + /* Get a rectangle describing the old Windows window */ + GetWindowRect (pRLWinPriv->hWnd, &rcOld); + + /* Check if the old rectangle and new rectangle are the same */ + if (!EqualRect (&rcNew, &rcOld)) + { + + g_fNoConfigureWindow = TRUE; + MoveWindow (pRLWinPriv->hWnd, + rcNew.left, rcNew.top, + rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, + TRUE); + g_fNoConfigureWindow = FALSE; + } +} + +void +winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + win32RootlessWindowPtr pRLNextWinPriv = (win32RootlessWindowPtr) nextWid; + winScreenPriv(pRLWinPriv->pFrame->win->drawable.pScreen); + winScreenInfo *pScreenInfo = NULL; + DWORD dwCurrentProcessID = GetCurrentProcessId (); + DWORD dwWindowProcessID = 0; + HWND hWnd; + Bool fFirst = TRUE; + Bool fNeedRestack = TRUE; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRestackFrame (%08x)\n", (int) pRLWinPriv); +#endif + + if (pScreenPriv->fRestacking) return; + + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + + pRLWinPriv->fRestackingNow = TRUE; + + /* Show window */ + if(!IsWindowVisible (pRLWinPriv->hWnd)) + ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE); + + if (pRLNextWinPriv == NULL) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("Win %08x is top\n", pRLWinPriv); +#endif + pScreenPriv->widTop = wid; + SetWindowPos (pRLWinPriv->hWnd, HWND_TOP, + 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + } + else if (winIsInternalWMRunning(pScreenInfo)) + { + /* using mulwinidow wm */ +#if CYGMULTIWINDOW_DEBUG + winDebug ("Win %08x is not top\n", pRLWinPriv); +#endif + for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDPREV); + fNeedRestack && hWnd != NULL; + hWnd = GetNextWindow (hWnd, GW_HWNDPREV)) + { + GetWindowThreadProcessId (hWnd, &dwWindowProcessID); + + if ((dwWindowProcessID == dwCurrentProcessID) + && GetProp (hWnd, WIN_WINDOW_PROP)) + { + if (hWnd == pRLNextWinPriv->hWnd) + { + /* Enable interleave X window and Windows window */ + if (!fFirst) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("raise: Insert after Win %08x\n", pRLNextWinPriv); +#endif + SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, + 0, 0, 0, 0, + SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + } + else + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("No change\n"); +#endif + } + fNeedRestack = FALSE; + break; + } + if (fFirst) fFirst = FALSE; + } + } + + for (hWnd = GetNextWindow (pRLWinPriv->hWnd, GW_HWNDNEXT); + fNeedRestack && hWnd != NULL; + hWnd = GetNextWindow (hWnd, GW_HWNDNEXT)) + { + GetWindowThreadProcessId (hWnd, &dwWindowProcessID); + + if ((dwWindowProcessID == dwCurrentProcessID) + && GetProp (hWnd, WIN_WINDOW_PROP)) + { + if (hWnd == pRLNextWinPriv->hWnd) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("lower: Insert after Win %08x\n", pRLNextWinPriv); +#endif + SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, + 0, 0, 0, 0, + SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + fNeedRestack = FALSE; + break; + } + } + } + } + else + { + /* using general wm like twm, wmaker etc. + Interleave X window and Windows window will cause problem. */ + SetWindowPos (pRLWinPriv->hWnd, pRLNextWinPriv->hWnd, + 0, 0, 0, 0, + SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); +#if 0 +#endif + } +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRestackFrame - done (%08x)\n", (int) pRLWinPriv); +#endif + + pRLWinPriv->fRestackingNow = FALSE; +} + +void +winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + HRGN hRgn, hRgnWindow, hRgnClient; + RECT rcWindow, rcClient; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMReshapeFrame (%08x)\n", (int) pRLWinPriv); +#endif + + hRgn = winMWExtWMCreateRgnFromRegion (pShape); + + /* Create region for non-client area */ + GetWindowRect (pRLWinPriv->hWnd, &rcWindow); + GetClientRect (pRLWinPriv->hWnd, &rcClient); + MapWindowPoints (pRLWinPriv->hWnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2); + OffsetRgn (hRgn, rcClient.left - rcWindow.left, rcClient.top - rcWindow.top); + OffsetRect (&rcClient, -rcWindow.left, -rcWindow.top); + OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top); + hRgnWindow = CreateRectRgnIndirect (&rcWindow); + hRgnClient = CreateRectRgnIndirect (&rcClient); + CombineRgn (hRgnWindow, hRgnWindow, hRgnClient, RGN_DIFF); + CombineRgn (hRgn, hRgnWindow, hRgn, RGN_OR); + + + SetWindowRgn (pRLWinPriv->hWnd, hRgn, TRUE); + + DeleteObject (hRgnWindow); + DeleteObject (hRgnClient); +} + +void +winMWExtWMUnmapFrame (RootlessFrameID wid) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMUnmapFrame (%08x)\n", (int) pRLWinPriv); +#endif + + g_fNoConfigureWindow = TRUE; + //ShowWindow (pRLWinPriv->hWnd, SW_MINIMIZE); + ShowWindow (pRLWinPriv->hWnd, SW_HIDE); + g_fNoConfigureWindow = FALSE; +} + +/* + * Fixme: Code sharing with winshadgdi.c and other engine support + */ +void +winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + winPrivScreenPtr pScreenPriv = NULL; + winScreenInfo *pScreenInfo = NULL; + ScreenPtr pScreen = NULL; + DIBSECTION dibsection; + Bool fReturn = TRUE; + HDC hdcNew; + HBITMAP hbmpNew; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing (%08x) %08x\n", (int) pRLWinPriv, pRLWinPriv->fDestroyed); +#endif + + if (!pRLWinPriv->fDestroyed) + { + pScreen = pRLWinPriv->pFrame->win->drawable.pScreen; + if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); + if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("\tpScreenPriv %08X\n", (int) pScreenPriv); + winDebug ("\tpScreenInfo %08X\n", (int) pScreenInfo); + winDebug ("\t(%d, %d)\n", (int)pRLWinPriv->pFrame->width, + (int) pRLWinPriv->pFrame->height); +#endif + if (pRLWinPriv->hdcScreen == NULL) + { + InitWin32RootlessEngine (pRLWinPriv); + } + + if (pRLWinPriv->fResized) + { + /* width * bpp must be multiple of 4 to match 32bit alignment */ + int stridesize; + int misalignment; + + pRLWinPriv->pbmihShadow->biWidth = pRLWinPriv->pFrame->width; + pRLWinPriv->pbmihShadow->biHeight = -pRLWinPriv->pFrame->height; + + stridesize = pRLWinPriv->pFrame->width * (pScreenInfo->dwBPP >> 3); + misalignment = stridesize & 3; + if (misalignment != 0) + { + stridesize += 4 - misalignment; + pRLWinPriv->pbmihShadow->biWidth = stridesize / (pScreenInfo->dwBPP >> 3); + winDebug("\tresizing to %d (was %d)\n", + pRLWinPriv->pbmihShadow->biWidth, pRLWinPriv->pFrame->width); + } + + hdcNew = CreateCompatibleDC (pRLWinPriv->hdcScreen); + /* Create a DI shadow bitmap with a bit pointer */ + hbmpNew = CreateDIBSection (pRLWinPriv->hdcScreen, + (BITMAPINFO *) pRLWinPriv->pbmihShadow, + DIB_RGB_COLORS, + (VOID**) &pRLWinPriv->pfb, + NULL, + 0); + if (hbmpNew == NULL || pRLWinPriv->pfb == NULL) + { + ErrorF ("winMWExtWMStartDrawing - CreateDIBSection failed\n"); + //return FALSE; + } + else + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - Shadow buffer allocated\n"); +#endif + } + + /* Get information about the bitmap that was allocated */ + GetObject (hbmpNew, sizeof (dibsection), &dibsection); + +#if CYGMULTIWINDOW_DEBUG + /* Print information about bitmap allocated */ + winDebug ("winMWExtWMStartDrawing - Dibsection width: %d height: %d " + "depth: %d size image: %d\n", + (unsigned int)dibsection.dsBmih.biWidth, + (unsigned int)dibsection.dsBmih.biHeight, + (unsigned int)dibsection.dsBmih.biBitCount, + (unsigned int)dibsection.dsBmih.biSizeImage); +#endif + + /* Select the shadow bitmap into the shadow DC */ + SelectObject (hdcNew, hbmpNew); + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - Attempting a shadow blit\n"); +#endif + + /* Blit from the old shadow to the new shadow */ + fReturn = BitBlt (hdcNew, + 0, 0, + pRLWinPriv->pFrame->width, pRLWinPriv->pFrame->height, + pRLWinPriv->hdcShadow, + 0, 0, + SRCCOPY); + if (fReturn) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - Shadow blit success\n"); +#endif + } + else + { + ErrorF ("winMWExtWMStartDrawing - Shadow blit failure\n"); + } + + /* Look for height weirdness */ + if (dibsection.dsBmih.biHeight < 0) + { + /* FIXME: Figure out why biHeight is sometimes negative */ + ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - " + "biHeight still negative: %d\n", + (int) dibsection.dsBmih.biHeight); + ErrorF ("winMWExtWMStartDrawing - WEIRDNESS - " + "Flipping biHeight sign\n"); + dibsection.dsBmih.biHeight = -dibsection.dsBmih.biHeight; + } + + pRLWinPriv->dwWidthBytes = dibsection.dsBm.bmWidthBytes; + +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - bytesPerRow: %d\n", + (unsigned int)dibsection.dsBm.bmWidthBytes); +#endif + + /* Free the old shadow bitmap */ + DeleteObject (pRLWinPriv->hdcShadow); + DeleteObject (pRLWinPriv->hbmpShadow); + + pRLWinPriv->hdcShadow = hdcNew; + pRLWinPriv->hbmpShadow = hbmpNew; + + pRLWinPriv->fResized = FALSE; +#if CYGMULTIWINDOW_DEBUG && FALSE + winDebug ("winMWExtWMStartDrawing - 0x%08x %d\n", + (unsigned int)pRLWinPriv->pfb, + (unsigned int)dibsection.dsBm.bmWidthBytes); +#endif + } + } + else + { + ErrorF ("winMWExtWMStartDrawing - Already window was destroyed \n"); + } +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMStartDrawing - done (0x%08x) 0x%08x %d\n", + (int) pRLWinPriv, + (unsigned int)pRLWinPriv->pfb, (unsigned int)pRLWinPriv->dwWidthBytes); +#endif + *pixelData = pRLWinPriv->pfb; + *bytesPerRow = pRLWinPriv->dwWidthBytes; +} + +void +winMWExtWMStopDrawing (RootlessFrameID wid, Bool fFlush) +{ +#if 0 + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + BLENDFUNCTION bfBlend; + SIZE szWin; + POINT ptSrc; +#if CYGMULTIWINDOW_DEBUG || TRUE + winDebug ("winMWExtWMStopDrawing (%08x)\n", pRLWinPriv); +#endif + szWin.cx = pRLWinPriv->dwWidth; + szWin.cy = pRLWinPriv->dwHeight; + ptSrc.x = 0; + ptSrc.y = 0; + bfBlend.BlendOp = AC_SRC_OVER; + bfBlend.BlendFlags = 0; + bfBlend.SourceConstantAlpha = 255; + bfBlend.AlphaFormat = AC_SRC_ALPHA; + + if (!UpdateLayeredWindow (pRLWinPriv->hWnd, + NULL, NULL, &szWin, + pRLWinPriv->hdcShadow, &ptSrc, + 0, &bfBlend, ULW_ALPHA)) + { + ErrorF ("winMWExtWMStopDrawing - UpdateLayeredWindow failed\n"); + } +#endif +} + +void +winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; +#if 0 + BLENDFUNCTION bfBlend; + SIZE szWin; + POINT ptSrc; +#endif +#if CYGMULTIWINDOW_DEBUG && 0 + winDebug ("winMWExtWMUpdateRegion (%08x)\n", pRLWinPriv); +#endif +#if 0 + szWin.cx = pRLWinPriv->dwWidth; + szWin.cy = pRLWinPriv->dwHeight; + ptSrc.x = 0; + ptSrc.y = 0; + bfBlend.BlendOp = AC_SRC_OVER; + bfBlend.BlendFlags = 0; + bfBlend.SourceConstantAlpha = 255; + bfBlend.AlphaFormat = AC_SRC_ALPHA; + + if (!UpdateLayeredWindow (pRLWinPriv->hWnd, + NULL, NULL, &szWin, + pRLWinPriv->hdcShadow, &ptSrc, + 0, &bfBlend, ULW_ALPHA)) + { + LPVOID lpMsgBuf; + + /* Display a fancy error message */ + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError (), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, NULL); + + ErrorF ("winMWExtWMUpdateRegion - UpdateLayeredWindow failed: %s\n", + (LPSTR)lpMsgBuf); + LocalFree (lpMsgBuf); + } +#endif + if (!g_fNoConfigureWindow) UpdateWindow (pRLWinPriv->hWnd); +} + +void +winMWExtWMDamageRects (RootlessFrameID wid, int nCount, const BoxRec *pRects, + int shift_x, int shift_y) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + const BoxRec *pEnd; +#if CYGMULTIWINDOW_DEBUG && 0 + winDebug ("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n", + pRLWinPriv, nCount, pRects, shift_x, shift_y); +#endif + + for (pEnd = pRects + nCount; pRects < pEnd; pRects++) { + RECT rcDmg; + rcDmg.left = pRects->x1 + shift_x; + rcDmg.top = pRects->y1 + shift_y; + rcDmg.right = pRects->x2 + shift_x; + rcDmg.bottom = pRects->y2 + shift_y; + + InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE); + } +} + +void +winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMRootlessSwitchWindow (%08x) %08x\n", + (int) pRLWinPriv, (int) pRLWinPriv->hWnd); +#endif + pRLWinPriv->pFrame = pFrame; + pRLWinPriv->fResized = TRUE; + + /* Set the window extended style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); + + /* Set the window standard style flags */ + SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, + WS_POPUP | WS_CLIPCHILDREN); + + DeleteProperty (serverClient, oldWin, AtmWindowsWmNativeHwnd ()); + winMWExtWMSetNativeProperty (pFrame); +#if CYGMULTIWINDOW_DEBUG +#if 0 + { + WindowPtr pWin2 = NULL; + win32RootlessWindowPtr pRLWinPriv2 = NULL; + + /* Check if the Windows window property for our X window pointer is valid */ + if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) + { + pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); + } + winDebug ("winMWExtWMSwitchFrame2 (%08x) %08x\n", + pRLWinPriv2, pRLWinPriv2->hWnd); + if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) + { + winDebug ("Error param missmatch\n"); + } + } +#endif +#endif +} + +void +winMWExtWMCopyBytes (unsigned int width, unsigned int height, + const void *src, unsigned int srcRowBytes, + void *dst, unsigned int dstRowBytes) +{ +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCopyBytes - Not implemented\n"); +#endif +} + +void +winMWExtWMCopyWindow (RootlessFrameID wid, int nDstRects, const BoxRec *pDstRects, + int nDx, int nDy) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; + const BoxRec *pEnd; + RECT rcDmg; +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCopyWindow (%08x, %d, %08x, %d, %d)\n", + (int) pRLWinPriv, nDstRects, (int) pDstRects, nDx, nDy); +#endif + + for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++) + { +#if CYGMULTIWINDOW_DEBUG + winDebug ("BitBlt (%d, %d, %d, %d) (%d, %d)\n", + pDstRects->x1, pDstRects->y1, + pDstRects->x2 - pDstRects->x1, + pDstRects->y2 - pDstRects->y1, + pDstRects->x1 + nDx, + pDstRects->y1 + nDy); +#endif + + if (!BitBlt (pRLWinPriv->hdcShadow, + pDstRects->x1, pDstRects->y1, + pDstRects->x2 - pDstRects->x1, + pDstRects->y2 - pDstRects->y1, + pRLWinPriv->hdcShadow, + pDstRects->x1 + nDx, pDstRects->y1 + nDy, + SRCCOPY)) + { + ErrorF ("winMWExtWMCopyWindow - BitBlt failed.\n"); + } + + rcDmg.left = pDstRects->x1; + rcDmg.top = pDstRects->y1; + rcDmg.right = pDstRects->x2; + rcDmg.bottom = pDstRects->y2; + + InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE); + } +#if CYGMULTIWINDOW_DEBUG + winDebug ("winMWExtWMCopyWindow - done\n"); +#endif +} + + +/* + * winMWExtWMSetNativeProperty + */ + +static void +winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame) +{ + win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid; + long lData; + + /* FIXME: move this to WindowsWM extension */ + + lData = (long) pRLWinPriv->hWnd; + dixChangeWindowProperty(serverClient, pFrame->win, AtmWindowsWmNativeHwnd(), + XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE); +} |