735 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			735 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
| /**************************************************************
 | |
|  *
 | |
|  * Cursor support for Darwin X Server
 | |
|  *
 | |
|  * Three different cursor modes are possible:
 | |
|  *  X (0)         - tracking via Darwin kernel,
 | |
|  *                  display via X machine independent
 | |
|  *  Kernel (1)    - tracking and display via Darwin kernel
 | |
|  *                  (not currently supported)
 | |
|  *  Hardware (2)  - tracking and display via hardware
 | |
|  *
 | |
|  * The X software cursor uses the Darwin software cursor
 | |
|  * routines in IOFramebuffer.cpp to track the cursor, but
 | |
|  * displays the cursor image using the X machine
 | |
|  * independent display cursor routines in midispcur.c.
 | |
|  *
 | |
|  * The kernel cursor uses IOFramebuffer.cpp routines to
 | |
|  * track and display the cursor. This gives better
 | |
|  * performance as the display calls don't have to cross
 | |
|  * the kernel boundary. Unfortunately, this mode has
 | |
|  * synchronization issues with the user land X server
 | |
|  * and isn't currently used.
 | |
|  *
 | |
|  * Hardware cursor support lets the hardware handle these
 | |
|  * details.
 | |
|  *
 | |
|  * Kernel and hardware cursor mode only work for cursors
 | |
|  * up to a certain size, currently 16x16 pixels. If a
 | |
|  * bigger cursor is set, we fallback to X cursor mode.
 | |
|  *
 | |
|  * HISTORY:
 | |
|  * 1.0 by Torrey T. Lyons, October 30, 2000
 | |
|  *
 | |
|  **************************************************************/
 | |
| /*
 | |
|  * Copyright (c) 2001-2002 Torrey T. Lyons. All Rights Reserved.
 | |
|  *
 | |
|  * Permission is hereby granted, free of charge, to any person obtaining a
 | |
|  * copy of this software and associated documentation files (the "Software"),
 | |
|  * to deal in the Software without restriction, including without limitation
 | |
|  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | |
|  * and/or sell copies of the Software, and to permit persons to whom the
 | |
|  * Software is furnished to do so, subject to the following conditions:
 | |
|  *
 | |
|  * The above copyright notice and this permission notice shall be included in
 | |
|  * all copies or substantial portions of the Software.
 | |
|  *
 | |
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | |
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | |
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | |
|  * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 | |
|  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 | |
|  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | |
|  * DEALINGS IN THE SOFTWARE.
 | |
|  *
 | |
|  * Except as contained in this notice, the name(s) of the above copyright
 | |
|  * holders shall not be used in advertising or otherwise to promote the sale,
 | |
|  * use or other dealings in this Software without prior written authorization.
 | |
|  */
 | |
| 
 | |
| #include "scrnintstr.h"
 | |
| #include "cursorstr.h"
 | |
| #include "mipointrst.h"
 | |
| #include "micmap.h"
 | |
| #define NO_CFPLUGIN
 | |
| #include <IOKit/graphics/IOGraphicsLib.h>
 | |
| #include <IOKit/hidsystem/IOHIDLib.h>
 | |
| #include "darwin.h"
 | |
| #include "xfIOKit.h"
 | |
| 
 | |
| #define DUMP_DARWIN_CURSOR FALSE
 | |
| 
 | |
| #define CURSOR_PRIV(pScreen) \
 | |
|     ((XFIOKitCursorScreenPtr)pScreen->devPrivates[darwinCursorScreenIndex].ptr)
 | |
| 
 | |
| // The cursors format are documented in IOFramebufferShared.h.
 | |
| #define RGBto34WithGamma(red, green, blue)  \
 | |
|     (  0x000F                               \
 | |
|      | (((red) & 0xF) << 12)                \
 | |
|      | (((green) & 0xF) << 8)               \
 | |
|      | (((blue) & 0xF) << 4) )
 | |
| #define RGBto38WithGamma(red, green, blue)  \
 | |
|     (  0xFF << 24                           \
 | |
|      | (((red) & 0xFF) << 16)               \
 | |
|      | (((green) & 0xFF) << 8)              \
 | |
|      | (((blue) & 0xFF)) )
 | |
| #define HighBitOf32 0x80000000
 | |
| 
 | |
