aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen')
-rw-r--r--nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/Imakefile19
-rw-r--r--nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c569
-rw-r--r--nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/quartzCursor.c653
-rw-r--r--nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/quartzCursor.h44
4 files changed, 1285 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/Imakefile b/nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/Imakefile
new file mode 100644
index 000000000..59c295050
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/Imakefile
@@ -0,0 +1,19 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/darwin/quartz/cr/Imakefile,v 1.1 2003/06/07 05:49:07 torrey Exp $
+
+#include <Server.tmpl>
+
+SRCS = fullscreen.c \
+ quartzCursor.c
+
+OBJS = fullscreen.o \
+ quartzCursor.o
+
+INCLUDES = -I. -I$(SERVERSRC)/mi -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(FONTINCSRC) -I$(SERVERSRC)/render -I$(SERVERSRC)/miext/shadow \
+ -I$(EXTINCSRC) -I.. -I../..
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(fullscreen,$(OBJS))
+
+DependTarget()
+
diff --git a/nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c b/nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c
new file mode 100644
index 000000000..fc0744ca5
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c
@@ -0,0 +1,569 @@
+/*
+ * Screen routines for full screen Quartz mode
+ *
+ * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * TORREY T. LYONS 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.
+ */
+/* $XdotOrg: xc/programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c,v 1.4 2005/07/01 22:43:08 daniels Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/fullscreen/fullscreen.c,v 1.3 2003/11/27 01:59:53 torrey Exp $ */
+
+#include "quartzCommon.h"
+#include "darwin.h"
+#include "quartz.h"
+#include "quartzCursor.h"
+#include "colormapst.h"
+#include "scrnintstr.h"
+#include "micmap.h"
+#include "shadow.h"
+
+// Full screen specific per screen storage structure
+typedef struct {
+ CGDirectDisplayID displayID;
+ CFDictionaryRef xDisplayMode;
+ CFDictionaryRef aquaDisplayMode;
+ CGDirectPaletteRef xPalette;
+ CGDirectPaletteRef aquaPalette;
+ unsigned char *framebuffer;
+ unsigned char *shadowPtr;
+} FSScreenRec, *FSScreenPtr;
+
+#define FULLSCREEN_PRIV(pScreen) \
+ ((FSScreenPtr)pScreen->devPrivates[fsScreenIndex].ptr)
+
+static int fsScreenIndex;
+static CGDirectDisplayID *quartzDisplayList = NULL;
+static int quartzNumScreens = 0;
+static FSScreenPtr quartzScreens[MAXSCREENS];
+
+static int darwinCmapPrivateIndex = -1;
+static unsigned long darwinCmapGeneration = 0;
+
+#define CMAP_PRIV(pCmap) \
+ ((CGDirectPaletteRef) (pCmap)->devPrivates[darwinCmapPrivateIndex].ptr)
+
+/*
+ =============================================================================
+
+ Colormap handling
+
+ =============================================================================
+*/
+
+/*
+ * FSInitCmapPrivates
+ * Colormap privates may be allocated after the default colormap has
+ * already been created for some screens. This initialization procedure
+ * is called for each default colormap that is found.
+ */
+static Bool
+FSInitCmapPrivates(
+ ColormapPtr pCmap)
+{
+ return TRUE;
+}
+
+
+/*
+ * FSCreateColormap
+ * This is a callback from X after a new colormap is created.
+ * We allocate a new CoreGraphics pallete for each colormap.
+ */
+static Bool
+FSCreateColormap(
+ ColormapPtr pCmap)
+{
+ CGDirectPaletteRef pallete;
+
+ // Allocate private storage for the hardware dependent colormap info.
+ if (darwinCmapGeneration != serverGeneration) {
+ if ((darwinCmapPrivateIndex =
+ AllocateColormapPrivateIndex(FSInitCmapPrivates)) < 0)
+ {
+ return FALSE;
+ }
+ darwinCmapGeneration = serverGeneration;
+ }
+
+ pallete = CGPaletteCreateDefaultColorPalette();
+ if (!pallete) return FALSE;
+
+ CMAP_PRIV(pCmap) = pallete;
+ return TRUE;
+}
+
+
+/*
+ * FSDestroyColormap
+ * This is called by DIX FreeColormap after it has uninstalled a colormap
+ * and notified all interested parties. We deallocated the corresponding
+ * CoreGraphics pallete.
+ */
+static void
+FSDestroyColormap(
+ ColormapPtr pCmap)
+{
+ CGPaletteRelease( CMAP_PRIV(pCmap) );
+}
+
+
+/*
+ * FSInstallColormap
+ * Set the current CoreGraphics pallete to the pallete corresponding
+ * to the provided colormap.
+ */
+static void
+FSInstallColormap(
+ ColormapPtr pCmap)
+{
+ CGDirectPaletteRef palette = CMAP_PRIV(pCmap);
+ ScreenPtr pScreen = pCmap->pScreen;
+ FSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen);
+
+ // Inform all interested parties that the map is being changed.
+ miInstallColormap(pCmap);
+
+ if (quartzServerVisible)
+ CGDisplaySetPalette(fsDisplayInfo->displayID, palette);
+
+ fsDisplayInfo->xPalette = palette;
+}
+
+
+/*
+ * FSStoreColors
+ * This is a callback from X to change the hardware colormap
+ * when using PsuedoColor in full screen mode.
+ */
+static void
+FSStoreColors(
+ ColormapPtr pCmap,
+ int numEntries,
+ xColorItem *pdefs)
+{
+ CGDirectPaletteRef palette = CMAP_PRIV(pCmap);
+ ScreenPtr pScreen = pCmap->pScreen;
+ FSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen);
+ CGDeviceColor color;
+ int i;
+
+ if (! palette)
+ return;
+
+ for (i = 0; i < numEntries; i++) {
+ color.red = pdefs[i].red / 65535.0;
+ color.green = pdefs[i].green / 65535.0;
+ color.blue = pdefs[i].blue / 65535.0;
+ CGPaletteSetColorAtIndex(palette, color, pdefs[i].pixel);
+ }
+
+ // Update hardware colormap
+ if (quartzServerVisible)
+ CGDisplaySetPalette(fsDisplayInfo->displayID, palette);
+}
+
+
+/*
+ =============================================================================
+
+ Switching between Aqua and X
+
+ =============================================================================
+*/
+
+/*
+ * FSCapture
+ * Capture the screen so we can draw. Called directly from the main thread
+ * to synchronize with hiding the menubar.
+ */
+static void FSCapture(void)
+{
+ int i;
+
+ if (quartzRootless) return;
+
+ for (i = 0; i < quartzNumScreens; i++) {
+ FSScreenPtr fsDisplayInfo = quartzScreens[i];
+ CGDirectDisplayID cgID = fsDisplayInfo->displayID;
+
+ if (!CGDisplayIsCaptured(cgID)) {
+ CGDisplayCapture(cgID);
+ fsDisplayInfo->aquaDisplayMode = CGDisplayCurrentMode(cgID);
+ if (fsDisplayInfo->xDisplayMode != fsDisplayInfo->aquaDisplayMode)
+ CGDisplaySwitchToMode(cgID, fsDisplayInfo->xDisplayMode);
+ if (fsDisplayInfo->xPalette)
+ CGDisplaySetPalette(cgID, fsDisplayInfo->xPalette);
+ }
+ }
+}
+
+
+/*
+ * FSRelease
+ * Release the screen so others can draw.
+ */
+static void FSRelease(void)
+{
+ int i;
+
+ if (quartzRootless) return;
+
+ for (i = 0; i < quartzNumScreens; i++) {
+ FSScreenPtr fsDisplayInfo = quartzScreens[i];
+ CGDirectDisplayID cgID = fsDisplayInfo->displayID;
+
+ if (CGDisplayIsCaptured(cgID)) {
+ if (fsDisplayInfo->xDisplayMode != fsDisplayInfo->aquaDisplayMode)
+ CGDisplaySwitchToMode(cgID, fsDisplayInfo->aquaDisplayMode);
+ if (fsDisplayInfo->aquaPalette)
+ CGDisplaySetPalette(cgID, fsDisplayInfo->aquaPalette);
+ CGDisplayRelease(cgID);
+ }
+ }
+}
+
+
+/*
+ * FSSuspendScreen
+ * Suspend X11 cursor and drawing to the screen.
+ */
+static void FSSuspendScreen(
+ ScreenPtr pScreen)
+{
+ QuartzSuspendXCursor(pScreen);
+ xf86SetRootClip(pScreen, FALSE);
+}
+
+
+/*
+ * FSResumeScreen
+ * Resume X11 cursor and drawing to the screen.
+ */
+static void FSResumeScreen(
+ ScreenPtr pScreen,
+ int x, // cursor location
+ int y )
+{
+ QuartzResumeXCursor(pScreen, x, y);
+ xf86SetRootClip(pScreen, TRUE);
+}
+
+
+/*
+ =============================================================================
+
+ Screen initialization
+
+ =============================================================================
+*/
+
+/*
+ * FSDisplayInit
+ * Full screen specific initialization called from InitOutput.
+ */
+static void FSDisplayInit(void)
+{
+ static unsigned long generation = 0;
+ CGDisplayCount quartzDisplayCount = 0;
+
+ ErrorF("Display mode: Full screen Quartz -- Direct Display\n");
+
+ // Allocate private storage for each screen's mode specific info
+ if (generation != serverGeneration) {
+ fsScreenIndex = AllocateScreenPrivateIndex();
+ generation = serverGeneration;
+ }
+
+ // Find all the CoreGraphics displays
+ CGGetActiveDisplayList(0, NULL, &quartzDisplayCount);
+ quartzDisplayList = xalloc(quartzDisplayCount * sizeof(CGDirectDisplayID));
+ CGGetActiveDisplayList(quartzDisplayCount, quartzDisplayList,
+ &quartzDisplayCount);
+
+ darwinScreensFound = quartzDisplayCount;
+ atexit(FSRelease);
+}
+
+
+/*
+ * FSFindDisplayMode
+ * Find the appropriate display mode to use in full screen mode.
+ * If display mode is not the same as the current Aqua mode, switch
+ * to the new mode.
+ */
+static Bool FSFindDisplayMode(
+ FSScreenPtr fsDisplayInfo)
+{
+ CGDirectDisplayID cgID = fsDisplayInfo->displayID;
+ size_t height, width, bpp;
+ boolean_t exactMatch;
+
+ fsDisplayInfo->aquaDisplayMode = CGDisplayCurrentMode(cgID);
+
+ // If no user options, use current display mode
+ if (darwinDesiredWidth == 0 && darwinDesiredDepth == -1 &&
+ darwinDesiredRefresh == -1)
+ {
+ fsDisplayInfo->xDisplayMode = fsDisplayInfo->aquaDisplayMode;
+ return TRUE;
+ }
+
+ // If the user has no choice for size, use current
+ if (darwinDesiredWidth == 0) {
+ width = CGDisplayPixelsWide(cgID);
+ height = CGDisplayPixelsHigh(cgID);
+ } else {
+ width = darwinDesiredWidth;
+ height = darwinDesiredHeight;
+ }
+
+ switch (darwinDesiredDepth) {
+ case 0:
+ bpp = 8;
+ break;
+ case 1:
+ bpp = 16;
+ break;
+ case 2:
+ bpp = 32;
+ break;
+ default:
+ bpp = CGDisplayBitsPerPixel(cgID);
+ }
+
+ if (darwinDesiredRefresh == -1) {
+ fsDisplayInfo->xDisplayMode =
+ CGDisplayBestModeForParameters(cgID, bpp, width, height,
+ &exactMatch);
+ } else {
+ fsDisplayInfo->xDisplayMode =
+ CGDisplayBestModeForParametersAndRefreshRate(cgID, bpp,
+ width, height, darwinDesiredRefresh, &exactMatch);
+ }
+ if (!exactMatch) {
+ fsDisplayInfo->xDisplayMode = fsDisplayInfo->aquaDisplayMode;
+ return FALSE;
+ }
+
+ // Switch to the new display mode
+ CGDisplaySwitchToMode(cgID, fsDisplayInfo->xDisplayMode);
+ return TRUE;
+}
+
+
+/*
+ * FSAddScreen
+ * Do initialization of each screen for Quartz in full screen mode.
+ */
+static Bool FSAddScreen(
+ int index,
+ ScreenPtr pScreen)
+{
+ DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
+ QuartzScreenPtr displayInfo = QUARTZ_PRIV(pScreen);
+ CGDirectDisplayID cgID = quartzDisplayList[index];
+ CGRect bounds;
+ FSScreenPtr fsDisplayInfo;
+
+ // Allocate space for private per screen fullscreen specific storage.
+ fsDisplayInfo = xalloc(sizeof(FSScreenRec));
+ FULLSCREEN_PRIV(pScreen) = fsDisplayInfo;
+
+ displayInfo->displayCount = 1;
+ displayInfo->displayIDs = xrealloc(displayInfo->displayIDs,
+ 1 * sizeof(CGDirectDisplayID));
+ displayInfo->displayIDs[0] = cgID;
+
+ fsDisplayInfo->displayID = cgID;
+ fsDisplayInfo->xDisplayMode = 0;
+ fsDisplayInfo->aquaDisplayMode = 0;
+ fsDisplayInfo->xPalette = 0;
+ fsDisplayInfo->aquaPalette = 0;
+
+ // Capture full screen because X doesn't like read-only framebuffer.
+ // We need to do this before we (potentially) switch the display mode.
+ CGDisplayCapture(cgID);
+
+ if (! FSFindDisplayMode(fsDisplayInfo)) {
+ ErrorF("Could not support specified display mode on screen %i.\n",
+ index);
+ xfree(fsDisplayInfo);
+ return FALSE;
+ }
+
+ // Don't need to flip y-coordinate as CoreGraphics treats (0, 0)
+ // as the top left of main screen.
+ bounds = CGDisplayBounds(cgID);
+ dfb->x = bounds.origin.x;
+ dfb->y = bounds.origin.y;
+ dfb->width = bounds.size.width;
+ dfb->height = bounds.size.height;
+ dfb->pitch = CGDisplayBytesPerRow(cgID);
+ dfb->bitsPerPixel = CGDisplayBitsPerPixel(cgID);
+
+ if (dfb->bitsPerPixel == 8) {
+ if (CGDisplayCanSetPalette(cgID)) {
+ dfb->colorType = PseudoColor;
+ } else {
+ dfb->colorType = StaticColor;
+ }
+ dfb->bitsPerComponent = 8;
+ dfb->colorBitsPerPixel = 8;
+ } else {
+ dfb->colorType = TrueColor;
+ dfb->bitsPerComponent = CGDisplayBitsPerSample(cgID);
+ dfb->colorBitsPerPixel = CGDisplaySamplesPerPixel(cgID) *
+ dfb->bitsPerComponent;
+ }
+
+ fsDisplayInfo->framebuffer = CGDisplayBaseAddress(cgID);
+
+ // allocate shadow framebuffer
+ fsDisplayInfo->shadowPtr = xalloc(dfb->pitch * dfb->height);
+ dfb->framebuffer = fsDisplayInfo->shadowPtr;
+
+ return TRUE;
+}
+
+
+/*
+ * FSShadowUpdate
+ * Update the damaged regions of the shadow framebuffer on the display.
+ */
+static void FSShadowUpdate(
+ ScreenPtr pScreen,
+ shadowBufPtr pBuf)
+{
+ DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
+ FSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen);
+ RegionPtr damage = &pBuf->damage;
+ int numBox = REGION_NUM_RECTS(damage);
+ BoxPtr pBox = REGION_RECTS(damage);
+ int pitch = dfb->pitch;
+ int bpp = dfb->bitsPerPixel/8;
+
+ // Don't update if the X server is not visible
+ if (!quartzServerVisible)
+ return;
+
+ // Loop through all the damaged boxes
+ while (numBox--) {
+ int width, height, offset;
+ unsigned char *src, *dst;
+
+ width = (pBox->x2 - pBox->x1) * bpp;
+ height = pBox->y2 - pBox->y1;
+ offset = (pBox->y1 * pitch) + (pBox->x1 * bpp);
+ src = fsDisplayInfo->shadowPtr + offset;
+ dst = fsDisplayInfo->framebuffer + offset;
+
+ while (height--) {
+ memcpy(dst, src, width);
+ dst += pitch;
+ src += pitch;
+ }
+
+ // Get the next box
+ pBox++;
+ }
+}
+
+
+/*
+ * FSSetupScreen
+ * Finalize full screen specific setup of each screen.
+ */
+static Bool FSSetupScreen(
+ int index,
+ ScreenPtr pScreen)
+{
+ DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
+ FSScreenPtr fsDisplayInfo = FULLSCREEN_PRIV(pScreen);
+ CGDirectDisplayID cgID = fsDisplayInfo->displayID;
+
+ // Initialize shadow framebuffer support
+ if (! shadowInit(pScreen, FSShadowUpdate, NULL)) {
+ ErrorF("Failed to initalize shadow framebuffer for screen %i.\n",
+ index);
+ return FALSE;
+ }
+
+ if (dfb->colorType == PseudoColor) {
+ // Initialize colormap handling
+ size_t aquaBpp;
+
+ // If Aqua is using 8 bits we need to keep track of its pallete.
+ CFNumberGetValue(CFDictionaryGetValue(fsDisplayInfo->aquaDisplayMode,
+ kCGDisplayBitsPerPixel), kCFNumberLongType, &aquaBpp);
+ if (aquaBpp <= 8)
+ fsDisplayInfo->aquaPalette = CGPaletteCreateWithDisplay(cgID);
+
+ pScreen->CreateColormap = FSCreateColormap;
+ pScreen->DestroyColormap = FSDestroyColormap;
+ pScreen->InstallColormap = FSInstallColormap;
+ pScreen->StoreColors = FSStoreColors;
+
+ }
+
+ quartzScreens[quartzNumScreens++] = fsDisplayInfo;
+ return TRUE;
+}
+
+
+/*
+ * Quartz display mode function list.
+ */
+static QuartzModeProcsRec fsModeProcs = {
+ FSDisplayInit,
+ FSAddScreen,
+ FSSetupScreen,
+ NULL, // Not needed
+ QuartzInitCursor,
+ QuartzReallySetCursor,
+ FSSuspendScreen,
+ FSResumeScreen,
+ FSCapture,
+ FSRelease,
+ NULL, // No dynamic screen change support
+ NULL,
+ NULL,
+ NULL, // No rootless code in fullscreen
+ NULL,
+ NULL,
+ NULL,
+ NULL, // No support for DRI surfaces
+ NULL
+};
+
+
+/*
+ * QuartzModeBundleInit
+ * Initialize the display mode bundle after loading.
+ */
+Bool
+QuartzModeBundleInit(void)
+{
+ quartzProcs = &fsModeProcs;
+ quartzOpenGLBundle = NULL; // Only Mesa support for now
+ return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/quartzCursor.c b/nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/quartzCursor.c
new file mode 100644
index 000000000..8abce2318
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/quartzCursor.c
@@ -0,0 +1,653 @@
+/**************************************************************
+ *
+ * Support for using the Quartz Window Manager cursor
+ *
+ **************************************************************/
+/*
+ * Copyright (c) 2001-2003 Torrey T. Lyons and Greg Parker.
+ * 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.
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzCursor.c,v 1.5 2003/01/23 00:34:26 torrey Exp $ */
+
+#include "quartzCommon.h"
+#include "quartzCursor.h"
+#include "darwin.h"
+
+#include <pthread.h>
+
+#include "mi.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "mipointrst.h"
+#include "globals.h"
+
+// Size of the QuickDraw cursor
+#define CURSORWIDTH 16
+#define CURSORHEIGHT 16
+
+typedef struct {
+ int qdCursorMode;
+ int qdCursorVisible;
+ int useQDCursor;
+ QueryBestSizeProcPtr QueryBestSize;
+ miPointerSpriteFuncPtr spriteFuncs;
+} QuartzCursorScreenRec, *QuartzCursorScreenPtr;
+
+static int darwinCursorScreenIndex = -1;
+static unsigned long darwinCursorGeneration = 0;
+static CursorPtr quartzLatentCursor = NULL;
+static QD_Cursor gQDArrow; // QuickDraw arrow cursor
+
+// Cursor for the main thread to set (NULL = arrow cursor).
+static CCrsrHandle currentCursor = NULL;
+static pthread_mutex_t cursorMutex;
+static pthread_cond_t cursorCondition;
+
+#define CURSOR_PRIV(pScreen) \
+ ((QuartzCursorScreenPtr)pScreen->devPrivates[darwinCursorScreenIndex].ptr)
+
+#define HIDE_QD_CURSOR(pScreen, visible) \
+ if (visible) { \
+ int ix; \
+ for (ix = 0; ix < QUARTZ_PRIV(pScreen)->displayCount; ix++) { \
+ CGDisplayHideCursor(QUARTZ_PRIV(pScreen)->displayIDs[ix]); \
+ } \
+ visible = FALSE; \
+ } ((void)0)
+
+#define SHOW_QD_CURSOR(pScreen, visible) \
+ { \
+ int ix; \
+ for (ix = 0; ix < QUARTZ_PRIV(pScreen)->displayCount; ix++) { \
+ CGDisplayShowCursor(QUARTZ_PRIV(pScreen)->displayIDs[ix]); \
+ } \
+ visible = TRUE; \
+ } ((void)0)
+
+#define CHANGE_QD_CURSOR(cursorH) \
+ if (!quartzServerQuitting) { \
+ /* Acquire lock and tell the main thread to change cursor */ \
+ pthread_mutex_lock(&cursorMutex); \
+ currentCursor = (CCrsrHandle) (cursorH); \
+ QuartzMessageMainThread(kQuartzCursorUpdate, NULL, 0); \
+ \
+ /* Wait for the main thread to change the cursor */ \
+ pthread_cond_wait(&cursorCondition, &cursorMutex); \
+ pthread_mutex_unlock(&cursorMutex); \
+ } ((void)0)
+
+
+/*
+ * MakeQDCursor helpers: CTAB_ENTER, interleave
+ */
+
+// Add a color entry to a ctab
+#define CTAB_ENTER(ctab, index, r, g, b) \
+ ctab->ctTable[index].value = index; \
+ ctab->ctTable[index].rgb.red = r; \
+ ctab->ctTable[index].rgb.green = g; \
+ ctab->ctTable[index].rgb.blue = b
+
+// Make an unsigned short by interleaving the bits of bytes c1 and c2.
+// High bit of c1 is first; low bit of c2 is last.
+// Interleave is a built-in INTERCAL operator.
+static unsigned short
+interleave(
+ unsigned char c1,
+ unsigned char c2 )
+{
+ return
+ ((c1 & 0x80) << 8) | ((c2 & 0x80) << 7) |
+ ((c1 & 0x40) << 7) | ((c2 & 0x40) << 6) |
+ ((c1 & 0x20) << 6) | ((c2 & 0x20) << 5) |
+ ((c1 & 0x10) << 5) | ((c2 & 0x10) << 4) |
+ ((c1 & 0x08) << 4) | ((c2 & 0x08) << 3) |
+ ((c1 & 0x04) << 3) | ((c2 & 0x04) << 2) |
+ ((c1 & 0x02) << 2) | ((c2 & 0x02) << 1) |
+ ((c1 & 0x01) << 1) | ((c2 & 0x01) << 0) ;
+}
+
+/*
+ * MakeQDCursor
+ * Make a QuickDraw color cursor from the given X11 cursor.
+ * Warning: This code is nasty. Color cursors were meant to be read
+ * from resources; constructing the structures programmatically is messy.
+ */
+/*
+ QuickDraw cursor representation:
+ Our color cursor is a 2 bit per pixel pixmap.
+ Each pixel's bits are (source<<1 | mask) from the original X cursor pixel.
+ The cursor's color table maps the colors like this:
+ (2-bit value | X result | colortable | Mac result)
+ 00 | transparent | white | transparent (white outside mask)
+ 01 | back color | back color | back color
+ 10 | undefined | black | invert background (just for fun)
+ 11 | fore color | fore color | fore color
+*/
+static CCrsrHandle
+MakeQDCursor(
+ CursorPtr pCursor )
+{
+ CCrsrHandle result;
+ CCrsrPtr curs;
+ int i, w, h;
+ unsigned short rowMask;
+ PixMap *pix;
+ ColorTable *ctab;
+ unsigned short *image;
+
+ result = (CCrsrHandle) NewHandleClear(sizeof(CCrsr));
+ if (!result) return NULL;
+ HLock((Handle)result);
+ curs = *result;
+
+ // Initialize CCrsr
+ curs->crsrType = 0x8001; // 0x8000 = b&w, 0x8001 = color
+ curs->crsrMap = (PixMapHandle) NewHandleClear(sizeof(PixMap));
+ if (!curs->crsrMap) goto pixAllocFailed;
+ HLock((Handle)curs->crsrMap);
+ pix = *curs->crsrMap;
+ curs->crsrData = NULL; // raw cursor image data (set below)
+ curs->crsrXData = NULL; // QD's processed data
+ curs->crsrXValid = 0; // zero means QD must re-process cursor data
+ curs->crsrXHandle = NULL; // reserved
+ memset(curs->crsr1Data, 0, CURSORWIDTH*CURSORHEIGHT/8); // b&w data
+ memset(curs->crsrMask, 0, CURSORWIDTH*CURSORHEIGHT/8); // b&w & color mask
+ curs->crsrHotSpot.h = min(CURSORWIDTH, pCursor->bits->xhot); // hot spot
+ curs->crsrHotSpot.v = min(CURSORHEIGHT, pCursor->bits->yhot); // hot spot
+ curs->crsrXTable = 0; // reserved
+ curs->crsrID = GetCTSeed(); // unique ID from Color Manager
+
+ // Set the b&w data and mask
+ w = min(pCursor->bits->width, CURSORWIDTH);
+ h = min(pCursor->bits->height, CURSORHEIGHT);
+ rowMask = ~((1 << (CURSORWIDTH - w)) - 1);
+ for (i = 0; i < h; i++) {
+ curs->crsr1Data[i] = rowMask &
+ ((pCursor->bits->source[i*4]<<8) | pCursor->bits->source[i*4+1]);
+ curs->crsrMask[i] = rowMask &
+ ((pCursor->bits->mask[i*4]<<8) | pCursor->bits->mask[i*4+1]);
+ }
+
+ // Set the color data and mask
+ // crsrMap: defines bit depth and size and colortable only
+ pix->rowBytes = (CURSORWIDTH * 2 / 8) | 0x8000; // last bit on means PixMap
+ SetRect(&pix->bounds, 0, 0, CURSORWIDTH, CURSORHEIGHT); // see TN 1020
+ pix->pixelSize = 2;
+ pix->cmpCount = 1;
+ pix->cmpSize = 2;
+ // pix->pmTable set below
+
+ // crsrData is the pixel data. crsrMap's baseAddr is not used.
+ curs->crsrData = NewHandleClear(CURSORWIDTH*CURSORHEIGHT * 2 / 8);
+ if (!curs->crsrData) goto imageAllocFailed;
+ HLock((Handle)curs->crsrData);
+ image = (unsigned short *) *curs->crsrData;
+ // Pixel data is just 1-bit data and mask interleaved (see above)
+ for (i = 0; i < h; i++) {
+ unsigned char s, m;
+ s = pCursor->bits->source[i*4] & (rowMask >> 8);
+ m = pCursor->bits->mask[i*4] & (rowMask >> 8);
+ image[2*i] = interleave(s, m);
+ s = pCursor->bits->source[i*4+1] & (rowMask & 0x00ff);
+ m = pCursor->bits->mask[i*4+1] & (rowMask & 0x00ff);
+ image[2*i+1] = interleave(s, m);
+ }
+
+ // Build the color table (entries described above)
+ // NewPixMap allocates a color table handle.
+ pix->pmTable = (CTabHandle) NewHandleClear(sizeof(ColorTable) + 3
+ * sizeof(ColorSpec));
+ if (!pix->pmTable) goto ctabAllocFailed;
+ HLock((Handle)pix->pmTable);
+ ctab = *pix->pmTable;
+ ctab->ctSeed = GetCTSeed();
+ ctab->ctFlags = 0;
+ ctab->ctSize = 3; // color count - 1
+ CTAB_ENTER(ctab, 0, 0xffff, 0xffff, 0xffff);
+ CTAB_ENTER(ctab, 1, pCursor->backRed, pCursor->backGreen,
+ pCursor->backBlue);
+ CTAB_ENTER(ctab, 2, 0x0000, 0x0000, 0x0000);
+ CTAB_ENTER(ctab, 3, pCursor->foreRed, pCursor->foreGreen,
+ pCursor->foreBlue);
+
+ HUnlock((Handle)pix->pmTable); // ctab
+ HUnlock((Handle)curs->crsrData); // image data
+ HUnlock((Handle)curs->crsrMap); // pix
+ HUnlock((Handle)result); // cursor
+
+ return result;
+
+ // "What we have here is a failure to allocate"
+ctabAllocFailed:
+ HUnlock((Handle)curs->crsrData);
+ DisposeHandle((Handle)curs->crsrData);
+imageAllocFailed:
+ HUnlock((Handle)curs->crsrMap);
+ DisposeHandle((Handle)curs->crsrMap);
+pixAllocFailed:
+ HUnlock((Handle)result);
+ DisposeHandle((Handle)result);
+ return NULL;
+}
+
+
+/*
+ * FreeQDCursor
+ * Destroy a QuickDraw color cursor created with MakeQDCursor().
+ * The cursor must not currently be on screen.
+ */
+static void FreeQDCursor(CCrsrHandle cursHandle)
+{
+ CCrsrPtr curs;
+ PixMap *pix;
+
+ HLock((Handle)cursHandle);
+ curs = *cursHandle;
+ HLock((Handle)curs->crsrMap);
+ pix = *curs->crsrMap;
+ DisposeHandle((Handle)pix->pmTable);
+ HUnlock((Handle)curs->crsrMap);
+ DisposeHandle((Handle)curs->crsrMap);
+ DisposeHandle((Handle)curs->crsrData);
+ HUnlock((Handle)cursHandle);
+ DisposeHandle((Handle)cursHandle);
+}
+
+
+/*
+===========================================================================
+
+ Pointer sprite functions
+
+===========================================================================
+*/
+
+/*
+ * QuartzRealizeCursor
+ * Convert the X cursor representation to QuickDraw format if possible.
+ */
+Bool
+QuartzRealizeCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor )
+{
+ CCrsrHandle qdCursor;
+ QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
+
+ if(!pCursor || !pCursor->bits)
+ return FALSE;
+
+ // if the cursor is too big we use a software cursor
+ if ((pCursor->bits->height > CURSORHEIGHT) ||
+ (pCursor->bits->width > CURSORWIDTH) || !ScreenPriv->useQDCursor)
+ {
+ if (quartzRootless) {
+ // rootless can't use a software cursor
+ return TRUE;
+ } else {
+ return (*ScreenPriv->spriteFuncs->RealizeCursor)
+ (pScreen, pCursor);
+ }
+ }
+
+ // make new cursor image
+ qdCursor = MakeQDCursor(pCursor);
+ if (!qdCursor) return FALSE;
+
+ // save the result
+ pCursor->devPriv[pScreen->myNum] = (pointer) qdCursor;
+
+ return TRUE;
+}
+
+
+/*
+ * QuartzUnrealizeCursor
+ * Free the storage space associated with a realized cursor.
+ */
+Bool
+QuartzUnrealizeCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor )
+{
+ QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
+
+ if ((pCursor->bits->height > CURSORHEIGHT) ||
+ (pCursor->bits->width > CURSORWIDTH) || !ScreenPriv->useQDCursor)
+ {
+ if (quartzRootless) {
+ return TRUE;
+ } else {
+ return (*ScreenPriv->spriteFuncs->UnrealizeCursor)
+ (pScreen, pCursor);
+ }
+ } else {
+ CCrsrHandle oldCursor = (CCrsrHandle) pCursor->devPriv[pScreen->myNum];
+
+ if (currentCursor != oldCursor) {
+ // This should only fail when quitting, in which case we just leak.
+ FreeQDCursor(oldCursor);
+ }
+ pCursor->devPriv[pScreen->myNum] = NULL;
+ return TRUE;
+ }
+}
+
+
+/*
+ * QuartzSetCursor
+ * Set the cursor sprite and position.
+ * Use QuickDraw cursor if possible.
+ */
+static void
+QuartzSetCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor,
+ int x,
+ int y)
+{
+ QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
+
+ quartzLatentCursor = pCursor;
+
+ // Don't touch Mac OS cursor if X is hidden!
+ if (!quartzServerVisible)
+ return;
+
+ if (!pCursor) {
+ // Remove the cursor completely.
+ HIDE_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
+ if (! ScreenPriv->qdCursorMode)
+ (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
+ }
+ else if ((pCursor->bits->height <= CURSORHEIGHT) &&
+ (pCursor->bits->width <= CURSORWIDTH) && ScreenPriv->useQDCursor)
+ {
+ // Cursor is small enough to use QuickDraw directly.
+ if (! ScreenPriv->qdCursorMode) // remove the X cursor
+ (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
+ ScreenPriv->qdCursorMode = TRUE;
+
+ CHANGE_QD_CURSOR(pCursor->devPriv[pScreen->myNum]);
+ SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
+ }
+ else if (quartzRootless) {
+ // Rootless can't use a software cursor, so we just use Mac OS arrow.
+ CHANGE_QD_CURSOR(NULL);
+ SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
+ }
+ else {
+ // Cursor is too big for QuickDraw. Use X software cursor.
+ HIDE_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
+ ScreenPriv->qdCursorMode = FALSE;
+ (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCursor, x, y);
+ }
+}
+
+
+/*
+ * QuartzReallySetCursor
+ * Set the QuickDraw cursor. Called from the main thread since changing the
+ * cursor with QuickDraw is not thread safe on dual processor machines.
+ */
+void
+QuartzReallySetCursor()
+{
+ pthread_mutex_lock(&cursorMutex);
+
+ if (currentCursor) {
+ SetCCursor(currentCursor);
+ } else {
+ SetCursor(&gQDArrow);
+ }
+
+ pthread_cond_signal(&cursorCondition);
+ pthread_mutex_unlock(&cursorMutex);
+}
+
+
+/*
+ * QuartzMoveCursor
+ * Move the cursor. This is a noop for QuickDraw.
+ */
+static void
+QuartzMoveCursor(
+ ScreenPtr pScreen,
+ int x,
+ int y)
+{
+ QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
+
+ // only the X cursor needs to be explicitly moved
+ if (!ScreenPriv->qdCursorMode)
+ (*ScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, y);
+}
+
+
+static miPointerSpriteFuncRec quartzSpriteFuncsRec = {
+ QuartzRealizeCursor,
+ QuartzUnrealizeCursor,
+ QuartzSetCursor,
+ QuartzMoveCursor
+};
+
+
+/*
+===========================================================================
+
+ Pointer screen functions
+
+===========================================================================
+*/
+
+/*
+ * QuartzCursorOffScreen
+ */
+static Bool QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
+{
+ return FALSE;
+}
+
+
+/*
+ * QuartzCrossScreen
+ */
+static void QuartzCrossScreen(ScreenPtr pScreen, Bool entering)
+{
+ return;
+}
+
+
+/*
+ * QuartzWarpCursor
+ * Change the cursor position without generating an event or motion history.
+ * The input coordinates (x,y) are in pScreen-local X11 coordinates.
+ *
+ */
+static void
+QuartzWarpCursor(
+ ScreenPtr pScreen,
+ int x,
+ int y)
+{
+ static int neverMoved = TRUE;
+
+ if (neverMoved) {
+ // Don't move the cursor the first time. This is the jump-to-center
+ // initialization, and it's annoying because we may still be in MacOS.
+ neverMoved = FALSE;
+ return;
+ }
+
+ if (quartzServerVisible) {
+ CGDisplayErr cgErr;
+ CGPoint cgPoint;
+ // Only need to do this for one display. Any display will do.
+ CGDirectDisplayID cgID = QUARTZ_PRIV(pScreen)->displayIDs[0];
+ CGRect cgRect = CGDisplayBounds(cgID);
+
+ // Convert (x,y) to CoreGraphics screen-local CG coordinates.
+ // This is necessary because the X11 screen and CG screen may not
+ // coincide. (e.g. X11 screen may be moved to dodge the menu bar)
+
+ // Make point in X11 global coordinates
+ cgPoint = CGPointMake(x + dixScreenOrigins[pScreen->myNum].x,
+ y + dixScreenOrigins[pScreen->myNum].y);
+ // Shift to CoreGraphics global screen coordinates
+ cgPoint.x += darwinMainScreenX;
+ cgPoint.y += darwinMainScreenY;
+ // Shift to CoreGraphics screen-local coordinates
+ cgPoint.x -= cgRect.origin.x;
+ cgPoint.y -= cgRect.origin.y;
+
+ cgErr = CGDisplayMoveCursorToPoint(cgID, cgPoint);
+ if (cgErr != CGDisplayNoErr) {
+ ErrorF("Could not set cursor position with error code 0x%x.\n",
+ cgErr);
+ }
+ }
+
+ miPointerWarpCursor(pScreen, x, y);
+ miPointerUpdate();
+}
+
+
+static miPointerScreenFuncRec quartzScreenFuncsRec = {
+ QuartzCursorOffScreen,
+ QuartzCrossScreen,
+ QuartzWarpCursor,
+ DarwinEQPointerPost,
+ DarwinEQSwitchScreen
+};
+
+
+/*
+===========================================================================
+
+ Other screen functions
+
+===========================================================================
+*/
+
+/*
+ * QuartzCursorQueryBestSize
+ * Handle queries for best cursor size
+ */
+static void
+QuartzCursorQueryBestSize(
+ int class,
+ unsigned short *width,
+ unsigned short *height,
+ ScreenPtr pScreen)
+{
+ QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
+
+ if (class == CursorShape) {
+ *width = CURSORWIDTH;
+ *height = CURSORHEIGHT;
+ } else {
+ (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
+ }
+}
+
+
+/*
+ * QuartzInitCursor
+ * Initialize cursor support
+ */
+Bool
+QuartzInitCursor(
+ ScreenPtr pScreen )
+{
+ QuartzCursorScreenPtr ScreenPriv;
+ miPointerScreenPtr PointPriv;
+ DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
+
+ // initialize software cursor handling (always needed as backup)
+ if (!miDCInitialize(pScreen, &quartzScreenFuncsRec)) {
+ return FALSE;
+ }
+
+ // allocate private storage for this screen's QuickDraw cursor info
+ if (darwinCursorGeneration != serverGeneration) {
+ if ((darwinCursorScreenIndex = AllocateScreenPrivateIndex()) < 0)
+ return FALSE;
+ darwinCursorGeneration = serverGeneration;
+ }
+
+ ScreenPriv = xcalloc( 1, sizeof(QuartzCursorScreenRec) );
+ if (!ScreenPriv) return FALSE;
+
+ CURSOR_PRIV(pScreen) = ScreenPriv;
+
+ // override some screen procedures
+ ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
+ pScreen->QueryBestSize = QuartzCursorQueryBestSize;
+
+ // initialize QuickDraw cursor handling
+ GetQDGlobalsArrow(&gQDArrow);
+ PointPriv = (miPointerScreenPtr)
+ pScreen->devPrivates[miPointerScreenIndex].ptr;
+
+ ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
+ PointPriv->spriteFuncs = &quartzSpriteFuncsRec;
+
+ if (!quartzRootless)
+ ScreenPriv->useQDCursor = QuartzFSUseQDCursor(dfb->colorBitsPerPixel);
+ else
+ ScreenPriv->useQDCursor = TRUE;
+ ScreenPriv->qdCursorMode = TRUE;
+ ScreenPriv->qdCursorVisible = TRUE;
+
+ // initialize cursor mutex lock
+ pthread_mutex_init(&cursorMutex, NULL);
+
+ // initialize condition for waiting
+ pthread_cond_init(&cursorCondition, NULL);
+
+ return TRUE;
+}
+
+
+// X server is hiding. Restore the Aqua cursor.
+void QuartzSuspendXCursor(
+ ScreenPtr pScreen )
+{
+ QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
+
+ CHANGE_QD_CURSOR(NULL);
+ SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible);
+}
+
+
+// X server is showing. Restore the X cursor.
+void QuartzResumeXCursor(
+ ScreenPtr pScreen,
+ int x,
+ int y )
+{
+ QuartzSetCursor(pScreen, quartzLatentCursor, x, y);
+}
diff --git a/nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/quartzCursor.h b/nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/quartzCursor.h
new file mode 100644
index 000000000..efcc4435e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/darwin/quartz/fullscreen/quartzCursor.h
@@ -0,0 +1,44 @@
+/*
+ * quartzCursor.h
+ *
+ * External interface for Quartz hardware cursor
+ */
+/*
+ * Copyright (c) 2001 Torrey T. Lyons and Greg Parker.
+ * 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.
+ */
+/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/quartzCursor.h,v 1.1 2002/03/28 02:21:19 torrey Exp $ */
+
+#ifndef QUARTZCURSOR_H
+#define QUARTZCURSOR_H
+
+#include "screenint.h"
+
+Bool QuartzInitCursor(ScreenPtr pScreen);
+void QuartzReallySetCursor(void);
+void QuartzSuspendXCursor(ScreenPtr pScreen);
+void QuartzResumeXCursor(ScreenPtr pScreen, int x, int y);
+
+#endif