diff options
Diffstat (limited to 'hw/xwin/wincursor.c')
-rw-r--r-- | hw/xwin/wincursor.c | 864 |
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; } |