| typedef struct {
 | |
|     Bool                    canHWCursor;
 | |
|     short                   cursorMode;
 | |
|     RecolorCursorProcPtr    RecolorCursor;
 | |
|     InstallColormapProcPtr  InstallColormap;
 | |
|     QueryBestSizeProcPtr    QueryBestSize;
 | |
|     miPointerSpriteFuncPtr  spriteFuncs;
 | |
|     ColormapPtr             pInstalledMap;
 | |
| } XFIOKitCursorScreenRec, *XFIOKitCursorScreenPtr;
 | |
| 
 | |
| static int darwinCursorScreenIndex = -1;
 | |
| static unsigned long darwinCursorGeneration = 0;
 | |
| 
 | |
| /*
 | |
| ===========================================================================
 | |
| 
 | |
|  Pointer sprite functions
 | |
| 
 | |
| ===========================================================================
 | |
| */
 | |
| 
 | |
| /*
 | |
|     Realizing the Darwin hardware cursor (ie. converting from the
 | |
|     X representation to the IOKit representation) is complicated
 | |
|     by the fact that we have three different potential cursor
 | |
|     formats to go to, one for each bit depth (8, 15, or 24).
 | |
|     The IOKit formats are documented in IOFramebufferShared.h.
 | |
|     X cursors are represented as two pieces, a source and a mask.
 | |
|     The mask is a bitmap indicating which parts of the cursor are 
 | |
|     transparent and which parts are drawn.  The source is a bitmap
 | |
|     indicating which parts of the non-transparent portion of the the
 | |
|     cursor should be painted in the foreground color and which should
 | |
|     be painted in the background color. The bitmaps are given in
 | |
|     32-bit format with least significant byte and bit first.
 | |
|     (This is opposite PowerPC Darwin.)
 | |
| */
 | |
| 
 | |
| typedef struct {
 | |
|     unsigned char image[CURSORWIDTH*CURSORHEIGHT];
 | |
|     unsigned char mask[CURSORWIDTH*CURSORHEIGHT];
 | |
| } cursorPrivRec, *cursorPrivPtr;
 | |
| 
 | |
| /*
 | |
|  * XFIOKitRealizeCursor8
 | |
|  * Convert the X cursor representation to an 8-bit depth
 | |
|  * format for Darwin. This function assumes the maximum cursor
 | |
|  * width is a multiple of 8.
 | |
|  */
 | |
| static Bool
 | |
| XFIOKitRealizeCursor8(
 | |
|     ScreenPtr pScreen,
 | |
|     CursorPtr pCursor)
 | |
