From 10de58111c6a09a1ed89f180c80c98d50565426c Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Wed, 18 May 2016 19:23:03 +0300 Subject: [PATCH] Paste from host clipboard to emulated keyboard. --- include/keyboard.h | 1 + include/keybuf.h | 1 + inputdevice.cpp | 9 +- inputevents.def | 1 + keybuf.cpp | 188 +++++++++++++++++++++++++++++++++-- od-win32/clipboard_win32.cpp | 36 +++++-- od-win32/keyboard_win32.cpp | 2 +- 7 files changed, 220 insertions(+), 18 deletions(-) diff --git a/include/keyboard.h b/include/keyboard.h index 2bd97225..997caf38 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -167,6 +167,7 @@ enum aks { AKS_ENTERGUI = 0x200, AKS_TOGGLEMOUSEGRAB, AKS_SWITCHINTERPOL, AKS_TOGGLERTG, AKS_INPUT_CONFIG_1,AKS_INPUT_CONFIG_2,AKS_INPUT_CONFIG_3,AKS_INPUT_CONFIG_4, AKS_SWAPJOYPORTS, + AKS_PASTE, AKS_DISKSWAPPER_NEXT,AKS_DISKSWAPPER_PREV, AKS_DISKSWAPPER_INSERT0,AKS_DISKSWAPPER_INSERT1,AKS_DISKSWAPPER_INSERT2,AKS_DISKSWAPPER_INSERT3, AKS_DISK_PREV0, AKS_DISK_PREV1, AKS_DISK_PREV2, AKS_DISK_PREV3, diff --git a/include/keybuf.h b/include/keybuf.h index 436e36ed..aee8daf4 100644 --- a/include/keybuf.h +++ b/include/keybuf.h @@ -17,5 +17,6 @@ extern int record_key_direct (int); extern void keybuf_init (void); extern int getcapslockstate (void); extern void setcapslockstate (int); +extern void keybuf_inject(uae_char*); #endif /* UAE_KEYBUF_H */ diff --git a/inputdevice.cpp b/inputdevice.cpp index bfb9eb5d..4149d248 100644 --- a/inputdevice.cpp +++ b/inputdevice.cpp @@ -3738,6 +3738,8 @@ static bool needcputrace (int code) return false; } +void target_paste_to_keyboard(void); + static bool inputdevice_handle_inputcode2 (int code, int state) { static int swapperslot; @@ -3951,6 +3953,9 @@ static bool inputdevice_handle_inputcode2 (int code, int state) else if (state == 2) inputdevice_swap_compa_ports(&changed_prefs, 2); break; + case AKS_PASTE: + target_paste_to_keyboard(); + break; case AKS_SWITCHINTERPOL: changed_prefs.sound_interpol++; if (changed_prefs.sound_interpol > 4) @@ -4753,9 +4758,9 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode) if (newslot >= 0) { TCHAR cust[100]; _stprintf(cust, _T("custom%d"), newslot); - inputdevice_joyport_config(&changed_prefs, cust, NULL, newport, -1, 0, true); + inputdevice_joyport_config(&changed_prefs, cust, cust, newport, -1, 0, true); } else { - inputdevice_joyport_config (&changed_prefs, name, NULL, newport, -1, 1, true); + inputdevice_joyport_config (&changed_prefs, name, name, newport, -1, 1, true); } inputdevice_validate_jports (&changed_prefs, -1, NULL); inputdevice_copyconfig (&changed_prefs, &currprefs); diff --git a/inputevents.def b/inputevents.def index b9495c2b..0c42ab2a 100644 --- a/inputevents.def +++ b/inputevents.def @@ -369,6 +369,7 @@ DEFEVENT(SPC_INCREASE_REFRESHRATE,_T("Increase emulation speed"),AM_K,0,0,AKS_IN DEFEVENT(SPC_SWITCHINTERPOL,_T("Switch between audio interpolation methods"),AM_KT,0,0,AKS_SWITCHINTERPOL) DEFEVENT(SPC_TOGGLERTG,_T("Toggle chipset/RTG screen"),AM_KT,0,0,AKS_TOGGLERTG) DEFEVENT(SPC_SWAPJOYPORTS,_T("Swap joystick ports"),AM_KT,0,0,AKS_SWAPJOYPORTS) +DEFEVENT(SPC_PASTE,_T("Paste from host clipboard"),AM_KT,0,0,AKS_PASTE) DEFEVENT(SPC_DISKSWAPPER_NEXT,_T("Next slot in Disk Swapper"),AM_K,0,0,AKS_DISKSWAPPER_NEXT) DEFEVENT(SPC_DISKSWAPPER_PREV,_T("Previous slot in Disk Swapper"),AM_K,0,0,AKS_DISKSWAPPER_PREV) diff --git a/keybuf.cpp b/keybuf.cpp index afc321d6..44e557d1 100644 --- a/keybuf.cpp +++ b/keybuf.cpp @@ -27,17 +27,192 @@ static int kpb_first, kpb_last; #define KEYBUF_SIZE 256 static int keybuf[KEYBUF_SIZE]; +static uae_char *keyinject; +static int keyinject_offset; +static uae_u8 keyinject_previous; +static bool keyinject_state; + +struct kbtab +{ + int ascii; + uae_u8 code; + uae_u8 qual; +}; + +static const struct kbtab kbtable[] = +{ + { '~', 0x00, 0x60 }, + { '!', 0x01, 0x60 }, + { '@', 0x02, 0x60 }, + { '#', 0x03, 0x60 }, + { '$', 0x04, 0x60 }, + { '%', 0x05, 0x60 }, + { '^', 0x06, 0x60 }, + { '&', 0x07, 0x60 }, + { '*', 0x08, 0x60 }, + { '(', 0x09, 0x60 }, + { ')', 0x0a, 0x60 }, + { '_', 0x0b, 0x60 }, + { '+', 0x0c, 0x60 }, + { '|', 0x0d, 0x60 }, + + { '`', 0x00 }, + { '1', 0x01 }, + { '2', 0x02 }, + { '3', 0x03 }, + { '4', 0x04 }, + { '5', 0x05 }, + { '6', 0x06 }, + { '7', 0x07 }, + { '8', 0x08 }, + { '9', 0x09 }, + { '0', 0x0a }, + { '-', 0x0b }, + { '=', 0x0c }, + { '\\', 0x0d }, + + { '\t', 0x42 }, + { '\n', 0x44 }, + + { '{', 0x1a, 0x60 }, + { '}', 0x1b, 0x60 }, + { ':', 0x29, 0x60 }, + { '"', 0x2b, 0x60 }, + { '[', 0x1a }, + { ']', 0x1b }, + { ';', 0x29 }, + { '\'', 0x2b }, + + + { '<', 0x38, 0x60 }, + { '>', 0x39, 0x60 }, + { '?', 0x3a, 0x60 }, + { ',', 0x38 }, + { '.', 0x39 }, + { '/', 0x3a }, + + { ' ', 0x40 }, + + { 'q', 0x10 }, + { 'w', 0x11 }, + { 'e', 0x12 }, + { 'r', 0x13 }, + { 't', 0x14 }, + { 'y', 0x15 }, + { 'u', 0x16 }, + { 'i', 0x17 }, + { 'o', 0x18 }, + { 'p', 0x19 }, + + { 'a', 0x20 }, + { 's', 0x21 }, + { 'd', 0x22 }, + { 'f', 0x23 }, + { 'g', 0x24 }, + { 'h', 0x25 }, + { 'j', 0x26 }, + { 'k', 0x27 }, + { 'l', 0x28 }, + + { 'z', 0x31 }, + { 'x', 0x32 }, + { 'c', 0x33 }, + { 'v', 0x34 }, + { 'b', 0x35 }, + { 'n', 0x36 }, + { 'm', 0x37 }, + + { 'Q', 0x10, 0x60 }, + { 'W', 0x11, 0x60 }, + { 'E', 0x12, 0x60 }, + { 'R', 0x13, 0x60 }, + { 'T', 0x14, 0x60 }, + { 'Y', 0x15, 0x60 }, + { 'U', 0x16, 0x60 }, + { 'I', 0x17, 0x60 }, + { 'O', 0x18, 0x60 }, + { 'P', 0x19, 0x60 }, + + { 'A', 0x20, 0x60 }, + { 'S', 0x21, 0x60 }, + { 'D', 0x22, 0x60 }, + { 'F', 0x23, 0x60 }, + { 'G', 0x24, 0x60 }, + { 'H', 0x25, 0x60 }, + { 'J', 0x26, 0x60 }, + { 'K', 0x27, 0x60 }, + { 'L', 0x28, 0x60 }, + + { 'Z', 0x31, 0x60 }, + { 'X', 0x32, 0x60 }, + { 'C', 0x33, 0x60 }, + { 'V', 0x34, 0x60 }, + { 'B', 0x35, 0x60 }, + { 'N', 0x36, 0x60 }, + { 'M', 0x37, 0x60 }, + + { 0 } +}; + +static void keytoscancode(int key, bool release) +{ + int v = 0x40; + int q = 0x00; + int mask = release ? 0x80 : 0x00; + for (int i = 0; kbtable[i].ascii; i++) { + if (kbtable[i].ascii == key) { + v = kbtable[i].code; + q = kbtable[i].qual; + break; + } + } + v |= mask; + v = (v << 1) | (v >> 7); + q |= mask; + if (release) { + record_key(v); + if (q & 0x7f) { + q = (q << 1) | (q >> 7); + record_key(q); + } + } else { + if (q & 0x7f) { + q = (q << 1) | (q >> 7); + record_key(q); + } + record_key(v); + } +} int keys_available (void) { int val; val = kpb_first != kpb_last; + if ((keyinject && keyinject[keyinject_offset]) || keyinject_state) + val = 1; return val; } int get_next_key (void) { int key; + + if (keyinject_state) { + key = keyinject_previous; + keyinject_state = false; + keytoscancode(key, true); + } else if (keyinject) { + key = keyinject[keyinject_offset++]; + keyinject_previous = key; + keyinject_state = true; + if (keyinject[keyinject_offset] == 0) { + xfree(keyinject); + keyinject = NULL; + keyinject_offset =0; + } + keytoscancode(key, false); + } + assert (kpb_first != kpb_last); key = keybuf[kpb_last]; @@ -65,12 +240,6 @@ int record_key_direct (int kc) write_log (_T("Keyboard buffer overrun. Congratulations.\n")); return 0; } -#if 0 - if ((kc >> 1) == AK_RCTRL) { - kc ^= AK_RCTRL << 1; - kc ^= AK_CTRL << 1; - } -#endif keybuf[kpb_first] = kc; kpb_first = kpb_next; return 1; @@ -81,3 +250,10 @@ void keybuf_init (void) kpb_first = kpb_last = 0; inputdevice_updateconfig (&changed_prefs, &currprefs); } + +void keybuf_inject(uae_char *txt) +{ + xfree(keyinject); + keyinject_offset = 0; + keyinject = strdup(txt); +} diff --git a/od-win32/clipboard_win32.cpp b/od-win32/clipboard_win32.cpp index 3a1f05bc..827d27a5 100644 --- a/od-win32/clipboard_win32.cpp +++ b/od-win32/clipboard_win32.cpp @@ -10,6 +10,7 @@ #include "traps.h" #include "clipboard_win32.h" #include "clipboard.h" +#include "keybuf.h" #include "threaddep/thread.h" #include "memory.h" @@ -117,6 +118,13 @@ static int parsecsi (const char *txt, int off, int len) return off; } +static void to_keyboard(const TCHAR *pctxt) +{ + uae_char *txt = ua(pctxt); + keybuf_inject(txt); + xfree(txt); +} + static TCHAR *amigatopc (const char *txt) { int i, j, cnt; @@ -158,7 +166,6 @@ static TCHAR *amigatopc (const char *txt) return s; } - static void to_iff_text(TrapContext *ctx, const TCHAR *pctxt) { uae_u8 b[] = { 'F','O','R','M',0,0,0,0,'F','T','X','T','C','H','R','S',0,0,0,0 }; @@ -716,13 +723,13 @@ void clipboard_disable (bool disabled) clip_disabled = disabled; } -static void clipboard_read(TrapContext *ctx, HWND hwnd) +static void clipboard_read(TrapContext *ctx, HWND hwnd, bool keyboardinject) { HGLOBAL hglb; UINT f; int text = FALSE, bmp = FALSE; - if (clip_disabled) + if (clip_disabled || !hwnd) return; if (to_amiga) { #if DEBUG_CLIP > 0 @@ -740,7 +747,7 @@ static void clipboard_read(TrapContext *ctx, HWND hwnd) while (f = EnumClipboardFormats (f)) { if (f == CF_UNICODETEXT) text = TRUE; - if (f == CF_BITMAP) + if (f == CF_BITMAP && !keyboardinject) bmp = TRUE; } if (text) { @@ -751,7 +758,11 @@ static void clipboard_read(TrapContext *ctx, HWND hwnd) #if DEBUG_CLIP > 0 write_log (_T("clipboard: CF_UNICODETEXT '%s'\n"), lptstr); #endif - to_iff_text(ctx, lptstr); + if (keyboardinject) { + to_keyboard(lptstr); + } else { + to_iff_text(ctx, lptstr); + } GlobalUnlock (hglb); } } @@ -784,7 +795,9 @@ void clipboard_changed (HWND hwnd) #if DEBUG_CLIP > 0 write_log (_T("clipboard: windows clipboard changed message\n")); #endif - if (!clipboard_data || !initialized) + if (!initialized) + return; + if (!clipboard_data) return; if (clipopen) return; @@ -792,7 +805,7 @@ void clipboard_changed (HWND hwnd) clipboard_change = 1; return; } - clipboard_read(NULL, hwnd); + clipboard_read(NULL, hwnd, false); } static int clipboard_put_bmp_real (HBITMAP hbmp) @@ -868,7 +881,7 @@ void amiga_clipboard_init(TrapContext *ctx) signaling = 0; write_log (_T("clipboard initialized\n")); initialized = 1; - clipboard_read(ctx, chwnd); + clipboard_read(ctx, chwnd, false); } void amiga_clipboard_task_start(TrapContext *ctx, uaecptr data) @@ -931,7 +944,7 @@ void clipboard_active(HWND hwnd, int active) if (!initialized) return; if (clipactive && clipboard_change) { - clipboard_read(NULL, hwnd); + clipboard_read(NULL, hwnd, false); } if (!clipactive && clipboard_delayed_data) { if (clipboard_delayed_size < 0) { @@ -988,3 +1001,8 @@ void clipboard_init (HWND hwnd) chwnd = hwnd; hdc = GetDC (chwnd); } + +void target_paste_to_keyboard(void) +{ + clipboard_read(NULL, chwnd, true); +} diff --git a/od-win32/keyboard_win32.cpp b/od-win32/keyboard_win32.cpp index 5b776717..b1cfe0fc 100644 --- a/od-win32/keyboard_win32.cpp +++ b/od-win32/keyboard_win32.cpp @@ -144,7 +144,7 @@ static struct uae_input_device_kbr_default keytrans_amiga[] = { { DIK_LEFT, INPUTEVENT_KEY_CURSOR_LEFT }, { DIK_RIGHT, INPUTEVENT_KEY_CURSOR_RIGHT }, - { DIK_INSERT, INPUTEVENT_KEY_AMIGA_LEFT }, + { DIK_INSERT, INPUTEVENT_KEY_AMIGA_LEFT, 0, INPUTEVENT_SPC_PASTE, ID_FLAG_QUALIFIER_SPECIAL }, { DIK_DELETE, INPUTEVENT_KEY_DEL }, { DIK_HOME, INPUTEVENT_KEY_AMIGA_RIGHT }, { DIK_NEXT, INPUTEVENT_KEY_HELP }, -- 2.47.3