shithub: puzzles

Download patch

ref: 768ef770a351ee1528e6e7923d3b3b00654401cb
parent: 0db5fb525bb58056caf9303d2ac159fc51c04e04
author: Ben Harris <[email protected]>
date: Mon Oct 24 19:06:12 EDT 2022

js: Use KeyboardEvent.key for ASCII keystrokes

This requires passing in KeyboardEvent.location from JavaScript so
that we can detect the numeric keypad properly.  Out of caution we
currently only set MOD_NUM_KEYPAD on numbers, like we always have,
but we have enough information to set it on arrow keys, Enter, "+",
etc.

This finally gets '/' and '\' working in Slant again.

--- a/emcc.c
+++ b/emcc.c
@@ -262,9 +262,14 @@
 /*
  * Keyboard handler called from JS.
  */
-void key(int keycode, const char *key, const char *chr,
+void key(int keycode, const char *key, const char *chr, int location,
          bool shift, bool ctrl)
 {
+    /* Key location constants from JavaScript. */
+    #define DOM_KEY_LOCATION_STANDARD 0
+    #define DOM_KEY_LOCATION_LEFT     1
+    #define DOM_KEY_LOCATION_RIGHT    2
+    #define DOM_KEY_LOCATION_NUMPAD   3
     int keyevent = -1;
 
     if (!strnullcmp(key, "Backspace") || !strnullcmp(key, "Delete") ||
@@ -296,6 +301,9 @@
         keyevent = MOD_NUM_KEYPAD | '7';
     else if (!strnullcmp(key, "PageUp"))
         keyevent = MOD_NUM_KEYPAD | '9';
+    else if (key && (unsigned char)key[0] < 0x80 && key[1] == '\0')
+        /* Key generating a single ASCII character. */
+        keyevent = key[0];
     else if (keycode == 8 || keycode == 46)
         keyevent = 127;                /* Backspace / Delete */
     else if (keycode == 13)
@@ -339,6 +347,10 @@
             else
                 keyevent &= 0x1F;
         }
+
+        if ('0' <= keyevent && keyevent <= '9' &&
+            location == DOM_KEY_LOCATION_NUMPAD)
+            keyevent |= MOD_NUM_KEYPAD;
 
         midend_process_key(me, 0, 0, keyevent);
         update_undo_redo();
--- a/emccpre.js
+++ b/emccpre.js
@@ -311,10 +311,10 @@
     // the puzzle - so users of this puzzle collection in other media
     // can indulge their instinct to press ^R for redo, for example,
     // without accidentally reloading the page.
-    key = Module.cwrap('key', 'void', ['number', 'string',
-                                       'string', 'number', 'number']);
+    key = Module.cwrap('key', 'void', ['number', 'string', 'string',
+                                       'number', 'number', 'number']);
     onscreen_canvas.onkeydown = function(event) {
-        key(event.keyCode, event.key, event.char,
+        key(event.keyCode, event.key, event.char, event.location,
             event.shiftKey ? 1 : 0, event.ctrlKey ? 1 : 0);
         event.preventDefault();
     };