/* Event handling for GTK 3 and (in the future) GTK 4 -*- coding: utf-8 -*- Copyright (C) 2020 Free Software Foundation, Inc. This file is part of GNU Emacs. GNU Emacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GNU Emacs 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 General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . */ #ifndef __PGTK_EVENT_H #define __PGTK_EVENT_H #include "config.h" #include "gtkconfig.h" #include G_BEGIN_DECLS #if !defined (HAVE_GTK4) || defined (FIX_GTK_LEGACY_CONTROLLER_BUG) /* ATTENTION * * If Emacs fails to compile, or throws weird * errors during runtime, make sure to update * this section with the contents of gtkeventcontrollerprivate.h * from the GTK version you're using */ #ifndef HAVE_GTK4 struct _GtkEventController { GObject parent_instance; }; struct _GtkEventControllerClass { GObjectClass parent_class; void (* set_widget) (GtkEventController *controller, GtkWidget *widget); void (* unset_widget) (GtkEventController *controller); gboolean (* handle_event) (GtkEventController *controller, const GdkEvent *event); void (* reset) (GtkEventController *controller); /**/ /* Tells whether the event is filtered out, %TRUE makes * the event unseen by the handle_event vfunc. */ gboolean (* filter_event) (GtkEventController *controller, const GdkEvent *event); gpointer padding[10]; }; #else typedef enum { GTK_CROSSING_FOCUS, GTK_CROSSING_POINTER, GTK_CROSSING_DROP } GtkCrossingType; typedef enum { GTK_CROSSING_IN, GTK_CROSSING_OUT } GtkCrossingDirection; typedef struct _GtkCrossingData GtkCrossingData; /** * GtkCrossingData: * @type: the type of crossing event * @direction: whether this is a focus-in or focus-out event * @mode: the crossing mode * @old_target: the old target * @old_descendent: the direct child of the receiving widget that * is an ancestor of @old_target, or %NULL if @old_target is not * a descendent of the receiving widget * @new_target: the new target * @new_descendent: the direct child of the receiving widget that * is an ancestor of @new_target, or %NULL if @new_target is not * a descendent of the receiving widget * @drop: the #GdkDrop if this is info for a drop operation * * The struct that is passed to gtk_event_controller_handle_crossing(). * * The @old_target and @new_target fields are set to the old or new * focus, drop or hover location. */ struct _GtkCrossingData { GtkCrossingType type; GtkCrossingDirection direction; GdkCrossingMode mode; GtkWidget *old_target; GtkWidget *old_descendent; GtkWidget *new_target; GtkWidget *new_descendent; GdkDrop *drop; }; struct _GtkEventController { GObject parent_instance; }; struct _GtkEventControllerClass { GObjectClass parent_class; void (* set_widget) (GtkEventController *controller, GtkWidget *widget); void (* unset_widget) (GtkEventController *controller); gboolean (* handle_event) (GtkEventController *controller, GdkEvent *event, double x, double y); void (* reset) (GtkEventController *controller); void (* handle_crossing) (GtkEventController *controller, const GtkCrossingData *crossing, double x, double y); /**/ /* Tells whether the event is filtered out, %TRUE makes * the event unseen by the handle_event vfunc. */ gboolean (* filter_event) (GtkEventController *controller, GdkEvent *event); gpointer padding[10]; }; #endif #endif struct _EmacsGtkEventHandler { #if !defined (HAVE_GTK4) || defined (FIX_GTK_LEGACY_HANDLER_BUG) GtkEventController parent_instance; #else GObject parent_instance; #endif #ifdef HAVE_GTK4 // FIXME stupid hack gchar padding[1280]; #endif GtkWidget *widget; gboolean (*key_down) (GtkWidget *w, GdkEvent *ev, struct frame *frame); gboolean (*key_up) (GtkWidget *w, GdkEvent *ev, struct frame *f); gboolean (*button_down) (GtkWidget *w, GdkEvent *ev, struct frame *f); gboolean (*button_up) (GtkWidget *w, GdkEvent *ev, struct frame *f); gboolean (*window_state_event) (GtkWidget *w, GdkEvent *ev, struct frame *f); gboolean (*delete_event) (GtkWidget *w, GdkEvent *ev, struct frame *f); gboolean (*map_event) (GtkWidget *w, GdkEvent *ev, struct frame *f); gboolean (*size_allocate) (GtkWidget *w, GdkEvent *ev, struct frame *f); #ifndef HAVE_GTK4 gboolean (*scroll_event) (GtkWidget *w, GdkEvent *ev, struct frame *f); #else gboolean (*scroll_event) (GtkEventControllerScroll *widget, gdouble dx, gdouble dy, struct frame *_); gboolean (*long_press_event) (struct frame *f, gdouble ex, gdouble ey); #endif #ifndef HAVE_GTK4 gboolean (*selection_lost) (GtkWidget *w, GdkEventSelection *ev, struct frame *f); #endif gboolean (*configure) (GtkWidget *w, GdkEvent *ev, struct frame *f); #ifndef HAVE_GTK4 gboolean (*expose) (GtkWidget *w, GdkEventExpose *ev, gpointer ignored); #endif gboolean (*focus_in) (GtkWidget *w, GdkEvent *ev, gpointer frame_ptr); gboolean (*focus_out) (GtkWidget *w, GdkEvent *ev, gpointer frame_ptr); #ifdef HAVE_GTK4 gboolean (*enter_notify) (GtkWidget *w, GdkEvent *ev, gpointer frame_ptr); gboolean (*leave_notify) (GtkWidget *w, GdkEvent *ev, gpointer frame_ptr); gboolean (*motion_notify) (GtkWidget *w, GdkEvent *ev, gpointer frame_ptr); void (*enter) (GtkWidget *w, GdkCrossingMode cm, struct frame *f); void (*leave) (GtkWidget *w, GdkCrossingMode cm, struct frame *f); #ifndef FIX_GTK_LEGACY_HANDLER_BUG GtkEventControllerLegacy *legacy; #endif #ifdef HAVE_GTK4 GtkEventControllerScroll *scroll; GtkEventControllerMotion *focus; GtkGesture *drag; GtkGesture *lpress; gdouble dsy, dsx; bool_bf s_flag; bool_bf hq_flag; bool_bf se_blocked; #endif #endif }; #define EMACS_TYPE_GTK_EVENT_HANDLER (emacs_gtk_event_handler_get_type ()) G_DECLARE_FINAL_TYPE (EmacsGtkEventHandler, emacs_gtk_event_handler, EMACS, #if !defined (HAVE_GTK4) || defined (FIX_GTK_LEGACY_HANDLER_BUG) GTK_EVENT_HANDLER #else G_OBJECT #endif , #if !defined (HAVE_GTK4) || defined (FIX_GTK_LEGACY_HANDLER_BUG) GtkEventController #else GObject #endif ) EmacsGtkEventHandler *emacs_gtk_event_handler_new (struct frame *f); void emacs_gtk_event_handler_set_widget (EmacsGtkEventHandler *handler, GtkWidget *w); #ifdef HAVE_GTK4 void emacs_gtk_event_handler_toggle_scroll_evs (EmacsGtkEventHandler *handler, bool enable); #endif G_END_DECLS #endif /* __PGTK_EVENT_H */