You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
remmina/0001_paste_as_keystrokes_fi...

115 lines
5.0 KiB

From eb3d59fbc42ee5e0ee29ee194980b06e49eaed7e Mon Sep 17 00:00:00 2001
From: "Antenore Gatta (tmow)" <antenore@simbiosi.org>
Date: Wed, 1 Jun 2022 12:31:23 +0200
Subject: [PATCH] Fix #2739 - Send clipboard as keystrokes
---
src/rcw.c | 8 ++++++++
src/remmina_protocol_widget.c | 9 +++++++--
src/remmina_public.c | 3 ++-
src/remmina_ssh.c | 2 +-
4 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/src/rcw.c b/src/rcw.c
index d4093d3b4..27eb3bad1 100644
--- a/src/rcw.c
+++ b/src/rcw.c
@@ -2060,6 +2060,14 @@ static void rcw_toolbar_tools(GtkToolItem *toggle, RemminaConnectionWindow *cnnw
g_strfreev(keystroke_values);
}
menuitem = gtk_menu_item_new_with_label(_("Send clipboard content as keystrokes"));
+ static gchar k_tooltip[] =
+ N_("CAUTION! We send hardware codes from your local keyboard,\nmany characters can be different from the original text.\n"
+ "\n"
+ " • To get the best result, set the same keyboard on the client and server.\n"
+ "\n"
+ " • Non composable characters using your keyboard will not be transferred.\n"
+ "\n");
+ gtk_widget_set_tooltip_text(menuitem, k_tooltip);
gtk_menu_shell_append(GTK_MENU_SHELL(submenu_keystrokes), menuitem);
g_signal_connect_swapped(G_OBJECT(menuitem), "activate",
G_CALLBACK(remmina_protocol_widget_send_clipboard),
diff --git a/src/remmina_protocol_widget.c b/src/remmina_protocol_widget.c
index 1c590b0fc..e4adfd2a6 100644
--- a/src/remmina_protocol_widget.c
+++ b/src/remmina_protocol_widget.c
@@ -597,7 +597,7 @@ void remmina_protocol_widget_send_clip_strokes(GtkClipboard *clipboard, const gc
{
TRACE_CALL(__func__);
RemminaProtocolWidget *gp = REMMINA_PROTOCOL_WIDGET(data);
- gchar *text = g_strdup(clip_text);
+ gchar *text = g_utf8_normalize(clip_text, -1, G_NORMALIZE_DEFAULT_COMPOSE);
guint *keyvals;
gint i;
GdkKeymap *keymap = gdk_keymap_get_for_display(gdk_display_get_default());
@@ -634,18 +634,22 @@ void remmina_protocol_widget_send_clip_strokes(GtkClipboard *clipboard, const gc
REMMINA_DEBUG("Text clipboard after replacement is \'%s\'", text);
}
gchar *iter = g_strdup(text);
+ REMMINA_DEBUG("Iter: %s", iter),
keyvals = (guint *)g_malloc(strlen(text));
while (TRUE) {
/* Process each character in the keystrokes */
character = g_utf8_get_char_validated(iter, -1);
+ REMMINA_DEBUG("Char: U+%04" G_GINT32_FORMAT"X", character);
if (character == 0)
break;
keyval = gdk_unicode_to_keyval(character);
+ REMMINA_DEBUG("Keyval: %u", keyval);
/* Replace all the special character with its keyval */
for (i = 0; text_replaces[i].replace; i++) {
if (character == text_replaces[i].replace[0]) {
keys = g_new0(GdkKeymapKey, 1);
keyval = text_replaces[i].keyval;
+ REMMINA_DEBUG("Special Keyval: %u", keyval);
/* A special character was generated, no keyval lookup needed */
character = 0;
break;
@@ -655,7 +659,7 @@ void remmina_protocol_widget_send_clip_strokes(GtkClipboard *clipboard, const gc
if (character) {
/* get keyval without modifications */
if (!gdk_keymap_get_entries_for_keyval(keymap, keyval, &keys, &n_keys)) {
- g_warning("keyval 0x%04x has no keycode!", keyval);
+ REMMINA_WARNING("keyval 0x%04x has no keycode!", keyval);
iter = g_utf8_find_next_char(iter, NULL);
continue;
}
@@ -2111,6 +2115,7 @@ void remmina_protocol_widget_send_keys_signals(GtkWidget *widget, const guint *k
event.keyval = keyvals[i];
event.hardware_keycode = remmina_public_get_keycode_for_keyval(keymap, event.keyval);
event.is_modifier = (int)remmina_public_get_modifier_for_keycode(keymap, event.hardware_keycode);
+ REMMINA_DEBUG("Sending keyval: %u, hardware_keycode: %u", event.keyval, event.hardware_keycode);
g_signal_emit_by_name(G_OBJECT(widget), "key-press-event", &event, &result);
}
}
diff --git a/src/remmina_public.c b/src/remmina_public.c
index 02ff5c7d9..5c5c4640d 100644
--- a/src/remmina_public.c
+++ b/src/remmina_public.c
@@ -541,7 +541,8 @@ guint16 remmina_public_get_keycode_for_keyval(GdkKeymap *keymap, guint keyval)
gboolean remmina_public_get_modifier_for_keycode(GdkKeymap *keymap, guint16 keycode)
{
TRACE_CALL(__func__);
- g_return_val_if_fail(keycode > 0, FALSE);
+ //g_return_val_if_fail(keycode > 0, FALSE);
+ if (keycode > 0) return FALSE;
#ifdef GDK_WINDOWING_X11
return gdk_x11_keymap_key_is_modifier(keymap, keycode);
#else
diff --git a/src/remmina_ssh.c b/src/remmina_ssh.c
index 92e7a3e80..fee610fcd 100644
--- a/src/remmina_ssh.c
+++ b/src/remmina_ssh.c
@@ -497,7 +497,7 @@ remimna_ssh_cp_to_ch_cb(int fd, int revents, void *userdata)
sz = read(fd, buf, sizeof(buf));
if (sz > 0) {
ret = ssh_channel_write(channel, buf, sz);
- REMMINA_DEBUG("ssh_channel_write ret: %d sz: %d", ret, sz);
+ //TODO: too verbose REMMINA_DEBUG("ssh_channel_write ret: %d sz: %d", ret, sz);
} else if (sz < 0) {
// TODO: too verbose REMMINA_WARNING("fd bytes read: %d", sz);
return -1;
--
GitLab