/* 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 */