mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-11-13 12:09:35 +03:00
A faster version of SingleKey
This commit is contained in:
parent
9bb2c1a27b
commit
f228f8368a
@ -22,11 +22,6 @@
|
||||
typedef enum HASH_ALGORITHM { SHA1_HASH, SHA224_HASH, SHA256_HASH, SHA384_HASH, SHA512_HASH } HASH_ALGORITHM;
|
||||
static PyObject* Crypto_Exception = NULL;
|
||||
|
||||
#define ADD_TYPE(which) \
|
||||
if (PyType_Ready(&which##_Type) < 0) return false; \
|
||||
if (PyModule_AddObject(module, #which, (PyObject *)&which##_Type) != 0) return false; \
|
||||
Py_INCREF(&which##_Type);
|
||||
|
||||
static PyObject*
|
||||
set_error_from_openssl(const char *prefix) {
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
|
@ -133,6 +133,14 @@ typedef struct ImageAnchorPosition {
|
||||
#endif
|
||||
#define START_ALLOW_CASE_RANGE IGNORE_PEDANTIC_WARNINGS
|
||||
#define END_ALLOW_CASE_RANGE END_IGNORE_PEDANTIC_WARNINGS
|
||||
#define BIT_MASK(__TYPE__, __ONE_COUNT__) \
|
||||
((__TYPE__) (-((__ONE_COUNT__) != 0))) \
|
||||
& (((__TYPE__) -1) >> ((sizeof(__TYPE__) * CHAR_BIT) - (__ONE_COUNT__)))
|
||||
#define ADD_TYPE(which) \
|
||||
if (PyType_Ready(&which##_Type) < 0) return false; \
|
||||
if (PyModule_AddObject(module, #which, (PyObject *)&which##_Type) != 0) return false; \
|
||||
Py_INCREF(&which##_Type);
|
||||
|
||||
|
||||
typedef enum UTF8State { UTF8_ACCEPT = 0, UTF8_REJECT = 1} UTF8State;
|
||||
|
||||
|
@ -1466,3 +1466,17 @@ class AES256GCMDecrypt:
|
||||
def add_data_to_be_authenticated_but_not_decrypted(self, data: bytes) -> None: ...
|
||||
|
||||
def add_data_to_be_decrypted(self, data: bytes, finished: bool = False) -> bytes: ...
|
||||
|
||||
|
||||
class SingleKey:
|
||||
|
||||
def __init__(self, mods: int = 0, is_native: bool = False, key: int = -1): ...
|
||||
def __hash__(self) -> int: ...
|
||||
def __len__(self) -> int: ...
|
||||
def __getitem__(self, x: int) -> int: ...
|
||||
@property
|
||||
def mods(self) -> int: ...
|
||||
@property
|
||||
def is_native(self) -> bool: ...
|
||||
@property
|
||||
def key(self) -> int: ...
|
||||
|
144
kitty/keys.c
144
kitty/keys.c
@ -283,11 +283,155 @@ static PyMethodDef module_methods[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
// SingleKey {{{
|
||||
#define KEY_BITS 21
|
||||
#define MOD_BITS 10
|
||||
|
||||
typedef union Key {
|
||||
struct {
|
||||
uint32_t key : KEY_BITS;
|
||||
uint32_t mods : MOD_BITS;
|
||||
uint32_t is_native: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} Key;
|
||||
|
||||
static PyTypeObject SingleKey_Type;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
|
||||
Key key;
|
||||
} SingleKey;
|
||||
|
||||
static PyObject *
|
||||
SingleKey_new(PyTypeObject *type, PyObject *args, PyObject *kw) {
|
||||
static char *kwds[] = {"mods", "is_native", "key", NULL};
|
||||
long key = -1; unsigned short mods = 0; int is_native = 0;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw, "|Hpl", kwds, &mods, &is_native, &key)) return NULL;
|
||||
SingleKey *self = (SingleKey *)type->tp_alloc(type, 0);
|
||||
if (self) {
|
||||
if (key > 0 && key <= 0x10FFFF) {
|
||||
uint32_t k = (uint32_t)key;
|
||||
self->key.key = k & BIT_MASK(uint32_t, KEY_BITS);
|
||||
}
|
||||
self->key.mods = mods;
|
||||
if (is_native) self->key.is_native = 1u;
|
||||
}
|
||||
return (PyObject*)self;
|
||||
}
|
||||
|
||||
static void
|
||||
SingleKey_dealloc(SingleKey* self) {
|
||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
SingleKey_repr(PyObject *s) {
|
||||
SingleKey *self = (SingleKey*)s;
|
||||
char buf[128];
|
||||
int pos = 0;
|
||||
pos += PyOS_snprintf(buf + pos, sizeof(buf) - pos, "SingleKey(");
|
||||
unsigned int mods = self->key.mods;
|
||||
if (mods) pos += PyOS_snprintf(buf + pos, sizeof(buf) - pos, "mods=%u, ", mods);
|
||||
if (self->key.is_native) pos += PyOS_snprintf(buf + pos, sizeof(buf) - pos, "is_native=True, ");
|
||||
unsigned long key = self->key.key;
|
||||
if (key) pos += PyOS_snprintf(buf + pos, sizeof(buf) - pos, "key=%lu, ", key);
|
||||
if (buf[pos-1] == ' ') pos -= 2;
|
||||
pos += PyOS_snprintf(buf + pos, sizeof(buf) - pos, ")");
|
||||
return PyUnicode_FromString(buf);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
SingleKey_get_key(SingleKey *self, void UNUSED *closure) {
|
||||
const unsigned long val = self->key.key;
|
||||
if (val) return PyLong_FromUnsignedLong(val);
|
||||
return PyLong_FromLong(-1);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
SingleKey_get_mods(SingleKey *self, void UNUSED *closure) {
|
||||
const unsigned long mods = self->key.mods;
|
||||
return PyLong_FromUnsignedLong(mods);
|
||||
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
SingleKey_get_is_native(SingleKey *self, void UNUSED *closure) {
|
||||
if (self->key.is_native) Py_RETURN_TRUE;
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
static PyGetSetDef SingleKey_getsetters[] = {
|
||||
{"key", (getter)SingleKey_get_key, NULL, "The key as an integer", NULL},
|
||||
{"mods", (getter)SingleKey_get_mods, NULL, "The modifiers as an integer", NULL},
|
||||
{"is_native", (getter)SingleKey_get_is_native, NULL, "A bool", NULL},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
static Py_hash_t
|
||||
SingleKey_hash(PyObject *self) {
|
||||
Py_hash_t ans = ((SingleKey*)self)->key.val;
|
||||
if (ans == -1) ans = -2;
|
||||
return ans;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
SingleKey_richcompare(PyObject *self, PyObject *other, int op) {
|
||||
if (!PyObject_TypeCheck(other, &SingleKey_Type)) { PyErr_SetString(PyExc_TypeError, "Cannot compare SingleKey to other objects"); return NULL; }
|
||||
SingleKey *a = (SingleKey*)self, *b = (SingleKey*)other;
|
||||
Py_RETURN_RICHCOMPARE(a->key.val, b->key.val, op);
|
||||
}
|
||||
|
||||
static Py_ssize_t
|
||||
SingleKey___len__(PyObject *self UNUSED) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
SingleKey_item(PyObject *o, Py_ssize_t i) {
|
||||
SingleKey *self = (SingleKey*)o;
|
||||
switch(i) {
|
||||
case 0:
|
||||
return SingleKey_get_mods(self, NULL);
|
||||
case 1:
|
||||
return SingleKey_get_is_native(self, NULL);
|
||||
case 2:
|
||||
return SingleKey_get_key(self, NULL);
|
||||
}
|
||||
PyErr_SetString(PyExc_IndexError, "tuple index out of range");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PySequenceMethods SingleKey_sequence_methods = {
|
||||
.sq_length = SingleKey___len__,
|
||||
.sq_item = SingleKey_item,
|
||||
};
|
||||
|
||||
|
||||
static PyTypeObject SingleKey_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "fast_data_types.SingleKey",
|
||||
.tp_basicsize = sizeof(SingleKey),
|
||||
.tp_dealloc = (destructor)SingleKey_dealloc,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||
.tp_doc = "Compact and fast representation of a single key as defined in the config",
|
||||
.tp_new = SingleKey_new,
|
||||
.tp_hash = SingleKey_hash,
|
||||
.tp_richcompare = SingleKey_richcompare,
|
||||
.tp_as_sequence = &SingleKey_sequence_methods,
|
||||
.tp_repr = SingleKey_repr,
|
||||
/* .tp_methods = methods, */
|
||||
.tp_getset = SingleKey_getsetters,
|
||||
}; // }}}
|
||||
|
||||
|
||||
bool
|
||||
init_keys(PyObject *module) {
|
||||
if (PyModule_AddFunctions(module, module_methods) != 0) return false;
|
||||
if (PyType_Ready(&PyKeyEvent_Type) < 0) return false;
|
||||
if (PyModule_AddObject(module, "KeyEvent", (PyObject *)&PyKeyEvent_Type) != 0) return 0;
|
||||
Py_INCREF(&PyKeyEvent_Type);
|
||||
ADD_TYPE(SingleKey);
|
||||
return true;
|
||||
}
|
||||
|
@ -532,3 +532,15 @@ class TestDataTypes(BaseTest):
|
||||
q('a\x1bbc', 'ac')
|
||||
q('a\x1b[bc', 'ac')
|
||||
q('a\x1b[12;34:43mbc', 'abc')
|
||||
|
||||
def test_SingleKey(self):
|
||||
from kitty.fast_data_types import SingleKey, GLFW_MOD_NUM_LOCK, GLFW_MOD_SHIFT
|
||||
for m in (GLFW_MOD_NUM_LOCK, GLFW_MOD_SHIFT):
|
||||
s = SingleKey(mods=m)
|
||||
self.ae(s.mods, m)
|
||||
self.ae(tuple(SingleKey()), (0, False, -1))
|
||||
self.ae(tuple(SingleKey(key=0x10ffff, mods=GLFW_MOD_SHIFT, is_native=True)), (GLFW_MOD_SHIFT, True, 0x10ffff))
|
||||
self.ae(repr(SingleKey()), 'SingleKey()')
|
||||
self.ae(repr(SingleKey(key=23, mods=2, is_native=True)), 'SingleKey(mods=2, is_native=True, key=23)')
|
||||
self.ae(repr(SingleKey(key=23, mods=2)), 'SingleKey(mods=2, key=23)')
|
||||
self.ae(repr(SingleKey(key=23)), 'SingleKey(key=23)')
|
||||
|
Loading…
Reference in New Issue
Block a user