patch 9.0.0058: Win32: cannot test low level events
Problem: Win32: cannot test low level events.
Solution: Add "sendevent" to test_gui_event(). (Yegappan Lakshmanan,
closes #10679)
diff --git a/src/errors.h b/src/errors.h
index 43a1c9b..90aa292 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -3303,4 +3303,6 @@
#ifdef FEAT_EVAL
EXTERN char e_substitute_nesting_too_deep[]
INIT(= N_("E1290: substitute nesting too deep"));
+EXTERN char e_invalid_argument_nr[]
+ INIT(= N_("E1291: Invalid argument: %ld"));
#endif
diff --git a/src/gui_w32.c b/src/gui_w32.c
index f53318d..472cebf 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -8541,3 +8541,42 @@
SetPixel(s_hdc, x+2, y, gui.currFgColor);
}
#endif
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+ int
+test_gui_w32_sendevent(dict_T *args)
+{
+ char_u *event;
+ INPUT inputs[1];
+
+ event = dict_get_string(args, "event", TRUE);
+ if (event == NULL)
+ return FALSE;
+
+ ZeroMemory(inputs, sizeof(inputs));
+
+ if (STRICMP(event, "keydown") == 0 || STRICMP(event, "keyup") == 0)
+ {
+ WORD vkCode;
+
+ vkCode = dict_get_number_def(args, "keycode", 0);
+ if (vkCode <= 0 || vkCode >= 0xFF)
+ {
+ semsg(_(e_invalid_argument_nr), (long)vkCode);
+ return FALSE;
+ }
+
+ inputs[0].type = INPUT_KEYBOARD;
+ inputs[0].ki.wVk = vkCode;
+ if (STRICMP(event, "keyup") == 0)
+ inputs[0].ki.dwFlags = KEYEVENTF_KEYUP;
+ SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
+ }
+ else
+ semsg(_(e_invalid_argument_str), event);
+
+ vim_free(event);
+
+ return TRUE;
+}
+#endif
diff --git a/src/proto/gui_w32.pro b/src/proto/gui_w32.pro
index 43484ad..cab3343 100644
--- a/src/proto/gui_w32.pro
+++ b/src/proto/gui_w32.pro
@@ -96,4 +96,5 @@
BalloonEval *gui_mch_create_beval_area(void *target, char_u *mesg, void (*mesgCB)(BalloonEval *, int), void *clientData);
void gui_mch_destroy_beval_area(BalloonEval *beval);
void netbeans_draw_multisign_indicator(int row);
+int test_gui_w32_sendevent(dict_T *args);
/* vim: set ft=c : */
diff --git a/src/testdir/test_gui.vim b/src/testdir/test_gui.vim
index 2612812..1fadd5e 100644
--- a/src/testdir/test_gui.vim
+++ b/src/testdir/test_gui.vim
@@ -1606,4 +1606,88 @@
call delete('Xlines')
endfunc
+" Test for sending low level key presses
+func SendKeys(keylist)
+ for k in a:keylist
+ call test_gui_event("sendevent", #{event: "keydown", keycode: k})
+ endfor
+ for k in reverse(a:keylist)
+ call test_gui_event("sendevent", #{event: "keyup", keycode: k})
+ endfor
+endfunc
+
+func Test_gui_lowlevel_keyevent()
+ CheckMSWindows
+ new
+
+ " Test for <Ctrl-A> to <Ctrl-Z> keys
+ for kc in range(65, 90)
+ call SendKeys([0x11, kc])
+ let ch = getcharstr()
+ call assert_equal(nr2char(kc - 64), ch)
+ endfor
+
+ " Test for the various Ctrl and Shift key combinations.
+ let keytests = [
+ \ [[0x10, 0x21], "\<S-Pageup>", 2],
+ \ [[0x11, 0x21], "\<C-Pageup>", 4],
+ \ [[0x10, 0x22], "\<S-PageDown>", 2],
+ \ [[0x11, 0x22], "\<C-PageDown>", 4],
+ \ [[0x10, 0x23], "\<S-End>", 0],
+ \ [[0x11, 0x23], "\<C-End>", 0],
+ \ [[0x10, 0x24], "\<S-Home>", 0],
+ \ [[0x11, 0x24], "\<C-Home>", 0],
+ \ [[0x10, 0x25], "\<S-Left>", 0],
+ \ [[0x11, 0x25], "\<C-Left>", 0],
+ \ [[0x10, 0x26], "\<S-Up>", 0],
+ \ [[0x11, 0x26], "\<C-Up>", 4],
+ \ [[0x10, 0x27], "\<S-Right>", 0],
+ \ [[0x11, 0x27], "\<C-Right>", 0],
+ \ [[0x10, 0x28], "\<S-Down>", 0],
+ \ [[0x11, 0x28], "\<C-Down>", 4],
+ \ [[0x11, 0x30], "\<C-0>", 4],
+ \ [[0x11, 0x31], "\<C-1>", 4],
+ \ [[0x11, 0x32], "\<C-2>", 4],
+ \ [[0x11, 0x33], "\<C-3>", 4],
+ \ [[0x11, 0x34], "\<C-4>", 4],
+ \ [[0x11, 0x35], "\<C-5>", 4],
+ \ [[0x11, 0x36], "\<C-^>", 0],
+ \ [[0x11, 0x37], "\<C-7>", 4],
+ \ [[0x11, 0x38], "\<C-8>", 4],
+ \ [[0x11, 0x39], "\<C-9>", 4],
+ \ [[0x11, 0x60], "\<C-0>", 4],
+ \ [[0x11, 0x61], "\<C-1>", 4],
+ \ [[0x11, 0x62], "\<C-2>", 4],
+ \ [[0x11, 0x63], "\<C-3>", 4],
+ \ [[0x11, 0x64], "\<C-4>", 4],
+ \ [[0x11, 0x65], "\<C-5>", 4],
+ \ [[0x11, 0x66], "\<C-6>", 4],
+ \ [[0x11, 0x67], "\<C-7>", 4],
+ \ [[0x11, 0x68], "\<C-8>", 4],
+ \ [[0x11, 0x69], "\<C-9>", 4],
+ \ [[0x11, 0x6A], "\<C-*>", 4],
+ \ [[0x11, 0x6B], "\<C-+>", 4],
+ \ [[0x11, 0x6D], "\<C-->", 4],
+ \ [[0x11, 0x70], "\<C-F1>", 4],
+ \ [[0x11, 0x71], "\<C-F2>", 4],
+ \ [[0x11, 0x72], "\<C-F3>", 4],
+ \ [[0x11, 0x73], "\<C-F4>", 4],
+ \ [[0x11, 0x74], "\<C-F5>", 4],
+ \ [[0x11, 0x75], "\<C-F6>", 4],
+ \ [[0x11, 0x76], "\<C-F7>", 4],
+ \ [[0x11, 0x77], "\<C-F8>", 4],
+ \ [[0x11, 0x78], "\<C-F9>", 4],
+ \ ]
+
+ for [kcodes, kstr, kmod] in keytests
+ call SendKeys(kcodes)
+ let ch = getcharstr()
+ let mod = getcharmod()
+ call assert_equal(kstr, ch, $"key = {kstr}")
+ call assert_equal(kmod, mod)
+ endfor
+
+ bw!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testing.c b/src/testing.c
index 66a3281..b1f6322 100644
--- a/src/testing.c
+++ b/src/testing.c
@@ -1500,6 +1500,12 @@
rettv->v_type = VAR_BOOL;
rettv->vval.v_number = FALSE;
+ if (sandbox != 0)
+ {
+ emsg(_(e_not_allowed_in_sandbox));
+ return;
+ }
+
if (check_for_string_arg(argvars, 0) == FAIL
|| check_for_dict_arg(argvars, 1) == FAIL
|| argvars[1].vval.v_dict == NULL)
@@ -1520,6 +1526,10 @@
rettv->vval.v_number = test_gui_tabline_event(argvars[1].vval.v_dict);
else if (STRCMP(event, "tabmenu") == 0)
rettv->vval.v_number = test_gui_tabmenu_event(argvars[1].vval.v_dict);
+# ifdef FEAT_GUI_MSWIN
+ else if (STRCMP(event, "sendevent") == 0)
+ rettv->vval.v_number = test_gui_w32_sendevent(argvars[1].vval.v_dict);
+# endif
else
{
semsg(_(e_invalid_argument_str), event);
diff --git a/src/version.c b/src/version.c
index ee421e4..4db3a24 100644
--- a/src/version.c
+++ b/src/version.c
@@ -736,6 +736,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 58,
+/**/
57,
/**/
56,