----- Original Message ----- > Note: This is an ugly hack because there is currently no clean way to do it. > > But experiments showed that the X11 agent is the wrong place to do such > things, because it is started to late (after login). That should not be a big problem, the greeter should run an agent too. I don't think XTest is the best way to inject keysyms. Afaik, it's also quite insecure. I would rather rely on im/at framework, such as ibus or at-spi, but I haven't done enough research. > Future: Maybe it is possible to extent the linux uinput framework for that > purpose? I wouldn't count on that possibility. > > Index: new/src/vdagent.c > =================================================================== > --- new.orig/src/vdagent.c 2013-10-14 14:52:01.000000000 +0200 > +++ new/src/vdagent.c 2013-10-15 12:32:42.000000000 +0200 > @@ -57,6 +57,12 @@ > struct udscs_message_header *header, uint8_t *data) > { > switch (header->type) { > + case VDAGENTD_KEYSYM_MESSAGE: { > + VDAgentKeySym *info = (VDAgentKeySym *)data; > + vdagent_x11_send_keysym(x11, info->keysym, info->flags); > + free(data); > + break; > + } > case VDAGENTD_MONITORS_CONFIG: > vdagent_x11_set_monitor_config(x11, (VDAgentMonitorsConfig *)data, > 0); > free(data); > Index: new/src/vdagentd.c > =================================================================== > --- new.orig/src/vdagentd.c 2013-10-14 14:52:01.000000000 +0200 > +++ new/src/vdagentd.c 2013-10-15 12:34:34.000000000 +0200 > @@ -98,6 +98,7 @@ > VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_SELECTION); > VD_AGENT_SET_CAPABILITY(caps->caps, > VD_AGENT_CAP_SPARSE_MONITORS_CONFIG); > VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_GUEST_LINEEND_LF); > + VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_KEYSYM); > > vdagent_virtio_port_write(vport, VDP_CLIENT_PORT, > VD_AGENT_ANNOUNCE_CAPABILITIES, 0, > @@ -232,6 +233,20 @@ > data, size); > } > > +static void do_client_keysym(struct vdagent_virtio_port *vport, > + VDAgentMessage *message_header, uint8_t *data) > +{ > + if (!active_session_conn) { > + syslog(LOG_WARNING, > + "Could not find an agent connection belonging to the " > + "active session, ignoring client keysym request"); > + return; > + } > + > + udscs_write(active_session_conn, VDAGENTD_KEYSYM_MESSAGE, 0, 0, > + data, message_header->size); > +} > + > static void cancel_file_xfer(struct vdagent_virtio_port *vport, > const char *msg, uint32_t id) > { > @@ -304,6 +319,10 @@ > } > > switch (message_header->type) { > + case VD_AGENT_KEYSYM_MESSAGE: { > + do_client_keysym(vport, message_header, data); > + break; > + } > case VD_AGENT_MOUSE_STATE: > if (message_header->size != sizeof(VDAgentMouseState)) > goto size_error; > Index: new/src/vdagentd-proto.h > =================================================================== > --- new.orig/src/vdagentd-proto.h 2013-10-15 07:49:58.000000000 +0200 > +++ new/src/vdagentd-proto.h 2013-10-15 07:50:34.000000000 +0200 > @@ -40,6 +40,7 @@ > VDAGENTD_FILE_XFER_STATUS, > VDAGENTD_FILE_XFER_DATA, > VDAGENTD_CLIENT_DISCONNECTED, /* daemon -> client */ > + VDAGENTD_KEYSYM_MESSAGE, > VDAGENTD_NO_MESSAGES /* Must always be last */ > }; > > Index: new/src/vdagent-x11.c > =================================================================== > --- new.orig/src/vdagent-x11.c 2013-10-14 14:52:01.000000000 +0200 > +++ new/src/vdagent-x11.c 2013-10-15 12:35:32.000000000 +0200 > @@ -111,6 +111,56 @@ > return error; > } > > +void vdagent_x11_send_keysym(struct vdagent_x11 *x11, uint32_t keysym, > uint32_t flags) > +{ > + //syslog(LOG_INFO, "vdagent_x11_send_keysym %08x", keysym); > + > + /* Scratch space for temporary keycode bindings */ > + int scratch_keycode = 84; // use KEY_KPDOT > + int keymap_changed = 0; > + > + static int orig_keysym = 0; > + > + if (orig_keysym == 0) { > + int count = 0; > + KeySym *res = XGetKeyboardMapping(x11->display, scratch_keycode, 1, > &count); > + if (count == 1) { > + orig_keysym = res[0]; > + XFree(res); > + } else { > + orig_keysym = -1; > + } > + } > + > + int kc = XKeysymToKeycode(x11->display, keysym); > + if (kc && ((keysym >= 0xffe1 && keysym <= 0xffee) || > + (keysym >= 0xfe01 && keysym <= 0xfe0f))) { // never remap > Modifiers > + //syslog(LOG_INFO, "use real keycode %d for modifier %08x", kc, > keysym); > + scratch_keycode = kc; > + } else { > + KeySym keysym_list[] = { keysym }; > + keymap_changed = 1; > + XChangeKeyboardMapping(x11->display, scratch_keycode, 1, > keysym_list, 1); > + } > + > + if (flags & VD_AGENT_KEYSYM_FLAG_DOWN) { > + //syslog(LOG_INFO, "vdagent_x11_send_keysym down %08x", keysym); > + XTestFakeKeyEvent(x11->display, scratch_keycode, True, CurrentTime); > + } > + > + if (flags & VD_AGENT_KEYSYM_FLAG_UP) { > + //syslog(LOG_INFO, "vdagent_x11_send_keysym up %08x", keysym); > + XTestFakeKeyEvent(x11->display, scratch_keycode, False, > CurrentTime); > + } > + > + if (keymap_changed && (orig_keysym > 0)) { > + KeySym keysym_list[] = { orig_keysym }; > + XChangeKeyboardMapping(x11->display, scratch_keycode, 1, > keysym_list, 1); > + } > + > + XFlush(x11->display); > +} > + > static void vdagent_x11_get_wm_name(struct vdagent_x11 *x11) > { > Atom type_ret; > Index: new/src/vdagent-x11.h > =================================================================== > --- new.orig/src/vdagent-x11.h 2013-10-14 14:52:01.000000000 +0200 > +++ new/src/vdagent-x11.h 2013-10-15 09:06:44.000000000 +0200 > @@ -50,4 +50,6 @@ > > int vdagent_x11_has_icons_on_desktop(struct vdagent_x11 *x11); > > +void vdagent_x11_send_keysym(struct vdagent_x11 *x11, uint32_t keysmy, > uint32_t flags); > + > #endif > Index: new/Makefile.am > =================================================================== > --- new.orig/Makefile.am 2013-10-14 14:52:01.000000000 +0200 > +++ new/Makefile.am 2013-10-15 09:12:45.000000000 +0200 > @@ -5,7 +5,7 @@ > sbin_PROGRAMS = src/spice-vdagentd > > src_spice_vdagent_CFLAGS = $(X_CFLAGS) $(SPICE_CFLAGS) $(GLIB2_CFLAGS) > -src_spice_vdagent_LDADD = $(X_LIBS) $(SPICE_LIBS) $(GLIB2_LIBS) > +src_spice_vdagent_LDADD = -lXtst $(X_LIBS) $(SPICE_LIBS) $(GLIB2_LIBS) > src_spice_vdagent_SOURCES = src/vdagent.c src/vdagent-x11.c > src/vdagent-x11-randr.c src/vdagent-file-xfers.c src/udscs.c > > src_spice_vdagentd_CFLAGS = $(DBUS_CFLAGS) $(LIBSYSTEMD_LOGIN_CFLAGS) \ > > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/spice-devel > _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel