static XColor *GetShadowOrHiliteColor( Pixel background, float light, float dark, float factor) { long brightness; unsigned int red, green, blue; memset(&color, 0, sizeof(color)); color.pixel = background; XQueryColor(Pdpy, Pcmap, &color); red = color.red; green = color.green; blue = color.blue; brightness = BRIGHTNESS(red, green, blue); /* For "dark" backgrounds, make everything a fixed %age lighter */ if (brightness < XmDEFAULT_DARK_THRESHOLD * PCT_BRIGHTNESS) { color.red = (unsigned short) (0xffff - ((0xffff - red) * dark + 50) / 100); color.green = (unsigned short) (0xffff - ((0xffff - green) * dark + 50) / 100); color.blue = (unsigned short) (0xffff - ((0xffff - blue) * dark + 50) / 100); } /* For "light" background, make everything a fixed %age darker */ else if (brightness > XmDEFAULT_LIGHT_THRESHOLD * PCT_BRIGHTNESS) { color.red = (unsigned short)((red * light + 50) / 100); color.green = (unsigned short)((green * light + 50) / 100); color.blue = (unsigned short)((blue * light + 50) / 100); } /* For "medium" background, select is a fixed %age darker; * top (lighter) and bottom (darker) are a variable %age * based on the background's brightness */ else { color_mult(&color.red, &color.green, &color.blue, factor); } return &color; }
/* * Convert X cursor to Windows cursor * FIXME: Perhaps there are more smart code */ HCURSOR winXCursorToHCURSOR(WMUTIL_CURSOR *pCursor) { 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; unsigned char bit; HDC hDC; BITMAPV4HEADER bi; BITMAPINFO *pbmi; uint32_t *lpBits; int sm_cx = GetSystemMetrics(SM_CXCURSOR); int sm_cy = GetSystemMetrics(SM_CYCURSOR); WIN_DEBUG_MSG("winXCursorToHCURSOR: Win32 size: %dx%d X11 size: %dx%d hotspot: %d,%d\n", sm_cx, sm_cy, pCursor->width, pCursor->height, pCursor->xhot, pCursor->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 whether the X11 cursor is bigger than the win32 cursor */ if (sm_cx < pCursor->width || sm_cy < pCursor->height) { winError("winXCursorToHCURSOR - Windows requires %dx%d cursor but X requires %dx%d\n", sm_cx, sm_cy, pCursor->width, pCursor->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(sm_cx) * sm_cy; /* Get the effective width and height */ nCX = min(sm_cx, pCursor->width); nCY = min(sm_cy, pCursor->height); /* Allocate memory for the bitmaps */ pAnd = malloc(nBytes); memset(pAnd, 0xFF, nBytes); pXor = calloc(1, nBytes); memset(pXor, 0x00, nBytes); /* prepare the pointers */ hCursor = NULL; lpBits = NULL; /* We have a truecolor alpha-blended cursor and can use it! */ if (pCursor->argb) { WIN_DEBUG_MSG("winXCursorToHCURSOR: Trying truecolor alphablended cursor\n"); memset(&bi, 0, sizeof(BITMAPV4HEADER)); bi.bV4Size = sizeof(BITMAPV4HEADER); bi.bV4Width = sm_cx; bi.bV4Height = -(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 = (uint32_t *) calloc(sm_cx * sm_cy, sizeof(uint32_t)); if (lpBits) { int y; for (y = 0; y < nCY; y++) { void *src, *dst; src = &(pCursor->argb[y * pCursor->width]); dst = &(lpBits[y * sm_cx]); memcpy(dst, src, 4 * nCX); } } } /* End if-truecolor-icon */ else { /* Convert the X11 bitmap to a win32 bitmap * The first is for an empty mask */ if (pCursor->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(sm_cx) * y + x; int nXPix = BitmapBytePad(pCursor->width) * y + x; pAnd[nWinPix] = 0; if (fReverse) pXor[nWinPix] = reverse(~pCursor->source[nXPix]); else pXor[nWinPix] = reverse(pCursor->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(sm_cx) * y + x; int nXPix = BitmapBytePad(pCursor->width) * y + x; unsigned char mask = pCursor->mask[nXPix]; pAnd[nWinPix] = reverse(~mask); if (fReverse) pXor[nWinPix] = reverse(~pCursor->source[nXPix] & mask); else pXor[nWinPix] = reverse(pCursor->source[nXPix] & mask); } } } if (!lpBits) { RGBQUAD *pbmiColors; /* Bicolor, use a palettized DIB */ WIN_DEBUG_MSG("winXCursorToHCURSOR: Trying two color cursor\n"); pbmi = (BITMAPINFO *) &bi; pbmiColors = &(pbmi->bmiColors[0]); memset(pbmi, 0, sizeof(BITMAPINFOHEADER)); pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = sm_cx; pbmi->bmiHeader.biHeight = -abs(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; pbmiColors[0].rgbRed = 0; /* Empty */ pbmiColors[0].rgbGreen = 0; pbmiColors[0].rgbBlue = 0; pbmiColors[0].rgbReserved = 0; pbmiColors[1].rgbRed = pCursor->backRed >> 8; /* Background */ pbmiColors[1].rgbGreen = pCursor->backGreen >> 8; pbmiColors[1].rgbBlue = pCursor->backBlue >> 8; pbmiColors[1].rgbReserved = 0; pbmiColors[2].rgbRed = pCursor->foreRed >> 8; /* Foreground */ pbmiColors[2].rgbGreen = pCursor->foreGreen >> 8; pbmiColors[2].rgbBlue = pCursor->foreBlue >> 8; pbmiColors[2].rgbReserved = 0; lpBits = (uint32_t *) calloc(sm_cx * sm_cy, sizeof(char)); pCur = (unsigned char *) lpBits; if (lpBits) { int x, y; for (y = 0; y < sm_cy; y++) { for (x = 0; x < 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(sm_cx) * y + (x / 8); bit = pAnd[nWinPix]; bit = bit & (1 << (7 - (x & 7))); if (!bit) { /* Within the cursor mask? */ int nXPix = BitmapBytePad(pCursor->width) * y + (x / 8); bit = ~reverse(~pCursor-> source[nXPix] & pCursor-> 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) */ }