summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorРуслан Ижбулатов <lrn1986@gmail.com>2015-05-03 21:29:35 +0000
committerРуслан Ижбулатов <lrn1986@gmail.com>2015-05-20 08:40:43 +0000
commit641fbd86d796bb0f7838b1d7387031a106386439 (patch)
tree1d61a9cac3782c6d74dda4a0cae4161f149a47e4
parent7fef713224583ab906d0875eedcf7a76534eff0f (diff)
downloadgtk+-641fbd86d796bb0f7838b1d7387031a106386439.tar.gz
GDK: Use GdkCursor objects to keep track of W32 cursors, not HCURSOR
In particular this means that cursors are disposed of by the way of g_object_unref(), not DestroyCursor (which is documented to not to be used on certain kinds of cursors, and we can't tell which is which). It should also alleviate any concerns about destroying cursors that are still in use by other windows, except for cases where we would somehow get our hands on a HCURSOR that someone else is using and we make a GdkCursor out of it and later unref and finalize it while it is still in use. It also removes the need to call CopyCursor(), which makes animated cursors into non-animated ones as a side-effect (supposed to be a bug, but try explaining that to MS). Now cursors should be animated (if the are set up as such in the OS). https://bugzilla.gnome.org/show_bug.cgi?id=697477
-rw-r--r--gdk/win32/gdkdevice-virtual.c60
-rw-r--r--gdk/win32/gdkevents-win32.c26
-rw-r--r--gdk/win32/gdkprivate-win32.h2
-rw-r--r--gdk/win32/gdkwindow-win32.c49
-rw-r--r--gdk/win32/gdkwindow-win32.h2
5 files changed, 47 insertions, 92 deletions
diff --git a/gdk/win32/gdkdevice-virtual.c b/gdk/win32/gdkdevice-virtual.c
index 4371c16403..2ed341f106 100644
--- a/gdk/win32/gdkdevice-virtual.c
+++ b/gdk/win32/gdkdevice-virtual.c
@@ -157,30 +157,23 @@ gdk_device_virtual_set_window_cursor (GdkDevice *device,
GdkWindow *window,
GdkCursor *cursor)
{
- GdkWin32Cursor *cursor_private;
GdkWindow *parent_window;
GdkWindowImplWin32 *impl;
- HCURSOR hcursor;
- HCURSOR hprevcursor;
+ GdkCursor *replacement_cursor;
+ GdkCursor *previous_cursor;
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
- cursor_private = (GdkWin32Cursor*) cursor;
- hprevcursor = impl->hcursor;
+ previous_cursor = impl->cursor;
- if (!cursor)
- hcursor = NULL;
- else
- hcursor = cursor_private->hcursor;
-
- if (hcursor != NULL)
+ if (cursor != NULL && GDK_WIN32_CURSOR (cursor)->hcursor != NULL)
{
/* If the pointer is over our window, set new cursor */
GdkWindow *curr_window = gdk_window_get_device_position (window, device, NULL, NULL, NULL);
if (curr_window == window ||
(curr_window && window == gdk_window_get_toplevel (curr_window)))
- SetCursor (hcursor);
+ SetCursor (GDK_WIN32_CURSOR (cursor)->hcursor);
else
{
/* Climb up the tree and find whether our window is the
@@ -188,12 +181,12 @@ gdk_device_virtual_set_window_cursor (GdkDevice *device,
* new cursor.
*/
while (curr_window && curr_window->impl &&
- !GDK_WINDOW_IMPL_WIN32 (curr_window->impl)->hcursor)
+ !GDK_WINDOW_IMPL_WIN32 (curr_window->impl)->cursor)
{
curr_window = curr_window->parent;
if (curr_window == GDK_WINDOW (window))
{
- SetCursor (hcursor);
+ SetCursor (GDK_WIN32_CURSOR (cursor)->hcursor);
break;
}
}
@@ -204,26 +197,26 @@ gdk_device_virtual_set_window_cursor (GdkDevice *device,
* use before we destroy it, in case we're not over our window but
* the cursor is still set to our old one.
*/
- if (hprevcursor != NULL &&
- GetCursor () == hprevcursor)
+ if (previous_cursor != NULL &&
+ GetCursor () == GDK_WIN32_CURSOR (previous_cursor)->hcursor)
{
/* Look for a suitable cursor to use instead */
- hcursor = NULL;
+ replacement_cursor = NULL;
parent_window = GDK_WINDOW (window)->parent;
- while (hcursor == NULL)
+ while (replacement_cursor == NULL)
{
if (parent_window)
{
impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl);
- hcursor = impl->hcursor;
+ replacement_cursor = impl->cursor;
parent_window = parent_window->parent;
}
else
- hcursor = LoadCursor (NULL, IDC_ARROW);
+ replacement_cursor = _gdk_win32_display_get_cursor_for_type (_gdk_display, GDK_LEFT_PTR);
}
- SetCursor (hcursor);
+ SetCursor (GDK_WIN32_CURSOR (replacement_cursor)->hcursor);
}
}
@@ -266,31 +259,22 @@ gdk_device_virtual_grab (GdkDevice *device,
guint32 time_)
{
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
- HCURSOR hcursor;
- GdkWin32Cursor *cursor_private;
-
- cursor_private = (GdkWin32Cursor*) cursor;
if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
{
- if (!cursor)
- hcursor = NULL;
- else if ((hcursor = CopyCursor (cursor_private->hcursor)) == NULL)
- WIN32_API_FAILED ("CopyCursor");
-
if (_gdk_win32_grab_cursor != NULL)
{
- if (GetCursor () == _gdk_win32_grab_cursor)
+ if (GetCursor () == GDK_WIN32_CURSOR (_gdk_win32_grab_cursor)->hcursor)
SetCursor (NULL);
- DestroyCursor (_gdk_win32_grab_cursor);
+ g_clear_object (&_gdk_win32_grab_cursor);
}
- _gdk_win32_grab_cursor = hcursor;
+ _gdk_win32_grab_cursor = cursor;
if (_gdk_win32_grab_cursor != NULL)
- SetCursor (_gdk_win32_grab_cursor);
- else if (impl->hcursor != NULL)
- SetCursor (impl->hcursor);
+ SetCursor (GDK_WIN32_CURSOR (_gdk_win32_grab_cursor)->hcursor);
+ else if (impl->cursor != NULL)
+ SetCursor (GDK_WIN32_CURSOR (impl->cursor)->hcursor);
else
SetCursor (LoadCursor (NULL, IDC_ARROW));
@@ -317,9 +301,9 @@ gdk_device_virtual_ungrab (GdkDevice *device,
{
if (_gdk_win32_grab_cursor != NULL)
{
- if (GetCursor () == _gdk_win32_grab_cursor)
+ if (GetCursor () == GDK_WIN32_CURSOR (_gdk_win32_grab_cursor)->hcursor)
SetCursor (NULL);
- DestroyCursor (_gdk_win32_grab_cursor);
+ g_clear_object (&_gdk_win32_grab_cursor);
}
_gdk_win32_grab_cursor = NULL;
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index dc18405520..eed1bc6e5d 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -106,7 +106,7 @@ static gboolean gdk_event_dispatch (GSource *source,
static GList *client_filters; /* Filters for client messages */
extern gint _gdk_input_ignore_core;
-HCURSOR _gdk_win32_grab_cursor;
+GdkCursor *_gdk_win32_grab_cursor;
static GSourceFuncs event_funcs = {
gdk_event_prepare,
@@ -1840,7 +1840,7 @@ gdk_event_translate (MSG *msg,
MINMAXINFO *mmi;
LONG style;
HWND hwnd;
- HCURSOR hcursor;
+ GdkCursor *cursor;
BYTE key_state[256];
HIMC himc;
WINDOWPOS *windowpos;
@@ -2633,19 +2633,19 @@ gdk_event_translate (MSG *msg,
break;
if (grab_window != NULL && _gdk_win32_grab_cursor != NULL)
- hcursor = _gdk_win32_grab_cursor;
- else if (!GDK_WINDOW_DESTROYED (window))
- hcursor = GDK_WINDOW_IMPL_WIN32 (window->impl)->hcursor;
+ cursor = _gdk_win32_grab_cursor;
+ else if (!GDK_WINDOW_DESTROYED (window) && GDK_WINDOW_IMPL_WIN32 (window->impl)->cursor != NULL)
+ cursor = GDK_WINDOW_IMPL_WIN32 (window->impl)->cursor;
else
- hcursor = NULL;
+ cursor = NULL;
- if (hcursor != NULL)
- {
- GDK_NOTE (EVENTS, g_print (" (SetCursor(%p)", hcursor));
- SetCursor (hcursor);
- return_val = TRUE;
- *ret_valp = TRUE;
- }
+ if (cursor != NULL)
+ {
+ GDK_NOTE (EVENTS, g_print (" (SetCursor(%p)", cursor));
+ SetCursor (GDK_WIN32_CURSOR (cursor)->hcursor);
+ return_val = TRUE;
+ *ret_valp = TRUE;
+ }
break;
case WM_SYSCOMMAND:
diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h
index 93166a912f..98b64a3edb 100644
--- a/gdk/win32/gdkprivate-win32.h
+++ b/gdk/win32/gdkprivate-win32.h
@@ -361,7 +361,7 @@ extern GHashTable *_format_atom_table;
/* Hold the result of a delayed rendering */
extern HGLOBAL _delayed_rendering_data;
-extern HCURSOR _gdk_win32_grab_cursor;
+extern GdkCursor *_gdk_win32_grab_cursor;
HGLOBAL _gdk_win32_selection_convert_to_dib (HGLOBAL hdata,
GdkAtom target);
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index 43fb2d02ad..765ae01071 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -132,7 +132,7 @@ static void
gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
{
impl->toplevel_window_type = -1;
- impl->hcursor = NULL;
+ impl->cursor = NULL;
impl->hicon_big = NULL;
impl->hicon_small = NULL;
impl->hint_flags = 0;
@@ -160,14 +160,7 @@ gdk_window_impl_win32_finalize (GObject *object)
gdk_win32_handle_table_remove (window_impl->handle);
}
- if (window_impl->hcursor != NULL)
- {
- if (GetCursor () == window_impl->hcursor)
- SetCursor (NULL);
-
- GDI_CALL (DestroyCursor, (window_impl->hcursor));
- window_impl->hcursor = NULL;
- }
+ g_clear_object (&window_impl->cursor);
if (window_impl->hicon_big != NULL)
{
@@ -1957,55 +1950,33 @@ gdk_win32_window_set_device_cursor (GdkWindow *window,
GdkCursor *cursor)
{
GdkWindowImplWin32 *impl;
- GdkWin32Cursor *cursor_private;
- HCURSOR hcursor;
- HCURSOR hprevcursor;
+ GdkCursor *previous_cursor;
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
- cursor_private = (GdkWin32Cursor*) cursor;
if (GDK_WINDOW_DESTROYED (window))
return;
- if (!cursor)
- hcursor = NULL;
- else
- hcursor = cursor_private->hcursor;
-
GDK_NOTE (MISC, g_print ("gdk_win32_window_set_cursor: %p: %p\n",
GDK_WINDOW_HWND (window),
- hcursor));
+ cursor));
/* First get the old cursor, if any (we wait to free the old one
* since it may be the current cursor set in the Win32 API right
* now).
*/
- hprevcursor = impl->hcursor;
+ previous_cursor = impl->cursor;
GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
- if (hcursor == NULL)
- impl->hcursor = NULL;
+ if (cursor)
+ impl->cursor = g_object_ref (cursor);
else
- {
- /* We must copy the cursor as it is OK to destroy the GdkCursor
- * while still in use for some window. See for instance
- * gimp_change_win_cursor() which calls gdk_window_set_cursor
- * (win, cursor), and immediately afterwards gdk_cursor_destroy
- * (cursor).
- */
- if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
- WIN32_API_FAILED ("CopyCursor");
- GDK_NOTE (MISC, g_print ("... CopyCursor (%p) = %p\n",
- hcursor, impl->hcursor));
- }
+ impl->cursor = NULL;
/* Destroy the previous cursor */
- if (hprevcursor != NULL)
- {
- GDK_NOTE (MISC, g_print ("... DestroyCursor (%p)\n", hprevcursor));
- API_CALL (DestroyCursor, (hprevcursor));
- }
+ if (previous_cursor != NULL)
+ g_object_unref (previous_cursor);
}
static void
diff --git a/gdk/win32/gdkwindow-win32.h b/gdk/win32/gdkwindow-win32.h
index bc1575c71a..8f17ead033 100644
--- a/gdk/win32/gdkwindow-win32.h
+++ b/gdk/win32/gdkwindow-win32.h
@@ -55,7 +55,7 @@ struct _GdkWindowImplWin32
gint8 toplevel_window_type;
- HCURSOR hcursor;
+ GdkCursor *cursor;
HICON hicon_big;
HICON hicon_small;