]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Paste from host clipboard to emulated keyboard.
authorToni Wilen <twilen@winuae.net>
Wed, 18 May 2016 16:23:03 +0000 (19:23 +0300)
committerToni Wilen <twilen@winuae.net>
Wed, 18 May 2016 16:23:03 +0000 (19:23 +0300)
include/keyboard.h
include/keybuf.h
inputdevice.cpp
inputevents.def
keybuf.cpp
od-win32/clipboard_win32.cpp
od-win32/keyboard_win32.cpp

index 2bd97225828e72bdf49d8781d315e2e6ad842b9f..997caf384bdcd3acfca53c27fc717ad00c750085 100644 (file)
@@ -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,
index 436e36edd9a04fba8104f1400ae90028584a57a4..aee8daf45f45aff5ebde8ff2bbfb5ac61221fce3 100644 (file)
@@ -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 */
index bfb9eb5d29e6897cbd36dc35143c9e49e14e83d1..4149d248ad4886e7469f2fddbdb90b1219e3bf55 100644 (file)
@@ -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);
index b9495c2b3adbb5a88597da8126c9c938f3bb1fef..0c42ab2a65d9bd6dee2dbb0e35aa804f073b9610 100644 (file)
@@ -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)
index afc321d64e410e1738ed33027b6f8f123898e3c9..44e557d1fdcecabf73cc958146138389d634b02a 100644 (file)
@@ -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);
+}
index 3a1f05bcbecaac47ab75b49ece492e4ff93ae8a3..827d27a5d257c5c2c0f60227e439e7123c6b3a4e 100644 (file)
@@ -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);
+}
index 5b7767175687df717ac34c64181aa6ce5c2448f0..b1cfe0fc985b268528d4fcf74933b5c70221c50d 100644 (file)
@@ -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 },