mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-26 07:11:34 -08:00
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.
This commit is contained in:
parent
c9c1b436ae
commit
b39f1f158b
6 changed files with 117 additions and 5 deletions
|
|
@ -6878,6 +6878,21 @@ This function returns the current setting of @var{xwidget}s
|
|||
query-on-exit flag, either @code{t} or @code{nil}.
|
||||
@end defun
|
||||
|
||||
@defun xwidget-perform-lispy-event xwidget event frame
|
||||
Send an input event @var{event} to @var{xwidget}. The precise action
|
||||
performed is platform-specific. See @ref{Input Events}.
|
||||
|
||||
You can optionally pass the frame the event was generated from via
|
||||
@var{frame}. On X11, modifier keys in key events will not be
|
||||
considered if @var{frame} is @code{nil}, and the selected frame is not
|
||||
an X-Windows frame.
|
||||
|
||||
On GTK, only keyboard and function key events are implemented. Mouse,
|
||||
motion, and click events are dispatched to the xwidget without going
|
||||
through Lisp code, and as such shouldn't require this function to be
|
||||
sent.
|
||||
@end defun
|
||||
|
||||
@node Buttons
|
||||
@section Buttons
|
||||
@cindex buttons in buffers
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue