Store key combos that need special handling in a table for fast lookup

This commit is contained in:
Kovid Goyal 2017-09-15 18:06:26 +05:30
parent 0423c55dc1
commit b2c7272af1
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 42 additions and 4 deletions

View File

@ -317,3 +317,4 @@ void change_wcwidth(bool use9);
void set_mouse_cursor(MouseShape);
void mouse_event(int, int);
void scroll_event(double, double);
void set_special_key_combo(int glfw_key, int mods);

View File

@ -23,6 +23,12 @@ key_to_bytes(int glfw_key, bool smkx, bool extended, int mods, int action) {
return key_bytes[key];
}
void
set_special_key_combo(int glfw_key, int mods) {
int k = (glfw_key & 0x7f) | ( (mods & 0xF) << 7);
needs_special_handling[k] = true;
}
#define PYWRAP1(name) static PyObject* py##name(PyObject UNUSED *self, PyObject *args)
#define PA(fmt, ...) if(!PyArg_ParseTuple(args, fmt, __VA_ARGS__)) return NULL;
#define M(name, arg_type) {#name, (PyCFunction)py##name, arg_type, NULL}

View File

@ -1,13 +1,15 @@
// auto-generated from keys.py, do not edit!
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <limits.h>
static bool needs_special_handling[2048] = {0};
static const uint8_t key_map[349] = {
UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, 0, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, 1, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, UINT8_MAX, 16, UINT8_MAX, 17, UINT8_MAX, UINT8_MAX, UINT8_MAX, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, UINT8_MAX, 29, 30, 31, 32, 33, 34, 35, 36, UINT8_MAX, 37, 38, 39, 40, 41, 42, 43, 44, UINT8_MAX, UINT8_MAX, 45, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, 46, 47, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, 62, 63, 64, 65, 66, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, UINT8_MAX, UINT8_MAX, UINT8_MAX, 109, 110, 111, 112, 113, 114, 115, 116, 117, };
#define SIZE_OF_KEY_BYTES_MAP 32767
#define SIZE_OF_KEY_BYTES_MAP 32768
static const uint8_t key_bytes[32767][10] = {
static const uint8_t key_bytes[32768][10] = {
{0},
{0},
{0},
@ -32775,4 +32777,5 @@ static const uint8_t key_bytes[32767][10] = {
{0},
{0},
{0},
{0},
};

View File

@ -227,7 +227,9 @@ def generate_key_table():
w('// auto-generated from keys.py, do not edit!')
w('#pragma once')
w('#include <stdint.h>')
w('#include <stdbool.h>')
w('#include <limits.h>')
w('static bool needs_special_handling[%d] = {0};' % (128 * 16))
number_of_keys = defines.GLFW_KEY_LAST + 1
w('static const uint8_t key_map[%d] = {' % number_of_keys)
key_count = 0
@ -244,7 +246,7 @@ def generate_key_table():
if key_count > 128:
raise OverflowError('Too many keys')
w('};\n')
number_entries = 0x7f | (0xff << 7)
number_entries = 128 * 256
inits = []
longest = 0
for i in range(number_entries):

View File

@ -126,8 +126,24 @@ color_as_int(PyObject *color) {
#undef I
}
#define dict_iter(d) { \
PyObject *key, *value; Py_ssize_t pos; \
while (PyDict_Next(d, &pos, &key, &value))
static inline void
set_special_keys(PyObject *dict) {
dict_iter(dict) {
if (!PyTuple_Check(key)) { PyErr_SetString(PyExc_TypeError, "dict keys for special keys must be tuples"); return; }
int mods = PyLong_AsLong(PyTuple_GET_ITEM(key, 0));
int glfw_key = PyLong_AsLong(PyTuple_GET_ITEM(key, 1));
set_special_key_combo(glfw_key, mods);
}}
}
PYWRAP1(set_options) {
#define S(name, convert) { PyObject *ret = PyObject_GetAttrString(args, #name); if (ret == NULL) return NULL; global_state.opts.name = convert(ret); Py_DECREF(ret); if (PyErr_Occurred()) return NULL; }
PyObject *ret;
#define GA(name) ret = PyObject_GetAttrString(args, #name); if (ret == NULL) return NULL;
#define S(name, convert) { GA(name); global_state.opts.name = convert(ret); Py_DECREF(ret); if (PyErr_Occurred()) return NULL; }
S(visual_bell_duration, PyFloat_AsDouble);
S(enable_audio_bell, PyObject_IsTrue);
S(cursor_blink_interval, PyFloat_AsDouble);
@ -139,12 +155,22 @@ PYWRAP1(set_options) {
S(open_url_modifiers, PyLong_AsUnsignedLong);
S(click_interval, PyFloat_AsDouble);
S(url_color, color_as_int);
PyObject *chars = PyObject_GetAttrString(args, "select_by_word_characters");
if (chars == NULL) return NULL;
for (size_t i = 0; i < MIN((size_t)PyUnicode_GET_LENGTH(chars), sizeof(OPT(select_by_word_characters))/sizeof(OPT(select_by_word_characters[0]))); i++) {
OPT(select_by_word_characters)[i] = PyUnicode_READ(PyUnicode_KIND(chars), PyUnicode_DATA(chars), i);
}
OPT(select_by_word_characters_count) = PyUnicode_GET_LENGTH(chars);
GA(keymap); set_special_keys(ret);
Py_DECREF(ret); if (PyErr_Occurred()) return NULL;
GA(send_text_map);
dict_iter(ret) {
set_special_keys(value);
}}
Py_DECREF(ret); if (PyErr_Occurred()) return NULL;
Py_DECREF(chars);
#undef S
Py_RETURN_NONE;