gtk2/gdk/win32/gdkwin32cursor.h
Руслан Ижбулатов d8da6d38db GDK W32: New cursor class
Instead of now-unused GdkWin32Cursor class (a subclass of GdkCursor),
add a stand-alone GdkWin32HCursor class that is a wrapper around
HCURSOR handle.

On creation it's given a display instance, a HCURSOR handle and a boolean
that indicates whether the HCURSOR handle can or cannot be destroyed
(this depends on how the handle was obtained).
That information is stored in a hash table inside the GdkWin32Display
singleton, each entry of that table has reference count.
When the GdkWin32HCursor object is finalized, it reduces the reference
count on the table entry in the GdkWin32Display. When it's created,
it either adds such an entry or refs an existing one.
This way two pieces of code (or the same piece of code called
multiple times) that independently obtain the same HCURSOR from the OS
will get to different GdkWin32HCursor instances, but GdkWin32Display
will know that both use the same handle.

Once the reference count reaches 0 on the table entry, it is freed
and the handle (if destroyable) is put on the destruction list,
and an idle destruction function is queued.

If the same handle is once again registered for use before the
idle destructior is invoked (this happens, for example, when
an old cursor is destroyed and then replaced with a new one),
the handle gets removed from the destruction list.

The destructor just calls DestroyCursor() on each handle, calling
SetCursor(NULL) before doing that when the handle is in use.
This ensures that SetCursor(NULL) (which will cause cursor to disappear,
which is bad by itself, and which will also cause flickering if the
cursor is set to a non-NULL again shortly afterward)
is almost never called, unless GTK messes up and keeps using a cursor
beyond its lifetime.

This scheme also ensures that non-destructable cursors are not destroyed.

It's also possible to call _gdk_win32_display_hcursor_ref()
and _gdk_win32_display_hcursor_unref() manually instead of creating
GdkWin32HCursor objects, but that is not recommended.
2018-03-29 23:59:14 +00:00

87 lines
3.5 KiB
C

/* GDK - The GIMP Drawing Kit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GDK_WIN32_CURSOR_H__
#define __GDK_WIN32_CURSOR_H__
#if !defined (__GDKWIN32_H_INSIDE__) && !defined (GDK_COMPILATION)
#error "Only <gdk/gdkwin32.h> can be included directly."
#endif
#include <Windows.h>
#include <gdk/gdk.h>
#include <gdk/win32/gdkwin32display.h>
G_BEGIN_DECLS
typedef struct _GdkWin32HCursor GdkWin32HCursor;
typedef struct _GdkWin32HCursorClass GdkWin32HCursorClass;
#define GDK_TYPE_WIN32_HCURSOR (gdk_win32_hcursor_get_type())
#define GDK_WIN32_HCURSOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WIN32_HCURSOR, GdkWin32HCursor))
#define GDK_WIN32_HCURSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WIN32_HCURSOR, GdkWin32HCursorClass))
#define GDK_IS_WIN32_HCURSOR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WIN32_HCURSOR))
#define GDK_IS_WIN32_HCURSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WIN32_HCURSOR))
#define GDK_WIN32_HCURSOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WIN32_HCURSOR, GdkWin32HCursorClass))
GDK_AVAILABLE_IN_ALL
GType gdk_win32_hcursor_get_type (void);
struct _GdkWin32HCursorFake
{
GObject parent_instance;
HCURSOR readonly_handle;
};
#define gdk_win32_hcursor_get_handle_fast(x) (((struct _GdkWin32HCursorFake *) x)->readonly_handle)
#if defined (GDK_COMPILATION)
#define gdk_win32_hcursor_get_handle gdk_win32_hcursor_get_handle_fast
#else
GDK_AVAILABLE_IN_ALL
HCURSOR gdk_win32_hcursor_get_handle (GdkWin32HCursor *cursor);
#endif
GDK_AVAILABLE_IN_ALL
GdkWin32HCursor *gdk_win32_hcursor_new (GdkWin32Display *display,
HCURSOR handle,
gboolean destroyable);
GDK_AVAILABLE_IN_ALL
GdkWin32HCursor *gdk_win32_display_get_win32hcursor (GdkWin32Display *display,
GdkCursor *cursor);
GDK_AVAILABLE_IN_ALL
void _gdk_win32_display_hcursor_ref (GdkWin32Display *display,
HCURSOR handle,
gboolean destroyable);
GDK_AVAILABLE_IN_ALL
void _gdk_win32_display_hcursor_unref (GdkWin32Display *display,
HCURSOR handle);
G_END_DECLS
#endif /* __GDK_WIN32_CURSOR_H__ */