summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Third <alan@idiocy.org>2017-06-24 09:36:03 +0100
committerAlan Third <alan@idiocy.org>2017-06-25 23:12:50 +0100
commitb39042174d581dadef95cadd6ae28640f5cafc07 (patch)
tree45ae9cc1d511302cb108d52eeef6f2bd4c909cd4
parent1886246f6f40b8c376467f71605141035959cae0 (diff)
downloademacs-b39042174d581dadef95cadd6ae28640f5cafc07.tar.gz
Add touch events
* src/keyboard.c (syms_of_keyboard): Add `Qtouch_gesture' and initialize `touch_syms'. (touch_names): New variable containing touch gesture names. (make_lispy_event): Handle new touch gestures. * src/nsterm.m (EmacsView::mouseDown) [NS_IMPL_COCOA]: Use touch-based scrolling instead of using mousewheel compatibility. (EmacsView::magnifyWithEvent) [NS_IMPL_COCOA]: New function. (EmacsView::swipeWithEvent) [NS_IMPL_COCOA]: New function. (EmacsView::rotateWithEvent) [NS_IMPL_COCOA]: New function. src/termhooks.h (event_kind): New touch event types.
-rw-r--r--src/keyboard.c109
-rw-r--r--src/nsterm.m132
-rw-r--r--src/termhooks.h31
3 files changed, 259 insertions, 13 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 9e90899c569..747776f73dd 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4557,6 +4557,7 @@ static Lisp_Object accent_key_syms;
static Lisp_Object func_key_syms;
static Lisp_Object mouse_syms;
static Lisp_Object wheel_syms;
+static Lisp_Object touch_syms;
static Lisp_Object drag_n_drop_syms;
/* This is a list of keysym codes for special "accent" characters.
@@ -5107,6 +5108,12 @@ static const char *const lispy_wheel_names[] =
"wheel-up", "wheel-down", "wheel-left", "wheel-right"
};
+static const char *const touch_names[] =
+{
+ "touch-scroll", "touch-pinch", "touch-rotate", "touch-swipe-up",
+ "touch-swipe-down", "touch-swipe-left", "touch-swipe-right"
+};
+
/* drag-n-drop events are generated when a set of selected files are
dragged from another application and dropped onto an Emacs window. */
static const char *const lispy_drag_n_drop_names[] =
@@ -6025,6 +6032,105 @@ make_lispy_event (struct input_event *event)
return list3 (head, position, files);
}
+ case TOUCH_SCROLL_EVENT:
+ {
+ Lisp_Object position;
+ Lisp_Object head;
+ Lisp_Object deltas = event->arg;
+ struct frame *f = XFRAME (event->frame_or_window);
+
+ /* Ignore touch events that were made on frame that have
+ been deleted. */
+ if (! FRAME_LIVE_P (f))
+ return Qnil;
+
+ position = make_lispy_position (f, event->x, event->y,
+ event->timestamp);
+
+ head = modify_event_symbol (0, event->modifiers, Qtouch_gesture, Qnil,
+ touch_names, &touch_syms, ASIZE (touch_syms));
+
+ return list3 (head, position, deltas);
+ }
+
+ case TOUCH_PINCH_EVENT:
+ {
+ Lisp_Object position;
+ Lisp_Object head;
+ Lisp_Object delta = event->arg;
+ struct frame *f = XFRAME (event->frame_or_window);
+
+ /* Ignore touch events that were made on frame that have
+ been deleted. */
+ if (! FRAME_LIVE_P (f))
+ return Qnil;
+
+ position = make_lispy_position (f, event->x, event->y,
+ event->timestamp);
+
+ head = modify_event_symbol (1, event->modifiers, Qtouch_gesture, Qnil,
+ touch_names, &touch_syms, ASIZE (touch_syms));
+
+ return list3 (head, position, delta);
+ }
+
+ case TOUCH_SWIPE_UP_EVENT:
+ case TOUCH_SWIPE_DOWN_EVENT:
+ case TOUCH_SWIPE_LEFT_EVENT:
+ case TOUCH_SWIPE_RIGHT_EVENT:
+ {
+ Lisp_Object position;
+ Lisp_Object head;
+ struct frame *f = XFRAME (event->frame_or_window);
+ int symbol_num;
+
+ /* Ignore touch events that were made on frame that have
+ been deleted. */
+ if (! FRAME_LIVE_P (f))
+ return Qnil;
+
+ position = make_lispy_position (f, event->x, event->y,
+ event->timestamp);
+
+ switch (event->kind)
+ {
+ case TOUCH_SWIPE_UP_EVENT:
+ symbol_num = 3;
+ case TOUCH_SWIPE_DOWN_EVENT:
+ symbol_num = 4;
+ case TOUCH_SWIPE_LEFT_EVENT:
+ symbol_num = 5;
+ case TOUCH_SWIPE_RIGHT_EVENT:
+ symbol_num = 6;
+ }
+
+ head = modify_event_symbol (symbol_num, event->modifiers, Qtouch_gesture, Qnil,
+ touch_names, &touch_syms, ASIZE (touch_syms));
+
+ return list2 (head, position);
+ }
+
+ case TOUCH_ROTATE_EVENT:
+ {
+ Lisp_Object position;
+ Lisp_Object head;
+ Lisp_Object rotation = event->arg;
+ struct frame *f = XFRAME (event->frame_or_window);
+
+ /* Ignore touch events that were made on frame that have
+ been deleted. */
+ if (! FRAME_LIVE_P (f))
+ return Qnil;
+
+ position = make_lispy_position (f, event->x, event->y,
+ event->timestamp);
+
+ head = modify_event_symbol (2, event->modifiers, Qtouch_gesture, Qnil,
+ touch_names, &touch_syms, ASIZE (touch_syms));
+
+ return list3 (head, position, rotation);
+ }
+
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|| defined (HAVE_NS) || defined (USE_GTK)
case MENU_BAR_EVENT:
@@ -11079,6 +11185,7 @@ syms_of_keyboard (void)
/* The values of Qevent_kind properties. */
DEFSYM (Qmouse_click, "mouse-click");
+ DEFSYM (Qtouch_gesture, "touch-gesture");
DEFSYM (Qdrag_n_drop, "drag-n-drop");
DEFSYM (Qsave_session, "save-session");
@@ -11227,6 +11334,8 @@ syms_of_keyboard (void)
wheel_syms = Fmake_vector (make_number (ARRAYELTS (lispy_wheel_names)),
Qnil);
staticpro (&wheel_syms);
+ touch_syms = Fmake_vector (make_number (7), Qnil);
+ staticpro (&touch_syms);
{
int i;
diff --git a/src/nsterm.m b/src/nsterm.m
index e05dbf45fbc..f9710d573d6 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -6374,24 +6374,41 @@ not_in_argv (NSString *arg)
if ([theEvent type] == NSEventTypeScrollWheel)
{
- CGFloat delta = [theEvent deltaY];
- /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */
- if (delta == 0)
+#ifdef NS_IMPL_COCOA
+ if ([theEvent respondsToSelector: @selector(hasPreciseScrollingDeltas)]
+ && [theEvent hasPreciseScrollingDeltas])
+ {
+ Lisp_Object dx, dy;
+ dx = make_float ([theEvent scrollingDeltaX]);
+ dy = make_float ([theEvent scrollingDeltaY]);
+
+ emacs_event->kind = TOUCH_SCROLL_EVENT;
+ emacs_event->arg = list2 (dx, dy);
+ }
+ else
{
- delta = [theEvent deltaX];
+#endif
+ CGFloat delta = [theEvent deltaY];
+ /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */
if (delta == 0)
{
- NSTRACE_MSG ("deltaIsZero");
- return;
+ delta = [theEvent deltaX];
+ if (delta == 0)
+ {
+ NSTRACE_MSG ("deltaIsZero");
+ return;
+ }
+ emacs_event->kind = HORIZ_WHEEL_EVENT;
}
- emacs_event->kind = HORIZ_WHEEL_EVENT;
- }
- else
- emacs_event->kind = WHEEL_EVENT;
+ else
+ emacs_event->kind = WHEEL_EVENT;
- emacs_event->code = 0;
- emacs_event->modifiers = EV_MODIFIERS (theEvent) |
- ((delta > 0) ? up_modifier : down_modifier);
+ emacs_event->code = 0;
+ emacs_event->modifiers = EV_MODIFIERS (theEvent) |
+ ((delta > 0) ? up_modifier : down_modifier);
+#ifdef NS_IMPL_COCOA
+ }
+#endif
}
else
{
@@ -6537,6 +6554,95 @@ not_in_argv (NSString *arg)
}
+#ifdef NS_IMPL_COCOA
+/* GNUstep doesn't support touch gestures yet. */
+
+- (void)magnifyWithEvent: (NSEvent *) e
+{
+ struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe);
+ NSPoint p = [self convertPoint: [e locationInWindow] fromView: nil];
+ Lisp_Object delta;
+
+ NSTRACE ("[EmacsView magnifyWithEvent:]");
+
+ [self deleteWorkingText];
+
+ if (!emacs_event)
+ return;
+
+ dpyinfo->last_mouse_frame = emacsframe;
+
+ delta = make_float ([e magnification] * 25);
+
+ emacs_event->kind = TOUCH_PINCH_EVENT;
+ emacs_event->arg = delta;
+ emacs_event->modifiers = EV_MODIFIERS (e)
+ | EV_UDMODIFIERS (e);
+
+ XSETINT (emacs_event->x, lrint (p.x));
+ XSETINT (emacs_event->y, lrint (p.y));
+ EV_TRAILER (e);
+}
+
+
+- (void)swipeWithEvent: (NSEvent *) e
+{
+ struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe);
+ NSPoint p = [self convertPoint: [e locationInWindow] fromView: nil];
+ CGFloat dx = [e deltaX];
+ CGFloat dy = [e deltaY];
+
+ NSTRACE ("[EmacsView swipeWithEvent:]");
+
+ [self deleteWorkingText];
+
+ if (!emacs_event)
+ return;
+
+ dpyinfo->last_mouse_frame = emacsframe;
+
+ if (dx != 0)
+ emacs_event->kind = (dx > 0) ? TOUCH_SWIPE_LEFT_EVENT : TOUCH_SWIPE_RIGHT_EVENT;
+ else if (dy != 0)
+ emacs_event->kind = (dy > 0) ? TOUCH_SWIPE_UP_EVENT : TOUCH_SWIPE_DOWN_EVENT;
+ else
+ return; /* No swipe direction detected. */
+
+ emacs_event->modifiers = EV_MODIFIERS (e)
+ | EV_UDMODIFIERS (e);
+
+ XSETINT (emacs_event->x, lrint (p.x));
+ XSETINT (emacs_event->y, lrint (p.y));
+ EV_TRAILER (e);
+}
+
+
+- (void)rotateWithEvent: (NSEvent *) e
+{
+ struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe);
+ NSPoint p = [self convertPoint: [e locationInWindow] fromView: nil];
+
+ NSTRACE ("[EmacsView rotateWithEvent:]");
+
+ [self deleteWorkingText];
+
+ if (!emacs_event)
+ return;
+
+ dpyinfo->last_mouse_frame = emacsframe;
+
+ emacs_event->kind = TOUCH_ROTATE_EVENT;
+ emacs_event->arg = make_float([e rotation]);;
+ emacs_event->modifiers = EV_MODIFIERS (e)
+ | EV_UDMODIFIERS (e);
+
+ XSETINT (emacs_event->x, lrint (p.x));
+ XSETINT (emacs_event->y, lrint (p.y));
+ EV_TRAILER (e);
+}
+#endif /* NS_IMPL_COCOA */
+
+
- (BOOL)windowShouldClose: (id)sender
{
NSEvent *e =[[self window] currentEvent];
diff --git a/src/termhooks.h b/src/termhooks.h
index 14ec397346a..08f6884da44 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -120,6 +120,37 @@ enum event_kind
HORIZ_WHEEL_EVENT, /* A wheel event generated by a second
horizontal wheel that is present on some
mice. See WHEEL_EVENT. */
+ TOUCH_SCROLL_EVENT, /* Touch scroll event generated by a
+ touchpad or touch screen.
+ .modifiers holds the state of any
+ modifier keys.
+ .x and .y contain the mouse
+ position.
+ .arg holds a list in the form:
+ (delta-x delta-y). */
+ TOUCH_PINCH_EVENT, /* Touch pinch event generated by a
+ touchpad or touch screen.
+ .modifiers holds the state of any
+ modifier keys.
+ .x and .y contain the mouse
+ position.
+ .arg holds the pinch delta as a float. */
+ TOUCH_ROTATE_EVENT, /* Touch rotate event generated by a
+ touchpad or touch screen.
+ .modifiers holds the state of any
+ modifier keys.
+ .x and .y contain the mouse
+ position.
+ .arg holds the rotation delta as a
+ float. */
+ /* The following four events are touch swipe events generated by a
+ touchpad or touchscreen.
+ .modifiers holds the state of any modifier keys.
+ .x and .y contain the mouse position. */
+ TOUCH_SWIPE_UP_EVENT,
+ TOUCH_SWIPE_DOWN_EVENT,
+ TOUCH_SWIPE_LEFT_EVENT,
+ TOUCH_SWIPE_RIGHT_EVENT,
#ifdef HAVE_NTGUI
LANGUAGE_CHANGE_EVENT, /* A LANGUAGE_CHANGE_EVENT is
generated when HAVE_NTGUI or on Mac OS