| {
 | |
|     cursorPrivPtr   newCursor;
 | |
|     unsigned char   *newSourceP, *newMaskP;
 | |
|     CARD32          *oldSourceP, *oldMaskP;
 | |
|     xColorItem      fgColor, bgColor;
 | |
|     int             index, x, y, rowPad;
 | |
|     int             cursorWidth, cursorHeight;
 | |
|     ColormapPtr     pmap;
 | |
| 
 | |
|     // check cursor size just to be sure
 | |
|     cursorWidth = pCursor->bits->width;
 | |
|     cursorHeight = pCursor->bits->height;
 | |
|     if (cursorHeight > CURSORHEIGHT || cursorWidth > CURSORWIDTH)
 | |
|         return FALSE;
 | |
| 
 | |
|     // get cursor colors in colormap
 | |
|     index = pScreen->myNum;
 | |
|     pmap = miInstalledMaps[index];
 | |
|     if (!pmap) return FALSE;
 | |
| 
 | |
|     fgColor.red = pCursor->foreRed;
 | |
|     fgColor.green = pCursor->foreGreen;
 | |
|     fgColor.blue = pCursor->foreBlue;
 | |
|     FakeAllocColor(pmap, &fgColor);
 | |
|     bgColor.red = pCursor->backRed;
 | |
|     bgColor.green = pCursor->backGreen;
 | |
|     bgColor.blue = pCursor->backBlue;
 | |
|     FakeAllocColor(pmap, &bgColor);
 | |
|     FakeFreeColor(pmap, fgColor.pixel);
 | |
|     FakeFreeColor(pmap, bgColor.pixel);
 | |
| 
 | |
|     // allocate memory for new cursor image
 | |
|     newCursor = xalloc( sizeof(cursorPrivRec) );
 | |
|     if (!newCursor)
 | |
|         return FALSE;
 | |
|     memset( newCursor->image, pScreen->blackPixel, CURSORWIDTH*CURSORHEIGHT );
 | |
|     memset( newCursor->mask, 0, CURSORWIDTH*CURSORHEIGHT );
 | |
| 
 | |
|     // convert to 8-bit Darwin cursor format
 | |
|     oldSourceP = (CARD32 *) pCursor->bits->source;
 | |
|     oldMaskP = (CARD32 *) pCursor->bits->mask;
 | |
|     newSourceP = newCursor->image;
 | |
|     newMaskP = newCursor->mask;
 | |
|     rowPad = CURSORWIDTH - cursorWidth;
 | |
| 
 | |
|     for (y = 0; y < cursorHeight; y++) {
 | |
|         for (x = 0; x < cursorWidth; x++) {
 | |
|             if (*oldSourceP & (HighBitOf32 >> x))
 | |
|                 *newSourceP = fgColor.pixel;
 | |
|             else
 | |
|                 *newSourceP = bgColor.pixel;
 | |
|             if (*oldMaskP & (HighBitOf32 >> x))
 | |
|                 *newMaskP = 255;
 | |
|             else
 | |
|                 *newSourceP = pScreen->blackPixel;
 | |
|             newSourceP++; newMaskP++;
 | |
|         }
 | |
|         oldSourceP++; oldMaskP++;
 | |
|         newSourceP += rowPad; newMaskP += rowPad;
 | |
|     }
 | |
| 
 | |
|     // save the result
 | |
|     pCursor->devPriv[pScreen->myNum] = (pointer) newCursor;
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * XFIOKitRealizeCursor15
 | |
|  * Convert the X cursor representation to an 15-bit depth
 | |
|  * format for Darwin.
 | |
|  */
 | |
| static Bool
 | |
| XFIOKitRealizeCursor15(
 | |
|     ScreenPtr       pScreen,
 | |
|     CursorPtr       pCursor)
 | |
| {
 | |
|     unsigned short  *newCursor;
 | |
|     unsigned short  fgPixel, bgPixel;
 | |
|     unsigned short  *newSourceP;
 | |
|     CARD32          *oldSourceP, *oldMaskP;
 | |
|     int             x, y, rowPad;
 | |
|     int             cursorWidth, cursorHeight;
 | |
| 
 | |
|     // check cursor size just to be sure
 | |
|     cursorWidth = pCursor->bits->width;
 | |
|     cursorHeight = pCursor->bits->height;
 | |
|     if (cursorHeight > CURSORHEIGHT || cursorWidth > CURSORWIDTH)
 | |
|        return FALSE;
 | |
| 
 | |
|     // allocate memory for new cursor image
 | |
|     newCursor = xalloc( CURSORWIDTH*CURSORHEIGHT*sizeof(short) );
 | |
|     if (!newCursor)
 | |
|         return FALSE;
 | |
|     memset( newCursor, 0, CURSORWIDTH*CURSORHEIGHT*sizeof(short) );
 | |
| 
 | |
|     // calculate pixel values
 | |
|     fgPixel = RGBto34WithGamma( pCursor->foreRed, pCursor->foreGreen,
 | |
|                                 pCursor->foreBlue );
 | |
|     bgPixel = RGBto34WithGamma( pCursor->backRed, pCursor->backGreen,
 | |
|                                 pCursor->backBlue );
 | |
| 
 | |
|     // convert to 15-bit Darwin cursor format
 | |
|     oldSourceP = (CARD32 *) pCursor->bits->source;
 | |
|     oldMaskP = (CARD32 *) pCursor->bits->mask;
 | |
|     newSourceP = newCursor;
 | |
|     rowPad = CURSORWIDTH - cursorWidth;
 | |
| 
 | |
|     for (y = 0; y < cursorHeight; y++) {
 | |
|         for (x = 0; x < cursorWidth; x++) {
 | |
|             if (*oldMaskP & (HighBitOf32 >> x)) {
 | |
|                 if (*oldSourceP & (HighBitOf32 >> x))
 | |
|                     *newSourceP = fgPixel;
 | |
|                 else
 | |
|                     *newSourceP = bgPixel;
 | |
|             } else {
 | |
|                 *newSourceP = 0;
 | |
|             }
 | |
|             newSourceP++;
 | |
|         }
 | |
|         oldSourceP++; oldMaskP++;
 | |
|         newSourceP += rowPad;
 | |
|     }
 | |
| 
 | |
| #if DUMP_DARWIN_CURSOR
 | |
|     // Write out the cursor
 | |
|     ErrorF("Cursor: 0x%x\n", pCursor);
 | |
|     ErrorF("Width = %i, Height = %i, RowPad = %i\n", cursorWidth,
 | |
|             cursorHeight, rowPad);
 | |
|     for (y = 0; y < cursorHeight; y++) {
 | |
|         newSourceP = newCursor + y*CURSORWIDTH;
 | |
|         for (x = 0; x < cursorWidth; x++) {
 | |
|             if (*newSourceP == fgPixel)
 | |
|                 ErrorF("x");
 | |
|             else if (*newSourceP == bgPixel)
 | |
|                 ErrorF("o");
 | |
|             else
 | |
|                 ErrorF(" ");
 | |
|             newSourceP++;
 | |
|         }
 | |
|         ErrorF("\n");
 | |
|     }
 | |
| #endif
 | |
| 
 | |
|     // save the result
 | |
|     pCursor->devPriv[pScreen->myNum] = (pointer) newCursor;
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * XFIOKitRealizeCursor24
 | |
|  * Convert the X cursor representation to an 24-bit depth
 | |
|  * format for Darwin. This function assumes the maximum cursor
 | |
|  * width is a multiple of 8.
 | |
|  */
 | |
| static Bool
 | |
| XFIOKitRealizeCursor24(
 | |
|     ScreenPtr       pScreen,
 | |
|     CursorPtr       pCursor)
 | |
| {
 | |
|     unsigned int    *newCursor;
 | |
|     unsigned int    fgPixel, bgPixel;
 | |
|     unsigned int    *newSourceP;
 | |
|     CARD32          *oldSourceP, *oldMaskP;
 | |
|     int             x, y, rowPad;
 | |
|     int             cursorWidth, cursorHeight;
 | |
| 
 | |
|     // check cursor size just to be sure
 | |
|     cursorWidth = pCursor->bits->width;
 | |
|     cursorHeight = pCursor->bits->height;
 | |
|     if (cursorHeight > CURSORHEIGHT || cursorWidth > CURSORWIDTH)
 | |
|        return FALSE;
 | |
| 
 | |
|     // allocate memory for new cursor image
 | |
|     newCursor = xalloc( CURSORWIDTH*CURSORHEIGHT*sizeof(int) );
 | |
|     if (!newCursor)
 | |
|         return FALSE;
 | |
|     memset( newCursor, 0, CURSORWIDTH*CURSORHEIGHT*sizeof(int) );
 | |
| 
 | |
|     // calculate pixel values
 | |
|     fgPixel = RGBto38WithGamma( pCursor->foreRed, pCursor->foreGreen,
 | |
|                                 pCursor->foreBlue );
 | |
|     bgPixel = RGBto38WithGamma( pCursor->backRed, pCursor->backGreen,
 | |
|                                 pCursor->backBlue );
 | |
| 
 | |
|     // convert to 24-bit Darwin cursor format
 | |
|     oldSourceP = (CARD32 *) pCursor->bits->source;
 | |
|     oldMaskP = (CARD32 *) pCursor->bits->mask;
 | |
|     newSourceP = newCursor;
 | |
|     rowPad = CURSORWIDTH - cursorWidth;
 | |
| 
 | |
|     for (y = 0; y < cursorHeight; y++) {
 | |
|         for (x = 0; x < cursorWidth; x++) {
 | |
|             if (*oldMaskP & (HighBitOf32 >> x)) {
 | |
|                 if (*oldSourceP & (HighBitOf32 >> x))
 | |
|                     *newSourceP = fgPixel;
 | |
|                 else
 | |
|                     *newSourceP = bgPixel;
 | |
|             } else {
 | |
|                 *newSourceP = 0;
 | |
|             }
 | |
|             newSourceP++;
 | |
|         }
 | |
|         oldSourceP++; oldMaskP++;
 | |
|         newSourceP += rowPad;
 | |
|     }
 | |
| 
 | |
| #if DUMP_DARWIN_CURSOR
 | |
|     // Write out the cursor
 | |
|     ErrorF("Cursor: 0x%x\n", pCursor);
 | |
|     ErrorF("Width = %i, Height = %i, RowPad = %i\n", cursorWidth,
 | |
|             cursorHeight, rowPad);
 | |
|     for (y = 0; y < cursorHeight; y++) {
 | |
|         newSourceP = newCursor + y*CURSORWIDTH;
 | |
|         for (x = 0; x < cursorWidth; x++) {
 | |
|             if (*newSourceP == fgPixel)
 | |
|                 ErrorF("x");
 | |
|             else if (*newSourceP == bgPixel)
 | |
|                 ErrorF("o");
 | |
|             else
 | |
|                 ErrorF(" ");
 | |
|             newSourceP++;
 | |
|         }
 | |
|         ErrorF("\n");
 | |
|     }
 | |
| #endif
 | |
| 
 | |
|     // save the result
 | |
|     pCursor->devPriv[pScreen->myNum] = (pointer) newCursor;
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * XFIOKitRealizeCursor
 | |
|  * 
 | |
|  */
 | |
| static Bool
 | |
| XFIOKitRealizeCursor(
 | |
|     ScreenPtr       pScreen,
 | |
|     CursorPtr       pCursor)
 | |
| {
 | |
|     Bool                        result;
 | |
|     XFIOKitCursorScreenPtr      ScreenPriv = CURSOR_PRIV(pScreen);
 | |
|     DarwinFramebufferPtr        dfb = SCREEN_PRIV(pScreen);
 | |
| 
 | |
|     if ((pCursor->bits->height > CURSORHEIGHT) ||
 | |
|         (pCursor->bits->width > CURSORWIDTH) ||
 | |
|         // FIXME: this condition is not needed after kernel cursor works
 | |
|         !ScreenPriv->canHWCursor) {
 | |
|         result = (*ScreenPriv->spriteFuncs->RealizeCursor)(pScreen, pCursor);
 | |
|     } else if (dfb->bitsPerPixel == 8) {
 | |
|         result = XFIOKitRealizeCursor8(pScreen, pCursor);
 | |
|     } else if (dfb->bitsPerPixel == 16) {
 | |
|         result = XFIOKitRealizeCursor15(pScreen, pCursor);
 | |
|     } else {
 | |
|         result = XFIOKitRealizeCursor24(pScreen, pCursor);
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * XFIOKitUnrealizeCursor
 | |
|  * 
 | |
|  */
 | |
| static Bool
 | |
| XFIOKitUnrealizeCursor(
 | |
|     ScreenPtr pScreen,
 | |
|     CursorPtr pCursor)
 | |
| {
 | |
|     Bool                        result;
 | |
|     XFIOKitCursorScreenPtr      ScreenPriv = CURSOR_PRIV(pScreen);
 | |
| 
 | |
|     if ((pCursor->bits->height > CURSORHEIGHT) ||
 | |
|         (pCursor->bits->width > CURSORWIDTH) ||
 | |
|         // FIXME: this condition is not needed after kernel cursor works
 | |
|         !ScreenPriv->canHWCursor) {
 | |
|         result = (*ScreenPriv->spriteFuncs->UnrealizeCursor)(pScreen, pCursor);
 | |
|     } else {
 | |
|         xfree( pCursor->devPriv[pScreen->myNum] );
 | |
|         result = TRUE;
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * XFIOKitSetCursor
 | |
|  * Set the cursor sprite and position
 | |
|  * Use hardware cursor if possible
 | |
|  */
 | |
| static void
 | |
| XFIOKitSetCursor(
 | |
|     ScreenPtr       pScreen,
 | |
|     CursorPtr       pCursor,
 | |
|     int             x,
 | |
|     int             y)
 | |
| {
 | |
|     kern_return_t               kr;
 | |
|     DarwinFramebufferPtr        dfb = SCREEN_PRIV(pScreen);
 | |
|     XFIOKitScreenPtr            iokitScreen = XFIOKIT_SCREEN_PRIV(pScreen);
 | |
|     StdFBShmem_t                *cshmem = iokitScreen->cursorShmem;
 | |
|     XFIOKitCursorScreenPtr      ScreenPriv = CURSOR_PRIV(pScreen);
 | |
| 
 | |
|     // are we supposed to remove the cursor?
 | |
|     if (!pCursor) {
 | |
|         if (ScreenPriv->cursorMode == 0)
 | |
|             (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
 | |
|         else {
 | |
|             if (!cshmem->cursorShow) {
 | |
|                 cshmem->cursorShow++;
 | |
|                 if (cshmem->hardwareCursorActive) {
 | |
|                     kr = IOFBSetCursorVisible(iokitScreen->fbService, FALSE);
 | |
|                     kern_assert( kr );
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return;
 | |
|     } 
 | |
|  
 | |
|     // can we use the kernel or hardware cursor?
 | |
|     if ((pCursor->bits->height <= CURSORHEIGHT) &&
 | |
|         (pCursor->bits->width <= CURSORWIDTH) &&
 | |
|         // FIXME: condition not needed when kernel cursor works
 | |
|         ScreenPriv->canHWCursor) {
 | |
| 
 | |
|         if (ScreenPriv->cursorMode == 0)    // remove the X cursor
 | |
|             (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
 | |
|         ScreenPriv->cursorMode = 1;         // kernel cursor
 | |
| 
 | |
|         // change the cursor image in shared memory
 | |
|         if (dfb->bitsPerPixel == 8) {
 | |
|             cursorPrivPtr newCursor =
 | |
|                     (cursorPrivPtr) pCursor->devPriv[pScreen->myNum];
 | |
|             memcpy(cshmem->cursor.bw8.image[0], newCursor->image,
 | |
|                         CURSORWIDTH*CURSORHEIGHT);
 | |
|             memcpy(cshmem->cursor.bw8.mask[0], newCursor->mask,
 | |
|                         CURSORWIDTH*CURSORHEIGHT);
 | |
|         } else if (dfb->bitsPerPixel == 16) {
 | |
|             unsigned short *newCursor =
 | |
|                     (unsigned short *) pCursor->devPriv[pScreen->myNum];
 | |
|             memcpy(cshmem->cursor.rgb.image[0], newCursor,
 | |
|                         2*CURSORWIDTH*CURSORHEIGHT);
 | |
|         } else {
 | |
|             unsigned int *newCursor =
 | |
|                     (unsigned int *) pCursor->devPriv[pScreen->myNum];
 | |
|             memcpy(cshmem->cursor.rgb24.image[0], newCursor,
 | |
|                         4*CURSORWIDTH*CURSORHEIGHT);
 | |
|         }
 | |
| 
 | |
|         // FIXME: We always use a full size cursor, even if the image
 | |
|         // is smaller because I couldn't get the padding to come out
 | |
|         // right otherwise.
 | |
|         cshmem->cursorSize[0].width = CURSORWIDTH;
 | |
|         cshmem->cursorSize[0].height = CURSORHEIGHT;
 | |
|         cshmem->hotSpot[0].x = pCursor->bits->xhot;
 | |
|         cshmem->hotSpot[0].y = pCursor->bits->yhot;
 | |
| 
 | |
|         // try to use a hardware cursor
 | |
|         if (ScreenPriv->canHWCursor) {
 | |
|             kr = IOFBSetNewCursor(iokitScreen->fbService, 0, 0, 0);
 | |
|             // FIXME: this is a fatal error without the kernel cursor
 | |
|             kern_assert( kr );
 | |
| #if 0
 | |
|             if (kr != KERN_SUCCESS) {
 | |
|                 ErrorF("Could not set new cursor with kernel return 0x%x.\n", kr);
 | |
|                 ScreenPriv->canHWCursor = FALSE;
 | |
|             }
 | |
| #endif
 | |
|         }
 | |
| 
 | |
|         // make the new cursor visible
 | |
|         if (cshmem->cursorShow)
 | |
|             cshmem->cursorShow--;
 | |
| 
 | |
|         if (!cshmem->cursorShow && ScreenPriv->canHWCursor) {
 | |
|             kr = IOFBSetCursorVisible(iokitScreen->fbService, TRUE);
 | |
|             // FIXME: this is a fatal error without the kernel cursor
 | |
|             kern_assert( kr );
 | |
| #if 0
 | |
|             if (kr != KERN_SUCCESS) {
 | |
|                 ErrorF("Couldn't set hardware cursor visible with kernel return 0x%x.\n", kr);
 | |
|                 ScreenPriv->canHWCursor = FALSE;
 | |
|             } else
 | |
| #endif
 | |
|                 ScreenPriv->cursorMode = 2;     // hardware cursor
 | |
|         }
 | |
| 
 | |
| 	return; 
 | |
|     }
 | |
| 
 | |
|     // otherwise we use a software cursor
 | |
|     if (ScreenPriv->cursorMode) {
 | |
|         /* remove the kernel or hardware cursor */
 | |
|         XFIOKitSetCursor(pScreen, 0, x, y);
 | |
|     }
 | |
| 
 | |
|     ScreenPriv->cursorMode = 0;
 | |
|     (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCursor, x, y);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * XFIOKitMoveCursor
 | |
|  * Move the cursor. This is a noop for a kernel or hardware cursor.
 | |
|  */
 | |
| static void
 | |
| XFIOKitMoveCursor(
 | |
|     ScreenPtr   pScreen,
 | |
|     int         x,
 | |
|     int         y)
 | |
| {
 | |
|     XFIOKitCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
 | |
| 
 | |
|     // only the X cursor needs to be explicitly moved
 | |
|     if (!ScreenPriv->cursorMode)
 | |
|         (*ScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, y);
 | |
| }
 | |
| 
 | |
| static miPointerSpriteFuncRec darwinSpriteFuncsRec = {
 | |
|     XFIOKitRealizeCursor,
 | |
|     XFIOKitUnrealizeCursor,
 | |
|     XFIOKitSetCursor,
 | |
|     XFIOKitMoveCursor
 | |
| };
 | |
| 
 | |
| 
 | |
| /*
 | |
| ===========================================================================
 | |
| 
 | |
|  Pointer screen functions
 | |
| 
 | |
| ===========================================================================
 | |
| */
 | |
| 
 | |
| /*
 | |
|  * XFIOKitCursorOffScreen
 | |
|  */
 | |
| static Bool XFIOKitCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
 | |
| {	return FALSE;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * XFIOKitCrossScreen
 | |
|  */
 | |
| static void XFIOKitCrossScreen(ScreenPtr pScreen, Bool entering)
 | |
| {	return;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * XFIOKitWarpCursor
 | |
|  * Change the cursor position without generating an event or motion history
 | |
|  */
 | |
| static void
 | |
| XFIOKitWarpCursor(
 | |
|     ScreenPtr               pScreen,
 | |
|     int                     x,
 | |
|     int                     y)
 | |
| {
 | |
|     kern_return_t           kr;
 | |
| 
 | |
|     kr = IOHIDSetMouseLocation( xfIOKitInputConnect, x, y );
 | |
|     if (kr != KERN_SUCCESS) {
 | |
|         ErrorF("Could not set cursor position with kernel return 0x%x.\n", kr);
 | |
|     }
 | |
|     miPointerWarpCursor(pScreen, x, y);
 | |
| }
 | |
| 
 | |
| static miPointerScreenFuncRec darwinScreenFuncsRec = {
 | |
|   XFIOKitCursorOffScreen,
 | |
|   XFIOKitCrossScreen,
 | |
|   XFIOKitWarpCursor,
 | |
|   DarwinEQPointerPost,
 | |
|   DarwinEQSwitchScreen
 | |
| };
 | |
| 
 | |
| 
 | |
| /*
 | |
| ===========================================================================
 | |
| 
 | |
|  Other screen functions
 | |
| 
 | |
| ===========================================================================
 | |
| */
 | |
| 
 | |
| /*
 | |
|  * XFIOKitCursorQueryBestSize
 | |
|  * Handle queries for best cursor size
 | |
|  */
 | |
| static void
 | |
| XFIOKitCursorQueryBestSize(
 | |
|    int              class, 
 | |
|    unsigned short   *width,
 | |
|    unsigned short   *height,
 | |
|    ScreenPtr        pScreen)
 | |
| {
 | |
|     XFIOKitCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
 | |
| 
 | |
|     if (class == CursorShape) {
 | |
|         *width = CURSORWIDTH;
 | |
|         *height = CURSORHEIGHT;
 | |
|     } else
 | |
|         (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * XFIOKitInitCursor
 | |
|  * Initialize cursor support
 | |
|  */
 | |
| Bool 
 | |
| XFIOKitInitCursor(
 | |
|     ScreenPtr	pScreen)
 | |
| {
 | |
|     XFIOKitScreenPtr        iokitScreen = XFIOKIT_SCREEN_PRIV(pScreen);
 | |
|     XFIOKitCursorScreenPtr  ScreenPriv;
 | |
|     miPointerScreenPtr	    PointPriv;
 | |
|     kern_return_t           kr;
 | |
| 
 | |
|     // start with no cursor displayed
 | |
|     if (!iokitScreen->cursorShmem->cursorShow++) {
 | |
|         if (iokitScreen->cursorShmem->hardwareCursorActive) {
 | |
|             kr = IOFBSetCursorVisible(iokitScreen->fbService, FALSE);
 | |
|             kern_assert( kr );
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // initialize software cursor handling (always needed as backup)
 | |
|     if (!miDCInitialize(pScreen, &darwinScreenFuncsRec)) {
 | |
|         return FALSE;
 | |
|     }
 | |
| 
 | |
|     // allocate private storage for this screen's hardware cursor info
 | |
|     if (darwinCursorGeneration != serverGeneration) {
 | |
|         if ((darwinCursorScreenIndex = AllocateScreenPrivateIndex()) < 0)
 | |
|             return FALSE;
 | |
|         darwinCursorGeneration = serverGeneration; 	
 | |
|     }
 | |
| 
 | |
|     ScreenPriv = xcalloc( 1, sizeof(XFIOKitCursorScreenRec) );
 | |
|     if (!ScreenPriv) return FALSE;
 | |
| 
 | |
|     pScreen->devPrivates[darwinCursorScreenIndex].ptr = (pointer) ScreenPriv;
 | |
| 
 | |
|     // check if a hardware cursor is supported
 | |
|     if (!iokitScreen->cursorShmem->hardwareCursorCapable) {
 | |
|         ScreenPriv->canHWCursor = FALSE;
 | |
|         ErrorF("Hardware cursor not supported.\n");
 | |
|     } else {
 | |
|         // we need to make sure that the hardware cursor really works
 | |
|         ScreenPriv->canHWCursor = TRUE;
 | |
|         kr = IOFBSetNewCursor(iokitScreen->fbService, 0, 0, 0);
 | |
|         if (kr != KERN_SUCCESS) {
 | |
|             ErrorF("Could not set hardware cursor with kernel return 0x%x.\n", kr);
 | |
|             ScreenPriv->canHWCursor = FALSE;
 | |
|         }
 | |
|         kr = IOFBSetCursorVisible(iokitScreen->fbService, TRUE);
 | |
|         if (kr != KERN_SUCCESS) {
 | |
|             ErrorF("Couldn't set hardware cursor visible with kernel return 0x%x.\n", kr);
 | |
|             ScreenPriv->canHWCursor = FALSE;
 | |
|         }
 | |
|         IOFBSetCursorVisible(iokitScreen->fbService, FALSE);
 | |
|     }
 | |
| 
 | |
|     ScreenPriv->cursorMode = 0;
 | |
|     ScreenPriv->pInstalledMap = NULL;
 | |
| 
 | |
|     // override some screen procedures
 | |
|     ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
 | |
|     pScreen->QueryBestSize = XFIOKitCursorQueryBestSize;
 | |
| //    ScreenPriv->ConstrainCursor = pScreen->ConstrainCursor;
 | |
| //    pScreen->ConstrainCursor = XFIOKitConstrainCursor;
 | |
| 
 | |
|     // initialize hardware cursor handling
 | |
|     PointPriv = (miPointerScreenPtr)
 | |
|                     pScreen->devPrivates[miPointerScreenIndex].ptr;
 | |
| 
 | |
|     ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
 | |
|     PointPriv->spriteFuncs = &darwinSpriteFuncsRec; 
 | |
| 
 | |
|     /* Other routines that might be overridden */
 | |
| /*
 | |
|     CursorLimitsProcPtr		CursorLimits;
 | |
|     RecolorCursorProcPtr	RecolorCursor;
 | |
| */
 | |
| 
 | |
|     return TRUE;
 | |
| }
 |