gdk/win32/gdkcursor-win32.c gdk/win32/gdkwindow-win32.c Support
2005-06-04 Tor Lillqvist <tml@novell.com> * gdk/win32/gdkcursor-win32.c * gdk/win32/gdkwindow-win32.c * gdk/win32/gdkprivate-win32.h: Support full-colour cursors. Support cursors with alpha on XP. Use code in common with the support for alpha icons that already was present. (#306101, Tim Evans)
This commit is contained in:
parent
3dde363831
commit
d42fa02bc3
@ -1,5 +1,12 @@
|
|||||||
2005-06-04 Tor Lillqvist <tml@novell.com>
|
2005-06-04 Tor Lillqvist <tml@novell.com>
|
||||||
|
|
||||||
|
* gdk/win32/gdkcursor-win32.c
|
||||||
|
* gdk/win32/gdkwindow-win32.c
|
||||||
|
* gdk/win32/gdkprivate-win32.h: Support full-colour cursors.
|
||||||
|
Support cursors with alpha on XP. Use code in common with the
|
||||||
|
support for alpha icons that already was present. (#306101, Tim
|
||||||
|
Evans)
|
||||||
|
|
||||||
* modules/engines/ms-windows/msw_style.c: Render insensitive icons
|
* modules/engines/ms-windows/msw_style.c: Render insensitive icons
|
||||||
in a way that more closely matches Windows. (#305986, Tim Evans).
|
in a way that more closely matches Windows. (#305986, Tim Evans).
|
||||||
|
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
2005-06-04 Tor Lillqvist <tml@novell.com>
|
2005-06-04 Tor Lillqvist <tml@novell.com>
|
||||||
|
|
||||||
|
* gdk/win32/gdkcursor-win32.c
|
||||||
|
* gdk/win32/gdkwindow-win32.c
|
||||||
|
* gdk/win32/gdkprivate-win32.h: Support full-colour cursors.
|
||||||
|
Support cursors with alpha on XP. Use code in common with the
|
||||||
|
support for alpha icons that already was present. (#306101, Tim
|
||||||
|
Evans)
|
||||||
|
|
||||||
* modules/engines/ms-windows/msw_style.c: Render insensitive icons
|
* modules/engines/ms-windows/msw_style.c: Render insensitive icons
|
||||||
in a way that more closely matches Windows. (#305986, Tim Evans).
|
in a way that more closely matches Windows. (#305986, Tim Evans).
|
||||||
|
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
2005-06-04 Tor Lillqvist <tml@novell.com>
|
2005-06-04 Tor Lillqvist <tml@novell.com>
|
||||||
|
|
||||||
|
* gdk/win32/gdkcursor-win32.c
|
||||||
|
* gdk/win32/gdkwindow-win32.c
|
||||||
|
* gdk/win32/gdkprivate-win32.h: Support full-colour cursors.
|
||||||
|
Support cursors with alpha on XP. Use code in common with the
|
||||||
|
support for alpha icons that already was present. (#306101, Tim
|
||||||
|
Evans)
|
||||||
|
|
||||||
* modules/engines/ms-windows/msw_style.c: Render insensitive icons
|
* modules/engines/ms-windows/msw_style.c: Render insensitive icons
|
||||||
in a way that more closely matches Windows. (#305986, Tim Evans).
|
in a way that more closely matches Windows. (#305986, Tim Evans).
|
||||||
|
|
||||||
|
@ -26,6 +26,35 @@
|
|||||||
|
|
||||||
#include "xcursors.h"
|
#include "xcursors.h"
|
||||||
|
|
||||||
|
#if defined(__MINGW32__) || (defined(_MSC_VER) && (WINVER < 0x0500))
|
||||||
|
typedef struct {
|
||||||
|
DWORD bV5Size;
|
||||||
|
LONG bV5Width;
|
||||||
|
LONG bV5Height;
|
||||||
|
WORD bV5Planes;
|
||||||
|
WORD bV5BitCount;
|
||||||
|
DWORD bV5Compression;
|
||||||
|
DWORD bV5SizeImage;
|
||||||
|
LONG bV5XPelsPerMeter;
|
||||||
|
LONG bV5YPelsPerMeter;
|
||||||
|
DWORD bV5ClrUsed;
|
||||||
|
DWORD bV5ClrImportant;
|
||||||
|
DWORD bV5RedMask;
|
||||||
|
DWORD bV5GreenMask;
|
||||||
|
DWORD bV5BlueMask;
|
||||||
|
DWORD bV5AlphaMask;
|
||||||
|
DWORD bV5CSType;
|
||||||
|
CIEXYZTRIPLE bV5Endpoints;
|
||||||
|
DWORD bV5GammaRed;
|
||||||
|
DWORD bV5GammaGreen;
|
||||||
|
DWORD bV5GammaBlue;
|
||||||
|
DWORD bV5Intent;
|
||||||
|
DWORD bV5ProfileData;
|
||||||
|
DWORD bV5ProfileSize;
|
||||||
|
DWORD bV5Reserved;
|
||||||
|
} BITMAPV5HEADER;
|
||||||
|
#endif
|
||||||
|
|
||||||
static HCURSOR
|
static HCURSOR
|
||||||
_gdk_win32_data_to_wcursor (GdkCursorType cursor_type)
|
_gdk_win32_data_to_wcursor (GdkCursorType cursor_type)
|
||||||
{
|
{
|
||||||
@ -85,12 +114,25 @@ _gdk_win32_data_to_wcursor (GdkCursorType cursor_type)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GdkCursor*
|
||||||
|
_gdk_win32_cursor_new_from_hcursor (HCURSOR hcursor, GdkCursorType cursor_type)
|
||||||
|
{
|
||||||
|
GdkCursorPrivate *private;
|
||||||
|
GdkCursor *cursor;
|
||||||
|
|
||||||
|
private = g_new (GdkCursorPrivate, 1);
|
||||||
|
private->hcursor = hcursor;
|
||||||
|
cursor = (GdkCursor*) private;
|
||||||
|
cursor->type = cursor_type;
|
||||||
|
cursor->ref_count = 1;
|
||||||
|
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
GdkCursor*
|
GdkCursor*
|
||||||
gdk_cursor_new_for_display (GdkDisplay *display,
|
gdk_cursor_new_for_display (GdkDisplay *display,
|
||||||
GdkCursorType cursor_type)
|
GdkCursorType cursor_type)
|
||||||
{
|
{
|
||||||
GdkCursorPrivate *private;
|
|
||||||
GdkCursor *cursor;
|
|
||||||
HCURSOR hcursor;
|
HCURSOR hcursor;
|
||||||
|
|
||||||
g_return_val_if_fail (display == gdk_display_get_default (), NULL);
|
g_return_val_if_fail (display == gdk_display_get_default (), NULL);
|
||||||
@ -103,13 +145,7 @@ gdk_cursor_new_for_display (GdkDisplay *display,
|
|||||||
GDK_NOTE (MISC, g_print ("gdk_cursor_new_for_display: %d: %p\n",
|
GDK_NOTE (MISC, g_print ("gdk_cursor_new_for_display: %d: %p\n",
|
||||||
cursor_type, hcursor));
|
cursor_type, hcursor));
|
||||||
|
|
||||||
private = g_new (GdkCursorPrivate, 1);
|
return _gdk_win32_cursor_new_from_hcursor (hcursor, cursor_type);
|
||||||
private->hcursor = hcursor;
|
|
||||||
cursor = (GdkCursor*) private;
|
|
||||||
cursor->type = cursor_type;
|
|
||||||
cursor->ref_count = 1;
|
|
||||||
|
|
||||||
return cursor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -128,8 +164,6 @@ gdk_cursor_new_from_pixmap (GdkPixmap *source,
|
|||||||
gint x,
|
gint x,
|
||||||
gint y)
|
gint y)
|
||||||
{
|
{
|
||||||
GdkCursorPrivate *private;
|
|
||||||
GdkCursor *cursor;
|
|
||||||
GdkPixmapImplWin32 *source_impl, *mask_impl;
|
GdkPixmapImplWin32 *source_impl, *mask_impl;
|
||||||
guchar *source_bits, *mask_bits;
|
guchar *source_bits, *mask_bits;
|
||||||
gint source_bpl, mask_bpl;
|
gint source_bpl, mask_bpl;
|
||||||
@ -285,13 +319,7 @@ gdk_cursor_new_from_pixmap (GdkPixmap *source,
|
|||||||
g_free (xor_mask);
|
g_free (xor_mask);
|
||||||
g_free (and_mask);
|
g_free (and_mask);
|
||||||
|
|
||||||
private = g_new (GdkCursorPrivate, 1);
|
return _gdk_win32_cursor_new_from_hcursor (hcursor, GDK_CURSOR_IS_PIXMAP);
|
||||||
private->hcursor = hcursor;
|
|
||||||
cursor = (GdkCursor*) private;
|
|
||||||
cursor->type = GDK_CURSOR_IS_PIXMAP;
|
|
||||||
cursor->ref_count = 1;
|
|
||||||
|
|
||||||
return cursor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -326,71 +354,17 @@ gdk_cursor_new_from_pixbuf (GdkDisplay *display,
|
|||||||
gint x,
|
gint x,
|
||||||
gint y)
|
gint y)
|
||||||
{
|
{
|
||||||
/* FIXME: Use alpha if supported */
|
HCURSOR hcursor;
|
||||||
|
|
||||||
GdkCursor *cursor;
|
|
||||||
GdkPixmap *pixmap, *mask;
|
|
||||||
guint width, height, n_channels, rowstride, i, j;
|
|
||||||
guint8 *data, *mask_data, *pixels;
|
|
||||||
GdkColor fg = { 0, 0, 0, 0 };
|
|
||||||
GdkColor bg = { 0, 0xffff, 0xffff, 0xffff };
|
|
||||||
GdkScreen *screen;
|
|
||||||
|
|
||||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||||
g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
|
g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
|
||||||
|
g_return_val_if_fail (0 <= x && x < gdk_pixbuf_get_width (pixbuf), NULL);
|
||||||
|
g_return_val_if_fail (0 <= y && y < gdk_pixbuf_get_height (pixbuf), NULL);
|
||||||
|
|
||||||
width = gdk_pixbuf_get_width (pixbuf);
|
hcursor = _gdk_win32_pixbuf_to_hcursor (pixbuf, x, y);
|
||||||
height = gdk_pixbuf_get_height (pixbuf);
|
if (!hcursor)
|
||||||
|
return NULL;
|
||||||
g_return_val_if_fail (0 <= x && x < width, NULL);
|
return _gdk_win32_cursor_new_from_hcursor (hcursor, GDK_CURSOR_IS_PIXMAP);
|
||||||
g_return_val_if_fail (0 <= y && y < height, NULL);
|
|
||||||
|
|
||||||
n_channels = gdk_pixbuf_get_n_channels (pixbuf);
|
|
||||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
|
||||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
|
||||||
|
|
||||||
data = g_new0 (guint8, (width + 7) / 8 * height);
|
|
||||||
mask_data = g_new0 (guint8, (width + 7) / 8 * height);
|
|
||||||
|
|
||||||
for (j = 0; j < height; j++)
|
|
||||||
{
|
|
||||||
guint8 *src = pixels + j * rowstride;
|
|
||||||
guint8 *d = data + (width + 7) / 8 * j;
|
|
||||||
guint8 *md = mask_data + (width + 7) / 8 * j;
|
|
||||||
|
|
||||||
for (i = 0; i < width; i++)
|
|
||||||
{
|
|
||||||
if (src[1] < 0x80)
|
|
||||||
*d |= 1 << (i % 8);
|
|
||||||
|
|
||||||
if (n_channels == 3 || src[3] >= 0x80)
|
|
||||||
*md |= 1 << (i % 8);
|
|
||||||
|
|
||||||
src += n_channels;
|
|
||||||
if (i % 8 == 7)
|
|
||||||
{
|
|
||||||
d++;
|
|
||||||
md++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
screen = gdk_display_get_default_screen (display);
|
|
||||||
pixmap = gdk_bitmap_create_from_data (gdk_screen_get_root_window (screen),
|
|
||||||
data, width, height);
|
|
||||||
|
|
||||||
mask = gdk_bitmap_create_from_data (gdk_screen_get_root_window (screen),
|
|
||||||
mask_data, width, height);
|
|
||||||
|
|
||||||
cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg, x, y);
|
|
||||||
|
|
||||||
g_object_unref (pixmap);
|
|
||||||
g_object_unref (mask);
|
|
||||||
|
|
||||||
g_free (data);
|
|
||||||
g_free (mask_data);
|
|
||||||
|
|
||||||
return cursor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -398,8 +372,7 @@ gdk_display_supports_cursor_alpha (GdkDisplay *display)
|
|||||||
{
|
{
|
||||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||||
|
|
||||||
/* FIXME */
|
return _gdk_win32_pixbuf_to_hicon_supports_alpha ();
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -407,8 +380,7 @@ gdk_display_supports_cursor_color (GdkDisplay *display)
|
|||||||
{
|
{
|
||||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
||||||
|
|
||||||
/* FIXME */
|
return TRUE;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
guint
|
guint
|
||||||
@ -431,3 +403,254 @@ gdk_display_get_maximal_cursor_size (GdkDisplay *display,
|
|||||||
if (height)
|
if (height)
|
||||||
*height = GetSystemMetrics (SM_CYCURSOR);
|
*height = GetSystemMetrics (SM_CYCURSOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Convert a pixbuf to an HICON (or HCURSOR). Supports alpha under
|
||||||
|
* Windows XP, thresholds alpha otherwise. Also used from
|
||||||
|
* gdkwindow-win32.c for creating application icons.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static HBITMAP
|
||||||
|
create_alpha_bitmap (gint width, gint height, guchar **outdata)
|
||||||
|
{
|
||||||
|
BITMAPV5HEADER bi;
|
||||||
|
HDC hdc;
|
||||||
|
HBITMAP hBitmap;
|
||||||
|
|
||||||
|
ZeroMemory (&bi, sizeof (BITMAPV5HEADER));
|
||||||
|
bi.bV5Size = sizeof (BITMAPV5HEADER);
|
||||||
|
bi.bV5Width = width;
|
||||||
|
bi.bV5Height = height;
|
||||||
|
bi.bV5Planes = 1;
|
||||||
|
bi.bV5BitCount = 32;
|
||||||
|
bi.bV5Compression = BI_BITFIELDS;
|
||||||
|
/* The following mask specification specifies a supported 32 BPP
|
||||||
|
* alpha format for Windows XP (BGRA format).
|
||||||
|
*/
|
||||||
|
bi.bV5RedMask = 0x00FF0000;
|
||||||
|
bi.bV5GreenMask = 0x0000FF00;
|
||||||
|
bi.bV5BlueMask = 0x000000FF;
|
||||||
|
bi.bV5AlphaMask = 0xFF000000;
|
||||||
|
|
||||||
|
/* Create the DIB section with an alpha channel. */
|
||||||
|
hdc = GetDC (NULL);
|
||||||
|
if (!hdc)
|
||||||
|
{
|
||||||
|
WIN32_GDI_FAILED ("GetDC");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
hBitmap = CreateDIBSection (hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS,
|
||||||
|
(PVOID *) outdata, NULL, (DWORD)0);
|
||||||
|
if (hBitmap == NULL)
|
||||||
|
WIN32_GDI_FAILED ("CreateDIBSection");
|
||||||
|
ReleaseDC (NULL, hdc);
|
||||||
|
|
||||||
|
return hBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HBITMAP
|
||||||
|
create_color_bitmap (gint width, gint height, guchar **outdata)
|
||||||
|
{
|
||||||
|
BITMAPV4HEADER bi;
|
||||||
|
HDC hdc;
|
||||||
|
HBITMAP hBitmap;
|
||||||
|
|
||||||
|
ZeroMemory (&bi, sizeof (BITMAPV4HEADER));
|
||||||
|
bi.bV4Size = sizeof (BITMAPV4HEADER);
|
||||||
|
bi.bV4Width = width;
|
||||||
|
bi.bV4Height = height;
|
||||||
|
bi.bV4Planes = 1;
|
||||||
|
bi.bV4BitCount = 24;
|
||||||
|
bi.bV4V4Compression = BI_RGB;
|
||||||
|
|
||||||
|
hdc = GetDC (NULL);
|
||||||
|
if (!hdc)
|
||||||
|
{
|
||||||
|
WIN32_GDI_FAILED ("GetDC");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
hBitmap = CreateDIBSection (hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS,
|
||||||
|
(PVOID *) outdata, NULL, (DWORD)0);
|
||||||
|
if (hBitmap == NULL)
|
||||||
|
WIN32_GDI_FAILED ("CreateDIBSection");
|
||||||
|
ReleaseDC (NULL, hdc);
|
||||||
|
|
||||||
|
return hBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
pixbuf_to_hbitmaps_alpha_winxp (GdkPixbuf *pixbuf,
|
||||||
|
HBITMAP *color,
|
||||||
|
HBITMAP *mask)
|
||||||
|
{
|
||||||
|
/* Based on code from
|
||||||
|
* http://www.dotnet247.com/247reference/msgs/13/66301.aspx
|
||||||
|
*/
|
||||||
|
HBITMAP hColorBitmap, hMaskBitmap;
|
||||||
|
guchar *indata, *inrow;
|
||||||
|
guchar *outdata, *outrow;
|
||||||
|
gint width, height, i, j, rowstride;
|
||||||
|
|
||||||
|
width = gdk_pixbuf_get_width (pixbuf); /* width of icon */
|
||||||
|
height = gdk_pixbuf_get_height (pixbuf); /* height of icon */
|
||||||
|
|
||||||
|
hColorBitmap = create_alpha_bitmap (width, height, &outdata);
|
||||||
|
if (!hColorBitmap)
|
||||||
|
return FALSE;
|
||||||
|
hMaskBitmap = CreateBitmap (width, height, 1, 1, NULL);
|
||||||
|
if (!hMaskBitmap)
|
||||||
|
{
|
||||||
|
DeleteObject (hColorBitmap);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rows are always aligned on 4-byte boundarys, but here our pixels are always 4 bytes */
|
||||||
|
indata = gdk_pixbuf_get_pixels (pixbuf);
|
||||||
|
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||||
|
for (j=0; j<height; j++)
|
||||||
|
{
|
||||||
|
outrow = outdata + 4*j*width;
|
||||||
|
inrow = indata + (height-j-1)*rowstride;
|
||||||
|
for (i=0; i<width; i++)
|
||||||
|
{
|
||||||
|
outrow[4*i+0] = inrow[4*i+2];
|
||||||
|
outrow[4*i+1] = inrow[4*i+1];
|
||||||
|
outrow[4*i+2] = inrow[4*i+0];
|
||||||
|
outrow[4*i+3] = inrow[4*i+3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (color) *color = hColorBitmap;
|
||||||
|
if (mask) *mask = hMaskBitmap;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
pixbuf_to_hbitmaps_normal (GdkPixbuf *pixbuf,
|
||||||
|
HBITMAP *color,
|
||||||
|
HBITMAP *mask)
|
||||||
|
{
|
||||||
|
/* Based on code from
|
||||||
|
* http://www.dotnet247.com/247reference/msgs/13/66301.aspx
|
||||||
|
*/
|
||||||
|
HBITMAP hColorBitmap, hMaskBitmap;
|
||||||
|
guchar *indata, *inrow;
|
||||||
|
guchar *colordata, *colorrow, *maskdata, *maskrow;
|
||||||
|
gint width, height, i, j, rowstride, nc, bmstride;
|
||||||
|
gboolean has_alpha;
|
||||||
|
|
||||||
|
width = gdk_pixbuf_get_width (pixbuf); /* width of icon */
|
||||||
|
height = gdk_pixbuf_get_height (pixbuf); /* height of icon */
|
||||||
|
|
||||||
|
hColorBitmap = create_color_bitmap (width, height, &colordata);
|
||||||
|
if (!hColorBitmap)
|
||||||
|
return FALSE;
|
||||||
|
hMaskBitmap = create_color_bitmap (width, height, &maskdata);
|
||||||
|
if (!hMaskBitmap)
|
||||||
|
{
|
||||||
|
DeleteObject (hColorBitmap);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rows are always aligned on 4-byte boundarys */
|
||||||
|
bmstride = width * 3;
|
||||||
|
if (bmstride % 4 != 0)
|
||||||
|
bmstride += 4 - (bmstride % 4);
|
||||||
|
|
||||||
|
indata = gdk_pixbuf_get_pixels (pixbuf);
|
||||||
|
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||||
|
nc = gdk_pixbuf_get_n_channels (pixbuf);
|
||||||
|
has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
|
||||||
|
|
||||||
|
for (j=0; j<height; j++)
|
||||||
|
{
|
||||||
|
colorrow = colordata + j*bmstride;
|
||||||
|
maskrow = maskdata + j*bmstride;
|
||||||
|
inrow = indata + (height-j-1)*rowstride;
|
||||||
|
for (i=0; i<width; i++)
|
||||||
|
{
|
||||||
|
if (has_alpha && inrow[nc*i+3] < 128)
|
||||||
|
{
|
||||||
|
colorrow[3*i+0] = colorrow[3*i+1] = colorrow[3*i+2] = 0;
|
||||||
|
maskrow[3*i+0] = maskrow[3*i+1] = maskrow[3*i+2] = 255;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
colorrow[3*i+0] = inrow[nc*i+2];
|
||||||
|
colorrow[3*i+1] = inrow[nc*i+1];
|
||||||
|
colorrow[3*i+2] = inrow[nc*i+0];
|
||||||
|
maskrow[3*i+0] = maskrow[3*i+1] = maskrow[3*i+2] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (color) *color = hColorBitmap;
|
||||||
|
if (mask) *mask = hMaskBitmap;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HICON
|
||||||
|
pixbuf_to_hicon (GdkPixbuf *pixbuf,
|
||||||
|
gboolean is_icon,
|
||||||
|
gint x,
|
||||||
|
gint y)
|
||||||
|
{
|
||||||
|
ICONINFO ii;
|
||||||
|
HICON icon;
|
||||||
|
gboolean success;
|
||||||
|
|
||||||
|
if (pixbuf == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (_gdk_win32_pixbuf_to_hicon_supports_alpha() && gdk_pixbuf_get_has_alpha (pixbuf))
|
||||||
|
success = pixbuf_to_hbitmaps_alpha_winxp (pixbuf, &ii.hbmColor, &ii.hbmMask);
|
||||||
|
else
|
||||||
|
success = pixbuf_to_hbitmaps_normal (pixbuf, &ii.hbmColor, &ii.hbmMask);
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ii.fIcon = is_icon;
|
||||||
|
ii.xHotspot = x;
|
||||||
|
ii.yHotspot = y;
|
||||||
|
icon = CreateIconIndirect (&ii);
|
||||||
|
DeleteObject (ii.hbmColor);
|
||||||
|
DeleteObject (ii.hbmMask);
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
HICON
|
||||||
|
_gdk_win32_pixbuf_to_hicon (GdkPixbuf *pixbuf)
|
||||||
|
{
|
||||||
|
return pixbuf_to_hicon (pixbuf, TRUE, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
HICON
|
||||||
|
_gdk_win32_pixbuf_to_hcursor (GdkPixbuf *pixbuf,
|
||||||
|
gint x_hotspot,
|
||||||
|
gint y_hotspot)
|
||||||
|
{
|
||||||
|
return pixbuf_to_hicon (pixbuf, FALSE, x_hotspot, y_hotspot);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_gdk_win32_pixbuf_to_hicon_supports_alpha (void)
|
||||||
|
{
|
||||||
|
static gboolean is_win_xp=FALSE, is_win_xp_checked=FALSE;
|
||||||
|
|
||||||
|
if (!is_win_xp_checked)
|
||||||
|
{
|
||||||
|
OSVERSIONINFO version;
|
||||||
|
|
||||||
|
is_win_xp_checked = TRUE;
|
||||||
|
memset (&version, 0, sizeof (version));
|
||||||
|
version.dwOSVersionInfoSize = sizeof (version);
|
||||||
|
is_win_xp = GetVersionEx (&version)
|
||||||
|
&& version.dwPlatformId == VER_PLATFORM_WIN32_NT
|
||||||
|
&& (version.dwMajorVersion > 5
|
||||||
|
|| (version.dwMajorVersion == 5 && version.dwMinorVersion >= 1));
|
||||||
|
}
|
||||||
|
return is_win_xp;
|
||||||
|
}
|
||||||
|
@ -510,6 +510,15 @@ extern HGLOBAL _delayed_rendering_data;
|
|||||||
HGLOBAL _gdk_win32_selection_convert_to_dib (HGLOBAL hdata,
|
HGLOBAL _gdk_win32_selection_convert_to_dib (HGLOBAL hdata,
|
||||||
GdkAtom target);
|
GdkAtom target);
|
||||||
|
|
||||||
|
/* Convert a pixbuf to an HICON (or HCURSOR). Supports alpha under
|
||||||
|
* Windows XP, thresholds alpha otherwise.
|
||||||
|
*/
|
||||||
|
HICON _gdk_win32_pixbuf_to_hicon (GdkPixbuf *pixbuf);
|
||||||
|
HICON _gdk_win32_pixbuf_to_hcursor (GdkPixbuf *pixbuf,
|
||||||
|
gint x_hotspot,
|
||||||
|
gint y_hotspot);
|
||||||
|
gboolean _gdk_win32_pixbuf_to_hicon_supports_alpha (void);
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
void _gdk_windowing_window_init (void);
|
void _gdk_windowing_window_init (void);
|
||||||
void _gdk_root_window_size_init (void);
|
void _gdk_root_window_size_init (void);
|
||||||
|
@ -37,34 +37,7 @@
|
|||||||
#include "gdkprivate-win32.h"
|
#include "gdkprivate-win32.h"
|
||||||
#include "gdkinput-win32.h"
|
#include "gdkinput-win32.h"
|
||||||
|
|
||||||
#if defined __MINGW32__ || (WINVER < 0x0500)
|
#if defined(_MSC_VER) && (WINVER < 0x0500)
|
||||||
typedef struct {
|
|
||||||
DWORD bV5Size;
|
|
||||||
LONG bV5Width;
|
|
||||||
LONG bV5Height;
|
|
||||||
WORD bV5Planes;
|
|
||||||
WORD bV5BitCount;
|
|
||||||
DWORD bV5Compression;
|
|
||||||
DWORD bV5SizeImage;
|
|
||||||
LONG bV5XPelsPerMeter;
|
|
||||||
LONG bV5YPelsPerMeter;
|
|
||||||
DWORD bV5ClrUsed;
|
|
||||||
DWORD bV5ClrImportant;
|
|
||||||
DWORD bV5RedMask;
|
|
||||||
DWORD bV5GreenMask;
|
|
||||||
DWORD bV5BlueMask;
|
|
||||||
DWORD bV5AlphaMask;
|
|
||||||
DWORD bV5CSType;
|
|
||||||
CIEXYZTRIPLE bV5Endpoints;
|
|
||||||
DWORD bV5GammaRed;
|
|
||||||
DWORD bV5GammaGreen;
|
|
||||||
DWORD bV5GammaBlue;
|
|
||||||
DWORD bV5Intent;
|
|
||||||
DWORD bV5ProfileData;
|
|
||||||
DWORD bV5ProfileSize;
|
|
||||||
DWORD bV5Reserved;
|
|
||||||
} BITMAPV5HEADER;
|
|
||||||
|
|
||||||
#define GetAncestor(hwnd,what) _gdk_win32_get_ancestor_parent(hwnd)
|
#define GetAncestor(hwnd,what) _gdk_win32_get_ancestor_parent(hwnd)
|
||||||
|
|
||||||
static HWND
|
static HWND
|
||||||
@ -2406,193 +2379,6 @@ gdk_window_set_focus_on_map (GdkWindow *window,
|
|||||||
private->focus_on_map = focus_on_map;
|
private->focus_on_map = focus_on_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HICON
|
|
||||||
pixbuf_to_hicon_alpha_winxp (GdkWindow *window,
|
|
||||||
GdkPixbuf *pixbuf)
|
|
||||||
{
|
|
||||||
/* Based on code from
|
|
||||||
* http://www.dotnet247.com/247reference/msgs/13/66301.aspx
|
|
||||||
*/
|
|
||||||
HDC hdc;
|
|
||||||
BITMAPV5HEADER bi;
|
|
||||||
HBITMAP hBitmap, hMonoBitmap;
|
|
||||||
guchar *indata, *inrow;
|
|
||||||
guchar *outdata, *outrow;
|
|
||||||
HICON hAlphaIcon = NULL;
|
|
||||||
ICONINFO ii;
|
|
||||||
gint width, height, i, j, rowstride;
|
|
||||||
|
|
||||||
if (pixbuf == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
width = gdk_pixbuf_get_width (pixbuf); /* width of icon */
|
|
||||||
height = gdk_pixbuf_get_height (pixbuf); /* height of icon */
|
|
||||||
|
|
||||||
ZeroMemory (&bi, sizeof (BITMAPV5HEADER));
|
|
||||||
bi.bV5Size = sizeof (BITMAPV5HEADER);
|
|
||||||
bi.bV5Width = width;
|
|
||||||
bi.bV5Height = height;
|
|
||||||
bi.bV5Planes = 1;
|
|
||||||
bi.bV5BitCount = 32;
|
|
||||||
bi.bV5Compression = BI_BITFIELDS;
|
|
||||||
/* The following mask specification specifies a supported 32 BPP
|
|
||||||
* alpha format for Windows XP (BGRA format).
|
|
||||||
*/
|
|
||||||
bi.bV5RedMask = 0x00FF0000;
|
|
||||||
bi.bV5GreenMask = 0x0000FF00;
|
|
||||||
bi.bV5BlueMask = 0x000000FF;
|
|
||||||
bi.bV5AlphaMask = 0xFF000000;
|
|
||||||
|
|
||||||
/* Create the DIB section with an alpha channel. */
|
|
||||||
hdc = GetDC (NULL);
|
|
||||||
hBitmap = CreateDIBSection (hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS,
|
|
||||||
(void **)&outdata, NULL, (DWORD)0);
|
|
||||||
ReleaseDC (NULL, hdc);
|
|
||||||
|
|
||||||
/* Draw something on the DIB section */
|
|
||||||
indata = gdk_pixbuf_get_pixels (pixbuf);
|
|
||||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
|
||||||
for (j=0; j<height; j++)
|
|
||||||
{
|
|
||||||
outrow = outdata + 4*j*width;
|
|
||||||
inrow = indata + (height-j-1)*rowstride;
|
|
||||||
for (i=0; i<width; i++)
|
|
||||||
{
|
|
||||||
outrow[4*i+0] = inrow[4*i+2];
|
|
||||||
outrow[4*i+1] = inrow[4*i+1];
|
|
||||||
outrow[4*i+2] = inrow[4*i+0];
|
|
||||||
outrow[4*i+3] = inrow[4*i+3];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create an empty mask bitmap */
|
|
||||||
hMonoBitmap = CreateBitmap (width, height, 1, 1, NULL);
|
|
||||||
|
|
||||||
ii.fIcon = TRUE;
|
|
||||||
ii.xHotspot = 0;
|
|
||||||
ii.yHotspot = 0;
|
|
||||||
ii.hbmMask = hMonoBitmap;
|
|
||||||
ii.hbmColor = hBitmap;
|
|
||||||
|
|
||||||
/* Create the alpha cursor with the alpha DIB section */
|
|
||||||
hAlphaIcon = CreateIconIndirect (&ii);
|
|
||||||
|
|
||||||
GDI_CALL (DeleteObject, (hBitmap));
|
|
||||||
GDI_CALL (DeleteObject, (hMonoBitmap));
|
|
||||||
|
|
||||||
return hAlphaIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HICON
|
|
||||||
pixbuf_to_hicon_normal (GdkWindow *window,
|
|
||||||
GdkPixbuf *pixbuf)
|
|
||||||
{
|
|
||||||
GdkPixmap *pixmap;
|
|
||||||
GdkBitmap *mask;
|
|
||||||
HBITMAP hbmmask = NULL;
|
|
||||||
ICONINFO ii;
|
|
||||||
HICON hIcon;
|
|
||||||
gint w = 0, h = 0;
|
|
||||||
|
|
||||||
if (pixbuf == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* create a normal icon with a bitmap mask */
|
|
||||||
w = gdk_pixbuf_get_width (pixbuf);
|
|
||||||
h = gdk_pixbuf_get_height (pixbuf);
|
|
||||||
gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf,
|
|
||||||
gdk_drawable_get_colormap (window),
|
|
||||||
&pixmap,
|
|
||||||
&mask,
|
|
||||||
128);
|
|
||||||
|
|
||||||
/* we need the inverted mask for the XOR op */
|
|
||||||
{
|
|
||||||
HDC hdc1 = CreateCompatibleDC (NULL);
|
|
||||||
HBITMAP hbmold1;
|
|
||||||
|
|
||||||
hbmmask = CreateCompatibleBitmap (hdc1, w, h);
|
|
||||||
hbmold1 = SelectObject (hdc1, hbmmask);
|
|
||||||
if (mask)
|
|
||||||
{
|
|
||||||
HDC hdc2 = CreateCompatibleDC (NULL);
|
|
||||||
HBITMAP hbmold2 = SelectObject (hdc2, GDK_PIXMAP_HBITMAP (mask));
|
|
||||||
GDI_CALL (BitBlt, (hdc1, 0,0,w,h, hdc2, 0,0, NOTSRCCOPY));
|
|
||||||
GDI_CALL (SelectObject, (hdc2, hbmold2));
|
|
||||||
GDI_CALL (DeleteDC, (hdc2));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RECT rect;
|
|
||||||
GetClipBox (hdc1, &rect);
|
|
||||||
GDI_CALL (FillRect, (hdc1, &rect, GetStockObject (BLACK_BRUSH)));
|
|
||||||
}
|
|
||||||
GDI_CALL (SelectObject, (hdc1, hbmold1));
|
|
||||||
GDI_CALL (DeleteDC, (hdc1));
|
|
||||||
}
|
|
||||||
|
|
||||||
ii.fIcon = TRUE;
|
|
||||||
ii.xHotspot = ii.yHotspot = 0; /* ignored for icons */
|
|
||||||
ii.hbmMask = hbmmask;
|
|
||||||
ii.hbmColor = GDK_PIXMAP_HBITMAP (pixmap);
|
|
||||||
hIcon = CreateIconIndirect (&ii);
|
|
||||||
if (!hIcon)
|
|
||||||
WIN32_API_FAILED ("CreateIconIndirect");
|
|
||||||
GDI_CALL (DeleteObject, (hbmmask));
|
|
||||||
|
|
||||||
#if 0 /* to debug pixmap and mask setting */
|
|
||||||
{
|
|
||||||
static int num = 0;
|
|
||||||
GdkPixbuf* pixbuf = NULL;
|
|
||||||
char name[256];
|
|
||||||
|
|
||||||
pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0, w, h);
|
|
||||||
if (pixbuf)
|
|
||||||
{
|
|
||||||
num = (num + 1) % 999; /* restrict maximim number */
|
|
||||||
sprintf (name, "c:\\temp\\ico%03dpixm.png", num);
|
|
||||||
gdk_pixbuf_save (pixbuf, name, "png", NULL, NULL);
|
|
||||||
gdk_pixbuf_unref (pixbuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (pixmap)
|
|
||||||
g_object_unref (pixmap);
|
|
||||||
if (mask)
|
|
||||||
g_object_unref (mask);
|
|
||||||
|
|
||||||
return hIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HICON
|
|
||||||
pixbuf_to_hicon (GdkWindow *window,
|
|
||||||
GdkPixbuf *pixbuf)
|
|
||||||
{
|
|
||||||
static gboolean is_win_xp=FALSE, is_win_xp_checked=FALSE;
|
|
||||||
|
|
||||||
if (!is_win_xp_checked)
|
|
||||||
{
|
|
||||||
OSVERSIONINFO version;
|
|
||||||
|
|
||||||
is_win_xp_checked = TRUE;
|
|
||||||
memset (&version, 0, sizeof (version));
|
|
||||||
version.dwOSVersionInfoSize = sizeof (version);
|
|
||||||
is_win_xp = GetVersionEx (&version)
|
|
||||||
&& version.dwPlatformId == VER_PLATFORM_WIN32_NT
|
|
||||||
&& (version.dwMajorVersion > 5
|
|
||||||
|| (version.dwMajorVersion == 5 && version.dwMinorVersion >= 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pixbuf == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (is_win_xp && gdk_pixbuf_get_has_alpha (pixbuf))
|
|
||||||
return pixbuf_to_hicon_alpha_winxp (window, pixbuf);
|
|
||||||
else
|
|
||||||
return pixbuf_to_hicon_normal (window, pixbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gdk_window_set_icon_list (GdkWindow *window,
|
gdk_window_set_icon_list (GdkWindow *window,
|
||||||
GList *pixbufs)
|
GList *pixbufs)
|
||||||
@ -2656,8 +2442,8 @@ gdk_window_set_icon_list (GdkWindow *window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create the icons */
|
/* Create the icons */
|
||||||
big_hicon = pixbuf_to_hicon (window, big_pixbuf);
|
big_hicon = _gdk_win32_pixbuf_to_hicon (big_pixbuf);
|
||||||
small_hicon = pixbuf_to_hicon (window, small_pixbuf);
|
small_hicon = _gdk_win32_pixbuf_to_hicon (small_pixbuf);
|
||||||
|
|
||||||
/* Set the icons */
|
/* Set the icons */
|
||||||
SendMessage (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
|
SendMessage (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
|
||||||
|
Loading…
Reference in New Issue
Block a user