summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2021-11-04 18:51:28 +0800
committerLars Ingebrigtsen <larsi@gnus.org>2021-11-07 02:59:40 +0100
commitb39f1f158ba38d9db43fc714cf3041125ec0fa8a (patch)
tree70b3ea84ed72f137e60fd78f43fd87d59a32993b /src
parentc9c1b436ae638cc7f54e203674c61a9a2633d4ec (diff)
Implement function for sending events to widgets
* doc/lispref/display.texi (Xwidgets): Document changes. * src/keyboard.c (lispy_function_keys): Make non-static on X. * src/keyboard.h (lispy_function_keys): Expose lispy_function_keys on X. * src/xterm.c (x_emacs_to_x_modifiers): Export function. * src/xterm.h (x_emacs_to_x_modifiers): Likewise. * src/xwidget.c (Fxwidget_perform_lispy_event) (find_suitable_keyboard): New functions. (syms_of_xwidget): Define new subr.
Diffstat (limited to 'src')
-rw-r--r--src/keyboard.c2
-rw-r--r--src/keyboard.h2
-rw-r--r--src/xterm.c4
-rw-r--r--src/xterm.h1
-rw-r--r--src/xwidget.c98
5 files changed, 102 insertions, 5 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index aa6a4b9e976..46dce5755a8 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4897,7 +4897,7 @@ static const char *const lispy_kana_keys[] =
/* You'll notice that this table is arranged to be conveniently
indexed by X Windows keysym values. */
-static const char *const lispy_function_keys[] =
+const char *const lispy_function_keys[] =
{
/* X Keysym value */
diff --git a/src/keyboard.h b/src/keyboard.h
index 8bdffaa2bff..21c51ec3862 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -491,7 +491,7 @@ extern void process_pending_signals (void);
extern struct timespec timer_check (void);
extern void mark_kboards (void);
-#ifdef HAVE_NTGUI
+#if defined HAVE_NTGUI || defined HAVE_X_WINDOWS
extern const char *const lispy_function_keys[];
#endif
diff --git a/src/xterm.c b/src/xterm.c
index 12dad6ae806..fa7dd9b9ca0 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -5087,7 +5087,7 @@ x_x_to_emacs_modifiers (struct x_display_info *dpyinfo, int state)
| ((state & dpyinfo->hyper_mod_mask) ? mod_hyper : 0));
}
-static int
+int
x_emacs_to_x_modifiers (struct x_display_info *dpyinfo, intmax_t state)
{
EMACS_INT mod_ctrl = ctrl_modifier;
@@ -9278,7 +9278,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
event->xbutton.x, event->xbutton.y,
event->xbutton.button, event->xbutton.state,
event->xbutton.time);
-
+ goto OTHER;
}
#endif
/* If we decide we want to generate an event to be seen
diff --git a/src/xterm.h b/src/xterm.h
index de6ea50385d..9d9534dd629 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1108,6 +1108,7 @@ extern void x_mouse_leave (struct x_display_info *);
extern int x_dispatch_event (XEvent *, Display *);
#endif
extern int x_x_to_emacs_modifiers (struct x_display_info *, int);
+extern int x_emacs_to_x_modifiers (struct x_display_info *, intmax_t);
#ifdef USE_CAIRO
extern void x_cr_destroy_frame_context (struct frame *);
extern void x_cr_update_surface_desired_size (struct frame *, int, int);
diff --git a/src/xwidget.c b/src/xwidget.c
index 5a4cb36ee47..ff7d09549bf 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -47,7 +47,8 @@ static uint32_t xwidget_counter = 0;
#ifdef USE_GTK
static Lisp_Object x_window_to_xwv_map;
static gboolean offscreen_damage_event (GtkWidget *, GdkEvent *, gpointer);
-static void synthesize_focus_in_event (GtkWidget *offscreen_window);
+static void synthesize_focus_in_event (GtkWidget *);
+static GdkDevice *find_suitable_keyboard (struct frame *);
#endif
static struct xwidget *
@@ -208,6 +209,88 @@ Returns the newly constructed xwidget, or nil if construction fails. */)
return val;
}
+DEFUN ("xwidget-perform-lispy-event",
+ Fxwidget_perform_lispy_event, Sxwidget_perform_lispy_event,
+ 2, 3, 0, doc: /* Send a lispy event to XWIDGET.
+EVENT should be the event that will be sent. FRAME should be the
+frame which generated the event, or nil. On X11, modifier keys will
+not be processed if FRAME is nil and the selected frame is not an
+X-Windows frame. */)
+ (Lisp_Object xwidget, Lisp_Object event, Lisp_Object frame)
+{
+ struct xwidget *xw;
+ struct frame *f = NULL;
+ int character = -1, keycode = -1;
+ int modifiers = 0;
+ GdkEvent *xg_event;
+
+ CHECK_XWIDGET (xwidget);
+ xw = XXWIDGET (xwidget);
+
+ if (!NILP (frame))
+ f = decode_window_system_frame (frame);
+ else if (FRAME_X_P (SELECTED_FRAME ()))
+ f = SELECTED_FRAME ();
+
+#ifdef USE_GTK
+ if (RANGED_FIXNUMP (0, event, INT_MAX))
+ {
+ character = XFIXNUM (event);
+ modifiers = x_emacs_to_x_modifiers (FRAME_DISPLAY_INFO (f), character);
+ }
+ else if (SYMBOLP (event))
+ {
+ Lisp_Object decoded = parse_modifiers (event);
+ Lisp_Object decoded_name = SYMBOL_NAME (XCAR (decoded));
+ int off = 0;
+ bool found = false;
+
+ while (off < 256)
+ {
+ puts (SSDATA (decoded_name));
+ if (lispy_function_keys[off]
+ && !strcmp (lispy_function_keys[off],
+ SSDATA (decoded_name)))
+ {
+ found = true;
+ break;
+ }
+ ++off;
+ }
+
+ if (found)
+ keycode = off + 0xff00;
+ }
+
+ if (character == -1 && keycode == -1)
+ return Qnil;
+
+ block_input ();
+ xg_event = gdk_event_new (GDK_KEY_PRESS);
+ xg_event->any.window = gtk_widget_get_window (xw->widget_osr);
+ g_object_ref (xg_event->any.window);
+
+ if (character > -1)
+ xg_event->key.keyval = gdk_unicode_to_keyval (character & ~(1 << 21));
+ else if (keycode > -1)
+ xg_event->key.keyval = keycode;
+
+ xg_event->key.state = modifiers;
+
+ if (f)
+ gdk_event_set_device (xg_event,
+ find_suitable_keyboard (SELECTED_FRAME ()));
+
+ gtk_main_do_event (xg_event);
+ xg_event->type = GDK_KEY_RELEASE;
+ gtk_main_do_event (xg_event);
+ gdk_event_free (xg_event);
+ unblock_input ();
+#endif
+
+ return Qnil;
+}
+
DEFUN ("get-buffer-xwidgets", Fget_buffer_xwidgets, Sget_buffer_xwidgets,
1, 1, 0,
doc: /* Return a list of xwidgets associated with BUFFER.
@@ -265,6 +348,18 @@ find_suitable_pointer (struct frame *f)
return gdk_seat_get_pointer (seat);
}
+static GdkDevice *
+find_suitable_keyboard (struct frame *f)
+{
+ GdkSeat *seat = gdk_display_get_default_seat
+ (gtk_widget_get_display (FRAME_GTK_WIDGET (f)));
+
+ if (!seat)
+ return NULL;
+
+ return gdk_seat_get_keyboard (seat);
+}
+
static void
xwidget_button_1 (struct xwidget_view *view,
bool down_p, int x, int y, int button,
@@ -1382,6 +1477,7 @@ syms_of_xwidget (void)
defsubr (&Sxwidget_plist);
defsubr (&Sxwidget_buffer);
defsubr (&Sset_xwidget_plist);
+ defsubr (&Sxwidget_perform_lispy_event);
DEFSYM (QCxwidget, ":xwidget");
DEFSYM (QCtitle, ":title");