summaryrefslogtreecommitdiff
path: root/hw/xwin/wincursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xwin/wincursor.c')
-rw-r--r--hw/xwin/wincursor.c864
1 files changed, 425 insertions, 439 deletions
diff --git a/hw/xwin/wincursor.c b/hw/xwin/wincursor.c
index 0ed1d1349..b56104fde 100644
--- a/hw/xwin/wincursor.c
+++ b/hw/xwin/wincursor.c
@@ -44,9 +44,9 @@
#define BRIGHTNESS(x) (x##Red * 0.299 + x##Green * 0.587 + x##Blue * 0.114)
#if 0
-# define WIN_DEBUG_MSG winDebug
+#define WIN_DEBUG_MSG winDebug
#else
-# define WIN_DEBUG_MSG(...)
+#define WIN_DEBUG_MSG(...)
#endif
/*
@@ -54,95 +54,90 @@
*/
static void
-winPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
+ winPointerWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
static Bool
-winCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y);
+ winCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y);
static void
-winCrossScreen (ScreenPtr pScreen, Bool fEntering);
+ winCrossScreen(ScreenPtr pScreen, Bool fEntering);
-miPointerScreenFuncRec g_winPointerCursorFuncs =
-{
- winCursorOffScreen,
- winCrossScreen,
- winPointerWarpCursor
+miPointerScreenFuncRec g_winPointerCursorFuncs = {
+ winCursorOffScreen,
+ winCrossScreen,
+ winPointerWarpCursor
};
-
static void
-winPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+winPointerWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
{
- winScreenPriv(pScreen);
- RECT rcClient;
- static Bool s_fInitialWarp = TRUE;
-
- /* Discard first warp call */
- if (s_fInitialWarp)
- {
- /* First warp moves mouse to center of window, just ignore it */
-
- /* Don't ignore subsequent warps */
- s_fInitialWarp = FALSE;
-
- winErrorFVerb (2, "winPointerWarpCursor - Discarding first warp: %d %d\n",
- x, y);
-
- return;
+ winScreenPriv(pScreen);
+ RECT rcClient;
+ static Bool s_fInitialWarp = TRUE;
+
+ /* Discard first warp call */
+ if (s_fInitialWarp) {
+ /* First warp moves mouse to center of window, just ignore it */
+
+ /* Don't ignore subsequent warps */
+ s_fInitialWarp = FALSE;
+
+ winErrorFVerb(2,
+ "winPointerWarpCursor - Discarding first warp: %d %d\n",
+ x, y);
+
+ return;
}
- /*
- Only update the Windows cursor position if root window is active,
- or we are in a rootless mode
- */
- if ((pScreenPriv->hwndScreen == GetForegroundWindow ())
- || pScreenPriv->pScreenInfo->fRootless
+ /*
+ Only update the Windows cursor position if root window is active,
+ or we are in a rootless mode
+ */
+ if ((pScreenPriv->hwndScreen == GetForegroundWindow())
+ || pScreenPriv->pScreenInfo->fRootless
#ifdef XWIN_MULTIWINDOW
- || pScreenPriv->pScreenInfo->fMultiWindow
+ || pScreenPriv->pScreenInfo->fMultiWindow
#endif
- )
- {
- /* Get the client area coordinates */
- GetClientRect (pScreenPriv->hwndScreen, &rcClient);
-
- /* Translate the client area coords to screen coords */
- MapWindowPoints (pScreenPriv->hwndScreen,
- HWND_DESKTOP,
- (LPPOINT)&rcClient,
- 2);
-
- /*
- * Update the Windows cursor position so that we don't
- * immediately warp back to the current position.
- */
- SetCursorPos (rcClient.left + x, rcClient.top + y);
+ ) {
+ /* Get the client area coordinates */
+ GetClientRect(pScreenPriv->hwndScreen, &rcClient);
+
+ /* Translate the client area coords to screen coords */
+ MapWindowPoints(pScreenPriv->hwndScreen,
+ HWND_DESKTOP, (LPPOINT) & rcClient, 2);
+
+ /*
+ * Update the Windows cursor position so that we don't
+ * immediately warp back to the current position.
+ */
+ SetCursorPos(rcClient.left + x, rcClient.top + y);
}
- /* Call the mi warp procedure to do the actual warping in X. */
- miPointerWarpCursor (pDev, pScreen, x, y);
+ /* Call the mi warp procedure to do the actual warping in X. */
+ miPointerWarpCursor(pDev, pScreen, x, y);
}
static Bool
-winCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
+winCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
{
- return FALSE;
+ return FALSE;
}
static void
-winCrossScreen (ScreenPtr pScreen, Bool fEntering)
+winCrossScreen(ScreenPtr pScreen, Bool fEntering)
{
}
static unsigned char
reverse(unsigned char c)
{
- int i;
- unsigned char ret = 0;
- for (i = 0; i < 8; ++i)
- {
- ret |= ((c >> i)&1) << (7 - i);
+ int i;
+ unsigned char ret = 0;
+
+ for (i = 0; i < 8; ++i) {
+ ret |= ((c >> i) & 1) << (7 - i);
}
- return ret;
+ return ret;
}
/*
@@ -150,276 +145,279 @@ reverse(unsigned char c)
* FIXME: Perhaps there are more smart code
*/
static HCURSOR
-winLoadCursor (ScreenPtr pScreen, CursorPtr pCursor, int screen)
+winLoadCursor(ScreenPtr pScreen, CursorPtr pCursor, int screen)
{
- winScreenPriv(pScreen);
- HCURSOR hCursor = NULL;
- unsigned char *pAnd;
- unsigned char *pXor;
- int nCX, nCY;
- int nBytes;
- double dForeY, dBackY;
- BOOL fReverse;
- HBITMAP hAnd, hXor;
- ICONINFO ii;
- unsigned char *pCur;
- int x, y;
- unsigned char bit;
- HDC hDC;
- BITMAPV4HEADER bi;
- BITMAPINFO *pbmi;
- unsigned long *lpBits;
-
- WIN_DEBUG_MSG("winLoadCursor: Win32: %dx%d X11: %dx%d hotspot: %d,%d\n",
- pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy,
- pCursor->bits->width, pCursor->bits->height,
- pCursor->bits->xhot, pCursor->bits->yhot
- );
-
- /* We can use only White and Black, so calc brightness of color
- * Also check if the cursor is inverted */
- dForeY = BRIGHTNESS(pCursor->fore);
- dBackY = BRIGHTNESS(pCursor->back);
- fReverse = dForeY < dBackY;
-
- /* Check wether the X11 cursor is bigger than the win32 cursor */
- if (pScreenPriv->cursor.sm_cx < pCursor->bits->width ||
- pScreenPriv->cursor.sm_cy < pCursor->bits->height)
- {
- winErrorFVerb (3, "winLoadCursor - Windows requires %dx%d cursor but X requires %dx%d\n",
- pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy,
- pCursor->bits->width, pCursor->bits->height);
+ winScreenPriv(pScreen);
+ HCURSOR hCursor = NULL;
+ unsigned char *pAnd;
+ unsigned char *pXor;
+ int nCX, nCY;
+ int nBytes;
+ double dForeY, dBackY;
+ BOOL fReverse;
+ HBITMAP hAnd, hXor;
+ ICONINFO ii;
+ unsigned char *pCur;
+ int x, y;
+ unsigned char bit;
+ HDC hDC;
+ BITMAPV4HEADER bi;
+ BITMAPINFO *pbmi;
+ unsigned long *lpBits;
+
+ WIN_DEBUG_MSG("winLoadCursor: Win32: %dx%d X11: %dx%d hotspot: %d,%d\n",
+ pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy,
+ pCursor->bits->width, pCursor->bits->height,
+ pCursor->bits->xhot, pCursor->bits->yhot);
+
+ /* We can use only White and Black, so calc brightness of color
+ * Also check if the cursor is inverted */
+ dForeY = BRIGHTNESS(pCursor->fore);
+ dBackY = BRIGHTNESS(pCursor->back);
+ fReverse = dForeY < dBackY;
+
+ /* Check wether the X11 cursor is bigger than the win32 cursor */
+ if (pScreenPriv->cursor.sm_cx < pCursor->bits->width ||
+ pScreenPriv->cursor.sm_cy < pCursor->bits->height) {
+ winErrorFVerb(3,
+ "winLoadCursor - Windows requires %dx%d cursor but X requires %dx%d\n",
+ pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy,
+ pCursor->bits->width, pCursor->bits->height);
}
- /* Get the number of bytes required to store the whole cursor image
- * This is roughly (sm_cx * sm_cy) / 8
- * round up to 8 pixel boundary so we can convert whole bytes */
- nBytes = bits_to_bytes(pScreenPriv->cursor.sm_cx) * pScreenPriv->cursor.sm_cy;
-
- /* Get the effective width and height */
- nCX = min(pScreenPriv->cursor.sm_cx, pCursor->bits->width);
- nCY = min(pScreenPriv->cursor.sm_cy, pCursor->bits->height);
-
- /* Allocate memory for the bitmaps */
- pAnd = malloc (nBytes);
- memset (pAnd, 0xFF, nBytes);
- pXor = calloc (1, nBytes);
-
- /* Convert the X11 bitmap to a win32 bitmap
- * The first is for an empty mask */
- if (pCursor->bits->emptyMask)
- {
- int x, y, xmax = bits_to_bytes(nCX);
- for (y = 0; y < nCY; ++y)
- for (x = 0; x < xmax; ++x)
- {
- int nWinPix = bits_to_bytes(pScreenPriv->cursor.sm_cx) * y + x;
- int nXPix = BitmapBytePad(pCursor->bits->width) * y + x;
-
- pAnd[nWinPix] = 0;
- if (fReverse)
- pXor[nWinPix] = reverse (~pCursor->bits->source[nXPix]);
- else
- pXor[nWinPix] = reverse (pCursor->bits->source[nXPix]);
- }
+ /* Get the number of bytes required to store the whole cursor image
+ * This is roughly (sm_cx * sm_cy) / 8
+ * round up to 8 pixel boundary so we can convert whole bytes */
+ nBytes =
+ bits_to_bytes(pScreenPriv->cursor.sm_cx) * pScreenPriv->cursor.sm_cy;
+
+ /* Get the effective width and height */
+ nCX = min(pScreenPriv->cursor.sm_cx, pCursor->bits->width);
+ nCY = min(pScreenPriv->cursor.sm_cy, pCursor->bits->height);
+
+ /* Allocate memory for the bitmaps */
+ pAnd = malloc(nBytes);
+ memset(pAnd, 0xFF, nBytes);
+ pXor = calloc(1, nBytes);
+
+ /* Convert the X11 bitmap to a win32 bitmap
+ * The first is for an empty mask */
+ if (pCursor->bits->emptyMask) {
+ int x, y, xmax = bits_to_bytes(nCX);
+
+ for (y = 0; y < nCY; ++y)
+ for (x = 0; x < xmax; ++x) {
+ int nWinPix = bits_to_bytes(pScreenPriv->cursor.sm_cx) * y + x;
+ int nXPix = BitmapBytePad(pCursor->bits->width) * y + x;
+
+ pAnd[nWinPix] = 0;
+ if (fReverse)
+ pXor[nWinPix] = reverse(~pCursor->bits->source[nXPix]);
+ else
+ pXor[nWinPix] = reverse(pCursor->bits->source[nXPix]);
+ }
}
- else
- {
- int x, y, xmax = bits_to_bytes(nCX);
- for (y = 0; y < nCY; ++y)
- for (x = 0; x < xmax; ++x)
- {
- int nWinPix = bits_to_bytes(pScreenPriv->cursor.sm_cx) * y + x;
- int nXPix = BitmapBytePad(pCursor->bits->width) * y + x;
-
- unsigned char mask = pCursor->bits->mask[nXPix];
- pAnd[nWinPix] = reverse (~mask);
- if (fReverse)
- pXor[nWinPix] = reverse (~pCursor->bits->source[nXPix] & mask);
- else
- pXor[nWinPix] = reverse (pCursor->bits->source[nXPix] & mask);
- }
+ else {
+ int x, y, xmax = bits_to_bytes(nCX);
+
+ for (y = 0; y < nCY; ++y)
+ for (x = 0; x < xmax; ++x) {
+ int nWinPix = bits_to_bytes(pScreenPriv->cursor.sm_cx) * y + x;
+ int nXPix = BitmapBytePad(pCursor->bits->width) * y + x;
+
+ unsigned char mask = pCursor->bits->mask[nXPix];
+
+ pAnd[nWinPix] = reverse(~mask);
+ if (fReverse)
+ pXor[nWinPix] =
+ reverse(~pCursor->bits->source[nXPix] & mask);
+ else
+ pXor[nWinPix] =
+ reverse(pCursor->bits->source[nXPix] & mask);
+ }
}
- /* prepare the pointers */
- hCursor = NULL;
- lpBits = NULL;
-
- /* We have a truecolor alpha-blended cursor and can use it! */
- if (pCursor->bits->argb)
- {
- WIN_DEBUG_MSG("winLoadCursor: Trying truecolor alphablended cursor\n");
- memset (&bi, 0, sizeof (BITMAPV4HEADER));
- bi.bV4Size = sizeof(BITMAPV4HEADER);
- bi.bV4Width = pScreenPriv->cursor.sm_cx;
- bi.bV4Height = -(pScreenPriv->cursor.sm_cy); /* right-side up */
- bi.bV4Planes = 1;
- bi.bV4BitCount = 32;
- bi.bV4V4Compression = BI_BITFIELDS;
- bi.bV4RedMask = 0x00FF0000;
- bi.bV4GreenMask = 0x0000FF00;
- bi.bV4BlueMask = 0x000000FF;
- bi.bV4AlphaMask = 0xFF000000;
-
- lpBits = (unsigned long *) calloc (pScreenPriv->cursor.sm_cx*pScreenPriv->cursor.sm_cy,
- sizeof (unsigned long));
-
- if (lpBits)
- {
- for (y=0; y<nCY; y++)
- {
- unsigned long *src, *dst;
- src = &(pCursor->bits->argb[y * pCursor->bits->width]);
- dst = &(lpBits[y * pScreenPriv->cursor.sm_cx]);
- memcpy (dst, src, 4*nCX);
- }
- }
- } /* End if-truecolor-icon */
-
- if (!lpBits)
- {
- /* Bicolor, use a palettized DIB */
- WIN_DEBUG_MSG("winLoadCursor: Trying two color cursor\n");
- pbmi = (BITMAPINFO*)&bi;
- memset (pbmi, 0, sizeof (BITMAPINFOHEADER));
- pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pbmi->bmiHeader.biWidth = pScreenPriv->cursor.sm_cx;
- pbmi->bmiHeader.biHeight = -abs(pScreenPriv->cursor.sm_cy); /* right-side up */
- pbmi->bmiHeader.biPlanes = 1;
- pbmi->bmiHeader.biBitCount = 8;
- pbmi->bmiHeader.biCompression = BI_RGB;
- pbmi->bmiHeader.biSizeImage = 0;
- pbmi->bmiHeader.biClrUsed = 3;
- pbmi->bmiHeader.biClrImportant = 3;
- pbmi->bmiColors[0].rgbRed = 0; /* Empty */
- pbmi->bmiColors[0].rgbGreen = 0;
- pbmi->bmiColors[0].rgbBlue = 0;
- pbmi->bmiColors[0].rgbReserved = 0;
- pbmi->bmiColors[1].rgbRed = pCursor->backRed>>8; /* Background */
- pbmi->bmiColors[1].rgbGreen = pCursor->backGreen>>8;
- pbmi->bmiColors[1].rgbBlue = pCursor->backBlue>>8;
- pbmi->bmiColors[1].rgbReserved = 0;
- pbmi->bmiColors[2].rgbRed = pCursor->foreRed>>8; /* Foreground */
- pbmi->bmiColors[2].rgbGreen = pCursor->foreGreen>>8;
- pbmi->bmiColors[2].rgbBlue = pCursor->foreBlue>>8;
- pbmi->bmiColors[2].rgbReserved = 0;
-
- lpBits = (unsigned long *) calloc (pScreenPriv->cursor.sm_cx*pScreenPriv->cursor.sm_cy,
- sizeof (char));
-
- pCur = (unsigned char *)lpBits;
- if (lpBits)
- {
- for (y=0; y<pScreenPriv->cursor.sm_cy; y++)
- {
- for (x=0; x<pScreenPriv->cursor.sm_cx; x++)
- {
- if (x>=nCX || y>=nCY) /* Outside of X11 icon bounds */
- (*pCur++) = 0;
- else /* Within X11 icon bounds */
- {
- int nWinPix = bits_to_bytes(pScreenPriv->cursor.sm_cx) * y + (x/8);
-
- bit = pAnd[nWinPix];
- bit = bit & (1<<(7-(x&7)));
- if (!bit) /* Within the cursor mask? */
- {
- int nXPix = BitmapBytePad(pCursor->bits->width) * y + (x/8);
- bit = ~reverse(~pCursor->bits->source[nXPix] & pCursor->bits->mask[nXPix]);
- bit = bit & (1<<(7-(x&7)));
- if (bit) /* Draw foreground */
- (*pCur++) = 2;
- else /* Draw background */
- (*pCur++) = 1;
- }
- else /* Outside the cursor mask */
- (*pCur++) = 0;
- }
- } /* end for (x) */
- } /* end for (y) */
- } /* end if (lpbits) */
+ /* prepare the pointers */
+ hCursor = NULL;
+ lpBits = NULL;
+
+ /* We have a truecolor alpha-blended cursor and can use it! */
+ if (pCursor->bits->argb) {
+ WIN_DEBUG_MSG("winLoadCursor: Trying truecolor alphablended cursor\n");
+ memset(&bi, 0, sizeof(BITMAPV4HEADER));
+ bi.bV4Size = sizeof(BITMAPV4HEADER);
+ bi.bV4Width = pScreenPriv->cursor.sm_cx;
+ bi.bV4Height = -(pScreenPriv->cursor.sm_cy); /* right-side up */
+ bi.bV4Planes = 1;
+ bi.bV4BitCount = 32;
+ bi.bV4V4Compression = BI_BITFIELDS;
+ bi.bV4RedMask = 0x00FF0000;
+ bi.bV4GreenMask = 0x0000FF00;
+ bi.bV4BlueMask = 0x000000FF;
+ bi.bV4AlphaMask = 0xFF000000;
+
+ lpBits =
+ (unsigned long *) calloc(pScreenPriv->cursor.sm_cx *
+ pScreenPriv->cursor.sm_cy,
+ sizeof(unsigned long));
+
+ if (lpBits) {
+ for (y = 0; y < nCY; y++) {
+ unsigned long *src, *dst;
+
+ src = &(pCursor->bits->argb[y * pCursor->bits->width]);
+ dst = &(lpBits[y * pScreenPriv->cursor.sm_cx]);
+ memcpy(dst, src, 4 * nCX);
+ }
+ }
+ } /* End if-truecolor-icon */
+
+ if (!lpBits) {
+ /* Bicolor, use a palettized DIB */
+ WIN_DEBUG_MSG("winLoadCursor: Trying two color cursor\n");
+ pbmi = (BITMAPINFO *) & bi;
+ memset(pbmi, 0, sizeof(BITMAPINFOHEADER));
+ pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pbmi->bmiHeader.biWidth = pScreenPriv->cursor.sm_cx;
+ pbmi->bmiHeader.biHeight = -abs(pScreenPriv->cursor.sm_cy); /* right-side up */
+ pbmi->bmiHeader.biPlanes = 1;
+ pbmi->bmiHeader.biBitCount = 8;
+ pbmi->bmiHeader.biCompression = BI_RGB;
+ pbmi->bmiHeader.biSizeImage = 0;
+ pbmi->bmiHeader.biClrUsed = 3;
+ pbmi->bmiHeader.biClrImportant = 3;
+ pbmi->bmiColors[0].rgbRed = 0; /* Empty */
+ pbmi->bmiColors[0].rgbGreen = 0;
+ pbmi->bmiColors[0].rgbBlue = 0;
+ pbmi->bmiColors[0].rgbReserved = 0;
+ pbmi->bmiColors[1].rgbRed = pCursor->backRed >> 8; /* Background */
+ pbmi->bmiColors[1].rgbGreen = pCursor->backGreen >> 8;
+ pbmi->bmiColors[1].rgbBlue = pCursor->backBlue >> 8;
+ pbmi->bmiColors[1].rgbReserved = 0;
+ pbmi->bmiColors[2].rgbRed = pCursor->foreRed >> 8; /* Foreground */
+ pbmi->bmiColors[2].rgbGreen = pCursor->foreGreen >> 8;
+ pbmi->bmiColors[2].rgbBlue = pCursor->foreBlue >> 8;
+ pbmi->bmiColors[2].rgbReserved = 0;
+
+ lpBits =
+ (unsigned long *) calloc(pScreenPriv->cursor.sm_cx *
+ pScreenPriv->cursor.sm_cy, sizeof(char));
+
+ pCur = (unsigned char *) lpBits;
+ if (lpBits) {
+ for (y = 0; y < pScreenPriv->cursor.sm_cy; y++) {
+ for (x = 0; x < pScreenPriv->cursor.sm_cx; x++) {
+ if (x >= nCX || y >= nCY) /* Outside of X11 icon bounds */
+ (*pCur++) = 0;
+ else { /* Within X11 icon bounds */
+
+ int nWinPix =
+ bits_to_bytes(pScreenPriv->cursor.sm_cx) * y +
+ (x / 8);
+
+ bit = pAnd[nWinPix];
+ bit = bit & (1 << (7 - (x & 7)));
+ if (!bit) { /* Within the cursor mask? */
+ int nXPix =
+ BitmapBytePad(pCursor->bits->width) * y +
+ (x / 8);
+ bit =
+ ~reverse(~pCursor->bits->
+ source[nXPix] & pCursor->bits->
+ mask[nXPix]);
+ bit = bit & (1 << (7 - (x & 7)));
+ if (bit) /* Draw foreground */
+ (*pCur++) = 2;
+ else /* Draw background */
+ (*pCur++) = 1;
+ }
+ else /* Outside the cursor mask */
+ (*pCur++) = 0;
+ }
+ } /* end for (x) */
+ } /* end for (y) */
+ } /* end if (lpbits) */
}
- /* If one of the previous two methods gave us the bitmap we need, make a cursor */
- if (lpBits)
- {
- WIN_DEBUG_MSG("winLoadCursor: Creating bitmap cursor: hotspot %d,%d\n",
- pCursor->bits->xhot, pCursor->bits->yhot);
-
- hAnd = NULL;
- hXor = NULL;
-
- hAnd = CreateBitmap (pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy, 1, 1, pAnd);
-
- hDC = GetDC (NULL);
- if (hDC)
- {
- hXor = CreateCompatibleBitmap (hDC, pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy);
- SetDIBits (hDC, hXor, 0, pScreenPriv->cursor.sm_cy, lpBits, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
- ReleaseDC (NULL, hDC);
- }
- free (lpBits);
-
-
- if (hAnd && hXor)
- {
- ii.fIcon = FALSE;
- ii.xHotspot = pCursor->bits->xhot;
- ii.yHotspot = pCursor->bits->yhot;
- ii.hbmMask = hAnd;
- ii.hbmColor = hXor;
- hCursor = (HCURSOR) CreateIconIndirect( &ii );
-
- if (hCursor == NULL)
- winW32Error(2, "winLoadCursor - CreateIconIndirect failed:");
- else
- {
- if (GetIconInfo(hCursor, &ii))
- {
- if (ii.fIcon)
- {
- WIN_DEBUG_MSG("winLoadCursor: CreateIconIndirect returned no cursor. Trying again.\n");
-
- DestroyCursor(hCursor);
-
- ii.fIcon = FALSE;
- ii.xHotspot = pCursor->bits->xhot;
- ii.yHotspot = pCursor->bits->yhot;
- hCursor = (HCURSOR) CreateIconIndirect( &ii );
-
- if (hCursor == NULL)
- winW32Error(2, "winLoadCursor - CreateIconIndirect failed:");
- }
- /* GetIconInfo creates new bitmaps. Destroy them again */
- if (ii.hbmMask)
- DeleteObject(ii.hbmMask);
- if (ii.hbmColor)
- DeleteObject(ii.hbmColor);
- }
- }
- }
-
- if (hAnd)
- DeleteObject (hAnd);
- if (hXor)
- DeleteObject (hXor);
+ /* If one of the previous two methods gave us the bitmap we need, make a cursor */
+ if (lpBits) {
+ WIN_DEBUG_MSG("winLoadCursor: Creating bitmap cursor: hotspot %d,%d\n",
+ pCursor->bits->xhot, pCursor->bits->yhot);
+
+ hAnd = NULL;
+ hXor = NULL;
+
+ hAnd =
+ CreateBitmap(pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy,
+ 1, 1, pAnd);
+
+ hDC = GetDC(NULL);
+ if (hDC) {
+ hXor =
+ CreateCompatibleBitmap(hDC, pScreenPriv->cursor.sm_cx,
+ pScreenPriv->cursor.sm_cy);
+ SetDIBits(hDC, hXor, 0, pScreenPriv->cursor.sm_cy, lpBits,
+ (BITMAPINFO *) & bi, DIB_RGB_COLORS);
+ ReleaseDC(NULL, hDC);
+ }
+ free(lpBits);
+
+ if (hAnd && hXor) {
+ ii.fIcon = FALSE;
+ ii.xHotspot = pCursor->bits->xhot;
+ ii.yHotspot = pCursor->bits->yhot;
+ ii.hbmMask = hAnd;
+ ii.hbmColor = hXor;
+ hCursor = (HCURSOR) CreateIconIndirect(&ii);
+
+ if (hCursor == NULL)
+ winW32Error(2, "winLoadCursor - CreateIconIndirect failed:");
+ else {
+ if (GetIconInfo(hCursor, &ii)) {
+ if (ii.fIcon) {
+ WIN_DEBUG_MSG
+ ("winLoadCursor: CreateIconIndirect returned no cursor. Trying again.\n");
+
+ DestroyCursor(hCursor);
+
+ ii.fIcon = FALSE;
+ ii.xHotspot = pCursor->bits->xhot;
+ ii.yHotspot = pCursor->bits->yhot;
+ hCursor = (HCURSOR) CreateIconIndirect(&ii);
+
+ if (hCursor == NULL)
+ winW32Error(2,
+ "winLoadCursor - CreateIconIndirect failed:");
+ }
+ /* GetIconInfo creates new bitmaps. Destroy them again */
+ if (ii.hbmMask)
+ DeleteObject(ii.hbmMask);
+ if (ii.hbmColor)
+ DeleteObject(ii.hbmColor);
+ }
+ }
+ }
+
+ if (hAnd)
+ DeleteObject(hAnd);
+ if (hXor)
+ DeleteObject(hXor);
}
- if (!hCursor)
- {
- /* We couldn't make a color cursor for this screen, use
- black and white instead */
- hCursor = CreateCursor (g_hInstance,
- pCursor->bits->xhot, pCursor->bits->yhot,
- pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy,
- pAnd, pXor);
- if (hCursor == NULL)
- winW32Error(2, "winLoadCursor - CreateCursor failed:");
+ if (!hCursor) {
+ /* We couldn't make a color cursor for this screen, use
+ black and white instead */
+ hCursor = CreateCursor(g_hInstance,
+ pCursor->bits->xhot, pCursor->bits->yhot,
+ pScreenPriv->cursor.sm_cx,
+ pScreenPriv->cursor.sm_cy, pAnd, pXor);
+ if (hCursor == NULL)
+ winW32Error(2, "winLoadCursor - CreateCursor failed:");
}
- free (pAnd);
- free (pXor);
+ free(pAnd);
+ free(pXor);
- return hCursor;
+ return hCursor;
}
/*
@@ -435,16 +433,15 @@ winLoadCursor (ScreenPtr pScreen, CursorPtr pCursor, int screen)
* Convert the X cursor representation to native format if possible.
*/
static Bool
-winRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+winRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
{
- if(pCursor == NULL || pCursor->bits == NULL)
- return FALSE;
-
- /* FIXME: cache ARGB8888 representation? */
+ if (pCursor == NULL || pCursor->bits == NULL)
+ return FALSE;
- return TRUE;
-}
+ /* FIXME: cache ARGB8888 representation? */
+ return TRUE;
+}
/*
* winUnrealizeCursor
@@ -453,121 +450,110 @@ winRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
static Bool
winUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
{
- return TRUE;
+ return TRUE;
}
-
/*
* winSetCursor
* Set the cursor sprite and position.
*/
static void
-winSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+winSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x,
+ int y)
{
- POINT ptCurPos, ptTemp;
- HWND hwnd;
- RECT rcClient;
- BOOL bInhibit;
- winScreenPriv(pScreen);
- WIN_DEBUG_MSG("winSetCursor: cursor=%p\n", pCursor);
-
- /* Inhibit changing the cursor if the mouse is not in a client area */
- bInhibit = FALSE;
- if (GetCursorPos (&ptCurPos))
- {
- hwnd = WindowFromPoint (ptCurPos);
- if (hwnd)
- {
- if (GetClientRect (hwnd, &rcClient))
- {
- ptTemp.x = rcClient.left;
- ptTemp.y = rcClient.top;
- if (ClientToScreen (hwnd, &ptTemp))
- {
- rcClient.left = ptTemp.x;
- rcClient.top = ptTemp.y;
- ptTemp.x = rcClient.right;
- ptTemp.y = rcClient.bottom;
- if (ClientToScreen (hwnd, &ptTemp))
- {
- rcClient.right = ptTemp.x;
- rcClient.bottom = ptTemp.y;
- if (!PtInRect (&rcClient, ptCurPos))
- bInhibit = TRUE;
- }
- }
- }
- }
+ POINT ptCurPos, ptTemp;
+ HWND hwnd;
+ RECT rcClient;
+ BOOL bInhibit;
+
+ winScreenPriv(pScreen);
+ WIN_DEBUG_MSG("winSetCursor: cursor=%p\n", pCursor);
+
+ /* Inhibit changing the cursor if the mouse is not in a client area */
+ bInhibit = FALSE;
+ if (GetCursorPos(&ptCurPos)) {
+ hwnd = WindowFromPoint(ptCurPos);
+ if (hwnd) {
+ if (GetClientRect(hwnd, &rcClient)) {
+ ptTemp.x = rcClient.left;
+ ptTemp.y = rcClient.top;
+ if (ClientToScreen(hwnd, &ptTemp)) {
+ rcClient.left = ptTemp.x;
+ rcClient.top = ptTemp.y;
+ ptTemp.x = rcClient.right;
+ ptTemp.y = rcClient.bottom;
+ if (ClientToScreen(hwnd, &ptTemp)) {
+ rcClient.right = ptTemp.x;
+ rcClient.bottom = ptTemp.y;
+ if (!PtInRect(&rcClient, ptCurPos))
+ bInhibit = TRUE;
+ }
+ }
+ }
+ }
}
- if (pCursor == NULL)
- {
- if (pScreenPriv->cursor.visible)
- {
- if (!bInhibit && g_fSoftwareCursor)
- ShowCursor (FALSE);
- pScreenPriv->cursor.visible = FALSE;
- }
+ if (pCursor == NULL) {
+ if (pScreenPriv->cursor.visible) {
+ if (!bInhibit && g_fSoftwareCursor)
+ ShowCursor(FALSE);
+ pScreenPriv->cursor.visible = FALSE;
+ }
}
- else
- {
- if (pScreenPriv->cursor.handle)
- {
- if (!bInhibit)
- SetCursor (NULL);
- DestroyCursor (pScreenPriv->cursor.handle);
- pScreenPriv->cursor.handle = NULL;
- }
- pScreenPriv->cursor.handle =
- winLoadCursor (pScreen, pCursor, pScreen->myNum);
- WIN_DEBUG_MSG("winSetCursor: handle=%p\n", pScreenPriv->cursor.handle);
-
- if (!bInhibit)
- SetCursor (pScreenPriv->cursor.handle);
-
- if (!pScreenPriv->cursor.visible)
- {
- if (!bInhibit && g_fSoftwareCursor)
- ShowCursor (TRUE);
- pScreenPriv->cursor.visible = TRUE;
- }
+ else {
+ if (pScreenPriv->cursor.handle) {
+ if (!bInhibit)
+ SetCursor(NULL);
+ DestroyCursor(pScreenPriv->cursor.handle);
+ pScreenPriv->cursor.handle = NULL;
+ }
+ pScreenPriv->cursor.handle =
+ winLoadCursor(pScreen, pCursor, pScreen->myNum);
+ WIN_DEBUG_MSG("winSetCursor: handle=%p\n", pScreenPriv->cursor.handle);
+
+ if (!bInhibit)
+ SetCursor(pScreenPriv->cursor.handle);
+
+ if (!pScreenPriv->cursor.visible) {
+ if (!bInhibit && g_fSoftwareCursor)
+ ShowCursor(TRUE);
+ pScreenPriv->cursor.visible = TRUE;
+ }
}
}
-
/*
* winMoveCursor
* Move the cursor. This is a noop for us.
*/
static void
-winMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+winMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
{
}
static Bool
winDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr)
{
- winScreenPriv(pScr);
- return pScreenPriv->cursor.spriteFuncs->DeviceCursorInitialize(pDev, pScr);
+ winScreenPriv(pScr);
+ return pScreenPriv->cursor.spriteFuncs->DeviceCursorInitialize(pDev, pScr);
}
static void
winDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr)
{
- winScreenPriv(pScr);
- pScreenPriv->cursor.spriteFuncs->DeviceCursorCleanup(pDev, pScr);
+ winScreenPriv(pScr);
+ pScreenPriv->cursor.spriteFuncs->DeviceCursorCleanup(pDev, pScr);
}
static miPointerSpriteFuncRec winSpriteFuncsRec = {
- winRealizeCursor,
- winUnrealizeCursor,
- winSetCursor,
- winMoveCursor,
- winDeviceCursorInitialize,
- winDeviceCursorCleanup
+ winRealizeCursor,
+ winUnrealizeCursor,
+ winSetCursor,
+ winMoveCursor,
+ winDeviceCursorInitialize,
+ winDeviceCursorCleanup
};
-
/*
===========================================================================
@@ -581,20 +567,19 @@ static miPointerSpriteFuncRec winSpriteFuncsRec = {
* Handle queries for best cursor size
*/
static void
-winCursorQueryBestSize (int class, unsigned short *width,
- unsigned short *height, ScreenPtr pScreen)
+winCursorQueryBestSize(int class, unsigned short *width,
+ unsigned short *height, ScreenPtr pScreen)
{
- winScreenPriv(pScreen);
-
- if (class == CursorShape)
- {
- *width = pScreenPriv->cursor.sm_cx;
- *height = pScreenPriv->cursor.sm_cy;
+ winScreenPriv(pScreen);
+
+ if (class == CursorShape) {
+ *width = pScreenPriv->cursor.sm_cx;
+ *height = pScreenPriv->cursor.sm_cy;
}
- else
- {
- if (pScreenPriv->cursor.QueryBestSize)
- (*pScreenPriv->cursor.QueryBestSize)(class, width, height, pScreen);
+ else {
+ if (pScreenPriv->cursor.QueryBestSize)
+ (*pScreenPriv->cursor.QueryBestSize) (class, width, height,
+ pScreen);
}
}
@@ -603,25 +588,26 @@ winCursorQueryBestSize (int class, unsigned short *width,
* Initialize cursor support
*/
Bool
-winInitCursor (ScreenPtr pScreen)
+winInitCursor(ScreenPtr pScreen)
{
- winScreenPriv(pScreen);
- miPointerScreenPtr pPointPriv;
- /* override some screen procedures */
- pScreenPriv->cursor.QueryBestSize = pScreen->QueryBestSize;
- pScreen->QueryBestSize = winCursorQueryBestSize;
-
- pPointPriv = (miPointerScreenPtr)
- dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
-
- pScreenPriv->cursor.spriteFuncs = pPointPriv->spriteFuncs;
- pPointPriv->spriteFuncs = &winSpriteFuncsRec;
-
- pScreenPriv->cursor.handle = NULL;
- pScreenPriv->cursor.visible = FALSE;
-
- pScreenPriv->cursor.sm_cx = GetSystemMetrics (SM_CXCURSOR);
- pScreenPriv->cursor.sm_cy = GetSystemMetrics (SM_CYCURSOR);
-
- return TRUE;
+ winScreenPriv(pScreen);
+ miPointerScreenPtr pPointPriv;
+
+ /* override some screen procedures */
+ pScreenPriv->cursor.QueryBestSize = pScreen->QueryBestSize;
+ pScreen->QueryBestSize = winCursorQueryBestSize;
+
+ pPointPriv = (miPointerScreenPtr)
+ dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
+
+ pScreenPriv->cursor.spriteFuncs = pPointPriv->spriteFuncs;
+ pPointPriv->spriteFuncs = &winSpriteFuncsRec;
+
+ pScreenPriv->cursor.handle = NULL;
+ pScreenPriv->cursor.visible = FALSE;
+
+ pScreenPriv->cursor.sm_cx = GetSystemMetrics(SM_CXCURSOR);
+ pScreenPriv->cursor.sm_cy = GetSystemMetrics(SM_CYCURSOR);
+
+ return TRUE;
}