gtk2/gdk/gdkevents.c

3197 lines
83 KiB
C
Raw Normal View History

/* 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
2012-02-27 13:01:10 +00:00
* 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/.
*/
#include "config.h"
#include "gdkintl.h"
#include "gdkeventsprivate.h"
2000-03-28 01:24:44 +00:00
#include "gdkinternals.h"
#include "gdkdisplayprivate.h"
#include "gdkdragprivate.h"
#include "gdkdropprivate.h"
#include "gdkkeysprivate.h"
#include "gdk-private.h"
#include <gobject/gvaluecollector.h>
#include <string.h>
#include <math.h>
/**
* SECTION:events
* @Short_description: Functions for handling events from the window system
* @Title: Events
*
* This section describes functions dealing with events from the window
* system.
*
* In GTK applications the events are handled automatically by toplevel
* widgets and passed on to the event controllers of appropriate widgets,
* so these functions are rarely needed.
*/
2017-12-26 19:39:24 +00:00
/**
* GdkEvent: (ref-func gdk_event_ref) (unref-func gdk_event_unref)
2017-12-26 19:39:24 +00:00
*
* The GdkEvent struct contains only private fields and
* should not be accessed directly.
*/
/**
* GdkEventSequence:
*
* GdkEventSequence is an opaque type representing a sequence
* of related touch events.
*/
static void
value_event_init (GValue *value)
{
value->data[0].v_pointer = NULL;
}
static void
value_event_free_value (GValue *value)
{
if (value->data[0].v_pointer != NULL)
gdk_event_unref (value->data[0].v_pointer);
}
static void
value_event_copy_value (const GValue *src,
GValue *dst)
{
if (src->data[0].v_pointer != NULL)
dst->data[0].v_pointer = gdk_event_ref (src->data[0].v_pointer);
else
dst->data[0].v_pointer = NULL;
}
static gpointer
value_event_peek_pointer (const GValue *value)
{
return value->data[0].v_pointer;
}
static char *
value_event_collect_value (GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
GdkEvent *event = collect_values[0].v_pointer;
if (event == NULL)
{
value->data[0].v_pointer = NULL;
return NULL;
}
if (event->parent_instance.g_class == NULL)
return g_strconcat ("invalid unclassed GdkEvent pointer for "
"value type '",
G_VALUE_TYPE_NAME (value),
"'",
NULL);
value->data[0].v_pointer = gdk_event_ref (event);
return NULL;
}
2020-07-24 18:40:36 +00:00
static char *
value_event_lcopy_value (const GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
GdkEvent **event_p = collect_values[0].v_pointer;
if (event_p == NULL)
return g_strconcat ("value location for '",
G_VALUE_TYPE_NAME (value),
"' passed as NULL",
NULL);
if (value->data[0].v_pointer == NULL)
*event_p = NULL;
else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
*event_p = value->data[0].v_pointer;
else
*event_p = gdk_event_ref (value->data[0].v_pointer);
return NULL;
}
static void
gdk_event_finalize (GdkEvent *self)
{
GdkDisplay *display = gdk_event_get_display (self);
if (display != NULL)
_gdk_display_event_data_free (display, self);
g_clear_object (&self->surface);
g_clear_object (&self->device);
g_clear_object (&self->source_device);
g_type_free_instance ((GTypeInstance *) self);
}
static GdkModifierType
gdk_event_real_get_state (GdkEvent *self)
{
return 0;
}
static gboolean
gdk_event_real_get_position (GdkEvent *self,
double *x,
double *y)
{
*x = NAN;
*y = NAN;
return FALSE;
}
static GdkEventSequence *
gdk_event_real_get_sequence (GdkEvent *self)
{
return NULL;
}
static GdkDeviceTool *
gdk_event_real_get_tool (GdkEvent *self)
{
return NULL;
}
static gboolean
gdk_event_real_get_axes (GdkEvent *self,
double **axes,
guint *n_axes)
{
return FALSE;
}
static void
gdk_event_class_init (GdkEventClass *klass)
{
klass->finalize = gdk_event_finalize;
klass->get_state = gdk_event_real_get_state;
klass->get_position = gdk_event_real_get_position;
klass->get_sequence = gdk_event_real_get_sequence;
klass->get_tool = gdk_event_real_get_tool;
klass->get_axes = gdk_event_real_get_axes;
}
static void
gdk_event_init (GdkEvent *self)
{
g_ref_count_init (&self->ref_count);
}
GType
gdk_event_get_type (void)
{
static volatile gsize event_type__volatile;
if (g_once_init_enter (&event_type__volatile))
{
static const GTypeFundamentalInfo finfo = {
(G_TYPE_FLAG_CLASSED |
G_TYPE_FLAG_INSTANTIATABLE |
G_TYPE_FLAG_DERIVABLE |
G_TYPE_FLAG_DEEP_DERIVABLE),
};
static const GTypeValueTable value_table = {
value_event_init,
value_event_free_value,
value_event_copy_value,
value_event_peek_pointer,
"p",
value_event_collect_value,
"p",
value_event_lcopy_value,
};
const GTypeInfo event_info = {
/* Class */
sizeof (GdkEventClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gdk_event_class_init,
(GClassFinalizeFunc) NULL,
NULL,
/* Instance */
sizeof (GdkEvent),
0,
(GInstanceInitFunc) gdk_event_init,
/* GValue */
&value_table,
};
GType event_type =
g_type_register_fundamental (g_type_fundamental_next (),
g_intern_static_string ("GdkEvent"),
&event_info, &finfo,
G_TYPE_FLAG_ABSTRACT);
g_once_init_leave (&event_type__volatile, event_type);
}
return event_type__volatile;
}
/*< private >
* GdkEventTypeInfo:
* @instance_size: the size of the instance of a GdkEvent subclass
* @instance_init: (nullable): the function to initialize the instance data
* @finalize: (nullable): the function to free the instance data
* @get_state: (nullable): the function to retrieve the #GdkModifierType
* associated to the event
* @get_position: (nullable): the function to retrieve the event coordinates
* @get_sequence: (nullable): the function to retrieve the event sequence
* @get_tool: (nullable): the function to retrieve the event's device tool
* @get_axes: (nullable): the function to retrieve the event's axes
*
* A structure used when registering a new GdkEvent type.
*/
typedef struct {
gsize instance_size;
void (* instance_init) (GdkEvent *event);
void (* finalize) (GdkEvent *event);
GdkModifierType (* get_state) (GdkEvent *event);
gboolean (* get_position) (GdkEvent *event,
double *x,
double *y);
GdkEventSequence *(* get_sequence) (GdkEvent *event);
GdkDeviceTool *(* get_tool) (GdkEvent *event);
gboolean (* get_axes) (GdkEvent *event,
double **axes,
guint *n_axes);
} GdkEventTypeInfo;
static void
gdk_event_generic_class_init (gpointer g_class,
gpointer class_data)
{
GdkEventTypeInfo *info = class_data;
GdkEventClass *event_class = g_class;
/* Optional */
if (info->finalize != NULL)
event_class->finalize = info->finalize;
if (info->get_state != NULL)
event_class->get_state = info->get_state;
if (info->get_position != NULL)
event_class->get_position = info->get_position;
if (info->get_sequence != NULL)
event_class->get_sequence = info->get_sequence;
if (info->get_tool != NULL)
event_class->get_tool = info->get_tool;
if (info->get_axes != NULL)
event_class->get_axes = info->get_axes;
g_free (info);
}
static GType
gdk_event_type_register_static (const char *type_name,
const GdkEventTypeInfo *type_info)
{
GTypeInfo info;
info.class_size = sizeof (GdkEventClass);
info.base_init = NULL;
info.base_finalize = NULL;
info.class_init = gdk_event_generic_class_init;
info.class_finalize = NULL;
info.class_data = g_memdup (type_info, sizeof (GdkEventTypeInfo));
info.instance_size = type_info->instance_size;
info.n_preallocs = 0;
info.instance_init = (GInstanceInitFunc) type_info->instance_init;
info.value_table = NULL;
return g_type_register_static (GDK_TYPE_EVENT, type_name, &info, 0);
}
/* Map GdkEventType to the appropriate GType */
static GType gdk_event_types[GDK_EVENT_LAST];
/*< private >
* GDK_EVENT_TYPE_SLOT:
* @ETYPE: a #GdkEventType
*
* Associates a #GdkEvent type with the given #GdkEventType enumeration.
*
* This macro can only be used with %GDK_DEFINE_EVENT_TYPE.
*/
#define GDK_EVENT_TYPE_SLOT(ETYPE) { gdk_event_types[ETYPE] = gdk_define_event_type_id; }
/*< private >
* GDK_DEFINE_EVENT_TYPE:
* @TypeName: the type name, in camel case
* @type_name: the type name, in snake case
* @type_info: the address of the #GdkEventTypeInfo for the event type
* @_C_: custom code to call after registering the event type
*
* Registers a new #GdkEvent subclass with the given @TypeName and @type_info.
*
* Similarly to %G_DEFINE_TYPE_WITH_CODE, this macro will generate a `get_type()`
* function that registers the event type.
*
* You can specify code to be run after the type registration; the #GType of
* the event is available in the `gdk_define_event_type_id` variable.
*/
#define GDK_DEFINE_EVENT_TYPE(TypeName, type_name, type_info, _C_) \
GType \
type_name ## _get_type (void) \
{ \
static volatile gsize gdk_define_event_type_id__volatile; \
if (g_once_init_enter (&gdk_define_event_type_id__volatile)) \
{ \
GType gdk_define_event_type_id = \
gdk_event_type_register_static (g_intern_static_string (#TypeName), type_info); \
{ _C_ } \
g_once_init_leave (&gdk_define_event_type_id__volatile, gdk_define_event_type_id); \
} \
return gdk_define_event_type_id__volatile; \
}
#define GDK_EVENT_SUPER(event) \
((GdkEventClass *) g_type_class_peek (g_type_parent (G_TYPE_FROM_INSTANCE (event))))
/*< private >
* gdk_event_alloc:
* @event_type: the #GdkEventType to allocate
* @surface: (nullable): the #GdkSurface of the event
* @device: (nullable): the #GdkDevice of the event
* @source_device: (nullable): the source #GdkDevice of the event
* @time_: the event serial
*
* Allocates a #GdkEvent for the given @event_type, and sets its
* common fields with the given parameters.
*
* Returns: (transfer full): the newly allocated #GdkEvent instance
*/
static gpointer
gdk_event_alloc (GdkEventType event_type,
GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
guint32 time_)
{
g_assert (event_type >= GDK_DELETE && event_type < GDK_EVENT_LAST);
g_assert (gdk_event_types[event_type] != G_TYPE_INVALID);
GdkEvent *event = (GdkEvent *) g_type_create_instance (gdk_event_types[event_type]);
GDK_NOTE (EVENTS, {
char *str = g_enum_to_string (GDK_TYPE_EVENT_TYPE, event_type);
g_message ("Allocating a new %s for event type %s",
g_type_name (gdk_event_types[event_type]), str);
g_free (str);
});
event->event_type = event_type;
event->surface = surface != NULL ? g_object_ref (surface) : NULL;
event->device = device != NULL ? g_object_ref (device) : NULL;
event->source_device = source_device != NULL ? g_object_ref (source_device) : NULL;
event->time = time_;
return event;
}
static void
gdk_event_init_types_once (void)
{
g_type_ensure (GDK_TYPE_BUTTON_EVENT);
g_type_ensure (GDK_TYPE_CONFIGURE_EVENT);
g_type_ensure (GDK_TYPE_CROSSING_EVENT);
g_type_ensure (GDK_TYPE_DELETE_EVENT);
g_type_ensure (GDK_TYPE_DND_EVENT);
g_type_ensure (GDK_TYPE_FOCUS_EVENT);
g_type_ensure (GDK_TYPE_GRAB_BROKEN_EVENT);
g_type_ensure (GDK_TYPE_KEY_EVENT);
g_type_ensure (GDK_TYPE_MOTION_EVENT);
g_type_ensure (GDK_TYPE_PAD_EVENT);
g_type_ensure (GDK_TYPE_PROXIMITY_EVENT);
g_type_ensure (GDK_TYPE_SCROLL_EVENT);
g_type_ensure (GDK_TYPE_TOUCH_EVENT);
g_type_ensure (GDK_TYPE_TOUCHPAD_EVENT);
}
/*< private >
* gdk_event_init_types:
*
* Initializes all GdkEvent types.
*/
void
gdk_event_init_types (void)
{
static volatile gsize event_types__volatile;
if (g_once_init_enter (&event_types__volatile))
{
gboolean initialized = FALSE;
gdk_event_init_types_once ();
initialized = TRUE;
g_once_init_leave (&event_types__volatile, initialized);
}
}
#ifdef G_ENABLE_DEBUG
2020-02-20 22:13:21 +00:00
static gboolean
check_event_sanity (GdkEvent *event)
{
if (event->device != NULL &&
gdk_surface_get_display (event->surface) != gdk_device_get_display (event->device))
{
char *type = g_enum_to_string (GDK_TYPE_EVENT_TYPE, event->event_type);
2020-02-20 22:13:21 +00:00
g_warning ("Event of type %s with mismatched device display", type);
g_free (type);
return FALSE;
}
if (event->source_device != NULL &&
gdk_surface_get_display (event->surface) != gdk_device_get_display (event->source_device))
{
char *type = g_enum_to_string (GDK_TYPE_EVENT_TYPE, event->event_type);
2020-02-20 22:13:21 +00:00
g_warning ("Event of type %s with mismatched source device display", type);
g_free (type);
return FALSE;
}
return TRUE;
}
#endif
void
_gdk_event_emit (GdkEvent *event)
{
#ifdef G_ENABLE_DEBUG
if (!check_event_sanity (event))
return;
#endif
if (gdk_drag_handle_source_event (event))
return;
gdk_surface_handle_event (event);
}
/*********************************************
* Functions for maintaining the event queue *
*********************************************/
Start of integration of Erwann Chenede's multihead work from the Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com> Start of integration of Erwann Chenede's multihead work from the gtk-multihead branch. * gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch] New classes representing a set of screens with attached input devices and a single contiguous area, respectively. * gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c: gdk/x11/gdkprivate-x11.h: Make the initialization interface simple _gdk_windowing_init() and do the rest in gdk_open_display() calls. * gdk/gdk.[ch]: Add gdk_parse_args() which can be used to do the display-independent part of initialization instead of gdk_init_[check]. * gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h: Add multihead variants (_for_display(), for_screen()) of functions getting information specific to a particular screen screen or display. * gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions like gdk_rgb_get_colormap() that used to get/list global objects. * gdk/x11/gdkx.h: Add functions for converting GdkScreen and GdkDisplay into the X equivalents. * gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords() not in the headers and unused. * configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}: Remove gxid support ... has not been tested for a long time... "xfree" support is more portable to non XFree86. * gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be used to turn off functions that are inherently non-multihead safe. * gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions are used in non-multihead-safe ways. * gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK multihead safe.
2002-04-25 22:29:14 +00:00
/**
Make gdkx.h the only installed header from gdk/x11. All structures in Fri Sep 7 11:51:44 2001 Owen Taylor <otaylor@redhat.com> Make gdkx.h the only installed header from gdk/x11. All structures in gdk/x11 are opaque. * gdk/x11/Makefile.am gdk/x11/gdkx.h gdk/x11/gdkprivate-x11.h: Don't install gdk{drawable,pixmap,window}-x11.h. * gdk/x11/{gdkcolormap-x11.c, gdkfont-x11.c, gdkx.h, gdkvisual-x11.c: Move GdkColormapPrivateX11, GdkFontPrivateX GdkImagePrivateX11, GdkVisualClass into C files. * gdk/gdkpixmap-x11.[ch]: Make gdk_pixmap_impl_get_type() static. * gdk/x11/{gdkcolor-x11.c, gdkcursor-x11.c, gdkdrawable-x11.c, gdkfont-x11.c, gdkgc-x11.c, gdkx.h, gdkimage-x11,gdkvisual-x11.c} Add public functions to replace previously exported direct structure access. gdk_x11_colormap_get_{xdisplay,xcolormap} gdk_x11_cursor_get_{xdisplay,xcursor}, gdk_x11_drawable_get_{xdisplay,xcursor,gdk_x11_visual_get_xvisual, gdk_x11_font_get_{xdisplay,xfont}, gdk_x11_image_get_{xdisplay,ximage}, gdk_x11_gc_get_{xdisplay,ximage} * gdk/gdkprivate.h gdk/gdkinternals.h: Move GdkColorInfo, GdkEventFilter, GdkClientFilter, GdkFontPrivate to gdkinternals. Fix a number of variables and functions that were exported "accidentally" from GDK. * gdk/**.[ch]: gdk => _gdk for gdk_visual_init, gdk_events_init, gdk_input_init, gdk_dnd_init, gdk_image_exit, gdk_input_exit, gdk_windowing_exit, gdk_event_func, gdk_event_data, gdk_event_notify, gdk_queued_events, gdk_queued_tail, gdk_event_new, gdk_events_queue, gdk_events_unqueue, gdk_event_queue_find_first, gdk_event_queue_remove_link, gdk_event_queue_append, gdk_event_button_generate, gdk_debug_flags, gdk_default_filters, gdk_parent_root. * gdk/x11/{gdkevents-x11.c, gdkglobals-x11.c, gdkimage-x11.c, gdkmain-x11.c, gdkprivate-x11.h, gdk/x11/gdkwindow-x11.c}: gdk => _gdk for gdk_event_mask_table, gkd_nevent_masks, gdk_wm_window_protocols, gdk_leader_window, gdk_xgrab_window, gdk_use_xshm, gdk_input_ignore_core. * gdk/x11/xsettings-common.h (xsettings_list_insert): Add #defines to namespace functions into the private _gdk_ namespace. * gdk/gdkwindow.[ch] gdk/x11/gdkx.h: Add gdk_get_default_root_window () to replace gdk_parent_root exported variable. Adjust and deprecate GDK_ROOT_PARENT(). * demos/{testpixbuf-drawable.c,testpixbuf-save.c}: Fix GDK_ROOT_PARENT usage, remove includes of port-specific headers. * gdk/{win32,x11,fb}/gdkinput*.[ch]: s/gdk/_gdk/ for _gdk_input_gxid_host, _gdk_input_gxid_port, _gdk_input_ignore_core, gdk_input_devices, _gdk_input_windows, gdk_init_input_core. * gdk/x11/{gdkevents-x11.,c gdkglobals-x11.c, gdkmain-x11.c} docs/Changes-2.0.txt: Remove gdk_wm_protocols, gdk_wm_delete_window functions, gdk_wm_take_focus, use gdk_atom_intern() instead. * gdk/linux-fb/{gdkselection-fb.c, gdkmain-fb.c, gdkprivatefb.h} gdk/win32/{gdkselection-win32.c, gdkmgdkwin32.h, gdkprivate-win32.h} gdk/x11/{gdkselection-x11.c gdkx.h, gtkprivate-x11.h} gtk/gtkselection.c Unexport gdk_selection_property, just use gdk_atom_intern ("GDK_SELECTION"). * gdk/x11/{gdkprivate-x11.h,gdkdrawable-x11h,gdkgc-x11.c,gdkx.h}: Unexport gdk_drawable_impl_x11_get_type, gdk_gc_x11_get_type, GDK_GC_X11 cast macros, GdkGCX11 structures, GdkCursorPrivate, GdkVisualprivate, gdk_x11_gc_flush. Make a number of public exports of variables into functions to increase encapsulation. * gdk/gdkinternals.h gdk/gdkinput.h gdk/gdkevents.h gdk/linux-fb/gdkmouse-fb.c: gdk_core_pointer => _gdk_core_pointer, move to gdkinternals.h. Add gdk_device_get_core_pointer (). * gdk/gdkprivate.h gdk/gdkpango.c gdk/gdkinternals.h docs/Changes-2.0.txt: Unexport gdk_parent_root, gdk_error_code, gdk_error_warnings. * gdk/x11/{gdkcolormap-x11.c, gdkmain-x11.c, gdkx.h} docs/Changes-2.0.txt: s/gdk_screen/_gdk_screen/, add gdk_x11_get_default_screen() s/gdk_root_window/_gdk_root_window/, add gdk_x11_get_default_root_xwindow() Add gdk_x11_get_default_xdisplay(). * gdk/gdk.h gdk/gdk.c linux-fb/gdkfb.h linux-fb/gdkglobals-fb.c win32/gdkwin32.h x11/gdkglobals-x11.c gdk/x11/gdkmain-x11.c gdk/x11/gdkx.h: gdk/gdk.def: Add gdk_get/set_program_class, Don't export gdk_progclass, move --class command line option and handling to common portion of GDK. Miscellaneous fixes: * gdk/x11/gdkwindow-x11.c (gdk_window_set_icon_list): Fix g_return_val_if_fail that should have been g_return_if_fail. * gdk/gdkinternals.h gdk/gdkprivate.h: Move gdk_synthesize_window_state() to the semi-public gdkprivate.h. * gtk/gtkdnd.c (_gtk_drag_source_handle_event): Remove uneeded X11 dependency. * gdk/linux-fb/gdkmain-fb.c gdk/win32/gdkmain-win32.c gdk/TODO: Remove unused gdk_key_repeat_disable/restore. * linux-fb/gdkglobals-fb.c win32/gdkglobals-win32.c x11/gdkglobals-x11.c x11/gdkprivate-x11.h gdk/gdk.def: Remove unused gdk_null_window_warnings variable. * gdk/Makefile.am (DIST_SUBDIRS) nanox/*: cvs remove nanox; it can be retrieved from the repository; it is too far from functional to be worth having people check out; it would be easier to start from scratch, I suspect. * gdk/x11/gdkpixmap-x11.c: Fix lvalue usage of GDK_PIXMAP_XID(). * gdk/x11/gdkkeys-x11.c gdk/gdkrgb.c gdk/gdkwindow.c gdk/x11/gdkpango-x11.c gdk/x11/gdkselection-x11.c: Fix some accidentally global variables and unused global variables. * gdk/x11/gdkkeys-x11.c gdk/gdkrgb.c gdk/gdkwindow.c gdk/x11/gdkpango-x11.c gdk/x11/gdkselection-x11.c: Fix some accidentally global variables and unused global variables. Add some space for future expansion to multihead. * gdk/gdkdrawable.h: Add four reserved function pointers for future expansion of GdkDrawableClass. * gtk/gtkwindow.h gtk/gtkinvisible.h: Add reserved pointer where we can put a GdkScreen * later.
2001-09-07 21:50:20 +00:00
* _gdk_event_queue_find_first:
Start of integration of Erwann Chenede's multihead work from the Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com> Start of integration of Erwann Chenede's multihead work from the gtk-multihead branch. * gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch] New classes representing a set of screens with attached input devices and a single contiguous area, respectively. * gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c: gdk/x11/gdkprivate-x11.h: Make the initialization interface simple _gdk_windowing_init() and do the rest in gdk_open_display() calls. * gdk/gdk.[ch]: Add gdk_parse_args() which can be used to do the display-independent part of initialization instead of gdk_init_[check]. * gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h: Add multihead variants (_for_display(), for_screen()) of functions getting information specific to a particular screen screen or display. * gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions like gdk_rgb_get_colormap() that used to get/list global objects. * gdk/x11/gdkx.h: Add functions for converting GdkScreen and GdkDisplay into the X equivalents. * gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords() not in the headers and unused. * configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}: Remove gxid support ... has not been tested for a long time... "xfree" support is more portable to non XFree86. * gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be used to turn off functions that are inherently non-multihead safe. * gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions are used in non-multihead-safe ways. * gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK multihead safe.
2002-04-25 22:29:14 +00:00
* @display: a #GdkDisplay
*
* Find the first event on the queue that is not still
* being filled in.
*
* Returns: (nullable): Pointer to the list node for that event, or
* %NULL.
Start of integration of Erwann Chenede's multihead work from the Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com> Start of integration of Erwann Chenede's multihead work from the gtk-multihead branch. * gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch] New classes representing a set of screens with attached input devices and a single contiguous area, respectively. * gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c: gdk/x11/gdkprivate-x11.h: Make the initialization interface simple _gdk_windowing_init() and do the rest in gdk_open_display() calls. * gdk/gdk.[ch]: Add gdk_parse_args() which can be used to do the display-independent part of initialization instead of gdk_init_[check]. * gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h: Add multihead variants (_for_display(), for_screen()) of functions getting information specific to a particular screen screen or display. * gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions like gdk_rgb_get_colormap() that used to get/list global objects. * gdk/x11/gdkx.h: Add functions for converting GdkScreen and GdkDisplay into the X equivalents. * gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords() not in the headers and unused. * configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}: Remove gxid support ... has not been tested for a long time... "xfree" support is more portable to non XFree86. * gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be used to turn off functions that are inherently non-multihead safe. * gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions are used in non-multihead-safe ways. * gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK multihead safe.
2002-04-25 22:29:14 +00:00
**/
Move all X specific code into the x11/ directory. Aside from shuffling Mon Nov 8 14:47:04 1999 Owen Taylor <otaylor@redhat.com> Move all X specific code into the x11/ directory. Aside from shuffling things around, did the following: * gdk/gdkprivate.h gdk/gdk.h gdk/x11/gdkmain-x11.h: Add gdk_arg_context_* - a simple argument parsing system in the style of popt. * gdk/gdkdrawable.[ch] gdk/gdkprivate.h gdk/gdkwindow.[ch] gdk/x11/gdkprivate-x11.h: Remove X specific stuff from GdkDrawable and GdkWindowPrivate - add ->klass and ->klass_data fields. The klass_data field points to an auxilliary structure that is windowing system dependent. * gdk/gdkfont.c: Make most of the measurement functions simply wrappers around gdk_text_extents(). * gdk/gdkfont.c gdk/gdkprivate.h gdk/x11/gdkfont-x11.c: Add a _gdk_font_strlen() function that hides the weird behavior in gtk+-1.[02] where a string is interpreted differently for 8-bit and 16-bit fonts. * gdk/gdkevents.c: Add a new function gdk_event_button_generate() to store common code for synthesizing double/triple press events. * gdk/gdkgc.[ch]: Virtualize in the same way as gdkdrawable.h. Make all the function that modify an existing GC simply wrappers around gdk_gc_set_values(). * gdk/gdkcc.[ch]: Moved into x11/ directory in preparation for throwing out later. * gdk/gdkfont.c gdk/gdkimage.c gdk/gdkcolor.c: Change GdkFontPrivate, GdkImagePrivate and GdkColormapPrivate to have a windowing system dependent part (GdkFontPrivateX etc.) that "derives" from the system-independent part. * configure.in gdk/x11/Makefile.in gdk/x11/gdkinput*.c: Got rid of the included-source-files for XInput in favor of automake conditionals. (Which didn't exist when XInput support was originally added.) * gdk/gdkrgb.c: Remove the visual id from the debugging statements since that is X11 specific; print out type/depth info instead.
1999-11-08 20:14:59 +00:00
GList*
Start of integration of Erwann Chenede's multihead work from the Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com> Start of integration of Erwann Chenede's multihead work from the gtk-multihead branch. * gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch] New classes representing a set of screens with attached input devices and a single contiguous area, respectively. * gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c: gdk/x11/gdkprivate-x11.h: Make the initialization interface simple _gdk_windowing_init() and do the rest in gdk_open_display() calls. * gdk/gdk.[ch]: Add gdk_parse_args() which can be used to do the display-independent part of initialization instead of gdk_init_[check]. * gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h: Add multihead variants (_for_display(), for_screen()) of functions getting information specific to a particular screen screen or display. * gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions like gdk_rgb_get_colormap() that used to get/list global objects. * gdk/x11/gdkx.h: Add functions for converting GdkScreen and GdkDisplay into the X equivalents. * gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords() not in the headers and unused. * configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}: Remove gxid support ... has not been tested for a long time... "xfree" support is more portable to non XFree86. * gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be used to turn off functions that are inherently non-multihead safe. * gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions are used in non-multihead-safe ways. * gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK multihead safe.
2002-04-25 22:29:14 +00:00
_gdk_event_queue_find_first (GdkDisplay *display)
{
GList *tmp_list;
GList *pending_motion = NULL;
gboolean paused = display->event_pause_count > 0;
tmp_list = g_queue_peek_head_link (&display->queued_events);
while (tmp_list)
{
GdkEvent *event = tmp_list->data;
if ((event->flags & GDK_EVENT_PENDING) == 0 &&
(!paused || (event->flags & GDK_EVENT_FLUSHED) != 0))
{
if (pending_motion)
return pending_motion;
if (event->event_type == GDK_MOTION_NOTIFY && (event->flags & GDK_EVENT_FLUSHED) == 0)
pending_motion = tmp_list;
else
return tmp_list;
}
tmp_list = tmp_list->next;
}
return NULL;
}
Start of integration of Erwann Chenede's multihead work from the Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com> Start of integration of Erwann Chenede's multihead work from the gtk-multihead branch. * gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch] New classes representing a set of screens with attached input devices and a single contiguous area, respectively. * gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c: gdk/x11/gdkprivate-x11.h: Make the initialization interface simple _gdk_windowing_init() and do the rest in gdk_open_display() calls. * gdk/gdk.[ch]: Add gdk_parse_args() which can be used to do the display-independent part of initialization instead of gdk_init_[check]. * gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h: Add multihead variants (_for_display(), for_screen()) of functions getting information specific to a particular screen screen or display. * gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions like gdk_rgb_get_colormap() that used to get/list global objects. * gdk/x11/gdkx.h: Add functions for converting GdkScreen and GdkDisplay into the X equivalents. * gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords() not in the headers and unused. * configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}: Remove gxid support ... has not been tested for a long time... "xfree" support is more portable to non XFree86. * gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be used to turn off functions that are inherently non-multihead safe. * gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions are used in non-multihead-safe ways. * gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK multihead safe.
2002-04-25 22:29:14 +00:00
/**
* _gdk_event_queue_append:
* @display: a #GdkDisplay
* @event: Event to append.
*
* Appends an event onto the tail of the event queue.
*
* Returns: the newly appended list node.
**/
GList *
_gdk_event_queue_append (GdkDisplay *display,
GdkEvent *event)
{
g_queue_push_tail (&display->queued_events, event);
Start of integration of Erwann Chenede's multihead work from the Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com> Start of integration of Erwann Chenede's multihead work from the gtk-multihead branch. * gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch] New classes representing a set of screens with attached input devices and a single contiguous area, respectively. * gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c: gdk/x11/gdkprivate-x11.h: Make the initialization interface simple _gdk_windowing_init() and do the rest in gdk_open_display() calls. * gdk/gdk.[ch]: Add gdk_parse_args() which can be used to do the display-independent part of initialization instead of gdk_init_[check]. * gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h: Add multihead variants (_for_display(), for_screen()) of functions getting information specific to a particular screen screen or display. * gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions like gdk_rgb_get_colormap() that used to get/list global objects. * gdk/x11/gdkx.h: Add functions for converting GdkScreen and GdkDisplay into the X equivalents. * gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords() not in the headers and unused. * configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}: Remove gxid support ... has not been tested for a long time... "xfree" support is more portable to non XFree86. * gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be used to turn off functions that are inherently non-multihead safe. * gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions are used in non-multihead-safe ways. * gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK multihead safe.
2002-04-25 22:29:14 +00:00
return g_queue_peek_tail_link (&display->queued_events);
Start of integration of Erwann Chenede's multihead work from the Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com> Start of integration of Erwann Chenede's multihead work from the gtk-multihead branch. * gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch] New classes representing a set of screens with attached input devices and a single contiguous area, respectively. * gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c: gdk/x11/gdkprivate-x11.h: Make the initialization interface simple _gdk_windowing_init() and do the rest in gdk_open_display() calls. * gdk/gdk.[ch]: Add gdk_parse_args() which can be used to do the display-independent part of initialization instead of gdk_init_[check]. * gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h: Add multihead variants (_for_display(), for_screen()) of functions getting information specific to a particular screen screen or display. * gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions like gdk_rgb_get_colormap() that used to get/list global objects. * gdk/x11/gdkx.h: Add functions for converting GdkScreen and GdkDisplay into the X equivalents. * gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords() not in the headers and unused. * configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}: Remove gxid support ... has not been tested for a long time... "xfree" support is more portable to non XFree86. * gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be used to turn off functions that are inherently non-multihead safe. * gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions are used in non-multihead-safe ways. * gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK multihead safe.
2002-04-25 22:29:14 +00:00
}
Start of integration of Erwann Chenede's multihead work from the Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com> Start of integration of Erwann Chenede's multihead work from the gtk-multihead branch. * gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch] New classes representing a set of screens with attached input devices and a single contiguous area, respectively. * gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c: gdk/x11/gdkprivate-x11.h: Make the initialization interface simple _gdk_windowing_init() and do the rest in gdk_open_display() calls. * gdk/gdk.[ch]: Add gdk_parse_args() which can be used to do the display-independent part of initialization instead of gdk_init_[check]. * gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h: Add multihead variants (_for_display(), for_screen()) of functions getting information specific to a particular screen screen or display. * gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions like gdk_rgb_get_colormap() that used to get/list global objects. * gdk/x11/gdkx.h: Add functions for converting GdkScreen and GdkDisplay into the X equivalents. * gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords() not in the headers and unused. * configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}: Remove gxid support ... has not been tested for a long time... "xfree" support is more portable to non XFree86. * gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be used to turn off functions that are inherently non-multihead safe. * gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions are used in non-multihead-safe ways. * gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK multihead safe.
2002-04-25 22:29:14 +00:00
/**
* _gdk_event_queue_remove_link:
* @display: a #GdkDisplay
* @node: node to remove
*
* Removes a specified list node from the event queue.
**/
Move all X specific code into the x11/ directory. Aside from shuffling Mon Nov 8 14:47:04 1999 Owen Taylor <otaylor@redhat.com> Move all X specific code into the x11/ directory. Aside from shuffling things around, did the following: * gdk/gdkprivate.h gdk/gdk.h gdk/x11/gdkmain-x11.h: Add gdk_arg_context_* - a simple argument parsing system in the style of popt. * gdk/gdkdrawable.[ch] gdk/gdkprivate.h gdk/gdkwindow.[ch] gdk/x11/gdkprivate-x11.h: Remove X specific stuff from GdkDrawable and GdkWindowPrivate - add ->klass and ->klass_data fields. The klass_data field points to an auxilliary structure that is windowing system dependent. * gdk/gdkfont.c: Make most of the measurement functions simply wrappers around gdk_text_extents(). * gdk/gdkfont.c gdk/gdkprivate.h gdk/x11/gdkfont-x11.c: Add a _gdk_font_strlen() function that hides the weird behavior in gtk+-1.[02] where a string is interpreted differently for 8-bit and 16-bit fonts. * gdk/gdkevents.c: Add a new function gdk_event_button_generate() to store common code for synthesizing double/triple press events. * gdk/gdkgc.[ch]: Virtualize in the same way as gdkdrawable.h. Make all the function that modify an existing GC simply wrappers around gdk_gc_set_values(). * gdk/gdkcc.[ch]: Moved into x11/ directory in preparation for throwing out later. * gdk/gdkfont.c gdk/gdkimage.c gdk/gdkcolor.c: Change GdkFontPrivate, GdkImagePrivate and GdkColormapPrivate to have a windowing system dependent part (GdkFontPrivateX etc.) that "derives" from the system-independent part. * configure.in gdk/x11/Makefile.in gdk/x11/gdkinput*.c: Got rid of the included-source-files for XInput in favor of automake conditionals. (Which didn't exist when XInput support was originally added.) * gdk/gdkrgb.c: Remove the visual id from the debugging statements since that is X11 specific; print out type/depth info instead.
1999-11-08 20:14:59 +00:00
void
Start of integration of Erwann Chenede's multihead work from the Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com> Start of integration of Erwann Chenede's multihead work from the gtk-multihead branch. * gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch] New classes representing a set of screens with attached input devices and a single contiguous area, respectively. * gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c: gdk/x11/gdkprivate-x11.h: Make the initialization interface simple _gdk_windowing_init() and do the rest in gdk_open_display() calls. * gdk/gdk.[ch]: Add gdk_parse_args() which can be used to do the display-independent part of initialization instead of gdk_init_[check]. * gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h: Add multihead variants (_for_display(), for_screen()) of functions getting information specific to a particular screen screen or display. * gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions like gdk_rgb_get_colormap() that used to get/list global objects. * gdk/x11/gdkx.h: Add functions for converting GdkScreen and GdkDisplay into the X equivalents. * gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords() not in the headers and unused. * configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}: Remove gxid support ... has not been tested for a long time... "xfree" support is more portable to non XFree86. * gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be used to turn off functions that are inherently non-multihead safe. * gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions are used in non-multihead-safe ways. * gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK multihead safe.
2002-04-25 22:29:14 +00:00
_gdk_event_queue_remove_link (GdkDisplay *display,
GList *node)
{
g_queue_unlink (&display->queued_events, node);
}
Start of integration of Erwann Chenede's multihead work from the Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com> Start of integration of Erwann Chenede's multihead work from the gtk-multihead branch. * gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch] New classes representing a set of screens with attached input devices and a single contiguous area, respectively. * gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c: gdk/x11/gdkprivate-x11.h: Make the initialization interface simple _gdk_windowing_init() and do the rest in gdk_open_display() calls. * gdk/gdk.[ch]: Add gdk_parse_args() which can be used to do the display-independent part of initialization instead of gdk_init_[check]. * gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h: Add multihead variants (_for_display(), for_screen()) of functions getting information specific to a particular screen screen or display. * gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions like gdk_rgb_get_colormap() that used to get/list global objects. * gdk/x11/gdkx.h: Add functions for converting GdkScreen and GdkDisplay into the X equivalents. * gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords() not in the headers and unused. * configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}: Remove gxid support ... has not been tested for a long time... "xfree" support is more portable to non XFree86. * gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be used to turn off functions that are inherently non-multihead safe. * gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions are used in non-multihead-safe ways. * gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK multihead safe.
2002-04-25 22:29:14 +00:00
/**
* _gdk_event_unqueue:
* @display: a #GdkDisplay
*
* Removes and returns the first event from the event
* queue that is not still being filled in.
*
* Returns: (nullable): the event, or %NULL. Ownership is transferred
Start of integration of Erwann Chenede's multihead work from the Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com> Start of integration of Erwann Chenede's multihead work from the gtk-multihead branch. * gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch] New classes representing a set of screens with attached input devices and a single contiguous area, respectively. * gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c: gdk/x11/gdkprivate-x11.h: Make the initialization interface simple _gdk_windowing_init() and do the rest in gdk_open_display() calls. * gdk/gdk.[ch]: Add gdk_parse_args() which can be used to do the display-independent part of initialization instead of gdk_init_[check]. * gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h: Add multihead variants (_for_display(), for_screen()) of functions getting information specific to a particular screen screen or display. * gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions like gdk_rgb_get_colormap() that used to get/list global objects. * gdk/x11/gdkx.h: Add functions for converting GdkScreen and GdkDisplay into the X equivalents. * gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords() not in the headers and unused. * configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}: Remove gxid support ... has not been tested for a long time... "xfree" support is more portable to non XFree86. * gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be used to turn off functions that are inherently non-multihead safe. * gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions are used in non-multihead-safe ways. * gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK multihead safe.
2002-04-25 22:29:14 +00:00
* to the caller.
**/
GdkEvent*
_gdk_event_unqueue (GdkDisplay *display)
{
Start of integration of Erwann Chenede's multihead work from the Thu Apr 25 16:51:40 2002 Owen Taylor <otaylor@redhat.com> Start of integration of Erwann Chenede's multihead work from the gtk-multihead branch. * gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch] gdk/x11/gdkdisplay-x11.[ch] gdk/x11/gdkscreen-x11.[ch] New classes representing a set of screens with attached input devices and a single contiguous area, respectively. * gdk/gdk.[ch] gdk/gdkinternals.h gdk/x11/gdkmain-x11.c: gdk/x11/gdkprivate-x11.h: Make the initialization interface simple _gdk_windowing_init() and do the rest in gdk_open_display() calls. * gdk/gdk.[ch]: Add gdk_parse_args() which can be used to do the display-independent part of initialization instead of gdk_init_[check]. * gdk/gdkcursor.h gdk/gdkfont.h gdk/gdkkeys.h gdk/gdkpixmap.h gdk/gdkproperty.h gdk/gdkselection.h gdk/gdkwindow.h: Add multihead variants (_for_display(), for_screen()) of functions getting information specific to a particular screen screen or display. * gdk/gdkscreen.[ch]: Add gdk_screen__* variants of functions like gdk_rgb_get_colormap() that used to get/list global objects. * gdk/x11/gdkx.h: Add functions for converting GdkScreen and GdkDisplay into the X equivalents. * gdk/x11/gdkwindow-x11.c: Removed gdk_window_xid_at_coords() not in the headers and unused. * configure.in gdk/x11/{gxid.c,gxid_lib.[ch],gdkinput-gxi.c}: Remove gxid support ... has not been tested for a long time... "xfree" support is more portable to non XFree86. * gdk/**.h: Add a GDK_MULTIHEAD_SAFE define that can be used to turn off functions that are inherently non-multihead safe. * gdk/**.c: add GDK_NOTE(multihead, ...) calls when functions are used in non-multihead-safe ways. * gdk/*.c gdk/x11/*.c: Changes to make the internals of GDK multihead safe.
2002-04-25 22:29:14 +00:00
GdkEvent *event = NULL;
GList *tmp_list;
tmp_list = _gdk_event_queue_find_first (display);
if (tmp_list)
{
event = tmp_list->data;
_gdk_event_queue_remove_link (display, tmp_list);
g_list_free_1 (tmp_list);
}
return event;
}
/*
* If the last N events in the event queue are smooth scroll events
* for the same surface and device, combine them into one.
*/
void
gdk_event_queue_handle_scroll_compression (GdkDisplay *display)
{
GList *l;
GdkSurface *surface = NULL;
GdkDevice *device = NULL;
GdkEvent *last_event = NULL;
GList *scrolls = NULL;
double delta_x, delta_y;
GArray *history = NULL;
GdkTimeCoord hist;
l = g_queue_peek_tail_link (&display->queued_events);
while (l)
{
GdkEvent *event = l->data;
if (event->flags & GDK_EVENT_PENDING)
break;
if (event->event_type != GDK_SCROLL ||
gdk_scroll_event_get_direction (event) != GDK_SCROLL_SMOOTH)
break;
if (surface != NULL &&
surface != event->surface)
break;
if (device != NULL &&
device != event->device)
break;
if (!last_event)
last_event = event;
surface = event->surface;
device = event->device;
scrolls = l;
l = l->prev;
}
delta_x = delta_y = 0;
while (scrolls && scrolls->next != NULL)
{
GdkEvent *event = scrolls->data;
GList *next = scrolls->next;
double dx, dy;
if (!history)
history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
gdk_scroll_event_get_deltas (event, &dx, &dy);
delta_x += dx;
delta_y += dy;
memset (&hist, 0, sizeof (GdkTimeCoord));
hist.time = gdk_event_get_time (event);
hist.flags = GDK_AXIS_FLAG_DELTA_X | GDK_AXIS_FLAG_DELTA_Y;
hist.axes[GDK_AXIS_DELTA_X] = dx;
hist.axes[GDK_AXIS_DELTA_Y] = dy;
g_array_append_val (history, hist);
gdk_event_unref (event);
g_queue_delete_link (&display->queued_events, scrolls);
scrolls = next;
}
if (scrolls)
{
GdkEvent *old_event, *event;
double dx, dy;
old_event = scrolls->data;
gdk_scroll_event_get_deltas (old_event, &dx, &dy);
event = gdk_scroll_event_new (surface,
device,
gdk_event_get_source_device (old_event),
gdk_event_get_device_tool (old_event),
gdk_event_get_time (old_event),
gdk_event_get_modifier_state (old_event),
delta_x + dx,
delta_y + dy,
gdk_scroll_event_is_stop (old_event));
((GdkScrollEvent *)event)->history = history;
g_queue_delete_link (&display->queued_events, scrolls);
g_queue_push_tail (&display->queued_events, event);
}
if (g_queue_get_length (&display->queued_events) == 1 &&
g_queue_peek_head_link (&display->queued_events) == scrolls)
{
GdkFrameClock *clock = gdk_surface_get_frame_clock (surface);
if (clock) /* might be NULL if surface was destroyed */
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
}
}
static void
gdk_motion_event_push_history (GdkEvent *event,
GdkEvent *history_event)
{
GdkMotionEvent *self = (GdkMotionEvent *) event;
GdkTimeCoord hist;
GdkDevice *device;
2020-07-24 13:54:49 +00:00
int i, n_axes;
g_assert (GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY));
g_assert (GDK_IS_EVENT_TYPE (history_event, GDK_MOTION_NOTIFY));
device = gdk_event_get_device (history_event);
n_axes = gdk_device_get_n_axes (device);
memset (&hist, 0, sizeof (GdkTimeCoord));
hist.time = gdk_event_get_time (history_event);
hist.flags = gdk_device_get_axes (device);
for (i = 0; i < n_axes; i++)
{
GdkAxisUse use = gdk_device_get_axis_use (device, i);
gdk_event_get_axis (history_event, use, &hist.axes[use]);
}
if (G_UNLIKELY (!self->history))
self->history = g_array_new (FALSE, TRUE, sizeof (GdkTimeCoord));
g_array_append_val (self->history, hist);
}
void
_gdk_event_queue_handle_motion_compression (GdkDisplay *display)
{
GList *tmp_list;
GList *pending_motions = NULL;
GdkSurface *pending_motion_surface = NULL;
GdkDevice *pending_motion_device = NULL;
GdkEvent *last_motion = NULL;
/* If the last N events in the event queue are motion notify
* events for the same surface, drop all but the last */
tmp_list = g_queue_peek_tail_link (&display->queued_events);
while (tmp_list)
{
GdkEvent *event = tmp_list->data;
if (event->flags & GDK_EVENT_PENDING)
break;
if (event->event_type != GDK_MOTION_NOTIFY)
break;
if (pending_motion_surface != NULL &&
pending_motion_surface != event->surface)
break;
if (pending_motion_device != NULL &&
pending_motion_device != event->device)
break;
if (!last_motion)
last_motion = event;
pending_motion_surface = event->surface;
pending_motion_device = event->device;
pending_motions = tmp_list;
tmp_list = tmp_list->prev;
}
while (pending_motions && pending_motions->next != NULL)
{
GList *next = pending_motions->next;
if (last_motion != NULL)
{
GdkModifierType state = gdk_event_get_modifier_state (last_motion);
if (state &
(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK |
GDK_BUTTON4_MASK | GDK_BUTTON5_MASK))
gdk_motion_event_push_history (last_motion, pending_motions->data);
}
gdk_event_unref (pending_motions->data);
g_queue_delete_link (&display->queued_events, pending_motions);
pending_motions = next;
}
if (g_queue_get_length (&display->queued_events) == 1 &&
g_queue_peek_head_link (&display->queued_events) == pending_motions)
{
GdkFrameClock *clock = gdk_surface_get_frame_clock (pending_motion_surface);
if (clock) /* might be NULL if surface was destroyed */
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
}
}
void
_gdk_event_queue_flush (GdkDisplay *display)
{
GList *tmp_list;
for (tmp_list = display->queued_events.head; tmp_list; tmp_list = tmp_list->next)
{
GdkEvent *event = tmp_list->data;
event->flags |= GDK_EVENT_FLUSHED;
}
}
/**
* gdk_event_ref:
* @event: a #GdkEvent
*
* Increase the ref count of @event.
*
* Returns: (transfer full): @event
*/
GdkEvent *
gdk_event_ref (GdkEvent *event)
{
g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
g_ref_count_inc (&event->ref_count);
2020-02-15 20:40:03 +00:00
return event;
}
/**
* gdk_event_unref:
* @event: (transfer full): a #GdkEvent
*
* Decrease the ref count of @event, and free it
* if the last reference is dropped.
*/
void
gdk_event_unref (GdkEvent *event)
{
g_return_if_fail (GDK_IS_EVENT (event));
if (g_ref_count_dec (&event->ref_count))
GDK_EVENT_GET_CLASS (event)->finalize (event);
}
2016-05-10 19:22:35 +00:00
/**
* gdk_event_get_pointer_emulated:
* @event: a #GdkEvent
2016-05-10 19:22:35 +00:00
*
* Returns whether this event is an 'emulated' pointer event (typically
* from a touch event), as opposed to a real one.
*
* Returns: %TRUE if this event is emulated
*/
gboolean
gdk_event_get_pointer_emulated (GdkEvent *event)
{
switch ((int) event->event_type)
{
case GDK_TOUCH_BEGIN:
case GDK_TOUCH_END:
case GDK_TOUCH_UPDATE:
case GDK_TOUCH_CANCEL:
{
GdkTouchEvent *tevent = (GdkTouchEvent *) event;
return tevent->pointer_emulated;
}
case GDK_SCROLL:
case GDK_SCROLL_SMOOTH:
{
GdkScrollEvent *sevent = (GdkScrollEvent *) event;
return sevent->pointer_emulated;
}
default:
break;
}
return FALSE;
}
/**
* gdk_event_get_axis:
* @event: a #GdkEvent
* @axis_use: the axis use to look for
* @value: (out): location to store the value found
*
* Extract the axis value for a particular axis use from
* an event structure.
*
* Returns: %TRUE if the specified axis was found, otherwise %FALSE
**/
gboolean
gdk_event_get_axis (GdkEvent *event,
GdkAxisUse axis_use,
double *value)
{
double *axes;
guint n_axes;
g_return_val_if_fail (GDK_IS_EVENT (event), FALSE);
if (axis_use == GDK_AXIS_X || axis_use == GDK_AXIS_Y)
{
double x, y;
if (!gdk_event_get_position (event, &x, &y))
return FALSE;
if (axis_use == GDK_AXIS_X && value != NULL)
*value = x;
if (axis_use == GDK_AXIS_Y && value != NULL)
*value = y;
return TRUE;
}
if (!gdk_event_get_axes (event, &axes, &n_axes))
return FALSE;
if (axis_use >= gdk_device_get_n_axes (event->device))
return FALSE;
return gdk_device_get_axis (event->device, axes, axis_use, value);
}
Port to GObject, can go back in gdk-pixbuf after setting up a 2000-12-16 Havoc Pennington <hp@pobox.com> * gtk/gdk-pixbuf-loader.h, gtk/gdk-pixbuf-loader.c: Port to GObject, can go back in gdk-pixbuf after setting up a gdk-pixbuf-marshal.h header over there. * gtk/gtktreeview.c: s/SEPERATOR/SEPARATOR/g; (gtk_tree_view_class_init): specify GTK_TYPE_ADJUSTMENT for signal args (gtk_tree_view_init): don't unset GTK_NO_WINDOW, it shouldn't be set (gtk_tree_view_realize_buttons): don't gtk_widget_show() buttons here, do it when we create the buttons later (gtk_tree_view_realize_buttons): add some g_return_if_fail (gtk_tree_view_map): paranoia checks that column->button is shown and unmapped (gtk_tree_view_size_request): only request visible children. Move header size calculation in here, for cleanliness, and to maintain invariants for child widgets if we eventually let users set different children inside the buttons (gtk_tree_view_map_buttons): factor out code to map buttons, since it was being called several times (gtk_tree_view_size_allocate_buttons): move_resize the drag windows instead of just moving them; their height may change if we allow random widgets in there, or the theme changes. (gtk_tree_view_size_allocate): move button size allocation above emitting the scroll signals, to ensure a sane state when we hit user code (gtk_tree_view_button_release): remove queue_resize after tree_view_set_size(), set_size() will handle any resize queuing that's needed (gtk_tree_view_focus_in): just queue a draw, don't fool with draw_focus goo (gtk_tree_view_focus): use gtk_get_current_event() and gdk_event_get_state() (gtk_tree_view_deleted): don't queue_resize() after calling set_size() (gtk_tree_view_build_tree): fix a "if (foo); {}" bug - i.e. remove semicolon (gtk_tree_view_create_button): show the button here (gtk_tree_view_button_clicked): actually emit the clicked signal on the column (_gtk_tree_view_set_size): return right away if the size is unchanged, as a cheesy optimization (gtk_tree_view_setup_model): rename set_model_realized to setup_model to match the flag that indicates whether we've called it (gtk_tree_view_get_hadjustment): create adjustment if it doesn't exist, because set_scroll_adjustment does that and it shouldn't matter what order you call these in (gtk_tree_view_get_vadjustment): ditto (gtk_tree_view_set_headers_visible): canonicalize the bool, for paranoia (gtk_tree_view_set_headers_visible): call gtk_tree_view_map_buttons() instead of using cut-and-paste code (gtk_tree_view_append_column): clarify whether the return value is the count of columns before or after, and do the increment separately from the return statement so you can tell from the code. (gtk_tree_view_remove_column): ditto (gtk_tree_view_insert_column): ditto (gtk_tree_view_get_column): remove g_return_if_fail for columns outside the existing range, the docs say that outside-range columns are allowed, so we handle them as documented. (Presumably this allows a nice loop with column != NULL as test.) (gtk_tree_view_move_to): document what 0.0, 0.5, 1.0 alignments mean (left/right/center etc.). (gtk_tree_view_collapse_all): only queue a draw if we're mapped (gtk_tree_view_expand_row): add docs (gtk_tree_view_collapse_row): add docs * gtk/gtktreeviewcolumn.c (gtk_tree_view_column_clicked): new function to emit the clicked signal on a column * gdk/gdkevents.c (gdk_event_get_state): new function, to get the state of an event (gdk_event_get_time): don't treat GDK_SCROLL as a button event, remove default case from switch so gcc will whine if we don't explicitly handle all event types * gtk/gtktreeselection.h: added some FIXME * gtk/gtktreeprivate.h (struct _GtkTreeViewPrivate): rename "columns" to "n_columns" and "column" to "columns" for clarity
2000-12-17 23:50:00 +00:00
/**
* gdk_event_triggers_context_menu:
* @event: a #GdkEvent, currently only button events are meaningful values
*
* This function returns whether a #GdkEventButton should trigger a
* context menu, according to platform conventions. The right mouse
* button always triggers context menus.
*
* This function should always be used instead of simply checking for
* event->button == %GDK_BUTTON_SECONDARY.
*
* Returns: %TRUE if the event should trigger a context menu.
Port to GObject, can go back in gdk-pixbuf after setting up a 2000-12-16 Havoc Pennington <hp@pobox.com> * gtk/gdk-pixbuf-loader.h, gtk/gdk-pixbuf-loader.c: Port to GObject, can go back in gdk-pixbuf after setting up a gdk-pixbuf-marshal.h header over there. * gtk/gtktreeview.c: s/SEPERATOR/SEPARATOR/g; (gtk_tree_view_class_init): specify GTK_TYPE_ADJUSTMENT for signal args (gtk_tree_view_init): don't unset GTK_NO_WINDOW, it shouldn't be set (gtk_tree_view_realize_buttons): don't gtk_widget_show() buttons here, do it when we create the buttons later (gtk_tree_view_realize_buttons): add some g_return_if_fail (gtk_tree_view_map): paranoia checks that column->button is shown and unmapped (gtk_tree_view_size_request): only request visible children. Move header size calculation in here, for cleanliness, and to maintain invariants for child widgets if we eventually let users set different children inside the buttons (gtk_tree_view_map_buttons): factor out code to map buttons, since it was being called several times (gtk_tree_view_size_allocate_buttons): move_resize the drag windows instead of just moving them; their height may change if we allow random widgets in there, or the theme changes. (gtk_tree_view_size_allocate): move button size allocation above emitting the scroll signals, to ensure a sane state when we hit user code (gtk_tree_view_button_release): remove queue_resize after tree_view_set_size(), set_size() will handle any resize queuing that's needed (gtk_tree_view_focus_in): just queue a draw, don't fool with draw_focus goo (gtk_tree_view_focus): use gtk_get_current_event() and gdk_event_get_state() (gtk_tree_view_deleted): don't queue_resize() after calling set_size() (gtk_tree_view_build_tree): fix a "if (foo); {}" bug - i.e. remove semicolon (gtk_tree_view_create_button): show the button here (gtk_tree_view_button_clicked): actually emit the clicked signal on the column (_gtk_tree_view_set_size): return right away if the size is unchanged, as a cheesy optimization (gtk_tree_view_setup_model): rename set_model_realized to setup_model to match the flag that indicates whether we've called it (gtk_tree_view_get_hadjustment): create adjustment if it doesn't exist, because set_scroll_adjustment does that and it shouldn't matter what order you call these in (gtk_tree_view_get_vadjustment): ditto (gtk_tree_view_set_headers_visible): canonicalize the bool, for paranoia (gtk_tree_view_set_headers_visible): call gtk_tree_view_map_buttons() instead of using cut-and-paste code (gtk_tree_view_append_column): clarify whether the return value is the count of columns before or after, and do the increment separately from the return statement so you can tell from the code. (gtk_tree_view_remove_column): ditto (gtk_tree_view_insert_column): ditto (gtk_tree_view_get_column): remove g_return_if_fail for columns outside the existing range, the docs say that outside-range columns are allowed, so we handle them as documented. (Presumably this allows a nice loop with column != NULL as test.) (gtk_tree_view_move_to): document what 0.0, 0.5, 1.0 alignments mean (left/right/center etc.). (gtk_tree_view_collapse_all): only queue a draw if we're mapped (gtk_tree_view_expand_row): add docs (gtk_tree_view_collapse_row): add docs * gtk/gtktreeviewcolumn.c (gtk_tree_view_column_clicked): new function to emit the clicked signal on a column * gdk/gdkevents.c (gdk_event_get_state): new function, to get the state of an event (gdk_event_get_time): don't treat GDK_SCROLL as a button event, remove default case from switch so gcc will whine if we don't explicitly handle all event types * gtk/gtktreeselection.h: added some FIXME * gtk/gtktreeprivate.h (struct _GtkTreeViewPrivate): rename "columns" to "n_columns" and "column" to "columns" for clarity
2000-12-17 23:50:00 +00:00
**/
gboolean
gdk_event_triggers_context_menu (GdkEvent *event)
Port to GObject, can go back in gdk-pixbuf after setting up a 2000-12-16 Havoc Pennington <hp@pobox.com> * gtk/gdk-pixbuf-loader.h, gtk/gdk-pixbuf-loader.c: Port to GObject, can go back in gdk-pixbuf after setting up a gdk-pixbuf-marshal.h header over there. * gtk/gtktreeview.c: s/SEPERATOR/SEPARATOR/g; (gtk_tree_view_class_init): specify GTK_TYPE_ADJUSTMENT for signal args (gtk_tree_view_init): don't unset GTK_NO_WINDOW, it shouldn't be set (gtk_tree_view_realize_buttons): don't gtk_widget_show() buttons here, do it when we create the buttons later (gtk_tree_view_realize_buttons): add some g_return_if_fail (gtk_tree_view_map): paranoia checks that column->button is shown and unmapped (gtk_tree_view_size_request): only request visible children. Move header size calculation in here, for cleanliness, and to maintain invariants for child widgets if we eventually let users set different children inside the buttons (gtk_tree_view_map_buttons): factor out code to map buttons, since it was being called several times (gtk_tree_view_size_allocate_buttons): move_resize the drag windows instead of just moving them; their height may change if we allow random widgets in there, or the theme changes. (gtk_tree_view_size_allocate): move button size allocation above emitting the scroll signals, to ensure a sane state when we hit user code (gtk_tree_view_button_release): remove queue_resize after tree_view_set_size(), set_size() will handle any resize queuing that's needed (gtk_tree_view_focus_in): just queue a draw, don't fool with draw_focus goo (gtk_tree_view_focus): use gtk_get_current_event() and gdk_event_get_state() (gtk_tree_view_deleted): don't queue_resize() after calling set_size() (gtk_tree_view_build_tree): fix a "if (foo); {}" bug - i.e. remove semicolon (gtk_tree_view_create_button): show the button here (gtk_tree_view_button_clicked): actually emit the clicked signal on the column (_gtk_tree_view_set_size): return right away if the size is unchanged, as a cheesy optimization (gtk_tree_view_setup_model): rename set_model_realized to setup_model to match the flag that indicates whether we've called it (gtk_tree_view_get_hadjustment): create adjustment if it doesn't exist, because set_scroll_adjustment does that and it shouldn't matter what order you call these in (gtk_tree_view_get_vadjustment): ditto (gtk_tree_view_set_headers_visible): canonicalize the bool, for paranoia (gtk_tree_view_set_headers_visible): call gtk_tree_view_map_buttons() instead of using cut-and-paste code (gtk_tree_view_append_column): clarify whether the return value is the count of columns before or after, and do the increment separately from the return statement so you can tell from the code. (gtk_tree_view_remove_column): ditto (gtk_tree_view_insert_column): ditto (gtk_tree_view_get_column): remove g_return_if_fail for columns outside the existing range, the docs say that outside-range columns are allowed, so we handle them as documented. (Presumably this allows a nice loop with column != NULL as test.) (gtk_tree_view_move_to): document what 0.0, 0.5, 1.0 alignments mean (left/right/center etc.). (gtk_tree_view_collapse_all): only queue a draw if we're mapped (gtk_tree_view_expand_row): add docs (gtk_tree_view_collapse_row): add docs * gtk/gtktreeviewcolumn.c (gtk_tree_view_column_clicked): new function to emit the clicked signal on a column * gdk/gdkevents.c (gdk_event_get_state): new function, to get the state of an event (gdk_event_get_time): don't treat GDK_SCROLL as a button event, remove default case from switch so gcc will whine if we don't explicitly handle all event types * gtk/gtktreeselection.h: added some FIXME * gtk/gtktreeprivate.h (struct _GtkTreeViewPrivate): rename "columns" to "n_columns" and "column" to "columns" for clarity
2000-12-17 23:50:00 +00:00
{
g_return_val_if_fail (event != NULL, FALSE);
if (event->event_type == GDK_BUTTON_PRESS)
{
GdkButtonEvent *bevent = (GdkButtonEvent *) event;
g_return_val_if_fail (GDK_IS_SURFACE (event->surface), FALSE);
if (bevent->button == GDK_BUTTON_SECONDARY &&
! (bevent->state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK)))
return TRUE;
}
Port to GObject, can go back in gdk-pixbuf after setting up a 2000-12-16 Havoc Pennington <hp@pobox.com> * gtk/gdk-pixbuf-loader.h, gtk/gdk-pixbuf-loader.c: Port to GObject, can go back in gdk-pixbuf after setting up a gdk-pixbuf-marshal.h header over there. * gtk/gtktreeview.c: s/SEPERATOR/SEPARATOR/g; (gtk_tree_view_class_init): specify GTK_TYPE_ADJUSTMENT for signal args (gtk_tree_view_init): don't unset GTK_NO_WINDOW, it shouldn't be set (gtk_tree_view_realize_buttons): don't gtk_widget_show() buttons here, do it when we create the buttons later (gtk_tree_view_realize_buttons): add some g_return_if_fail (gtk_tree_view_map): paranoia checks that column->button is shown and unmapped (gtk_tree_view_size_request): only request visible children. Move header size calculation in here, for cleanliness, and to maintain invariants for child widgets if we eventually let users set different children inside the buttons (gtk_tree_view_map_buttons): factor out code to map buttons, since it was being called several times (gtk_tree_view_size_allocate_buttons): move_resize the drag windows instead of just moving them; their height may change if we allow random widgets in there, or the theme changes. (gtk_tree_view_size_allocate): move button size allocation above emitting the scroll signals, to ensure a sane state when we hit user code (gtk_tree_view_button_release): remove queue_resize after tree_view_set_size(), set_size() will handle any resize queuing that's needed (gtk_tree_view_focus_in): just queue a draw, don't fool with draw_focus goo (gtk_tree_view_focus): use gtk_get_current_event() and gdk_event_get_state() (gtk_tree_view_deleted): don't queue_resize() after calling set_size() (gtk_tree_view_build_tree): fix a "if (foo); {}" bug - i.e. remove semicolon (gtk_tree_view_create_button): show the button here (gtk_tree_view_button_clicked): actually emit the clicked signal on the column (_gtk_tree_view_set_size): return right away if the size is unchanged, as a cheesy optimization (gtk_tree_view_setup_model): rename set_model_realized to setup_model to match the flag that indicates whether we've called it (gtk_tree_view_get_hadjustment): create adjustment if it doesn't exist, because set_scroll_adjustment does that and it shouldn't matter what order you call these in (gtk_tree_view_get_vadjustment): ditto (gtk_tree_view_set_headers_visible): canonicalize the bool, for paranoia (gtk_tree_view_set_headers_visible): call gtk_tree_view_map_buttons() instead of using cut-and-paste code (gtk_tree_view_append_column): clarify whether the return value is the count of columns before or after, and do the increment separately from the return statement so you can tell from the code. (gtk_tree_view_remove_column): ditto (gtk_tree_view_insert_column): ditto (gtk_tree_view_get_column): remove g_return_if_fail for columns outside the existing range, the docs say that outside-range columns are allowed, so we handle them as documented. (Presumably this allows a nice loop with column != NULL as test.) (gtk_tree_view_move_to): document what 0.0, 0.5, 1.0 alignments mean (left/right/center etc.). (gtk_tree_view_collapse_all): only queue a draw if we're mapped (gtk_tree_view_expand_row): add docs (gtk_tree_view_collapse_row): add docs * gtk/gtktreeviewcolumn.c (gtk_tree_view_column_clicked): new function to emit the clicked signal on a column * gdk/gdkevents.c (gdk_event_get_state): new function, to get the state of an event (gdk_event_get_time): don't treat GDK_SCROLL as a button event, remove default case from switch so gcc will whine if we don't explicitly handle all event types * gtk/gtktreeselection.h: added some FIXME * gtk/gtktreeprivate.h (struct _GtkTreeViewPrivate): rename "columns" to "n_columns" and "column" to "columns" for clarity
2000-12-17 23:50:00 +00:00
return FALSE;
Port to GObject, can go back in gdk-pixbuf after setting up a 2000-12-16 Havoc Pennington <hp@pobox.com> * gtk/gdk-pixbuf-loader.h, gtk/gdk-pixbuf-loader.c: Port to GObject, can go back in gdk-pixbuf after setting up a gdk-pixbuf-marshal.h header over there. * gtk/gtktreeview.c: s/SEPERATOR/SEPARATOR/g; (gtk_tree_view_class_init): specify GTK_TYPE_ADJUSTMENT for signal args (gtk_tree_view_init): don't unset GTK_NO_WINDOW, it shouldn't be set (gtk_tree_view_realize_buttons): don't gtk_widget_show() buttons here, do it when we create the buttons later (gtk_tree_view_realize_buttons): add some g_return_if_fail (gtk_tree_view_map): paranoia checks that column->button is shown and unmapped (gtk_tree_view_size_request): only request visible children. Move header size calculation in here, for cleanliness, and to maintain invariants for child widgets if we eventually let users set different children inside the buttons (gtk_tree_view_map_buttons): factor out code to map buttons, since it was being called several times (gtk_tree_view_size_allocate_buttons): move_resize the drag windows instead of just moving them; their height may change if we allow random widgets in there, or the theme changes. (gtk_tree_view_size_allocate): move button size allocation above emitting the scroll signals, to ensure a sane state when we hit user code (gtk_tree_view_button_release): remove queue_resize after tree_view_set_size(), set_size() will handle any resize queuing that's needed (gtk_tree_view_focus_in): just queue a draw, don't fool with draw_focus goo (gtk_tree_view_focus): use gtk_get_current_event() and gdk_event_get_state() (gtk_tree_view_deleted): don't queue_resize() after calling set_size() (gtk_tree_view_build_tree): fix a "if (foo); {}" bug - i.e. remove semicolon (gtk_tree_view_create_button): show the button here (gtk_tree_view_button_clicked): actually emit the clicked signal on the column (_gtk_tree_view_set_size): return right away if the size is unchanged, as a cheesy optimization (gtk_tree_view_setup_model): rename set_model_realized to setup_model to match the flag that indicates whether we've called it (gtk_tree_view_get_hadjustment): create adjustment if it doesn't exist, because set_scroll_adjustment does that and it shouldn't matter what order you call these in (gtk_tree_view_get_vadjustment): ditto (gtk_tree_view_set_headers_visible): canonicalize the bool, for paranoia (gtk_tree_view_set_headers_visible): call gtk_tree_view_map_buttons() instead of using cut-and-paste code (gtk_tree_view_append_column): clarify whether the return value is the count of columns before or after, and do the increment separately from the return statement so you can tell from the code. (gtk_tree_view_remove_column): ditto (gtk_tree_view_insert_column): ditto (gtk_tree_view_get_column): remove g_return_if_fail for columns outside the existing range, the docs say that outside-range columns are allowed, so we handle them as documented. (Presumably this allows a nice loop with column != NULL as test.) (gtk_tree_view_move_to): document what 0.0, 0.5, 1.0 alignments mean (left/right/center etc.). (gtk_tree_view_collapse_all): only queue a draw if we're mapped (gtk_tree_view_expand_row): add docs (gtk_tree_view_collapse_row): add docs * gtk/gtktreeviewcolumn.c (gtk_tree_view_column_clicked): new function to emit the clicked signal on a column * gdk/gdkevents.c (gdk_event_get_state): new function, to get the state of an event (gdk_event_get_time): don't treat GDK_SCROLL as a button event, remove default case from switch so gcc will whine if we don't explicitly handle all event types * gtk/gtktreeselection.h: added some FIXME * gtk/gtktreeprivate.h (struct _GtkTreeViewPrivate): rename "columns" to "n_columns" and "column" to "columns" for clarity
2000-12-17 23:50:00 +00:00
}
static gboolean
gdk_events_get_axis_distances (GdkEvent *event1,
GdkEvent *event2,
2020-07-24 20:32:16 +00:00
double *x_distance,
double *y_distance,
double *distance)
!GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for resize queueing. Thu Jun 28 23:53:31 2001 Tim Janik <timj@gtk.org> * gtk/gtkwidget.c (gtk_widget_hide): !GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for resize queueing. * gtk/gtkmain.c (gtk_main_do_event): !GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for post event delivery destruction upon GDK_DESTROY. * gtk/gtkwidget.c: added GtkWidget::event-after notification signal, to sompensate for former (pre-2.0) connect_after() facility. (gtk_widget_send_expose): (gtk_widget_event): assert the widget is realized, since event delivery to non-realized widgets is essentially a bug. event handlers should be able to unconditionally rely on widget->window (unless they emit events on their own which can trigger widget destruction). (gtk_widget_event_internal): removed old outdated GTK_OBJECT_DESTROYED() logic. event delivery happens as follows: a) emission of GtkWidget::event (RUN_LAST handler). returns was_handled. b) if !was_handled in (a) and the widget is still realized, emit event- specific signal (RUN_LAST handler). returns was_handled. c) emission of GtkWidget::event-after for notification if the widget is still realized (regardless of was_handled from previous stages, no class handler). no return value. d) was_handled gets passed on to caller, to determine further propagation. if the widget got unrealized meanwhile, was_handled is returned as TRUE. * gdk/gdkevents.[hc]: added gdk_event_get_root_coords() and gdk_event_get_coords().
2001-06-28 22:49:20 +00:00
{
2020-07-24 20:32:16 +00:00
double x1, x2, y1, y2;
double xd, yd;
if (!gdk_event_get_position (event1, &x1, &y1) ||
!gdk_event_get_position (event2, &x2, &y2))
return FALSE;
!GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for resize queueing. Thu Jun 28 23:53:31 2001 Tim Janik <timj@gtk.org> * gtk/gtkwidget.c (gtk_widget_hide): !GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for resize queueing. * gtk/gtkmain.c (gtk_main_do_event): !GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for post event delivery destruction upon GDK_DESTROY. * gtk/gtkwidget.c: added GtkWidget::event-after notification signal, to sompensate for former (pre-2.0) connect_after() facility. (gtk_widget_send_expose): (gtk_widget_event): assert the widget is realized, since event delivery to non-realized widgets is essentially a bug. event handlers should be able to unconditionally rely on widget->window (unless they emit events on their own which can trigger widget destruction). (gtk_widget_event_internal): removed old outdated GTK_OBJECT_DESTROYED() logic. event delivery happens as follows: a) emission of GtkWidget::event (RUN_LAST handler). returns was_handled. b) if !was_handled in (a) and the widget is still realized, emit event- specific signal (RUN_LAST handler). returns was_handled. c) emission of GtkWidget::event-after for notification if the widget is still realized (regardless of was_handled from previous stages, no class handler). no return value. d) was_handled gets passed on to caller, to determine further propagation. if the widget got unrealized meanwhile, was_handled is returned as TRUE. * gdk/gdkevents.[hc]: added gdk_event_get_root_coords() and gdk_event_get_coords().
2001-06-28 22:49:20 +00:00
xd = x2 - x1;
yd = y2 - y1;
if (x_distance)
*x_distance = xd;
!GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for resize queueing. Thu Jun 28 23:53:31 2001 Tim Janik <timj@gtk.org> * gtk/gtkwidget.c (gtk_widget_hide): !GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for resize queueing. * gtk/gtkmain.c (gtk_main_do_event): !GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for post event delivery destruction upon GDK_DESTROY. * gtk/gtkwidget.c: added GtkWidget::event-after notification signal, to sompensate for former (pre-2.0) connect_after() facility. (gtk_widget_send_expose): (gtk_widget_event): assert the widget is realized, since event delivery to non-realized widgets is essentially a bug. event handlers should be able to unconditionally rely on widget->window (unless they emit events on their own which can trigger widget destruction). (gtk_widget_event_internal): removed old outdated GTK_OBJECT_DESTROYED() logic. event delivery happens as follows: a) emission of GtkWidget::event (RUN_LAST handler). returns was_handled. b) if !was_handled in (a) and the widget is still realized, emit event- specific signal (RUN_LAST handler). returns was_handled. c) emission of GtkWidget::event-after for notification if the widget is still realized (regardless of was_handled from previous stages, no class handler). no return value. d) was_handled gets passed on to caller, to determine further propagation. if the widget got unrealized meanwhile, was_handled is returned as TRUE. * gdk/gdkevents.[hc]: added gdk_event_get_root_coords() and gdk_event_get_coords().
2001-06-28 22:49:20 +00:00
if (y_distance)
*y_distance = yd;
if (distance)
*distance = sqrt ((xd * xd) + (yd * yd));
!GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for resize queueing. Thu Jun 28 23:53:31 2001 Tim Janik <timj@gtk.org> * gtk/gtkwidget.c (gtk_widget_hide): !GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for resize queueing. * gtk/gtkmain.c (gtk_main_do_event): !GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for post event delivery destruction upon GDK_DESTROY. * gtk/gtkwidget.c: added GtkWidget::event-after notification signal, to sompensate for former (pre-2.0) connect_after() facility. (gtk_widget_send_expose): (gtk_widget_event): assert the widget is realized, since event delivery to non-realized widgets is essentially a bug. event handlers should be able to unconditionally rely on widget->window (unless they emit events on their own which can trigger widget destruction). (gtk_widget_event_internal): removed old outdated GTK_OBJECT_DESTROYED() logic. event delivery happens as follows: a) emission of GtkWidget::event (RUN_LAST handler). returns was_handled. b) if !was_handled in (a) and the widget is still realized, emit event- specific signal (RUN_LAST handler). returns was_handled. c) emission of GtkWidget::event-after for notification if the widget is still realized (regardless of was_handled from previous stages, no class handler). no return value. d) was_handled gets passed on to caller, to determine further propagation. if the widget got unrealized meanwhile, was_handled is returned as TRUE. * gdk/gdkevents.[hc]: added gdk_event_get_root_coords() and gdk_event_get_coords().
2001-06-28 22:49:20 +00:00
return TRUE;
!GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for resize queueing. Thu Jun 28 23:53:31 2001 Tim Janik <timj@gtk.org> * gtk/gtkwidget.c (gtk_widget_hide): !GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for resize queueing. * gtk/gtkmain.c (gtk_main_do_event): !GTK_OBJECT_DESTROYED() -> GTK_WIDGET_REALIZE() for post event delivery destruction upon GDK_DESTROY. * gtk/gtkwidget.c: added GtkWidget::event-after notification signal, to sompensate for former (pre-2.0) connect_after() facility. (gtk_widget_send_expose): (gtk_widget_event): assert the widget is realized, since event delivery to non-realized widgets is essentially a bug. event handlers should be able to unconditionally rely on widget->window (unless they emit events on their own which can trigger widget destruction). (gtk_widget_event_internal): removed old outdated GTK_OBJECT_DESTROYED() logic. event delivery happens as follows: a) emission of GtkWidget::event (RUN_LAST handler). returns was_handled. b) if !was_handled in (a) and the widget is still realized, emit event- specific signal (RUN_LAST handler). returns was_handled. c) emission of GtkWidget::event-after for notification if the widget is still realized (regardless of was_handled from previous stages, no class handler). no return value. d) was_handled gets passed on to caller, to determine further propagation. if the widget got unrealized meanwhile, was_handled is returned as TRUE. * gdk/gdkevents.[hc]: added gdk_event_get_root_coords() and gdk_event_get_coords().
2001-06-28 22:49:20 +00:00
}
/**
* gdk_events_get_distance:
* @event1: first #GdkEvent
* @event2: second #GdkEvent
* @distance: (out): return location for the distance
*
* If both events have X/Y information, the distance between both coordinates
* (as in a straight line going from @event1 to @event2) will be returned.
*
* Returns: %TRUE if the distance could be calculated.
**/
gboolean
gdk_events_get_distance (GdkEvent *event1,
GdkEvent *event2,
2020-07-24 20:32:16 +00:00
double *distance)
{
return gdk_events_get_axis_distances (event1, event2,
NULL, NULL,
distance);
}
/**
* gdk_events_get_angle:
* @event1: first #GdkEvent
* @event2: second #GdkEvent
* @angle: (out): return location for the relative angle between both events
*
* If both events contain X/Y information, this function will return %TRUE
* and return in @angle the relative angle from @event1 to @event2. The rotation
* direction for positive angles is from the positive X axis towards the positive
* Y axis.
*
* Returns: %TRUE if the angle could be calculated.
**/
gboolean
gdk_events_get_angle (GdkEvent *event1,
GdkEvent *event2,
2020-07-24 20:32:16 +00:00
double *angle)
{
2020-07-24 20:32:16 +00:00
double x_distance, y_distance, distance;
if (!gdk_events_get_axis_distances (event1, event2,
&x_distance, &y_distance,
&distance))
return FALSE;
if (angle)
{
*angle = atan2 (x_distance, y_distance);
/* Invert angle */
*angle = (2 * G_PI) - *angle;
/* Shift it 90° */
*angle += G_PI / 2;
/* And constraint it to 0°-360° */
*angle = fmod (*angle, 2 * G_PI);
}
return TRUE;
}
/**
* gdk_events_get_center:
* @event1: first #GdkEvent
* @event2: second #GdkEvent
* @x: (out): return location for the X coordinate of the center
* @y: (out): return location for the Y coordinate of the center
*
* If both events contain X/Y information, the center of both coordinates
* will be returned in @x and @y.
*
* Returns: %TRUE if the center could be calculated.
**/
2017-08-26 02:50:52 +00:00
gboolean
gdk_events_get_center (GdkEvent *event1,
GdkEvent *event2,
2020-07-24 20:32:16 +00:00
double *x,
double *y)
2017-08-26 02:50:52 +00:00
{
2020-07-24 20:32:16 +00:00
double x1, x2, y1, y2;
2017-08-26 02:50:52 +00:00
if (!gdk_event_get_position (event1, &x1, &y1) ||
!gdk_event_get_position (event2, &x2, &y2))
return FALSE;
2017-08-26 02:50:52 +00:00
if (x)
*x = (x2 + x1) / 2;
2017-08-26 02:50:52 +00:00
if (y)
*y = (y2 + y1) / 2;
2017-08-26 02:50:52 +00:00
return TRUE;
2017-08-26 02:50:52 +00:00
}
static GdkEventSequence *
gdk_event_sequence_copy (GdkEventSequence *sequence)
{
return sequence;
}
static void
gdk_event_sequence_free (GdkEventSequence *sequence)
{
/* Nothing to free here */
}
G_DEFINE_BOXED_TYPE (GdkEventSequence, gdk_event_sequence,
gdk_event_sequence_copy,
gdk_event_sequence_free)
/**
* gdk_event_get_axes:
* @event: a #GdkEvent
* @axes: (transfer none) (out) (array length=n_axes): the array of values for all axes
* @n_axes: (out): the length of array
*
* Extracts all axis values from an event.
*
* Returns: %TRUE on success, otherwise %FALSE
**/
gboolean
gdk_event_get_axes (GdkEvent *event,
double **axes,
guint *n_axes)
{
g_return_val_if_fail (GDK_IS_EVENT (event), FALSE);
return GDK_EVENT_GET_CLASS (event)->get_axes (event, axes, n_axes);
}
/**
* gdk_event_get_event_type:
* @event: a #GdkEvent
*
* Retrieves the type of the event.
*
* Returns: a #GdkEventType
*/
GdkEventType
gdk_event_get_event_type (GdkEvent *event)
{
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
return event->event_type;
}
/**
* gdk_event_get_surface:
* @event: a #GdkEvent
*
* Extracts the #GdkSurface associated with an event.
*
* Returns: (transfer none): The #GdkSurface associated with the event
*/
GdkSurface *
gdk_event_get_surface (GdkEvent *event)
{
g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
return event->surface;
}
/**
* gdk_event_get_seat:
* @event: a #GdkEvent
*
* Returns the seat that originated the event.
*
* Returns: (nullable) (transfer none): a #GdkSeat.
*/
GdkSeat *
gdk_event_get_seat (GdkEvent *event)
{
g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
return event->device ? gdk_device_get_seat (event->device) : NULL;
}
2010-05-25 22:38:44 +00:00
/**
* gdk_event_get_device:
* @event: a #GdkEvent.
2010-05-25 22:38:44 +00:00
*
* Returns the device of an event.
2010-05-25 22:38:44 +00:00
*
* Returns: (nullable) (transfer none): a #GdkDevice.
*/
GdkDevice *
gdk_event_get_device (GdkEvent *event)
2010-05-25 22:38:44 +00:00
{
g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
return event->device;
2010-05-25 22:38:44 +00:00
}
/**
* gdk_event_get_source_device:
* @event: a #GdkEvent
*
* This function returns the physical #GdkDevice that has triggered
* the event, falling back to the logical device, as returned by
* gdk_event_get_device(), if the event wasnt caused by
* interaction with a hardware device. This may happen for example
* in synthesized crossing events after a #GdkSurface updates its
* geometry or a grab is acquired/released.
*
* If the event does not contain a device field, this function will
* return %NULL.
*
* Returns: (nullable) (transfer none): a #GdkDevice, or %NULL.
**/
GdkDevice *
gdk_event_get_source_device (GdkEvent *event)
{
g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
if (event->source_device)
return event->source_device;
return event->device;
}
/**
* gdk_event_get_device_tool:
* @event: a #GdkEvent
*
* If the event was generated by a device that supports
* different tools (eg. a tablet), this function will
* return a #GdkDeviceTool representing the tool that
* caused the event. Otherwise, %NULL will be returned.
*
* Note: the #GdkDeviceTools will be constant during
* the application lifetime, if settings must be stored
* persistently across runs, see gdk_device_tool_get_serial()
*
* Returns: (transfer none) (nullable): The current device tool, or %NULL
**/
GdkDeviceTool *
gdk_event_get_device_tool (GdkEvent *event)
{
g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
return GDK_EVENT_GET_CLASS (event)->get_tool (event);
}
/**
* gdk_event_get_time:
* @event: a #GdkEvent
*
* Returns the time stamp from @event, if there is one; otherwise
* returns #GDK_CURRENT_TIME.
*
* Returns: time stamp field from @event
**/
guint32
gdk_event_get_time (GdkEvent *event)
{
g_return_val_if_fail (GDK_IS_EVENT (event), GDK_CURRENT_TIME);
return event->time;
}
/**
* gdk_event_get_display:
* @event: a #GdkEvent
*
* Retrieves the #GdkDisplay associated to the @event.
*
* Returns: (transfer none) (nullable): a #GdkDisplay
*/
GdkDisplay *
gdk_event_get_display (GdkEvent *event)
{
g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
if (event->surface)
return gdk_surface_get_display (event->surface);
return NULL;
}
/**
* gdk_event_get_event_sequence:
* @event: a #GdkEvent
*
* If @event is a touch event, returns the #GdkEventSequence
* to which the event belongs. Otherwise, return %NULL.
*
* Returns: (transfer none): the event sequence that the event belongs to
*/
GdkEventSequence *
gdk_event_get_event_sequence (GdkEvent *event)
2010-05-25 22:38:44 +00:00
{
g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
2010-05-25 22:38:44 +00:00
return GDK_EVENT_GET_CLASS (event)->get_sequence (event);
}
/**
* gdk_event_get_modifier_state:
* @event: a #GdkEvent
*
* Returns the modifier state field of an event.
*
* Returns: the modifier state of @event
**/
GdkModifierType
gdk_event_get_modifier_state (GdkEvent *event)
{
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
2010-05-25 22:38:44 +00:00
return GDK_EVENT_GET_CLASS (event)->get_state (event);
}
2010-05-25 22:38:44 +00:00
/**
* gdk_event_get_position:
* @event: a #GdkEvent
* @x: (out): location to put event surface x coordinate
* @y: (out): location to put event surface y coordinate
*
* Extract the event surface relative x/y coordinates from an event.
**/
gboolean
gdk_event_get_position (GdkEvent *event,
double *x,
double *y)
{
g_return_val_if_fail (GDK_IS_EVENT (event), FALSE);
2010-05-25 22:38:44 +00:00
return GDK_EVENT_GET_CLASS (event)->get_position (event, x, y);
}
2010-05-25 22:38:44 +00:00
/* {{{ GdkButtonEvent */
static void
gdk_button_event_finalize (GdkEvent *event)
{
GdkButtonEvent *self = (GdkButtonEvent *) event;
2010-05-25 22:38:44 +00:00
g_clear_object (&self->tool);
g_clear_pointer (&self->axes, g_free);
GDK_EVENT_SUPER (event)->finalize (event);
}
static GdkModifierType
gdk_button_event_get_state (GdkEvent *event)
{
GdkButtonEvent *self = (GdkButtonEvent *) event;
return self->state;
2010-05-25 22:38:44 +00:00
}
static gboolean
gdk_button_event_get_position (GdkEvent *event,
double *x,
double *y)
2010-05-25 22:38:44 +00:00
{
GdkButtonEvent *self = (GdkButtonEvent *) event;
*x = self->x;
*y = self->y;
return TRUE;
2010-05-25 22:38:44 +00:00
}
static GdkDeviceTool *
gdk_button_event_get_tool (GdkEvent *event)
2010-05-25 22:38:44 +00:00
{
GdkButtonEvent *self = (GdkButtonEvent *) event;
2010-05-25 22:38:44 +00:00
return self->tool;
2010-05-25 22:38:44 +00:00
}
static gboolean
gdk_button_event_get_axes (GdkEvent *event,
double **axes,
guint *n_axes)
2010-05-25 22:38:44 +00:00
{
GdkButtonEvent *self = (GdkButtonEvent *) event;
GdkDevice *source_device = gdk_event_get_source_device (event);
if (source_device == NULL)
return FALSE;
2010-05-25 22:38:44 +00:00
*axes = self->axes;
*n_axes = gdk_device_get_n_axes (source_device);
2010-05-25 22:38:44 +00:00
return TRUE;
}
static const GdkEventTypeInfo gdk_button_event_info = {
sizeof (GdkButtonEvent),
NULL,
gdk_button_event_finalize,
gdk_button_event_get_state,
gdk_button_event_get_position,
NULL,
gdk_button_event_get_tool,
gdk_button_event_get_axes,
};
GDK_DEFINE_EVENT_TYPE (GdkButtonEvent, gdk_button_event,
&gdk_button_event_info,
GDK_EVENT_TYPE_SLOT (GDK_BUTTON_PRESS)
GDK_EVENT_TYPE_SLOT (GDK_BUTTON_RELEASE))
GdkEvent *
gdk_button_event_new (GdkEventType type,
GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
GdkDeviceTool *tool,
guint32 time,
GdkModifierType state,
guint button,
double x,
double y,
double *axes)
{
g_return_val_if_fail (type == GDK_BUTTON_PRESS ||
type == GDK_BUTTON_RELEASE, NULL);
GdkButtonEvent *self = gdk_event_alloc (type, surface, device, source_device, time);
self->tool = tool != NULL ? g_object_ref (tool) : NULL;
self->axes = axes;
self->state = state;
self->button = button;
self->x = x;
self->y = y;
return (GdkEvent *) self;
}
/**
* gdk_button_event_get_button:
* @event: (type GdkButtonEvent): a button event
*
* Extract the button number from a button event.
*
* Returns: the button of @event
**/
guint
gdk_button_event_get_button (GdkEvent *event)
{
GdkButtonEvent *self = (GdkButtonEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_BUTTON_PRESS) ||
GDK_IS_EVENT_TYPE (event, GDK_BUTTON_RELEASE), 0);
return self->button;
}
/* }}} */
/* {{{ GdkKeyEvent */
static GdkModifierType
gdk_key_event_get_state (GdkEvent *event)
{
GdkKeyEvent *self = (GdkKeyEvent *) event;
return self->state;
}
static const GdkEventTypeInfo gdk_key_event_info = {
sizeof (GdkKeyEvent),
NULL,
NULL,
gdk_key_event_get_state,
NULL,
NULL,
NULL,
NULL,
};
GDK_DEFINE_EVENT_TYPE (GdkKeyEvent, gdk_key_event,
&gdk_key_event_info,
GDK_EVENT_TYPE_SLOT (GDK_KEY_PRESS)
GDK_EVENT_TYPE_SLOT (GDK_KEY_RELEASE))
/*< private >
* gdk_key_event_new:
* @type: the event type, either %GDK_KEY_PRESS or %GDK_KEY_RELEASE
* @surface: the #GdkSurface of the event
* @device: the #GdkDevice related to the event
* @source_device: the source #GdkDevice related to the event
* @time: the event's timestamp
* @keycode: the keycode of the event
* @state: the modifiers state
* @is_modifier: whether the event is a modifiers only event
* @translated: the translated key data for the given @state
* @no_lock: the translated key data without the given @state
*
* Creates a new #GdkKeyEvent.
*
* Returns: (transfer full) (type GdkKeyEvent): the newly created #GdkEvent
*/
GdkEvent *
gdk_key_event_new (GdkEventType type,
GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
guint32 time,
guint keycode,
GdkModifierType state,
gboolean is_modifier,
GdkTranslatedKey *translated,
GdkTranslatedKey *no_lock)
{
g_return_val_if_fail (type == GDK_KEY_PRESS ||
type == GDK_KEY_RELEASE, NULL);
GdkKeyEvent *self = gdk_event_alloc (type, surface, device, source_device, time);
GdkEvent *event = (GdkEvent *) self;
self->keycode = keycode;
self->state = state;
self->key_is_modifier = is_modifier;
self->translated[0] = *translated;
self->translated[1] = *no_lock;
return event;
}
/*< private >
* gdk_key_event_get_translated_key:
* @event: (type GdkKeyEvent): a key event
* @no_lock: whether the translated key should take the event
* state into account
*
* Extracts the translated key from a key event.
*
* Returns: (transfer none): the translated key
*/
GdkTranslatedKey *
gdk_key_event_get_translated_key (GdkEvent *event,
gboolean no_lock)
{
GdkKeyEvent *self = (GdkKeyEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_KEY_PRESS) ||
GDK_IS_EVENT_TYPE (event, GDK_KEY_RELEASE), NULL);
if (no_lock)
return &(self->translated[1]);
return &(self->translated[0]);
}
/**
* gdk_key_event_get_keyval:
* @event: (type GdkKeyEvent): a key event
*
* Extracts the keyval from a key event.
*
* Returns: the keyval of @event
*/
guint
gdk_key_event_get_keyval (GdkEvent *event)
{
GdkKeyEvent *self = (GdkKeyEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_KEY_PRESS) ||
GDK_IS_EVENT_TYPE (event, GDK_KEY_RELEASE), 0);
return self->translated[0].keyval;
}
/**
* gdk_key_event_get_keycode:
* @event: (type GdkKeyEvent): a key event
*
* Extracts the keycode from a key event.
*
* Returns: the keycode of @event
*/
guint
gdk_key_event_get_keycode (GdkEvent *event)
{
GdkKeyEvent *self = (GdkKeyEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_KEY_PRESS) ||
GDK_IS_EVENT_TYPE (event, GDK_KEY_RELEASE), 0);
return self->keycode;
}
/**
* gdk_key_event_get_level:
* @event: (type GdkKeyEvent): a key event
*
* Extracts the shift level from a key event.
*
* Returns: the shift level of @event
*/
guint
gdk_key_event_get_level (GdkEvent *event)
{
GdkKeyEvent *self = (GdkKeyEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_KEY_PRESS) ||
GDK_IS_EVENT_TYPE (event, GDK_KEY_RELEASE), 0);
return self->translated[0].level;
}
/**
* gdk_key_event_get_layout:
* @event: (type GdkKeyEvent): a key event
*
* Extracts the layout from a key event.
*
* Returns: the layout of @event
*/
guint
gdk_key_event_get_layout (GdkEvent *event)
{
GdkKeyEvent *self = (GdkKeyEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_KEY_PRESS) ||
GDK_IS_EVENT_TYPE (event, GDK_KEY_RELEASE), 0);
return self->translated[0].layout;
}
/**
* gdk_key_event_get_consumed_modifiers:
* @event: (type GdkKeyEvent): a key event
*
* Extracts the consumed modifiers from a key event.
*
* Returns: the consumed modifiers or @event
*/
GdkModifierType
gdk_key_event_get_consumed_modifiers (GdkEvent *event)
{
GdkKeyEvent *self = (GdkKeyEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_KEY_PRESS) ||
GDK_IS_EVENT_TYPE (event, GDK_KEY_RELEASE), 0);
return self->translated[0].consumed;
}
/**
* gdk_key_event_is_modifier:
* @event: (type GdkKeyEvent): a key event
*
* Extracts whether the key event is for a modifier key.
*
* Returns: %TRUE if the @event is for a modifier key
*/
gboolean
gdk_key_event_is_modifier (GdkEvent *event)
{
GdkKeyEvent *self = (GdkKeyEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_KEY_PRESS) ||
GDK_IS_EVENT_TYPE (event, GDK_KEY_RELEASE), FALSE);
return self->key_is_modifier;
}
/**
* gdk_key_event_matches:
* @event: (type GdkKeyEvent): a key #GdkEvent
* @keyval: the keyval to match
* @modifiers: the modifiers to match
*
* Matches a key event against a keyboard shortcut that is specified
* as a keyval and modifiers. Partial matches are possible where the
* combination matches if the currently active group is ignored.
*
* Note that we ignore Caps Lock for matching.
*
* Returns: a GdkKeyMatch value describing whether @event matches
*/
GdkKeyMatch
gdk_key_event_matches (GdkEvent *event,
guint keyval,
GdkModifierType modifiers)
{
GdkKeyEvent *self = (GdkKeyEvent *) event;
GdkKeymap *keymap;
guint keycode;
GdkModifierType state;
guint ev_keyval;
int layout;
int level;
GdkModifierType consumed_modifiers;
GdkModifierType shift_group_mask;
gboolean group_mod_is_accel_mod = FALSE;
const GdkModifierType mask = GDK_CONTROL_MASK |
GDK_SHIFT_MASK |
GDK_ALT_MASK |
GDK_SUPER_MASK |
GDK_HYPER_MASK |
GDK_META_MASK;
g_return_val_if_fail (GDK_IS_EVENT (event), GDK_KEY_MATCH_NONE);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_KEY_PRESS) ||
GDK_IS_EVENT_TYPE (event, GDK_KEY_RELEASE), GDK_KEY_MATCH_NONE);
keycode = self->keycode;
state = self->state & ~GDK_LOCK_MASK;
ev_keyval = self->translated[1].keyval;
layout = self->translated[1].layout;
level = self->translated[1].level;
consumed_modifiers = self->translated[1].consumed;
/* if the group-toggling modifier is part of the default accel mod
* mask, and it is active, disable it for matching
*
* FIXME: get shift group mask from backends
*/
shift_group_mask = 0;
if (mask & shift_group_mask)
group_mod_is_accel_mod = TRUE;
if ((modifiers & ~consumed_modifiers & mask) == (state & ~consumed_modifiers & mask))
{
/* modifier match */
GdkKeymapKey *keys;
guint n_keys;
int i;
guint key;
/* Shift gets consumed and applied for the event,
* so apply it to our keyval to match
*/
key = keyval;
if (modifiers & GDK_SHIFT_MASK)
{
if (key == GDK_KEY_Tab)
key = GDK_KEY_ISO_Left_Tab;
else
key = gdk_keyval_to_upper (key);
}
if (ev_keyval == key && /* exact match */
(!group_mod_is_accel_mod ||
(state & shift_group_mask) == (modifiers & shift_group_mask)))
{
return GDK_KEY_MATCH_EXACT;
}
keymap = gdk_display_get_keymap (gdk_event_get_display (event));
gdk_keymap_get_cached_entries_for_keyval (keymap, keyval, &keys, &n_keys);
for (i = 0; i < n_keys; i++)
{
if (keys[i].keycode == keycode &&
keys[i].level == level &&
/* Only match for group if it's an accel mod */
(!group_mod_is_accel_mod || keys[i].group == layout))
{
return GDK_KEY_MATCH_PARTIAL;
}
}
}
return GDK_KEY_MATCH_NONE;
}
/**
* gdk_key_event_get_match:
* @event: (type GdkKeyEvent): a key #GdkEvent
* @keyval: (out): return location for a keyval
* @modifiers: (out): return location for modifiers
*
* Gets a keyval and modifier combination that will cause
* gdk_key_event_matches() to successfully match the given event.
*
* Returns: %TRUE on success
*/
gboolean
gdk_key_event_get_match (GdkEvent *event,
guint *keyval,
GdkModifierType *modifiers)
{
GdkKeyEvent *self = (GdkKeyEvent *) event;
guint key;
guint accel_key;
GdkModifierType accel_mods;
GdkModifierType consumed_modifiers;
const GdkModifierType mask = GDK_CONTROL_MASK |
GDK_SHIFT_MASK |
GDK_ALT_MASK |
GDK_SUPER_MASK |
GDK_HYPER_MASK |
GDK_META_MASK;
g_return_val_if_fail (GDK_IS_EVENT (event), FALSE);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_KEY_PRESS) ||
GDK_IS_EVENT_TYPE (event, GDK_KEY_RELEASE), FALSE);
accel_key = self->translated[1].keyval;
accel_mods = self->state;
consumed_modifiers = self->translated[1].consumed;
if (accel_key == GDK_KEY_Sys_Req &&
(accel_mods & GDK_ALT_MASK) != 0)
{
/* HACK: we don't want to use SysRq as a keybinding (but we do
* want Alt+Print), so we avoid translation from Alt+Print to SysRq
*/
*keyval = GDK_KEY_Print;
*modifiers = accel_mods & mask;
return TRUE;
}
key = gdk_keyval_to_lower (accel_key);
if (key == GDK_KEY_ISO_Left_Tab)
key = GDK_KEY_Tab;
accel_mods &= mask & ~consumed_modifiers;
if (accel_key != key)
accel_mods |= GDK_SHIFT_MASK;
*keyval = key;
*modifiers = accel_mods;
return TRUE;
}
/* }}} */
/* {{{ GdkConfigureEvent */
static gboolean
gdk_configure_event_get_position (GdkEvent *event,
double *x,
double *y)
{
GdkConfigureEvent *self = (GdkConfigureEvent *) event;
*x = self->x;
*y = self->y;
return TRUE;
}
static const GdkEventTypeInfo gdk_configure_event_info = {
sizeof (GdkConfigureEvent),
NULL,
NULL,
NULL,
gdk_configure_event_get_position,
NULL,
NULL,
NULL,
};
GDK_DEFINE_EVENT_TYPE (GdkConfigureEvent, gdk_configure_event,
&gdk_configure_event_info,
GDK_EVENT_TYPE_SLOT (GDK_CONFIGURE))
GdkEvent *
gdk_configure_event_new (GdkSurface *surface,
int width,
int height)
{
GdkConfigureEvent *self;
g_return_val_if_fail (width >= 0 && height >= 0, NULL);
self = gdk_event_alloc (GDK_CONFIGURE, surface, NULL, NULL, GDK_CURRENT_TIME);
self->width = width;
self->height = height;
return (GdkEvent *) self;
}
/**
* gdk_configure_event_get_size:
* @event: (type GdkConfigureEvent): a configure event
* @width: (out): return location for surface width
* @height: (out): return location for surface height
*
* Extracts the surface size from a configure event.
*/
void
gdk_configure_event_get_size (GdkEvent *event,
int *width,
int *height)
{
GdkConfigureEvent *self = (GdkConfigureEvent *) event;
g_return_if_fail (GDK_IS_EVENT (event));
g_return_if_fail (GDK_IS_EVENT_TYPE (event, GDK_CONFIGURE));
*width = self->width;
*height = self->height;
}
/* }}} */
/* {{{ GdkTouchEvent */
static void
gdk_touch_event_finalize (GdkEvent *event)
{
GdkTouchEvent *self = (GdkTouchEvent *) event;
g_clear_pointer (&self->axes, g_free);
GDK_EVENT_SUPER (event)->finalize (event);
}
static GdkModifierType
gdk_touch_event_get_state (GdkEvent *event)
{
GdkTouchEvent *self = (GdkTouchEvent *) event;
return self->state;
}
static gboolean
gdk_touch_event_get_position (GdkEvent *event,
double *x,
double *y)
{
GdkTouchEvent *self = (GdkTouchEvent *) event;
*x = self->x;
*y = self->y;
return TRUE;
}
static GdkEventSequence *
gdk_touch_event_get_sequence (GdkEvent *event)
{
GdkTouchEvent *self = (GdkTouchEvent *) event;
return self->sequence;
}
static gboolean
gdk_touch_event_get_axes (GdkEvent *event,
double **axes,
guint *n_axes)
{
GdkTouchEvent *self = (GdkTouchEvent *) event;
GdkDevice *source_device = gdk_event_get_source_device (event);
if (source_device == NULL)
return FALSE;
*axes = self->axes;
*n_axes = gdk_device_get_n_axes (source_device);
return TRUE;
}
static const GdkEventTypeInfo gdk_touch_event_info = {
sizeof (GdkTouchEvent),
NULL,
gdk_touch_event_finalize,
gdk_touch_event_get_state,
gdk_touch_event_get_position,
gdk_touch_event_get_sequence,
NULL,
gdk_touch_event_get_axes,
};
GDK_DEFINE_EVENT_TYPE (GdkTouchEvent, gdk_touch_event,
&gdk_touch_event_info,
GDK_EVENT_TYPE_SLOT (GDK_TOUCH_BEGIN)
GDK_EVENT_TYPE_SLOT (GDK_TOUCH_END)
GDK_EVENT_TYPE_SLOT (GDK_TOUCH_UPDATE)
GDK_EVENT_TYPE_SLOT (GDK_TOUCH_CANCEL))
GdkEvent *
gdk_touch_event_new (GdkEventType type,
GdkEventSequence *sequence,
GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
guint32 time,
GdkModifierType state,
double x,
double y,
double *axes,
gboolean emulating)
{
GdkTouchEvent *self;
g_return_val_if_fail (type == GDK_TOUCH_BEGIN ||
type == GDK_TOUCH_END ||
type == GDK_TOUCH_UPDATE ||
type == GDK_TOUCH_CANCEL, NULL);
self = gdk_event_alloc (type, surface, device, source_device, time);
self->sequence = sequence;
self->state = state;
self->x = x;
self->y = y;
self->axes = axes;
self->touch_emulating = emulating;
self->pointer_emulated = emulating;
return (GdkEvent *) self;
}
/**
* gdk_touch_event_get_emulating_pointer:
* @event: (type GdkTouchEvent): a touch event
*
* Extracts whether a touch event is emulating a pointer event.
*
* Returns: %TRUE if @event is emulating
**/
gboolean
gdk_touch_event_get_emulating_pointer (GdkEvent *event)
{
GdkTouchEvent *self = (GdkTouchEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), FALSE);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCH_BEGIN) ||
GDK_IS_EVENT_TYPE (event, GDK_TOUCH_UPDATE) ||
GDK_IS_EVENT_TYPE (event, GDK_TOUCH_END) ||
GDK_IS_EVENT_TYPE (event, GDK_TOUCH_CANCEL), FALSE);
return self->touch_emulating;
}
/* }}} */
/* {{{ GdkCrossingEvent */
static void
gdk_crossing_event_finalize (GdkEvent *event)
{
GdkCrossingEvent *self = (GdkCrossingEvent *) event;
g_clear_object (&self->child_surface);
GDK_EVENT_SUPER (self)->finalize (event);
}
static GdkModifierType
gdk_crossing_event_get_state (GdkEvent *event)
{
GdkCrossingEvent *self = (GdkCrossingEvent *) event;
return self->state;
}
static gboolean
gdk_crossing_event_get_position (GdkEvent *event,
double *x,
double *y)
{
GdkCrossingEvent *self = (GdkCrossingEvent *) event;
*x = self->x;
*y = self->y;
return TRUE;
}
static const GdkEventTypeInfo gdk_crossing_event_info = {
sizeof (GdkCrossingEvent),
NULL,
gdk_crossing_event_finalize,
gdk_crossing_event_get_state,
gdk_crossing_event_get_position,
NULL,
NULL,
NULL,
};
GDK_DEFINE_EVENT_TYPE (GdkCrossingEvent, gdk_crossing_event,
&gdk_crossing_event_info,
GDK_EVENT_TYPE_SLOT (GDK_ENTER_NOTIFY)
GDK_EVENT_TYPE_SLOT (GDK_LEAVE_NOTIFY))
GdkEvent *
gdk_crossing_event_new (GdkEventType type,
GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
guint32 time,
GdkModifierType state,
double x,
double y,
GdkCrossingMode mode,
GdkNotifyType detail)
{
GdkCrossingEvent *self;
g_return_val_if_fail (type == GDK_ENTER_NOTIFY ||
type == GDK_LEAVE_NOTIFY, NULL);
self = gdk_event_alloc (type, surface, device, source_device, time);
self->state = state;
self->x = x;
self->y = y;
self->mode = mode;
self->detail = detail;
return (GdkEvent *) self;
}
/**
* gdk_crossing_event_get_mode:
* @event: (type GdkCrossingEvent): a crossing event
*
* Extracts the crossing mode from a crossing event.
*
* Returns: the mode of @event
*/
GdkCrossingMode
gdk_crossing_event_get_mode (GdkEvent *event)
{
GdkCrossingEvent *self = (GdkCrossingEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_ENTER_NOTIFY) ||
GDK_IS_EVENT_TYPE (event, GDK_LEAVE_NOTIFY), 0);
return self->mode;
}
/**
* gdk_crossing_event_get_focus:
* @event: (type GdkCrossingEvent): a crossing event
*
* Checks if the @event surface is the focus surface.
*
* Returns: %TRUE if the surface is the focus surface
*/
gboolean
gdk_crossing_event_get_focus (GdkEvent *event)
{
GdkCrossingEvent *self = (GdkCrossingEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), FALSE);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_ENTER_NOTIFY) ||
GDK_IS_EVENT_TYPE (event, GDK_LEAVE_NOTIFY), FALSE);
return self->focus;
}
/**
* gdk_crossing_event_get_detail:
* @event: (type GdkCrossingEvent): a crossing event
*
* Extracts the notify detail from a crossing event.
*
* Returns: the notify detail of @event
*/
GdkNotifyType
gdk_crossing_event_get_detail (GdkEvent *event)
{
GdkCrossingEvent *self = (GdkCrossingEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_ENTER_NOTIFY) ||
GDK_IS_EVENT_TYPE (event, GDK_LEAVE_NOTIFY), 0);
return self->detail;
}
/* }}} */
/* {{{ GdkDeleteEvent */
static const GdkEventTypeInfo gdk_delete_event_info = {
sizeof (GdkDeleteEvent),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
GDK_DEFINE_EVENT_TYPE (GdkDeleteEvent, gdk_delete_event,
&gdk_delete_event_info,
GDK_EVENT_TYPE_SLOT (GDK_DELETE))
GdkEvent *
gdk_delete_event_new (GdkSurface *surface)
{
return gdk_event_alloc (GDK_DELETE, surface, NULL, NULL, GDK_CURRENT_TIME);
}
/* }}} */
/* {{{ GdkFocusEvent */
static const GdkEventTypeInfo gdk_focus_event_info = {
sizeof (GdkFocusEvent),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
GDK_DEFINE_EVENT_TYPE (GdkFocusEvent, gdk_focus_event,
&gdk_focus_event_info,
GDK_EVENT_TYPE_SLOT (GDK_FOCUS_CHANGE))
GdkEvent *
gdk_focus_event_new (GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
gboolean focus_in)
{
GdkFocusEvent *self = gdk_event_alloc (GDK_FOCUS_CHANGE, surface, device, source_device, GDK_CURRENT_TIME);
self->focus_in = focus_in;
return (GdkEvent *) self;
}
/**
* gdk_focus_event_get_in:
* @event: (type GdkFocusEvent): a focus change event
*
* Extracts whether this event is about focus entering or
* leaving the surface.
*
* Returns: %TRUE of the focus is entering
*/
gboolean
gdk_focus_event_get_in (GdkEvent *event)
{
GdkFocusEvent *self = (GdkFocusEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), FALSE);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_FOCUS_CHANGE), FALSE);
return self->focus_in;
}
/* }}} */
/* {{{ GdkScrollEvent */
static void
gdk_scroll_event_finalize (GdkEvent *event)
{
GdkScrollEvent *self = (GdkScrollEvent *) event;
g_clear_object (&self->tool);
if (self->history)
g_array_free (self->history, TRUE);
GDK_EVENT_SUPER (self)->finalize (event);
}
static GdkModifierType
gdk_scroll_event_get_state (GdkEvent *event)
{
GdkScrollEvent *self = (GdkScrollEvent *) event;
return self->state;
}
static GdkDeviceTool *
gdk_scroll_event_get_tool (GdkEvent *event)
{
GdkScrollEvent *self = (GdkScrollEvent *) event;
return self->tool;
}
static const GdkEventTypeInfo gdk_scroll_event_info = {
sizeof (GdkScrollEvent),
NULL,
gdk_scroll_event_finalize,
gdk_scroll_event_get_state,
NULL,
NULL,
gdk_scroll_event_get_tool,
NULL,
};
GDK_DEFINE_EVENT_TYPE (GdkScrollEvent, gdk_scroll_event,
&gdk_scroll_event_info,
GDK_EVENT_TYPE_SLOT (GDK_SCROLL))
GdkEvent *
gdk_scroll_event_new (GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
GdkDeviceTool *tool,
guint32 time,
GdkModifierType state,
double delta_x,
double delta_y,
gboolean is_stop)
{
GdkScrollEvent *self = gdk_event_alloc (GDK_SCROLL, surface, device, source_device, time);
self->tool = tool != NULL ? g_object_ref (tool) : NULL;
self->state = state;
self->direction = GDK_SCROLL_SMOOTH;
self->delta_x = delta_x;
self->delta_y = delta_y;
self->is_stop = is_stop;
return (GdkEvent *) self;
}
GdkEvent *
gdk_scroll_event_new_discrete (GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
GdkDeviceTool *tool,
guint32 time,
GdkModifierType state,
GdkScrollDirection direction,
gboolean emulated)
{
GdkScrollEvent *self = gdk_event_alloc (GDK_SCROLL, surface, device, source_device, time);
self->tool = tool != NULL ? g_object_ref (tool) : NULL;
self->state = state;
self->direction = direction;
self->pointer_emulated = emulated;
return (GdkEvent *) self;
}
/**
* gdk_scroll_event_get_direction:
* @event: (type GdkScrollEvent): a scroll event
*
* Extracts the direction of a scroll event.
*
* Returns: the scroll direction of @event
*/
GdkScrollDirection
gdk_scroll_event_get_direction (GdkEvent *event)
{
GdkScrollEvent *self = (GdkScrollEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_SCROLL), 0);
return self->direction;
}
/**
* gdk_scroll_event_get_deltas:
* @event: (type GdkScrollEvent): a scroll event
* @delta_x: (out): return location for x scroll delta
* @delta_y: (out): return location for y scroll delta
*
* Extracts the scroll deltas of a scroll event.
*
* The deltas will be zero unless the scroll direction
* is %GDK_SCROLL_SMOOTH.
*/
void
gdk_scroll_event_get_deltas (GdkEvent *event,
double *delta_x,
double *delta_y)
2017-08-26 02:50:52 +00:00
{
GdkScrollEvent *self = (GdkScrollEvent *) event;
2017-08-26 02:50:52 +00:00
g_return_if_fail (GDK_IS_EVENT (event));
g_return_if_fail (GDK_IS_EVENT_TYPE (event, GDK_SCROLL));
*delta_x = self->delta_x;
*delta_y = self->delta_y;
2017-08-26 02:50:52 +00:00
}
/**
* gdk_scroll_event_is_stop:
* @event: (type GdkScrollEvent): a scroll event
*
* Check whether a scroll event is a stop scroll event. Scroll sequences
* with smooth scroll information may provide a stop scroll event once the
* interaction with the device finishes, e.g. by lifting a finger. This
* stop scroll event is the signal that a widget may trigger kinetic
* scrolling based on the current velocity.
*
* Stop scroll events always have a delta of 0/0.
*
* Returns: %TRUE if the event is a scroll stop event
*/
gboolean
gdk_scroll_event_is_stop (GdkEvent *event)
2017-08-26 02:50:52 +00:00
{
GdkScrollEvent *self = (GdkScrollEvent *) event;
2017-08-26 02:50:52 +00:00
g_return_val_if_fail (GDK_IS_EVENT (event), FALSE);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_SCROLL), FALSE);
return self->is_stop;
2017-08-26 02:50:52 +00:00
}
/* }}} */
2017-08-26 14:50:15 +00:00
/* {{{ GdkTouchpadEvent */
2017-08-26 14:50:15 +00:00
static GdkModifierType
gdk_touchpad_event_get_state (GdkEvent *event)
2017-08-26 14:50:15 +00:00
{
GdkTouchpadEvent *self = (GdkTouchpadEvent *) event;
return self->state;
2017-08-26 14:50:15 +00:00
}
static gboolean
gdk_touchpad_event_get_position (GdkEvent *event,
double *x,
double *y)
2017-08-26 14:50:15 +00:00
{
GdkTouchpadEvent *self = (GdkTouchpadEvent *) event;
2017-08-26 14:50:15 +00:00
*x = self->x;
*y = self->y;
return TRUE;
2017-08-26 14:50:15 +00:00
}
static const GdkEventTypeInfo gdk_touchpad_event_info = {
sizeof (GdkTouchpadEvent),
NULL,
NULL,
gdk_touchpad_event_get_state,
gdk_touchpad_event_get_position,
NULL,
NULL,
NULL,
};
GDK_DEFINE_EVENT_TYPE (GdkTouchpadEvent, gdk_touchpad_event,
&gdk_touchpad_event_info,
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_SWIPE)
GDK_EVENT_TYPE_SLOT (GDK_TOUCHPAD_PINCH))
GdkEvent *
gdk_touchpad_event_new_swipe (GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
guint32 time,
GdkModifierType state,
GdkTouchpadGesturePhase phase,
double x,
double y,
int n_fingers,
double dx,
double dy)
2017-08-26 14:50:15 +00:00
{
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_SWIPE, surface, device, source_device, time);
2017-08-26 14:50:15 +00:00
self->state = state;
self->phase = phase;
self->x = x;
self->y = y;
self->dx = dx;
self->dy = dy;
self->n_fingers = n_fingers;
return (GdkEvent *) self;
2017-08-26 14:50:15 +00:00
}
GdkEvent *
gdk_touchpad_event_new_pinch (GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
guint32 time,
GdkModifierType state,
GdkTouchpadGesturePhase phase,
double x,
double y,
int n_fingers,
double dx,
double dy,
double scale,
double angle_delta)
{
GdkTouchpadEvent *self = gdk_event_alloc (GDK_TOUCHPAD_PINCH, surface, device, source_device, time);
self->state = state;
self->phase = phase;
self->x = x;
self->y = y;
self->dx = dx;
self->dy = dy;
self->n_fingers = n_fingers;
self->scale = scale;
self->angle_delta = angle_delta;
2017-08-26 14:50:15 +00:00
return (GdkEvent *) self;
2017-08-26 14:50:15 +00:00
}
/**
* gdk_touchpad_event_get_gesture_phase:
* @event: (type GdkTouchpadEvent): a touchpad #GdkEvent
*
* Extracts the touchpad gesture phase from a touchpad event.
*
* Returns: the gesture phase of @event
**/
GdkTouchpadGesturePhase
gdk_touchpad_event_get_gesture_phase (GdkEvent *event)
{
GdkTouchpadEvent *self = (GdkTouchpadEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_PINCH) ||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE), 0);
return self->phase;
}
/**
* gdk_touchpad_event_get_n_fingers:
* @event: (type GdkTouchpadEvent): a touchpad event
*
* Extracts the number of fingers from a touchpad event.
*
* Returns: the number of fingers for @event
**/
guint
gdk_touchpad_event_get_n_fingers (GdkEvent *event)
{
GdkTouchpadEvent *self = (GdkTouchpadEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_PINCH) ||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE), 0);
return self->n_fingers;
}
/**
* gdk_touchpad_event_get_deltas:
* @event: (type GdkTouchpadEvent): a touchpad event
* @dx: (out): return location for x
* @dy: (out): return location for y
*
* Extracts delta information from a touchpad event.
**/
void
gdk_touchpad_event_get_deltas (GdkEvent *event,
double *dx,
double *dy)
{
GdkTouchpadEvent *self = (GdkTouchpadEvent *) event;
g_return_if_fail (GDK_IS_EVENT (event));
g_return_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_PINCH) ||
GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_SWIPE));
*dx = self->dx;
*dy = self->dy;
}
/**
* gdk_touchpad_event_get_pinch_angle_delta:
* @event: (type GdkTouchpadEvent): a touchpad pinch event
*
* Extracts the angle delta from a touchpad pinch event.
*
* Returns: the angle delta of @event
*/
double
gdk_touchpad_event_get_pinch_angle_delta (GdkEvent *event)
{
GdkTouchpadEvent *self = (GdkTouchpadEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0.0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_PINCH), 0.0);
return self->angle_delta;
}
/**
* gdk_touchpad_event_get_pinch_scale:
* @event: (type GdkTouchpadEvent): a touchpad pinch event
*
* Extracts the scale from a touchpad pinch event.
*
* Returns: the scale of @event
**/
double
gdk_touchpad_event_get_pinch_scale (GdkEvent *event)
{
GdkTouchpadEvent *self = (GdkTouchpadEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0.0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_TOUCHPAD_PINCH), 0.0);
return self->scale;
}
/* }}} */
/* {{{ GdkPadEvent */
static const GdkEventTypeInfo gdk_pad_event_info = {
sizeof (GdkPadEvent),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
GDK_DEFINE_EVENT_TYPE (GdkPadEvent, gdk_pad_event,
&gdk_pad_event_info,
GDK_EVENT_TYPE_SLOT (GDK_PAD_BUTTON_PRESS)
GDK_EVENT_TYPE_SLOT (GDK_PAD_BUTTON_RELEASE)
GDK_EVENT_TYPE_SLOT (GDK_PAD_RING)
GDK_EVENT_TYPE_SLOT (GDK_PAD_STRIP)
GDK_EVENT_TYPE_SLOT (GDK_PAD_GROUP_MODE))
GdkEvent *
gdk_pad_event_new_ring (GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
guint32 time,
guint group,
guint index,
guint mode,
double value)
{
GdkPadEvent *self = gdk_event_alloc (GDK_PAD_RING, surface, device, source_device, time);
self->group = group;
self->index = index;
self->mode = mode;
self->value = value;
return (GdkEvent *) self;
}
GdkEvent *
gdk_pad_event_new_strip (GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
guint32 time,
guint group,
guint index,
guint mode,
double value)
{
GdkPadEvent *self = gdk_event_alloc (GDK_PAD_STRIP, surface, device, source_device, time);
self->group = group;
self->index = index;
self->mode = mode;
self->value = value;
return (GdkEvent *) self;
}
GdkEvent *
gdk_pad_event_new_button (GdkEventType type,
GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
guint32 time,
guint group,
guint button,
guint mode)
{
GdkPadEvent *self;
g_return_val_if_fail (type == GDK_PAD_BUTTON_PRESS ||
type == GDK_PAD_BUTTON_RELEASE, NULL);
self = gdk_event_alloc (type, surface, device, source_device, time);
self->group = group;
self->button = button;
self->mode = mode;
return (GdkEvent *) self;
}
GdkEvent *
gdk_pad_event_new_group_mode (GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
guint32 time,
guint group,
guint mode)
{
GdkPadEvent *self = gdk_event_alloc (GDK_PAD_GROUP_MODE, surface, device, source_device, time);
self->group = group;
self->mode = mode;
return (GdkEvent *) self;
}
/**
* gdk_pad_event_get_button:
* @event: (type GdkPadEvent): a pad button event
*
* Extracts information about the pressed button from
* a pad event.
*
* Returns: the button of @event
**/
guint
gdk_pad_event_get_button (GdkEvent *event)
{
GdkPadEvent *self = (GdkPadEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), 0);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_PAD_BUTTON_PRESS) ||
GDK_IS_EVENT_TYPE (event, GDK_PAD_BUTTON_RELEASE), 0);
return self->button;
}
/**
* gdk_pad_event_get_axis_value:
* @event: (type GdkPadEvent): a pad strip or ring event
* @index: (out): Return location for the axis index
* @value: (out): Return location for the axis value
*
* Extracts the information from a pad strip or ring event.
**/
void
gdk_pad_event_get_axis_value (GdkEvent *event,
guint *index,
double *value)
{
GdkPadEvent *self = (GdkPadEvent *) event;
g_return_if_fail (GDK_IS_EVENT (event));
g_return_if_fail (GDK_IS_EVENT_TYPE (event, GDK_PAD_RING) ||
GDK_IS_EVENT_TYPE (event, GDK_PAD_STRIP));
*index = self->index;
*value = self->value;
}
/**
* gdk_pad_event_get_group_mode:
* @event: (type GdkPadEvent): a pad event
* @group: (out): return location for the group
* @mode: (out): return location for the mode
*
* Extracts group and mode information from a pad event.
**/
void
gdk_pad_event_get_group_mode (GdkEvent *event,
guint *group,
guint *mode)
{
GdkPadEvent *self = (GdkPadEvent *) event;
g_return_if_fail (GDK_IS_EVENT (event));
g_return_if_fail (GDK_IS_EVENT_TYPE (event, GDK_PAD_GROUP_MODE) ||
GDK_IS_EVENT_TYPE (event, GDK_PAD_BUTTON_PRESS) ||
GDK_IS_EVENT_TYPE (event, GDK_PAD_BUTTON_RELEASE) ||
GDK_IS_EVENT_TYPE (event, GDK_PAD_RING) ||
GDK_IS_EVENT_TYPE (event, GDK_PAD_STRIP));
*group = self->group;
*mode = self->mode;
}
/* }}} */
/* {{{ GdkMotionEvent */
static void
gdk_motion_event_finalize (GdkEvent *event)
{
GdkMotionEvent *self = (GdkMotionEvent *) event;
g_clear_object (&self->tool);
g_clear_pointer (&self->axes, g_free);
if (self->history)
g_array_free (self->history, TRUE);
GDK_EVENT_SUPER (event)->finalize (event);
}
static GdkModifierType
gdk_motion_event_get_state (GdkEvent *event)
{
GdkMotionEvent *self = (GdkMotionEvent *) event;
return self->state;
}
static gboolean
gdk_motion_event_get_position (GdkEvent *event,
double *x,
double *y)
{
GdkMotionEvent *self = (GdkMotionEvent *) event;
*x = self->x;
*y = self->y;
return TRUE;
}
static GdkDeviceTool *
gdk_motion_event_get_tool (GdkEvent *event)
{
GdkMotionEvent *self = (GdkMotionEvent *) event;
return self->tool;
}
static gboolean
gdk_motion_event_get_axes (GdkEvent *event,
double **axes,
guint *n_axes)
{
GdkMotionEvent *self = (GdkMotionEvent *) event;
GdkDevice *source_device = gdk_event_get_source_device (event);
if (source_device == NULL)
return FALSE;
*axes = self->axes;
*n_axes = gdk_device_get_n_axes (source_device);
return TRUE;
}
static const GdkEventTypeInfo gdk_motion_event_info = {
sizeof (GdkMotionEvent),
NULL,
gdk_motion_event_finalize,
gdk_motion_event_get_state,
gdk_motion_event_get_position,
NULL,
gdk_motion_event_get_tool,
gdk_motion_event_get_axes,
};
GDK_DEFINE_EVENT_TYPE (GdkMotionEvent, gdk_motion_event,
&gdk_motion_event_info,
GDK_EVENT_TYPE_SLOT (GDK_MOTION_NOTIFY))
GdkEvent *
gdk_motion_event_new (GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
GdkDeviceTool *tool,
guint32 time,
GdkModifierType state,
double x,
double y,
double *axes)
{
GdkMotionEvent *self = gdk_event_alloc (GDK_MOTION_NOTIFY, surface, device, source_device, time);
self->tool = tool ? g_object_ref (tool) : NULL;
self->state = state;
self->x = x;
self->y = y;
self->axes = axes;
self->state = state;
return (GdkEvent *) self;
}
/**
* gdk_event_get_history:
* @event: a motion or scroll #GdkEvent
* @out_n_coords: (out): Return location for the length of the returned array
*
* Retrieves the history of the @event, as a list of time and coordinates.
*
* The history includes events that are not delivered to the application
* because they occurred in the same frame as @event.
*
* Note that only motion and scroll events record history, and motion
* events only if one of the mouse buttons is down.
*
* Returns: (transfer container) (array length=out_n_coords) (nullable): an
* array of time and coordinates
*/
GdkTimeCoord *
gdk_event_get_history (GdkEvent *event,
guint *out_n_coords)
{
GArray *history;
g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY) ||
GDK_IS_EVENT_TYPE (event, GDK_SCROLL), NULL);
g_return_val_if_fail (out_n_coords != NULL, NULL);
if (GDK_IS_EVENT_TYPE (event, GDK_MOTION_NOTIFY))
{
GdkMotionEvent *self = (GdkMotionEvent *) event;
history = self->history;
}
else
{
GdkScrollEvent *self = (GdkScrollEvent *) event;
history = self->history;
}
if (history && history->len > 0)
{
GdkTimeCoord *result;
*out_n_coords = history->len;
result = g_malloc (sizeof (GdkTimeCoord) * history->len);
memcpy (result, history->data, sizeof (GdkTimeCoord) * history->len);
return result;
}
*out_n_coords = 0;
return NULL;
}
/* }}} */
/* {{{ GdkProximityEvent */
static void
gdk_proximity_event_finalize (GdkEvent *event)
{
GdkProximityEvent *self = (GdkProximityEvent *) event;
g_clear_object (&self->tool);
GDK_EVENT_SUPER (event)->finalize (event);
}
static GdkDeviceTool *
gdk_proximity_event_get_tool (GdkEvent *event)
{
GdkProximityEvent *self = (GdkProximityEvent *) event;
return self->tool;
}
static const GdkEventTypeInfo gdk_proximity_event_info = {
sizeof (GdkProximityEvent),
NULL,
gdk_proximity_event_finalize,
NULL,
NULL,
NULL,
gdk_proximity_event_get_tool,
NULL,
};
GDK_DEFINE_EVENT_TYPE (GdkProximityEvent, gdk_proximity_event,
&gdk_proximity_event_info,
GDK_EVENT_TYPE_SLOT (GDK_PROXIMITY_IN)
GDK_EVENT_TYPE_SLOT (GDK_PROXIMITY_OUT))
GdkEvent *
gdk_proximity_event_new (GdkEventType type,
GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
GdkDeviceTool *tool,
guint32 time)
{
GdkProximityEvent *self;
g_return_val_if_fail (type == GDK_PROXIMITY_IN ||
type == GDK_PROXIMITY_OUT, NULL);
self = gdk_event_alloc (type, surface, device, source_device, time);
self->tool = tool ? g_object_ref (tool) : NULL;
return (GdkEvent *) self;
}
/* }}} */
/* {{{ GdkDNDEvent */
static void
gdk_dnd_event_finalize (GdkEvent *event)
{
GdkDNDEvent *self = (GdkDNDEvent *) event;
g_clear_object (&self->drop);
GDK_EVENT_SUPER (event)->finalize (event);
}
static gboolean
gdk_dnd_event_get_position (GdkEvent *event,
double *x,
double *y)
{
GdkDNDEvent *self = (GdkDNDEvent *) event;
*x = self->x;
*y = self->y;
return TRUE;
}
static GdkEventSequence *
gdk_dnd_event_get_sequence (GdkEvent *event)
{
GdkDNDEvent *self = (GdkDNDEvent *) event;
return (GdkEventSequence *) self->drop;
}
static const GdkEventTypeInfo gdk_dnd_event_info = {
sizeof (GdkDNDEvent),
NULL,
gdk_dnd_event_finalize,
NULL,
gdk_dnd_event_get_position,
gdk_dnd_event_get_sequence,
NULL,
NULL,
};
GDK_DEFINE_EVENT_TYPE (GdkDNDEvent, gdk_dnd_event,
&gdk_dnd_event_info,
GDK_EVENT_TYPE_SLOT (GDK_DRAG_ENTER)
GDK_EVENT_TYPE_SLOT (GDK_DRAG_MOTION)
GDK_EVENT_TYPE_SLOT (GDK_DRAG_LEAVE)
GDK_EVENT_TYPE_SLOT (GDK_DROP_START))
GdkEvent *
gdk_dnd_event_new (GdkEventType type,
GdkSurface *surface,
GdkDevice *device,
GdkDrop *drop,
guint32 time,
double x,
double y)
{
GdkDNDEvent *self;
g_return_val_if_fail (type == GDK_DRAG_ENTER ||
type == GDK_DRAG_MOTION ||
type == GDK_DRAG_LEAVE ||
type == GDK_DROP_START, NULL);
self = gdk_event_alloc (type, surface, device, NULL, time);
self->drop = drop != NULL ? g_object_ref (drop) : NULL;
self->x = x;
self->y = y;
return (GdkEvent *) self;
}
/**
* gdk_dnd_event_get_drop:
* @event: (type GdkDNDEvent): a DND event
*
* Gets the #GdkDrop from a DND event.
*
* Returns: (transfer none) (nullable): the drop
**/
GdkDrop *
gdk_dnd_event_get_drop (GdkEvent *event)
{
GdkDNDEvent *self = (GdkDNDEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_DRAG_ENTER) ||
GDK_IS_EVENT_TYPE (event, GDK_DRAG_MOTION) ||
GDK_IS_EVENT_TYPE (event, GDK_DRAG_LEAVE) ||
GDK_IS_EVENT_TYPE (event, GDK_DROP_START), NULL);
return self->drop;
}
/* }}} */
/* {{{ GdkGrabBrokenEvent */
static const GdkEventTypeInfo gdk_grab_broken_event_info = {
sizeof (GdkGrabBrokenEvent),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
GDK_DEFINE_EVENT_TYPE (GdkGrabBrokenEvent, gdk_grab_broken_event,
&gdk_grab_broken_event_info,
GDK_EVENT_TYPE_SLOT (GDK_GRAB_BROKEN))
GdkEvent *
gdk_grab_broken_event_new (GdkSurface *surface,
GdkDevice *device,
GdkDevice *source_device,
GdkSurface *grab_surface,
gboolean implicit)
{
GdkGrabBrokenEvent *self = gdk_event_alloc (GDK_GRAB_BROKEN, surface, device, source_device, GDK_CURRENT_TIME);
self->grab_surface = grab_surface;
self->implicit = implicit;
self->keyboard = gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD;
return (GdkEvent *) self;
}
/**
* gdk_grab_broken_event_get_grab_surface:
* @event: (type GdkGrabBrokenEvent): a grab broken event
*
* Extracts the grab surface from a grab broken event.
*
* Returns: (transfer none): the grab surface of @event
**/
GdkSurface *
gdk_grab_broken_event_get_grab_surface (GdkEvent *event)
{
GdkGrabBrokenEvent *self = (GdkGrabBrokenEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), NULL);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_GRAB_BROKEN), NULL);
return self->grab_surface;
}
/**
* gdk_grab_broken_event_get_implicit:
* @event: (type GdkGrabBrokenEvent): a grab broken event
*
* Checks whether the grab broken event is for an implicit grab.
*
* Returns: %TRUE if the an implicit grab was broken
*/
gboolean
gdk_grab_broken_event_get_implicit (GdkEvent *event)
{
GdkGrabBrokenEvent *self = (GdkGrabBrokenEvent *) event;
g_return_val_if_fail (GDK_IS_EVENT (event), FALSE);
g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_GRAB_BROKEN), FALSE);
return self->implicit;
}
/* }}} */