Win32: Re-work cursor handling
Like the X11 and Wayland backends, re-work how the cursors are being handled. So, we use a hash table to cache up the HCURSORS that we create along the way. We still need to cache up the icon/cursor themes since this is something that is not part of Windows but was added on to support icon/cursor themes such as Adwaita on Windows, but should be in-line with what is going on in GdkCursor. Also, remove the _gdk_grab_cursor global variable in gdkprivate-win32.h, and replace it with another variable in the GdkWin32Display structure, to make things cleaner in the process. https://bugzilla.gnome.org/show_bug.cgi?id=773299
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
#include "gdkscreen.h"
|
#include "gdkscreen.h"
|
||||||
#include "gdkcursor.h"
|
#include "gdkcursor.h"
|
||||||
#include "gdkwin32.h"
|
#include "gdkwin32.h"
|
||||||
|
#include "gdktextureprivate.h"
|
||||||
|
|
||||||
#include "gdkdisplay-win32.h"
|
#include "gdkdisplay-win32.h"
|
||||||
|
|
||||||
@@ -77,8 +78,8 @@ static DefaultCursor default_cursors[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static HCURSOR
|
static HCURSOR
|
||||||
hcursor_from_x_cursor (gint i,
|
hcursor_from_x_cursor (gint i,
|
||||||
GdkCursorType cursor_type)
|
const gchar *name)
|
||||||
{
|
{
|
||||||
gint j, x, y, ofs;
|
gint j, x, y, ofs;
|
||||||
HCURSOR rv;
|
HCURSOR rv;
|
||||||
@@ -93,7 +94,7 @@ hcursor_from_x_cursor (gint i,
|
|||||||
xor_plane = g_malloc ((w/8) * h);
|
xor_plane = g_malloc ((w/8) * h);
|
||||||
memset (xor_plane, 0, (w/8) * h);
|
memset (xor_plane, 0, (w/8) * h);
|
||||||
|
|
||||||
if (cursor_type != GDK_BLANK_CURSOR)
|
if (strcmp (name, "none") != 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
#define SET_BIT(v,b) (v |= (1 << b))
|
#define SET_BIT(v,b) (v |= (1 << b))
|
||||||
@@ -142,7 +143,8 @@ hcursor_from_x_cursor (gint i,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static HCURSOR
|
static HCURSOR
|
||||||
win32_cursor_create_hcursor (Win32Cursor *cursor)
|
win32_cursor_create_hcursor (Win32Cursor *cursor,
|
||||||
|
const gchar *name)
|
||||||
{
|
{
|
||||||
HCURSOR result;
|
HCURSOR result;
|
||||||
|
|
||||||
@@ -174,7 +176,7 @@ win32_cursor_create_hcursor (Win32Cursor *cursor)
|
|||||||
break;
|
break;
|
||||||
case GDK_WIN32_CURSOR_CREATE:
|
case GDK_WIN32_CURSOR_CREATE:
|
||||||
result = hcursor_from_x_cursor (cursor->xcursor_number,
|
result = hcursor_from_x_cursor (cursor->xcursor_number,
|
||||||
cursor->cursor_type);
|
name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result = NULL;
|
result = NULL;
|
||||||
@@ -189,8 +191,7 @@ win32_cursor_new (GdkWin32CursorLoadType load_type,
|
|||||||
gint width,
|
gint width,
|
||||||
gint height,
|
gint height,
|
||||||
guint load_flags,
|
guint load_flags,
|
||||||
gint xcursor_number,
|
gint xcursor_number)
|
||||||
GdkCursorType cursor_type)
|
|
||||||
{
|
{
|
||||||
Win32Cursor *result;
|
Win32Cursor *result;
|
||||||
|
|
||||||
@@ -201,7 +202,6 @@ win32_cursor_new (GdkWin32CursorLoadType load_type,
|
|||||||
result->height = height;
|
result->height = height;
|
||||||
result->load_flags = load_flags;
|
result->load_flags = load_flags;
|
||||||
result->xcursor_number = xcursor_number;
|
result->xcursor_number = xcursor_number;
|
||||||
result->cursor_type = cursor_type;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -243,7 +243,7 @@ win32_cursor_theme_load_from (Win32CursorTheme *theme,
|
|||||||
gchar *dot;
|
gchar *dot;
|
||||||
Win32Cursor *cursor;
|
Win32Cursor *cursor;
|
||||||
|
|
||||||
fullname = g_strconcat (dir, "/", filename, NULL);
|
fullname = g_build_filename (dir, filename, NULL);
|
||||||
filenamew = g_utf8_to_utf16 (fullname, -1, NULL, NULL, NULL);
|
filenamew = g_utf8_to_utf16 (fullname, -1, NULL, NULL, NULL);
|
||||||
g_free (fullname);
|
g_free (fullname);
|
||||||
|
|
||||||
@@ -269,8 +269,8 @@ win32_cursor_theme_load_from (Win32CursorTheme *theme,
|
|||||||
size,
|
size,
|
||||||
size,
|
size,
|
||||||
LR_LOADFROMFILE | (size == 0 ? LR_DEFAULTSIZE : 0),
|
LR_LOADFROMFILE | (size == 0 ? LR_DEFAULTSIZE : 0),
|
||||||
0,
|
|
||||||
0);
|
0);
|
||||||
|
|
||||||
g_hash_table_insert (theme->named_cursors, cursor_name, cursor);
|
g_hash_table_insert (theme->named_cursors, cursor_name, cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,13 +289,13 @@ win32_cursor_theme_load_from_dirs (Win32CursorTheme *theme,
|
|||||||
/* <prefix>/share/icons */
|
/* <prefix>/share/icons */
|
||||||
for (i = 0; dirs[i]; i++)
|
for (i = 0; dirs[i]; i++)
|
||||||
{
|
{
|
||||||
theme_dir = g_strconcat (dirs[i], "/icons/", name, "/cursors", NULL);
|
theme_dir = g_build_filename (dirs[i], "icons", name, "cursors", NULL);
|
||||||
win32_cursor_theme_load_from (theme, size, theme_dir);
|
win32_cursor_theme_load_from (theme, size, theme_dir);
|
||||||
g_free (theme_dir);
|
g_free (theme_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ~/.icons */
|
/* ~/.icons */
|
||||||
theme_dir = g_strconcat (g_get_home_dir (), "/icons/", name, "/cursors", NULL);
|
theme_dir = g_build_filename (g_get_home_dir (), "icons", name, "cursors", NULL);
|
||||||
win32_cursor_theme_load_from (theme, size, theme_dir);
|
win32_cursor_theme_load_from (theme, size, theme_dir);
|
||||||
g_free (theme_dir);
|
g_free (theme_dir);
|
||||||
}
|
}
|
||||||
@@ -324,7 +324,7 @@ win32_cursor_theme_load_system (Win32CursorTheme *theme,
|
|||||||
|
|
||||||
/* Fall back to X cursors, but only if we've got no theme cursor */
|
/* Fall back to X cursors, but only if we've got no theme cursor */
|
||||||
if (hcursor == NULL && g_hash_table_lookup (theme->named_cursors, cursors[i].name) == NULL)
|
if (hcursor == NULL && g_hash_table_lookup (theme->named_cursors, cursors[i].name) == NULL)
|
||||||
hcursor = hcursor_from_x_cursor (i, cursors[i].type);
|
hcursor = hcursor_from_x_cursor (i, cursors[i].name);
|
||||||
|
|
||||||
if (hcursor == NULL)
|
if (hcursor == NULL)
|
||||||
continue;
|
continue;
|
||||||
@@ -335,7 +335,6 @@ win32_cursor_theme_load_system (Win32CursorTheme *theme,
|
|||||||
size,
|
size,
|
||||||
size,
|
size,
|
||||||
LR_SHARED | (size == 0 ? LR_DEFAULTSIZE : 0),
|
LR_SHARED | (size == 0 ? LR_DEFAULTSIZE : 0),
|
||||||
0,
|
|
||||||
0);
|
0);
|
||||||
g_hash_table_insert (theme->named_cursors,
|
g_hash_table_insert (theme->named_cursors,
|
||||||
g_strdup (cursors[i].name),
|
g_strdup (cursors[i].name),
|
||||||
@@ -359,7 +358,6 @@ win32_cursor_theme_load_system (Win32CursorTheme *theme,
|
|||||||
size,
|
size,
|
||||||
size,
|
size,
|
||||||
LR_SHARED | (size == 0 ? LR_DEFAULTSIZE : 0),
|
LR_SHARED | (size == 0 ? LR_DEFAULTSIZE : 0),
|
||||||
0,
|
|
||||||
0);
|
0);
|
||||||
g_hash_table_insert (theme->named_cursors,
|
g_hash_table_insert (theme->named_cursors,
|
||||||
g_strdup (default_cursors[i].name),
|
g_strdup (default_cursors[i].name),
|
||||||
@@ -369,7 +367,7 @@ win32_cursor_theme_load_system (Win32CursorTheme *theme,
|
|||||||
|
|
||||||
Win32CursorTheme *
|
Win32CursorTheme *
|
||||||
win32_cursor_theme_load (const gchar *name,
|
win32_cursor_theme_load (const gchar *name,
|
||||||
gint size)
|
gint size)
|
||||||
{
|
{
|
||||||
Win32CursorTheme *result = g_new0 (Win32CursorTheme, 1);
|
Win32CursorTheme *result = g_new0 (Win32CursorTheme, 1);
|
||||||
|
|
||||||
@@ -409,52 +407,52 @@ win32_cursor_theme_get_cursor (Win32CursorTheme *theme,
|
|||||||
return g_hash_table_lookup (theme->named_cursors, name);
|
return g_hash_table_lookup (theme->named_cursors, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HCURSOR
|
|
||||||
hcursor_from_type (GdkCursorType cursor_type)
|
|
||||||
{
|
|
||||||
gint i = 0;
|
|
||||||
|
|
||||||
if (cursor_type != GDK_BLANK_CURSOR)
|
|
||||||
{
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (cursors); i++)
|
|
||||||
if (cursors[i].type == cursor_type)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (i >= G_N_ELEMENTS (cursors) || !cursors[i].name)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Use real Win32 cursor if possible */
|
|
||||||
if (cursors[i].builtin)
|
|
||||||
return LoadImageA (NULL, cursors[i].builtin, IMAGE_CURSOR, 0, 0,
|
|
||||||
LR_SHARED | LR_DEFAULTSIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hcursor_from_x_cursor (i, cursor_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct _GdkWin32CursorClass
|
|
||||||
{
|
|
||||||
GdkCursorClass cursor_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (GdkWin32Cursor, gdk_win32_cursor, GDK_TYPE_CURSOR)
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_gdk_win32_cursor_finalize (GObject *object)
|
gdk_win32_cursor_remove_from_cache (gpointer data, GObject *cursor)
|
||||||
{
|
{
|
||||||
GdkWin32Cursor *private = GDK_WIN32_CURSOR (object);
|
GdkDisplay *display = data;
|
||||||
|
HCURSOR hcursor;
|
||||||
|
|
||||||
if (GetCursor () == private->hcursor)
|
hcursor = g_hash_table_lookup (GDK_WIN32_DISPLAY (display)->cursors, cursor);
|
||||||
|
|
||||||
|
if (GetCursor () == hcursor)
|
||||||
SetCursor (NULL);
|
SetCursor (NULL);
|
||||||
|
|
||||||
if (!DestroyCursor (private->hcursor))
|
if (!DestroyCursor (hcursor))
|
||||||
g_warning (G_STRLOC ": DestroyCursor (%p) failed: %lu", private->hcursor, GetLastError ());
|
g_warning (G_STRLOC ": DestroyCursor (%p) failed: %lu", hcursor, GetLastError ());
|
||||||
|
|
||||||
g_free (private->name);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (gdk_win32_cursor_parent_class)->finalize (object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_win32_display_finalize_cursors (GdkWin32Display *display)
|
||||||
|
{
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer cursor;
|
||||||
|
|
||||||
|
if (display->cursors)
|
||||||
|
{
|
||||||
|
g_hash_table_iter_init (&iter, display->cursors);
|
||||||
|
while (g_hash_table_iter_next (&iter, &cursor, NULL))
|
||||||
|
g_object_weak_unref (G_OBJECT (cursor),
|
||||||
|
gdk_win32_cursor_remove_from_cache,
|
||||||
|
GDK_DISPLAY (display));
|
||||||
|
g_hash_table_unref (display->cursors);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (display->cursor_theme_name);
|
||||||
|
|
||||||
|
if (display->cursor_theme)
|
||||||
|
win32_cursor_theme_destroy (display->cursor_theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_win32_display_init_cursors (GdkWin32Display *display)
|
||||||
|
{
|
||||||
|
display->cursors = g_hash_table_new (gdk_cursor_hash,
|
||||||
|
gdk_cursor_equal);
|
||||||
|
display->cursor_theme_name = g_strdup ("system");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is where we use the names mapped to the equivilants that Windows define by default */
|
||||||
static HCURSOR
|
static HCURSOR
|
||||||
hcursor_idc_from_name (const gchar *name)
|
hcursor_idc_from_name (const gchar *name)
|
||||||
{
|
{
|
||||||
@@ -479,7 +477,7 @@ hcursor_x_from_name (const gchar *name)
|
|||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (cursors); i++)
|
for (i = 0; i < G_N_ELEMENTS (cursors); i++)
|
||||||
if (cursors[i].name == NULL || strcmp (cursors[i].name, name) == 0)
|
if (cursors[i].name == NULL || strcmp (cursors[i].name, name) == 0)
|
||||||
return hcursor_from_x_cursor (i, cursors[i].type);
|
return hcursor_from_x_cursor (i, name);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -501,7 +499,7 @@ hcursor_from_theme (GdkDisplay *display,
|
|||||||
if (theme_cursor == NULL)
|
if (theme_cursor == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return win32_cursor_create_hcursor (theme_cursor);
|
return win32_cursor_create_hcursor (theme_cursor, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HCURSOR
|
static HCURSOR
|
||||||
@@ -510,9 +508,6 @@ hcursor_from_name (GdkDisplay *display,
|
|||||||
{
|
{
|
||||||
HCURSOR hcursor;
|
HCURSOR hcursor;
|
||||||
|
|
||||||
if (strcmp (name, "none") == 0)
|
|
||||||
return hcursor_from_type (GDK_BLANK_CURSOR);
|
|
||||||
|
|
||||||
/* Try current theme first */
|
/* Try current theme first */
|
||||||
hcursor = hcursor_from_theme (display, name);
|
hcursor = hcursor_from_theme (display, name);
|
||||||
|
|
||||||
@@ -529,172 +524,42 @@ hcursor_from_name (GdkDisplay *display,
|
|||||||
return hcursor;
|
return hcursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GdkCursor*
|
/* Create a blank cursor */
|
||||||
cursor_new_from_hcursor (GdkDisplay *display,
|
static HCURSOR
|
||||||
HCURSOR hcursor,
|
create_blank_cursor (void)
|
||||||
const gchar *name,
|
|
||||||
GdkCursorType cursor_type)
|
|
||||||
{
|
{
|
||||||
GdkWin32Cursor *private;
|
gint w, h;
|
||||||
GdkCursor *cursor;
|
guchar *and_plane, *xor_plane;
|
||||||
|
HCURSOR rv;
|
||||||
|
|
||||||
private = g_object_new (GDK_TYPE_WIN32_CURSOR,
|
w = GetSystemMetrics (SM_CXCURSOR);
|
||||||
"display", display,
|
h = GetSystemMetrics (SM_CYCURSOR);
|
||||||
NULL);
|
|
||||||
|
|
||||||
private->name = g_strdup (name);
|
and_plane = g_malloc ((w/8) * h);
|
||||||
|
memset (and_plane, 0xff, (w/8) * h);
|
||||||
|
xor_plane = g_malloc ((w/8) * h);
|
||||||
|
memset (xor_plane, 0, (w/8) * h);
|
||||||
|
|
||||||
private->hcursor = hcursor;
|
rv = CreateCursor (_gdk_app_hmodule, 0, 0,
|
||||||
cursor = (GdkCursor*) private;
|
w, h, and_plane, xor_plane);
|
||||||
|
|
||||||
return cursor;
|
if (rv == NULL)
|
||||||
|
WIN32_API_FAILED ("CreateCursor");
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static HCURSOR
|
||||||
_gdk_win32_cursor_update (GdkWin32Display *win32_display,
|
gdk_win32_cursor_create_for_name (GdkDisplay *display,
|
||||||
GdkWin32Cursor *cursor)
|
const gchar *name)
|
||||||
{
|
{
|
||||||
HCURSOR hcursor = NULL;
|
HCURSOR hcursor = NULL;
|
||||||
Win32CursorTheme *theme;
|
|
||||||
Win32Cursor *theme_cursor;
|
|
||||||
|
|
||||||
/* Do nothing if this is not a named cursor. */
|
|
||||||
if (cursor->name == NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
theme = _gdk_win32_display_get_cursor_theme (win32_display);
|
|
||||||
theme_cursor = win32_cursor_theme_get_cursor (theme, cursor->name);
|
|
||||||
|
|
||||||
if (theme_cursor != NULL)
|
|
||||||
hcursor = win32_cursor_create_hcursor (theme_cursor);
|
|
||||||
|
|
||||||
if (hcursor == NULL)
|
|
||||||
{
|
|
||||||
g_warning (G_STRLOC ": Unable to load %s from the cursor theme", cursor->name);
|
|
||||||
|
|
||||||
hcursor = hcursor_idc_from_name (cursor->name);
|
|
||||||
|
|
||||||
if (hcursor == NULL)
|
|
||||||
hcursor = hcursor_x_from_name (cursor->name);
|
|
||||||
|
|
||||||
if (hcursor == NULL)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetCursor () == cursor->hcursor)
|
|
||||||
SetCursor (hcursor);
|
|
||||||
|
|
||||||
if (!DestroyCursor (cursor->hcursor))
|
|
||||||
g_warning (G_STRLOC ": DestroyCursor (%p) failed: %lu", cursor->hcursor, GetLastError ());
|
|
||||||
|
|
||||||
cursor->hcursor = hcursor;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_gdk_win32_display_update_cursors (GdkWin32Display *display)
|
|
||||||
{
|
|
||||||
GHashTableIter iter;
|
|
||||||
const char *name;
|
|
||||||
GdkWin32Cursor *cursor;
|
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, display->cursor_cache);
|
|
||||||
|
|
||||||
while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &cursor))
|
|
||||||
_gdk_win32_cursor_update (display, cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_gdk_win32_display_init_cursors (GdkWin32Display *display)
|
|
||||||
{
|
|
||||||
display->cursor_cache = g_hash_table_new_full (g_str_hash,
|
|
||||||
g_str_equal,
|
|
||||||
NULL,
|
|
||||||
g_object_unref);
|
|
||||||
display->cursor_theme_name = g_strdup ("system");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
_gdk_win32_display_finalize_cursors (GdkWin32Display *display)
|
|
||||||
{
|
|
||||||
g_free (display->cursor_theme_name);
|
|
||||||
|
|
||||||
if (display->cursor_theme)
|
|
||||||
win32_cursor_theme_destroy (display->cursor_theme);
|
|
||||||
|
|
||||||
g_hash_table_destroy (display->cursor_cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GdkCursor*
|
|
||||||
_gdk_win32_display_get_cursor_for_type (GdkDisplay *display,
|
|
||||||
GdkCursorType cursor_type)
|
|
||||||
{
|
|
||||||
GEnumClass *enum_class;
|
|
||||||
GEnumValue *enum_value;
|
|
||||||
gchar *cursor_name;
|
|
||||||
HCURSOR hcursor;
|
|
||||||
GdkCursor *result;
|
GdkCursor *result;
|
||||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
|
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
|
||||||
|
|
||||||
enum_class = g_type_class_ref (GDK_TYPE_CURSOR_TYPE);
|
|
||||||
enum_value = g_enum_get_value (enum_class, cursor_type);
|
|
||||||
cursor_name = g_strdup (enum_value->value_nick);
|
|
||||||
g_strdelimit (cursor_name, "-", '_');
|
|
||||||
g_type_class_unref (enum_class);
|
|
||||||
|
|
||||||
result = g_hash_table_lookup (win32_display->cursor_cache, cursor_name);
|
|
||||||
if (result)
|
|
||||||
{
|
|
||||||
g_free (cursor_name);
|
|
||||||
return g_object_ref (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
hcursor = hcursor_from_name (display, cursor_name);
|
|
||||||
|
|
||||||
if (hcursor == NULL)
|
|
||||||
hcursor = hcursor_from_type (cursor_type);
|
|
||||||
|
|
||||||
if (hcursor == NULL)
|
|
||||||
g_warning ("gdk_cursor_new_for_display: no cursor %d found", cursor_type);
|
|
||||||
else
|
|
||||||
GDK_NOTE (CURSOR, g_print ("gdk_cursor_new_for_display: %d: %p\n",
|
|
||||||
cursor_type, hcursor));
|
|
||||||
|
|
||||||
result = cursor_new_from_hcursor (display, hcursor, cursor_name, cursor_type);
|
|
||||||
|
|
||||||
if (result == NULL)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
/* Blank cursor case */
|
/* Blank cursor case */
|
||||||
if (cursor_type == GDK_BLANK_CURSOR ||
|
if (strcmp (name, "none") == 0)
|
||||||
!cursor_name ||
|
return create_blank_cursor ();
|
||||||
g_str_equal (cursor_name, "none") ||
|
|
||||||
g_str_equal (cursor_name, "blank_cursor"))
|
|
||||||
{
|
|
||||||
g_free (cursor_name);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_hash_table_insert (win32_display->cursor_cache,
|
|
||||||
cursor_name,
|
|
||||||
g_object_ref (result));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
GdkCursor*
|
|
||||||
_gdk_win32_display_get_cursor_for_name (GdkDisplay *display,
|
|
||||||
const gchar *name)
|
|
||||||
{
|
|
||||||
HCURSOR hcursor = NULL;
|
|
||||||
GdkCursor *result;
|
|
||||||
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
|
|
||||||
|
|
||||||
result = g_hash_table_lookup (win32_display->cursor_cache, name);
|
|
||||||
if (result)
|
|
||||||
return g_object_ref (result);
|
|
||||||
|
|
||||||
hcursor = hcursor_from_name (display, name);
|
hcursor = hcursor_from_name (display, name);
|
||||||
|
|
||||||
@@ -705,19 +570,150 @@ _gdk_win32_display_get_cursor_for_name (GdkDisplay *display,
|
|||||||
if (hcursor == NULL)
|
if (hcursor == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
result = cursor_new_from_hcursor (display, hcursor, name, GDK_X_CURSOR);
|
return hcursor;
|
||||||
|
}
|
||||||
|
|
||||||
/* Blank cursor case */
|
static HICON
|
||||||
if (!name ||
|
pixbuf_to_hicon (GdkPixbuf *pixbuf,
|
||||||
g_str_equal (name, "none") ||
|
gboolean is_icon,
|
||||||
g_str_equal (name, "blank_cursor"))
|
gint x,
|
||||||
return result;
|
gint y);
|
||||||
|
|
||||||
g_hash_table_insert (win32_display->cursor_cache,
|
static HCURSOR
|
||||||
g_strdup (name),
|
gdk_win32_cursor_create_for_texture (GdkDisplay *display,
|
||||||
g_object_ref (result));
|
GdkTexture *texture,
|
||||||
|
int x,
|
||||||
|
int y)
|
||||||
|
{
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
gint width, height;
|
||||||
|
HICON icon;
|
||||||
|
|
||||||
return result;
|
surface = gdk_texture_download_surface (texture);
|
||||||
|
width = cairo_image_surface_get_width (surface);
|
||||||
|
height = cairo_image_surface_get_height (surface);
|
||||||
|
|
||||||
|
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
|
||||||
|
|
||||||
|
icon = pixbuf_to_hicon (pixbuf, TRUE, 0, 0);
|
||||||
|
|
||||||
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
|
return (HCURSOR)icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
GdkCursor *
|
||||||
|
gdk_win32_display_cursor_from_hcursor (GdkDisplay *display,
|
||||||
|
HCURSOR hcursor)
|
||||||
|
{
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer cursor_current, hcursor_current;
|
||||||
|
|
||||||
|
GdkCursor *cursor = NULL;
|
||||||
|
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
|
||||||
|
|
||||||
|
if (win32_display->cursors)
|
||||||
|
{
|
||||||
|
g_hash_table_iter_init (&iter, win32_display->cursors);
|
||||||
|
while (g_hash_table_iter_next (&iter, &cursor_current, &hcursor_current))
|
||||||
|
if ((HCURSOR)hcursor_current == hcursor)
|
||||||
|
{
|
||||||
|
cursor = (GdkCursor*) cursor_current;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
HCURSOR
|
||||||
|
_gdk_win32_display_get_cursor_for_surface (GdkDisplay *display,
|
||||||
|
cairo_surface_t *surface,
|
||||||
|
gdouble x,
|
||||||
|
gdouble y)
|
||||||
|
{
|
||||||
|
HCURSOR hcursor;
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
gint width, height;
|
||||||
|
|
||||||
|
g_return_val_if_fail (surface != NULL, NULL);
|
||||||
|
|
||||||
|
width = cairo_image_surface_get_width (surface);
|
||||||
|
height = cairo_image_surface_get_height (surface);
|
||||||
|
pixbuf = gdk_pixbuf_get_from_surface (surface,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
width,
|
||||||
|
height);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
hcursor = _gdk_win32_pixbuf_to_hcursor (pixbuf, x, y);
|
||||||
|
|
||||||
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
|
return hcursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_gdk_win32_cursor_update (GdkWin32Display *win32_display,
|
||||||
|
GdkCursor *cursor,
|
||||||
|
HCURSOR hcursor)
|
||||||
|
{
|
||||||
|
HCURSOR hcursor_new = NULL;
|
||||||
|
Win32CursorTheme *theme;
|
||||||
|
Win32Cursor *theme_cursor;
|
||||||
|
|
||||||
|
const gchar *name = gdk_cursor_get_name (cursor);
|
||||||
|
|
||||||
|
/* Do nothing if this is not a named cursor. */
|
||||||
|
if (name == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
theme = _gdk_win32_display_get_cursor_theme (win32_display);
|
||||||
|
theme_cursor = win32_cursor_theme_get_cursor (theme, name);
|
||||||
|
|
||||||
|
if (theme_cursor != NULL)
|
||||||
|
hcursor_new = win32_cursor_create_hcursor (theme_cursor, name);
|
||||||
|
|
||||||
|
if (hcursor_new == NULL)
|
||||||
|
{
|
||||||
|
g_warning (G_STRLOC ": Unable to load %s from the cursor theme", name);
|
||||||
|
|
||||||
|
hcursor_new = hcursor_idc_from_name (name);
|
||||||
|
|
||||||
|
if (hcursor_new == NULL)
|
||||||
|
hcursor_new = hcursor_x_from_name (name);
|
||||||
|
|
||||||
|
if (hcursor_new == NULL)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetCursor () == hcursor)
|
||||||
|
SetCursor (hcursor_new);
|
||||||
|
|
||||||
|
if (!DestroyCursor (hcursor))
|
||||||
|
g_warning (G_STRLOC ": DestroyCursor (%p) failed: %lu", hcursor, GetLastError ());
|
||||||
|
|
||||||
|
g_hash_table_replace (win32_display->cursors, cursor, hcursor_new);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gdk_win32_display_update_cursors (GdkWin32Display *display)
|
||||||
|
{
|
||||||
|
GHashTableIter iter;
|
||||||
|
GdkCursor *cursor;
|
||||||
|
HCURSOR hcursor;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, display->cursors);
|
||||||
|
|
||||||
|
while (g_hash_table_iter_next (&iter, (gpointer *) &cursor, &hcursor))
|
||||||
|
_gdk_win32_cursor_update (display, cursor, hcursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
GdkPixbuf *
|
GdkPixbuf *
|
||||||
@@ -896,38 +892,6 @@ gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon,
|
|||||||
return pixbuf;
|
return pixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
GdkCursor *
|
|
||||||
_gdk_win32_display_get_cursor_for_surface (GdkDisplay *display,
|
|
||||||
cairo_surface_t *surface,
|
|
||||||
gdouble x,
|
|
||||||
gdouble y)
|
|
||||||
{
|
|
||||||
HCURSOR hcursor;
|
|
||||||
GdkPixbuf *pixbuf;
|
|
||||||
gint width, height;
|
|
||||||
|
|
||||||
g_return_val_if_fail (surface != NULL, NULL);
|
|
||||||
|
|
||||||
width = cairo_image_surface_get_width (surface);
|
|
||||||
height = cairo_image_surface_get_height (surface);
|
|
||||||
pixbuf = gdk_pixbuf_get_from_surface (surface,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
width,
|
|
||||||
height);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
hcursor = _gdk_win32_pixbuf_to_hcursor (pixbuf, x, y);
|
|
||||||
|
|
||||||
g_object_unref (pixbuf);
|
|
||||||
if (!hcursor)
|
|
||||||
return NULL;
|
|
||||||
return cursor_new_from_hcursor (display, hcursor, NULL, GDK_CURSOR_IS_PIXMAP);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_gdk_win32_display_supports_cursor_alpha (GdkDisplay *display)
|
_gdk_win32_display_supports_cursor_alpha (GdkDisplay *display)
|
||||||
{
|
{
|
||||||
@@ -1252,9 +1216,24 @@ pixbuf_to_hicon (GdkPixbuf *pixbuf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
HICON
|
HICON
|
||||||
_gdk_win32_pixbuf_to_hicon (GdkPixbuf *pixbuf)
|
_gdk_win32_texture_to_hicon (GdkTexture *texture)
|
||||||
{
|
{
|
||||||
return pixbuf_to_hicon (pixbuf, TRUE, 0, 0);
|
cairo_surface_t *surface;
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
|
gint width, height;
|
||||||
|
HICON icon;
|
||||||
|
|
||||||
|
surface = gdk_texture_download_surface (texture);
|
||||||
|
width = cairo_image_surface_get_width (surface);
|
||||||
|
height = cairo_image_surface_get_height (surface);
|
||||||
|
|
||||||
|
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
|
||||||
|
|
||||||
|
icon = pixbuf_to_hicon (pixbuf, TRUE, 0, 0);
|
||||||
|
|
||||||
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
HICON
|
HICON
|
||||||
@@ -1265,20 +1244,54 @@ _gdk_win32_pixbuf_to_hcursor (GdkPixbuf *pixbuf,
|
|||||||
return pixbuf_to_hicon (pixbuf, FALSE, x_hotspot, y_hotspot);
|
return pixbuf_to_hicon (pixbuf, FALSE, x_hotspot, y_hotspot);
|
||||||
}
|
}
|
||||||
|
|
||||||
HICON
|
|
||||||
gdk_win32_pixbuf_to_hicon_libgtk_only (GdkPixbuf *pixbuf)
|
|
||||||
{
|
|
||||||
return _gdk_win32_pixbuf_to_hicon (pixbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gdk_win32_cursor_init (GdkWin32Cursor *cursor)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
static void
|
|
||||||
gdk_win32_cursor_class_init(GdkWin32CursorClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
|
|
||||||
object_class->finalize = _gdk_win32_cursor_finalize;
|
/**
|
||||||
|
* gdk_win32_display_get_hcursor:
|
||||||
|
* @display: (type GdkWin32Display): a #GdkDisplay
|
||||||
|
* @cursor: a #GdkCursor.
|
||||||
|
*
|
||||||
|
* Returns the Win32 HCURSOR belonging to a #GdkCursor, potentially
|
||||||
|
* creating the cursor.
|
||||||
|
*
|
||||||
|
* Be aware that the returned cursor may not be unique to @cursor.
|
||||||
|
* It may for example be shared with its fallback cursor.
|
||||||
|
*
|
||||||
|
* Returns: a Win32 HCURSOR.
|
||||||
|
**/
|
||||||
|
HCURSOR
|
||||||
|
gdk_win32_display_get_hcursor (GdkDisplay *display,
|
||||||
|
GdkCursor *cursor)
|
||||||
|
{
|
||||||
|
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
|
||||||
|
HCURSOR hcursor;
|
||||||
|
|
||||||
|
g_return_val_if_fail (cursor != NULL, NULL);
|
||||||
|
|
||||||
|
if (gdk_display_is_closed (display))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
hcursor = g_hash_table_lookup (win32_display->cursors, cursor);
|
||||||
|
if (hcursor != NULL)
|
||||||
|
return hcursor;
|
||||||
|
|
||||||
|
if (gdk_cursor_get_name (cursor))
|
||||||
|
hcursor = gdk_win32_cursor_create_for_name (display, gdk_cursor_get_name (cursor));
|
||||||
|
else
|
||||||
|
hcursor = gdk_win32_cursor_create_for_texture (display,
|
||||||
|
gdk_cursor_get_texture (cursor),
|
||||||
|
gdk_cursor_get_hotspot_x (cursor),
|
||||||
|
gdk_cursor_get_hotspot_y (cursor));
|
||||||
|
|
||||||
|
if (hcursor != NULL)
|
||||||
|
{
|
||||||
|
g_object_weak_ref (G_OBJECT (cursor), gdk_win32_cursor_remove_from_cache, display);
|
||||||
|
g_hash_table_insert (win32_display->cursors, cursor, hcursor);
|
||||||
|
return hcursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gdk_cursor_get_fallback (cursor))
|
||||||
|
return gdk_win32_display_get_hcursor (display, gdk_cursor_get_fallback (cursor));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "gdkdevice-virtual.h"
|
#include "gdkdevice-virtual.h"
|
||||||
#include "gdkdevice-win32.h"
|
#include "gdkdevice-win32.h"
|
||||||
#include "gdkwin32.h"
|
#include "gdkwin32.h"
|
||||||
|
#include "gdkdisplay-win32.h"
|
||||||
|
|
||||||
G_DEFINE_TYPE (GdkDeviceVirtual, gdk_device_virtual, GDK_TYPE_DEVICE)
|
G_DEFINE_TYPE (GdkDeviceVirtual, gdk_device_virtual, GDK_TYPE_DEVICE)
|
||||||
|
|
||||||
@@ -89,11 +90,20 @@ gdk_device_virtual_get_state (GdkDevice *device,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_device_virtual_set_window_cursor (GdkDevice *device,
|
gdk_device_virtual_set_window_cursor (GdkDevice *device,
|
||||||
GdkWindow *window,
|
GdkWindow *window,
|
||||||
GdkCursor *cursor)
|
GdkCursor *cursor)
|
||||||
{
|
{
|
||||||
if (cursor != NULL && GDK_WIN32_CURSOR (cursor)->hcursor != NULL)
|
if (cursor != NULL)
|
||||||
SetCursor (GDK_WIN32_CURSOR (cursor)->hcursor);
|
{
|
||||||
|
GdkDisplay *display = gdk_window_get_display (window);
|
||||||
|
HCURSOR hcursor = NULL;
|
||||||
|
|
||||||
|
if (display != NULL)
|
||||||
|
hcursor = gdk_win32_display_get_hcursor (display, cursor);
|
||||||
|
|
||||||
|
if (hcursor != NULL)
|
||||||
|
SetCursor (hcursor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -136,18 +146,19 @@ gdk_device_virtual_grab (GdkDevice *device,
|
|||||||
|
|
||||||
if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
|
if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
|
||||||
{
|
{
|
||||||
if (_gdk_win32_grab_cursor != NULL)
|
GdkWin32Display *display = GDK_WIN32_DISPLAY (gdk_device_get_display (device));
|
||||||
{
|
if (display->grab_cursor != NULL)
|
||||||
if (GetCursor () == GDK_WIN32_CURSOR (_gdk_win32_grab_cursor)->hcursor)
|
{
|
||||||
SetCursor (NULL);
|
if (GetCursor () == g_hash_table_lookup (display->cursors, display->grab_cursor))
|
||||||
}
|
SetCursor (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
g_set_object (&_gdk_win32_grab_cursor, cursor);
|
g_set_object (&display->grab_cursor, cursor);
|
||||||
|
|
||||||
if (_gdk_win32_grab_cursor != NULL)
|
if (display->grab_cursor != NULL)
|
||||||
SetCursor (GDK_WIN32_CURSOR (_gdk_win32_grab_cursor)->hcursor);
|
SetCursor (g_hash_table_lookup (display->cursors, display->grab_cursor));
|
||||||
else
|
else
|
||||||
SetCursor (LoadCursor (NULL, IDC_ARROW));
|
SetCursor (LoadCursor (NULL, IDC_ARROW));
|
||||||
|
|
||||||
SetCapture (GDK_WINDOW_HWND (window));
|
SetCapture (GDK_WINDOW_HWND (window));
|
||||||
}
|
}
|
||||||
@@ -157,12 +168,14 @@ gdk_device_virtual_grab (GdkDevice *device,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_device_virtual_ungrab (GdkDevice *device,
|
gdk_device_virtual_ungrab (GdkDevice *device,
|
||||||
guint32 time_)
|
guint32 time_)
|
||||||
{
|
{
|
||||||
GdkDeviceGrabInfo *info;
|
GdkDeviceGrabInfo *info;
|
||||||
GdkDisplay *display;
|
GdkDisplay *display;
|
||||||
|
GdkWin32Display *win32_display;
|
||||||
|
|
||||||
display = gdk_device_get_display (device);
|
display = gdk_device_get_display (device);
|
||||||
|
win32_display = GDK_WIN32_DISPLAY (display);
|
||||||
info = _gdk_display_get_last_device_grab (display, device);
|
info = _gdk_display_get_last_device_grab (display, device);
|
||||||
|
|
||||||
if (info)
|
if (info)
|
||||||
@@ -170,12 +183,13 @@ gdk_device_virtual_ungrab (GdkDevice *device,
|
|||||||
|
|
||||||
if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
|
if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
|
||||||
{
|
{
|
||||||
if (_gdk_win32_grab_cursor != NULL)
|
if (win32_display->grab_cursor != NULL)
|
||||||
{
|
{
|
||||||
if (GetCursor () == GDK_WIN32_CURSOR (_gdk_win32_grab_cursor)->hcursor)
|
if (GetCursor () == g_hash_table_lookup (win32_display->cursors, win32_display->grab_cursor))
|
||||||
SetCursor (NULL);
|
SetCursor (NULL);
|
||||||
}
|
}
|
||||||
g_clear_object (&_gdk_win32_grab_cursor);
|
|
||||||
|
g_clear_object (&win32_display->grab_cursor);
|
||||||
|
|
||||||
ReleaseCapture ();
|
ReleaseCapture ();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ struct _GdkWin32Display
|
|||||||
Win32CursorTheme *cursor_theme;
|
Win32CursorTheme *cursor_theme;
|
||||||
gchar *cursor_theme_name;
|
gchar *cursor_theme_name;
|
||||||
int cursor_theme_size;
|
int cursor_theme_size;
|
||||||
GHashTable *cursor_cache;
|
|
||||||
|
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
HWND clipboard_hwnd;
|
HWND clipboard_hwnd;
|
||||||
@@ -90,6 +89,10 @@ struct _GdkWin32Display
|
|||||||
|
|
||||||
GdkWin32ShcoreFuncs shcore_funcs;
|
GdkWin32ShcoreFuncs shcore_funcs;
|
||||||
GdkWin32User32DPIFuncs user32_dpi_funcs;
|
GdkWin32User32DPIFuncs user32_dpi_funcs;
|
||||||
|
|
||||||
|
/* Cursor Items (GdkCursor->HCURSOR) */
|
||||||
|
GHashTable *cursors;
|
||||||
|
GdkCursor *grab_cursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GdkWin32DisplayClass
|
struct _GdkWin32DisplayClass
|
||||||
|
|||||||
@@ -108,8 +108,6 @@ static gboolean gdk_event_dispatch (GSource *source,
|
|||||||
|
|
||||||
extern gint _gdk_input_ignore_core;
|
extern gint _gdk_input_ignore_core;
|
||||||
|
|
||||||
GdkCursor *_gdk_win32_grab_cursor;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GSource source;
|
GSource source;
|
||||||
@@ -2136,6 +2134,7 @@ gdk_event_translate (MSG *msg,
|
|||||||
GdkDisplay *display;
|
GdkDisplay *display;
|
||||||
GdkWindow *window = NULL;
|
GdkWindow *window = NULL;
|
||||||
GdkWindowImplWin32 *impl;
|
GdkWindowImplWin32 *impl;
|
||||||
|
GdkWin32Display *win32_display;
|
||||||
|
|
||||||
GdkWindow *new_window;
|
GdkWindow *new_window;
|
||||||
|
|
||||||
@@ -3063,15 +3062,20 @@ gdk_event_translate (MSG *msg,
|
|||||||
if (grab_window == NULL && LOWORD (msg->lParam) != HTCLIENT)
|
if (grab_window == NULL && LOWORD (msg->lParam) != HTCLIENT)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (grab_window != NULL && _gdk_win32_grab_cursor != NULL)
|
if (grab_window != NULL)
|
||||||
cursor = _gdk_win32_grab_cursor;
|
{
|
||||||
|
win32_display = GDK_WIN32_DISPLAY (gdk_window_get_display (grab_window));
|
||||||
|
|
||||||
|
if (win32_display->grab_cursor != NULL)
|
||||||
|
cursor = win32_display->grab_cursor;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
cursor = NULL;
|
cursor = NULL;
|
||||||
|
|
||||||
if (cursor != NULL)
|
if (cursor != NULL)
|
||||||
{
|
{
|
||||||
GDK_NOTE (EVENTS, g_print (" (SetCursor(%p)", cursor));
|
GDK_NOTE (EVENTS, g_print (" (SetCursor(%p)", cursor));
|
||||||
SetCursor (GDK_WIN32_CURSOR (cursor)->hcursor);
|
SetCursor (g_hash_table_lookup (win32_display->cursors, cursor));
|
||||||
return_val = TRUE;
|
return_val = TRUE;
|
||||||
*ret_valp = TRUE;
|
*ret_valp = TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,7 +132,6 @@ struct _GdkWin32Cursor
|
|||||||
{
|
{
|
||||||
GdkCursor cursor;
|
GdkCursor cursor;
|
||||||
|
|
||||||
gchar *name;
|
|
||||||
HCURSOR hcursor;
|
HCURSOR hcursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -354,15 +353,13 @@ extern GHashTable *_format_atom_table;
|
|||||||
/* Hold the result of a delayed rendering */
|
/* Hold the result of a delayed rendering */
|
||||||
extern HGLOBAL _delayed_rendering_data;
|
extern HGLOBAL _delayed_rendering_data;
|
||||||
|
|
||||||
extern GdkCursor *_gdk_win32_grab_cursor;
|
|
||||||
|
|
||||||
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
|
/* Convert a pixbuf to an HICON (or HCURSOR). Supports alpha under
|
||||||
* Windows XP, thresholds alpha otherwise.
|
* Windows XP, thresholds alpha otherwise.
|
||||||
*/
|
*/
|
||||||
HICON _gdk_win32_pixbuf_to_hicon (GdkPixbuf *pixbuf);
|
HICON _gdk_win32_texture_to_hicon (GdkTexture *texture);
|
||||||
HICON _gdk_win32_pixbuf_to_hcursor (GdkPixbuf *pixbuf,
|
HICON _gdk_win32_pixbuf_to_hcursor (GdkPixbuf *pixbuf,
|
||||||
gint x_hotspot,
|
gint x_hotspot,
|
||||||
gint y_hotspot);
|
gint y_hotspot);
|
||||||
@@ -370,6 +367,8 @@ HICON _gdk_win32_pixbuf_to_hcursor (GdkPixbuf *pixbuf,
|
|||||||
void _gdk_win32_display_init_cursors (GdkWin32Display *display);
|
void _gdk_win32_display_init_cursors (GdkWin32Display *display);
|
||||||
void _gdk_win32_display_finalize_cursors (GdkWin32Display *display);
|
void _gdk_win32_display_finalize_cursors (GdkWin32Display *display);
|
||||||
void _gdk_win32_display_update_cursors (GdkWin32Display *display);
|
void _gdk_win32_display_update_cursors (GdkWin32Display *display);
|
||||||
|
GdkCursor *_gdk_win32_display_get_cursor_for_name (GdkDisplay *display, const gchar* cursor_name);
|
||||||
|
GdkCursor *gdk_win32_display_cursor_from_hcursor (GdkDisplay *display, HCURSOR hcursor);
|
||||||
|
|
||||||
typedef struct _Win32CursorTheme Win32CursorTheme;
|
typedef struct _Win32CursorTheme Win32CursorTheme;
|
||||||
|
|
||||||
@@ -393,7 +392,6 @@ struct _Win32Cursor {
|
|||||||
gint height;
|
gint height;
|
||||||
guint load_flags;
|
guint load_flags;
|
||||||
gint xcursor_number;
|
gint xcursor_number;
|
||||||
GdkCursorType cursor_type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Win32CursorTheme *win32_cursor_theme_load (const gchar *name,
|
Win32CursorTheme *win32_cursor_theme_load (const gchar *name,
|
||||||
|
|||||||
@@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#ifdef GDK_COMPILATION
|
#ifdef GDK_COMPILATION
|
||||||
@@ -55,6 +57,10 @@ void gdk_win32_display_set_cursor_theme (GdkDisplay *display,
|
|||||||
const gchar *name,
|
const gchar *name,
|
||||||
gint size);
|
gint size);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_3_94
|
||||||
|
HCURSOR gdk_win32_display_get_hcursor (GdkDisplay *display,
|
||||||
|
GdkCursor *cursor);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GDK_WIN32_DISPLAY_H__ */
|
#endif /* __GDK_WIN32_DISPLAY_H__ */
|
||||||
|
|||||||
@@ -688,7 +688,7 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display,
|
|||||||
(window->window_type == GDK_WINDOW_TEMP ? "TEMP" : "???")),
|
(window->window_type == GDK_WINDOW_TEMP ? "TEMP" : "???")),
|
||||||
(attributes->wclass == GDK_INPUT_OUTPUT ? "" : "input-only")));
|
(attributes->wclass == GDK_INPUT_OUTPUT ? "" : "input-only")));
|
||||||
|
|
||||||
hparent = GDK_WINDOW_HWND (real_parent);
|
hparent = (real_parent != NULL) ? GDK_WINDOW_HWND (real_parent) : NULL;
|
||||||
|
|
||||||
impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
|
impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
|
||||||
impl->wrapper = GDK_WINDOW (window);
|
impl->wrapper = GDK_WINDOW (window);
|
||||||
@@ -725,7 +725,7 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display,
|
|||||||
hparent = GetDesktopWindow ();
|
hparent = GetDesktopWindow ();
|
||||||
}
|
}
|
||||||
/* Children of foreign windows aren't toplevel windows */
|
/* Children of foreign windows aren't toplevel windows */
|
||||||
if (GDK_WINDOW_TYPE (real_parent) == GDK_WINDOW_FOREIGN)
|
if (real_parent != NULL && GDK_WINDOW_TYPE (real_parent) == GDK_WINDOW_FOREIGN)
|
||||||
{
|
{
|
||||||
dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN;
|
dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN;
|
||||||
}
|
}
|
||||||
@@ -744,7 +744,9 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display,
|
|||||||
|
|
||||||
case GDK_WINDOW_TEMP:
|
case GDK_WINDOW_TEMP:
|
||||||
/* A temp window is not necessarily a top level window */
|
/* A temp window is not necessarily a top level window */
|
||||||
dwStyle = (real_parent == NULL || gdk_win32_display_get_root_window (display) == real_parent) ? WS_POPUP : WS_CHILDWINDOW);
|
dwStyle = (real_parent == NULL ||
|
||||||
|
gdk_win32_display_get_root_window (display) == real_parent) ?
|
||||||
|
WS_POPUP : WS_CHILDWINDOW;
|
||||||
dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||||
dwExStyle |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
|
dwExStyle |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
|
||||||
offset_x = _gdk_offset_x;
|
offset_x = _gdk_offset_x;
|
||||||
@@ -2005,8 +2007,6 @@ gdk_win32_window_get_geometry (GdkWindow *window,
|
|||||||
|
|
||||||
API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
|
API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
|
||||||
|
|
||||||
if (!window_is_root)
|
|
||||||
{
|
|
||||||
POINT pt;
|
POINT pt;
|
||||||
GdkWindow *parent = gdk_window_get_parent (window);
|
GdkWindow *parent = gdk_window_get_parent (window);
|
||||||
|
|
||||||
@@ -2033,7 +2033,6 @@ gdk_win32_window_get_geometry (GdkWindow *window,
|
|||||||
rect.right += _gdk_offset_x * impl->window_scale;
|
rect.right += _gdk_offset_x * impl->window_scale;
|
||||||
rect.bottom += _gdk_offset_y * impl->window_scale;
|
rect.bottom += _gdk_offset_y * impl->window_scale;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (x)
|
if (x)
|
||||||
*x = rect.left / impl->window_scale;
|
*x = rect.left / impl->window_scale;
|
||||||
@@ -2246,7 +2245,6 @@ gdk_win32_window_set_icon_list (GdkWindow *window,
|
|||||||
GList *textures)
|
GList *textures)
|
||||||
{
|
{
|
||||||
GdkTexture *big_texture, *small_texture;
|
GdkTexture *big_texture, *small_texture;
|
||||||
GdkPixbuf *big_pixbuf, *small_pixbuf;
|
|
||||||
gint big_diff, small_diff;
|
gint big_diff, small_diff;
|
||||||
gint big_w, big_h, small_w, small_h;
|
gint big_w, big_h, small_w, small_h;
|
||||||
gint w, h;
|
gint w, h;
|
||||||
@@ -2273,9 +2271,9 @@ gdk_win32_window_set_icon_list (GdkWindow *window,
|
|||||||
big_diff = 0;
|
big_diff = 0;
|
||||||
small_diff = 0;
|
small_diff = 0;
|
||||||
|
|
||||||
for (l = textures; l; l = l->next)
|
for (GList *l = textures; l; l = l->next)
|
||||||
{
|
{
|
||||||
texture = l->data;
|
GdkTexture *texture = l->data;
|
||||||
w = gdk_texture_get_width (texture);
|
w = gdk_texture_get_width (texture);
|
||||||
h = gdk_texture_get_height (texture);
|
h = gdk_texture_get_height (texture);
|
||||||
|
|
||||||
@@ -2301,10 +2299,10 @@ gdk_win32_window_set_icon_list (GdkWindow *window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create the icons */
|
/* Create the icons */
|
||||||
big_hicon = gdk_win32_texture_to_hicon (big_texture);
|
big_hicon = _gdk_win32_texture_to_hicon (big_texture);
|
||||||
g_object_unref (big_pixbuf);
|
g_object_unref (big_texture);
|
||||||
small_hicon = _gdk_win32_texture_to_hicon (small_texture);
|
small_hicon = _gdk_win32_texture_to_hicon (small_texture);
|
||||||
g_object_unref (small_pixbuf);
|
g_object_unref (small_texture);
|
||||||
|
|
||||||
/* Set the icons */
|
/* Set the icons */
|
||||||
SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
|
SendMessageW (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
|
||||||
@@ -4399,7 +4397,7 @@ setup_drag_move_resize_context (GdkWindow *window,
|
|||||||
|
|
||||||
cursor_name = get_cursor_name_from_op (op, edge);
|
cursor_name = get_cursor_name_from_op (op, edge);
|
||||||
|
|
||||||
context->cursor = _gdk_win32_display_get_cursor_for_name (display, cursor_name);
|
context->cursor = gdk_cursor_new_from_name (cursor_name, NULL);
|
||||||
|
|
||||||
pointer_window = child_window_at_coordinates (window, root_x, root_y);
|
pointer_window = child_window_at_coordinates (window, root_x, root_y);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user