internal override IntPtr DefineCursor(Bitmap bitmap, Bitmap mask, Color cursor_pixel, Color mask_pixel, int xHotSpot, int yHotSpot) {
IntPtr cursor;
Bitmap cursor_bitmap;
Bitmap cursor_mask;
Byte[] cursor_bits;
Byte[] mask_bits;
Color c_pixel;
Color m_pixel;
int width;
int height;
IntPtr cursor_pixmap;
IntPtr mask_pixmap;
XColor fg;
XColor bg;
bool and;
bool xor;
if (XQueryBestCursor(DisplayHandle, RootWindow, bitmap.Width, bitmap.Height, out width, out height) == 0) {
return IntPtr.Zero;
}
// Win32 only allows creation cursors of a certain size
if ((bitmap.Width != width) || (bitmap.Width != height)) {
cursor_bitmap = new Bitmap(bitmap, new Size(width, height));
cursor_mask = new Bitmap(mask, new Size(width, height));
} else {
cursor_bitmap = bitmap;
cursor_mask = mask;
}
width = cursor_bitmap.Width;
height = cursor_bitmap.Height;
cursor_bits = new Byte[(width / 8) * height];
mask_bits = new Byte[(width / 8) * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
c_pixel = cursor_bitmap.GetPixel(x, y);
m_pixel = cursor_mask.GetPixel(x, y);
and = c_pixel == cursor_pixel;
xor = m_pixel == mask_pixel;
if (!and && !xor) {
// Black
// cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8))); // The bit already is 0
mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
} else if (and && !xor) {
// White
cursor_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
mask_bits[y * width / 8 + x / 8] |= (byte)(1 << (x % 8));
#if notneeded
} else if (and && !xor) {
// Screen
} else if (and && xor) {
// Inverse Screen
// X11 doesn't know the 'reverse screen' concept, so we'll treat them the same
// we want both to be 0 so nothing to be done
//cursor_bits[y * width / 8 + x / 8] &= (byte)~((1 << (x % 8)));
//mask_bits[y * width / 8 + x / 8] |= (byte)(01 << (x % 8));
#endif
}
}
}
cursor_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, cursor_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
mask_pixmap = XCreatePixmapFromBitmapData(DisplayHandle, RootWindow, mask_bits, width, height, (IntPtr)1, (IntPtr)0, 1);
fg = new XColor();
bg = new XColor();
fg.pixel = XWhitePixel(DisplayHandle, ScreenNo);
fg.red = (ushort)65535;
fg.green = (ushort)65535;
fg.blue = (ushort)65535;
bg.pixel = XBlackPixel(DisplayHandle, ScreenNo);
cursor = XCreatePixmapCursor(DisplayHandle, cursor_pixmap, mask_pixmap, ref fg, ref bg, xHotSpot, yHotSpot);
XFreePixmap(DisplayHandle, cursor_pixmap);
XFreePixmap(DisplayHandle, mask_pixmap);
return cursor;
}