summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/xterm.c32
-rw-r--r--src/xwidget.c113
-rw-r--r--src/xwidget.h6
3 files changed, 151 insertions, 0 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 6a35b11d054..b78cfa70531 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -9927,6 +9927,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
x_display_set_last_user_time (dpyinfo, xi_event->time);
+#ifdef HAVE_XWIDGETS
+ struct xwidget_view *xv = xwidget_view_from_window (xev->event);
+ double xv_total_x = 0.0;
+ double xv_total_y = 0.0;
+#endif
+
for (int i = 0; i < states->mask_len * 8; i++)
{
if (XIMaskIsSet (states->mask, i))
@@ -9939,6 +9945,18 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (delta != DBL_MAX)
{
+#ifdef HAVE_XWIDGETS
+ if (xv)
+ {
+ if (val->horizontal)
+ xv_total_x += delta;
+ else
+ xv_total_y += -delta;
+
+ found_valuator = true;
+ continue;
+ }
+#endif
if (!f)
{
f = x_any_window_to_frame (dpyinfo, xev->event);
@@ -9999,6 +10017,20 @@ handle_one_xevent (struct x_display_info *dpyinfo,
inev.ie.kind = NO_EVENT;
}
+#ifdef HAVE_XWIDGETS
+ if (xv)
+ {
+ if (found_valuator)
+ xwidget_scroll (xv, xev->event_x, xev->event_y,
+ xv_total_x, xv_total_y, xev->mods.effective,
+ xev->time);
+ else
+ xwidget_motion_notify (xv, xev->event_x, xev->event_y,
+ xev->mods.effective, xev->time);
+
+ goto XI_OTHER;
+ }
+#endif
if (found_valuator)
goto XI_OTHER;
diff --git a/src/xwidget.c b/src/xwidget.c
index 1ab953d3c82..35e359458bc 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -40,10 +40,15 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <JavaScriptCore/JavaScript.h>
#include <cairo.h>
#include <X11/Xlib.h>
+#ifdef HAVE_XINPUT2
+#include <X11/extensions/XInput2.h>
+#endif
#elif defined NS_IMPL_COCOA
#include "nsxwidget.h"
#endif
+#include <math.h>
+
static Lisp_Object id_to_xwidget_map;
static Lisp_Object internal_xwidget_view_list;
static Lisp_Object internal_xwidget_list;
@@ -912,7 +917,12 @@ xwidget_button (struct xwidget_view *view,
if (button < 4 || button > 8)
xwidget_button_1 (view, down_p, x, y, button, modifier_state, time);
+#ifndef HAVE_XINPUT2
else
+#else
+ else if (!FRAME_DISPLAY_INFO (view->frame)->supports_xi2
+ || FRAME_DISPLAY_INFO (view->frame)->xi2_version < 1)
+#endif
{
GdkEvent *xg_event = gdk_event_new (GDK_SCROLL);
struct xwidget *model = XXWIDGET (view->model);
@@ -955,6 +965,93 @@ xwidget_button (struct xwidget_view *view,
}
}
+#ifdef HAVE_XINPUT2
+void
+xwidget_motion_notify (struct xwidget_view *view,
+ double x, double y, uint state, Time time)
+{
+ GdkEvent *xg_event;
+ GtkWidget *target;
+ struct xwidget *model = XXWIDGET (view->model);
+ int target_x, target_y;
+
+ if (NILP (model->buffer))
+ return;
+
+ record_osr_embedder (view);
+
+ target = find_widget_at_pos (model->widgetwindow_osr,
+ lrint (x), lrint (y),
+ &target_x, &target_y);
+
+ if (!target)
+ {
+ target_x = lrint (x);
+ target_y = lrint (y);
+ target = model->widget_osr;
+ }
+
+ xg_event = gdk_event_new (GDK_MOTION_NOTIFY);
+ xg_event->any.window = gtk_widget_get_window (target);
+ xg_event->motion.x = target_x;
+ xg_event->motion.y = target_y;
+ xg_event->motion.x_root = lrint (x);
+ xg_event->motion.y_root = lrint (y);
+ xg_event->motion.time = time;
+ xg_event->motion.state = state;
+ xg_event->motion.device = find_suitable_pointer (view->frame);
+
+ g_object_ref (xg_event->any.window);
+
+ gtk_main_do_event (xg_event);
+ gdk_event_free (xg_event);
+}
+
+void
+xwidget_scroll (struct xwidget_view *view, double x, double y,
+ double dx, double dy, uint state, Time time)
+{
+ GdkEvent *xg_event;
+ GtkWidget *target;
+ struct xwidget *model = XXWIDGET (view->model);
+ int target_x, target_y;
+
+ if (NILP (model->buffer))
+ return;
+
+ record_osr_embedder (view);
+
+ target = find_widget_at_pos (model->widgetwindow_osr,
+ lrint (x), lrint (y),
+ &target_x, &target_y);
+
+ if (!target)
+ {
+ target_x = lrint (x);
+ target_y = lrint (y);
+ target = model->widget_osr;
+ }
+
+ xg_event = gdk_event_new (GDK_SCROLL);
+ xg_event->any.window = gtk_widget_get_window (target);
+ xg_event->scroll.direction = GDK_SCROLL_SMOOTH;
+ xg_event->scroll.x = target_x;
+ xg_event->scroll.y = target_y;
+ xg_event->scroll.x_root = lrint (x);
+ xg_event->scroll.y_root = lrint (y);
+ xg_event->scroll.time = time;
+ xg_event->scroll.state = state;
+ xg_event->scroll.delta_x = dx;
+ xg_event->scroll.delta_y = dy;
+ xg_event->scroll.device = find_suitable_pointer (view->frame);
+
+ g_object_ref (xg_event->any.window);
+
+ gtk_main_do_event (xg_event);
+ gdk_event_free (xg_event);
+}
+#endif
+
void
xwidget_motion_or_crossing (struct xwidget_view *view, const XEvent *event)
{
@@ -1705,6 +1802,22 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
clip_bottom - clip_top, 0,
CopyFromParent, CopyFromParent,
CopyFromParent, CWEventMask, &a);
+#ifdef HAVE_XINPUT2
+ XIEventMask mask;
+ ptrdiff_t l = XIMaskLen (XI_LASTEVENT);
+ unsigned char *m;
+
+ if (FRAME_DISPLAY_INFO (s->f)->supports_xi2)
+ {
+ mask.mask = m = alloca (l);
+ memset (m, 0, l);
+ mask.mask_len = l;
+ mask.deviceid = XIAllMasterDevices;
+
+ XISetMask (m, XI_Motion);
+ XISelectEvents (xv->dpy, xv->wdesc, &mask, 1);
+ }
+#endif
XLowerWindow (xv->dpy, xv->wdesc);
XDefineCursor (xv->dpy, xv->wdesc, xv->cursor);
xv->cr_surface = cairo_xlib_surface_create (xv->dpy,
diff --git a/src/xwidget.h b/src/xwidget.h
index 78fe865dd84..f2d497c0920 100644
--- a/src/xwidget.h
+++ b/src/xwidget.h
@@ -195,6 +195,12 @@ extern void xwidget_button (struct xwidget_view *, bool, int,
int, int, int, Time);
extern void xwidget_motion_or_crossing (struct xwidget_view *,
const XEvent *);
+#ifdef HAVE_XINPUT2
+extern void xwidget_motion_notify (struct xwidget_view *, double,
+ double, uint, Time);
+extern void xwidget_scroll (struct xwidget_view *, double, double,
+ double, double, uint, Time);
+#endif
#endif
#else
INLINE_HEADER_BEGIN