diff --git a/kitty/options/to-c.h b/kitty/options/to-c.h new file mode 100644 index 000000000..0bdfcb444 --- /dev/null +++ b/kitty/options/to-c.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2021 Kovid Goyal + * + * Distributed under terms of the GPL3 license. + */ + +#pragma once + +#include "../state.h" + +static inline float +PyFloat_AsFloat(PyObject *o) { + return (float)PyFloat_AsDouble(o); +} + +static inline color_type +color_as_int(PyObject *color) { + if (!PyTuple_Check(color)) { PyErr_SetString(PyExc_TypeError, "Not a color tuple"); return 0; } +#define I(n, s) ((PyLong_AsUnsignedLong(PyTuple_GET_ITEM(color, n)) & 0xff) << s) + return (I(0, 16) | I(1, 8) | I(2, 0)) & 0xffffff; +#undef I +} + +static inline color_type +active_border_color(PyObject *color) { + if (color == Py_None) return 0x00ff00; + return color_as_int(color); +} + + +static inline monotonic_t +parse_s_double_to_monotonic_t(PyObject *val) { + return s_double_to_monotonic_t(PyFloat_AsDouble(val)); +} + +static inline monotonic_t +parse_ms_long_to_monotonic_t(PyObject *val) { + return ms_to_monotonic_t(PyLong_AsUnsignedLong(val)); +} + +static inline int +resolve_mods(int kitty_mod, int mods) { + if (mods & GLFW_MOD_KITTY) { + mods = (mods & ~GLFW_MOD_KITTY) | kitty_mod; + } + return mods; +} + +static WindowTitleIn +window_title_in(PyObject *title_in) { + const char *in = PyUnicode_AsUTF8(title_in); + switch(in[0]) { + case 'a': return ALL; + case 'w': return WINDOW; + case 'm': return MENUBAR; + case 'n': return NONE; + default: break; + } + return ALL; +} + +static BackgroundImageLayout +bglayout(PyObject *layout_name) { + const char *name = PyUnicode_AsUTF8(layout_name); + switch(name[0]) { + case 't': return TILING; + case 'm': return MIRRORED; + case 's': return SCALED; + default: break; + } + return TILING; +} + +static void +background_image(PyObject *src, Options *opts) { + if (opts->background_image) free(opts->background_image); + opts->background_image = NULL; + if (src == Py_None || !PyUnicode_Check(src)) return; + Py_ssize_t sz; + const char *s = PyUnicode_AsUTF8AndSize(src, &sz); + opts->background_image = calloc(sz + 1, 1); + if (opts->background_image) memcpy(opts->background_image, s, sz); +} + + +static MouseShape +pointer_shape(PyObject *shape_name) { + const char *name = PyUnicode_AsUTF8(shape_name); + switch(name[0]) { + case 'a': return ARROW; + case 'h': return HAND; + case 'b': return BEAM; + default: break; + } + return BEAM; +} + +static inline void +free_url_prefixes(void) { + OPT(url_prefixes).num = 0; + OPT(url_prefixes).max_prefix_len = 0; + if (OPT(url_prefixes).values) { + free(OPT(url_prefixes.values)); + OPT(url_prefixes).values = NULL; + } +} + +static void +url_prefixes(PyObject *up, Options *opts) { + if (!PyTuple_Check(up)) { PyErr_SetString(PyExc_TypeError, "url_prefixes must be a tuple"); return; } + free_url_prefixes(); + opts->url_prefixes.values = calloc(PyTuple_GET_SIZE(up), sizeof(UrlPrefix)); + if (!opts->url_prefixes.values) { PyErr_NoMemory(); return; } + opts->url_prefixes.num = PyTuple_GET_SIZE(up); + for (size_t i = 0; i < opts->url_prefixes.num; i++) { + PyObject *t = PyTuple_GET_ITEM(up, i); + if (!PyUnicode_Check(t)) { PyErr_SetString(PyExc_TypeError, "url_prefixes must be strings"); return; } + opts->url_prefixes.values[i].len = MIN(arraysz(opts->url_prefixes.values[i].string) - 1, (size_t)PyUnicode_GET_LENGTH(t)); + int kind = PyUnicode_KIND(t); + opts->url_prefixes.max_prefix_len = MAX(opts->url_prefixes.max_prefix_len, opts->url_prefixes.values[i].len); + for (size_t x = 0; x < opts->url_prefixes.values[i].len; x++) { + opts->url_prefixes.values[i].string[x] = PyUnicode_READ(kind, PyUnicode_DATA(t), x); + } + } +} + +static void +select_by_word_characters(PyObject *chars, Options *opts) { + if (!PyUnicode_Check(chars)) { PyErr_SetString(PyExc_TypeError, "select_by_word_characters must be a string"); return; } + for (size_t i = 0; i < MIN((size_t)PyUnicode_GET_LENGTH(chars), sizeof(opts->select_by_word_characters)/sizeof(opts->select_by_word_characters[0])); i++) { + opts->select_by_word_characters[i] = PyUnicode_READ(PyUnicode_KIND(chars), PyUnicode_DATA(chars), i); + } + opts->select_by_word_characters_count = PyUnicode_GET_LENGTH(chars); +} + +#define read_adjust(name) { \ + if (PyFloat_Check(al)) { \ + opts->name##_frac = (float)PyFloat_AsDouble(al); \ + opts->name##_px = 0; \ + } else { \ + opts->name##_frac = 0; \ + opts->name##_px = (int)PyLong_AsLong(al); \ + } \ +} + +static void +adjust_line_height(PyObject *al, Options *opts) { read_adjust(adjust_line_height); } +static void +adjust_column_width(PyObject *al, Options *opts) { read_adjust(adjust_column_width); } +#undef read_adjust diff --git a/kitty/state.c b/kitty/state.c index 4db238afa..4ba072efa 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -5,8 +5,8 @@ * Distributed under terms of the GPL3 license. */ -#include "state.h" #include "cleanup.h" +#include "options/to-c.h" #include GlobalState global_state = {{0}}; @@ -562,152 +562,10 @@ send_pending_click_to_window_id(id_type timer_id UNUSED, void *data) { #define KKKK(name) PYWRAP1(name) { id_type a, b, c, d; PA("KKKK", &a, &b, &c, &d); name(a, b, c, d); Py_RETURN_NONE; } #define KK5I(name) PYWRAP1(name) { id_type a, b; unsigned int c, d, e, f, g; PA("KKIIIII", &a, &b, &c, &d, &e, &f, &g); name(a, b, c, d, e, f, g); Py_RETURN_NONE; } #define BOOL_SET(name) PYWRAP1(set_##name) { global_state.name = PyObject_IsTrue(args); Py_RETURN_NONE; } - -static inline color_type -color_as_int(PyObject *color) { - if (!PyTuple_Check(color)) { PyErr_SetString(PyExc_TypeError, "Not a color tuple"); return 0; } -#define I(n, s) ((PyLong_AsUnsignedLong(PyTuple_GET_ITEM(color, n)) & 0xff) << s) - return (I(0, 16) | I(1, 8) | I(2, 0)) & 0xffffff; -#undef I -} - -static inline color_type -active_border_color(PyObject *color) { - if (color == Py_None) return 0x00ff00; - return color_as_int(color); -} - - -static inline monotonic_t -parse_s_double_to_monotonic_t(PyObject *val) { - return s_double_to_monotonic_t(PyFloat_AsDouble(val)); -} - -static inline monotonic_t -parse_ms_long_to_monotonic_t(PyObject *val) { - return ms_to_monotonic_t(PyLong_AsUnsignedLong(val)); -} - -static inline int -resolve_mods(int kitty_mod, int mods) { - if (mods & GLFW_MOD_KITTY) { - mods = (mods & ~GLFW_MOD_KITTY) | kitty_mod; - } - return mods; -} - -static WindowTitleIn -window_title_in(PyObject *title_in) { - const char *in = PyUnicode_AsUTF8(title_in); - switch(in[0]) { - case 'a': return ALL; - case 'w': return WINDOW; - case 'm': return MENUBAR; - case 'n': return NONE; - default: break; - } - return ALL; -} - -static BackgroundImageLayout -bglayout(PyObject *layout_name) { - const char *name = PyUnicode_AsUTF8(layout_name); - switch(name[0]) { - case 't': return TILING; - case 'm': return MIRRORED; - case 's': return SCALED; - default: break; - } - return TILING; -} - -static void -background_image(PyObject *src, Options *opts) { - if (opts->background_image) free(opts->background_image); - opts->background_image = NULL; - if (src == Py_None || !PyUnicode_Check(src)) return; - Py_ssize_t sz; - const char *s = PyUnicode_AsUTF8AndSize(src, &sz); - opts->background_image = calloc(sz + 1, 1); - if (opts->background_image) memcpy(opts->background_image, s, sz); -} - - -static MouseShape -pointer_shape(PyObject *shape_name) { - const char *name = PyUnicode_AsUTF8(shape_name); - switch(name[0]) { - case 'a': return ARROW; - case 'h': return HAND; - case 'b': return BEAM; - default: break; - } - return BEAM; -} - -static inline void -free_url_prefixes(void) { - OPT(url_prefixes).num = 0; - OPT(url_prefixes).max_prefix_len = 0; - if (OPT(url_prefixes).values) { - free(OPT(url_prefixes.values)); - OPT(url_prefixes).values = NULL; - } -} - -static void -url_prefixes(PyObject *up, Options *opts) { - if (!PyTuple_Check(up)) { PyErr_SetString(PyExc_TypeError, "url_prefixes must be a tuple"); return; } - free_url_prefixes(); - opts->url_prefixes.values = calloc(PyTuple_GET_SIZE(up), sizeof(UrlPrefix)); - if (!opts->url_prefixes.values) { PyErr_NoMemory(); return; } - opts->url_prefixes.num = PyTuple_GET_SIZE(up); - for (size_t i = 0; i < opts->url_prefixes.num; i++) { - PyObject *t = PyTuple_GET_ITEM(up, i); - if (!PyUnicode_Check(t)) { PyErr_SetString(PyExc_TypeError, "url_prefixes must be strings"); return; } - opts->url_prefixes.values[i].len = MIN(arraysz(opts->url_prefixes.values[i].string) - 1, (size_t)PyUnicode_GET_LENGTH(t)); - int kind = PyUnicode_KIND(t); - opts->url_prefixes.max_prefix_len = MAX(opts->url_prefixes.max_prefix_len, opts->url_prefixes.values[i].len); - for (size_t x = 0; x < opts->url_prefixes.values[i].len; x++) { - opts->url_prefixes.values[i].string[x] = PyUnicode_READ(kind, PyUnicode_DATA(t), x); - } - } -} - -static void -select_by_word_characters(PyObject *chars, Options *opts) { - if (!PyUnicode_Check(chars)) { PyErr_SetString(PyExc_TypeError, "select_by_word_characters must be a string"); return; } - for (size_t i = 0; i < MIN((size_t)PyUnicode_GET_LENGTH(chars), sizeof(opts->select_by_word_characters)/sizeof(opts->select_by_word_characters[0])); i++) { - opts->select_by_word_characters[i] = PyUnicode_READ(PyUnicode_KIND(chars), PyUnicode_DATA(chars), i); - } - opts->select_by_word_characters_count = PyUnicode_GET_LENGTH(chars); -} - -#define read_adjust(name) { \ - if (PyFloat_Check(al)) { \ - opts->name##_frac = (float)PyFloat_AsDouble(al); \ - opts->name##_px = 0; \ - } else { \ - opts->name##_frac = 0; \ - opts->name##_px = (int)PyLong_AsLong(al); \ - } \ -} - -static void -adjust_line_height(PyObject *al, Options *opts) { read_adjust(adjust_line_height); } -static void -adjust_column_width(PyObject *al, Options *opts) { read_adjust(adjust_column_width); } -#undef read_adjust - #define dict_iter(d) { \ PyObject *key, *value; Py_ssize_t pos = 0; \ while (PyDict_Next(d, &pos, &key, &value)) -static inline float -PyFloat_AsFloat(PyObject *o) { - return (float)PyFloat_AsDouble(o); -} - PYWRAP0(next_window_id) { return PyLong_FromUnsignedLongLong(global_state.window_id_counter + 1); }