linux-qubasis

linux oasis port as a qubes template

git clone https://9o.is/git/linux-qubasis.git

commit 982f894af4e0edd70f8a7889145355839590eb2a
parent dcd96c8a3d07641179b97fa57159c7e211d95bb1
Author: Jul <jul@9o.is>
Date:   Thu, 27 Nov 2025 11:22:31 -0500

add libevdev

Diffstat:
M.gitmodules | 4++++
Mpkg/gen.sh | 1+
Apkg/libevdev/config.h | 1+
Apkg/libevdev/eventnames.lua | 181+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apkg/libevdev/gen.sh | 38++++++++++++++++++++++++++++++++++++++
Apkg/libevdev/patch/0001-Revert-switch-to-VLAs-for-multitouch-state.patch | 273+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 498 insertions(+), 0 deletions(-)

diff --git a/.gitmodules b/.gitmodules @@ -38,6 +38,10 @@ path = pkg/fzy/src url = https://github.com/jhawthorn/fzy.git ignore = all +[submodule "libevdev"] + path = pkg/libevdev/src + url = https://gitlab.freedesktop.org/libevdev/libevdev.git + ignore = all [submodule "libpng"] path = pkg/libpng/src url = https://github.com/glennrp/libpng diff --git a/pkg/gen.sh b/pkg/gen.sh @@ -25,6 +25,7 @@ pkg freetype pkg fspec-sync pkg fzy pkg less +pkg libevdev pkg libpng pkg libtermkey pkg libtls-bearssl diff --git a/pkg/libevdev/config.h b/pkg/libevdev/config.h @@ -0,0 +1 @@ +#define _GNU_SOURCE 1 diff --git a/pkg/libevdev/eventnames.lua b/pkg/libevdev/eventnames.lua @@ -0,0 +1,181 @@ +local duplicates = { + EV_VERSION=true, + BTN_MISC=true, + BTN_MOUSE=true, + BTN_JOYSTICK=true, + BTN_GAMEPAD=true, + BTN_DIGI=true, + BTN_WHEEL=true, + BTN_TRIGGER_HAPPY=true, + SW_MAX=true, + REP_MAX=true, + FF_STATUS_MAX=true, +} + +local skip = { + BTN=true, + EV=true, + INPUT_PROP=true, + MT_TOOL=true, +} + +local prefixes = { + 'EV', + 'REL', + 'ABS', + 'KEY', + 'BTN', + 'LED', + 'SND', + 'MSC', + 'SW', + 'FF', + 'SYN', + 'REP', + 'INPUT_PROP', + 'MT_TOOL', +} + +local bits = {} +for _, prefix in ipairs(prefixes) do + bits[prefix] = {} +end +bits.EV.map = {} + +local function lookuptable(prefix) + local entries = {} + for _, name in ipairs(bits[prefix]) do + table.insert(entries, name) + end + local max = prefix..'_MAX' + if duplicates[max] then + table.insert(entries, max) + end + table.sort(entries) + for _, name in ipairs(entries) do + io.write(string.format(' { .name = "%s", .value = %s },\n', name, name)) + end +end + +for i = 1, #arg do + for line in io.lines(arg[i]) do + local name, value = line:match('^#define%s+([%w_]+)%s+(%dx?%x*)') + value = tonumber(value) + if name and not duplicates[name] then + for prefix, b in pairs(bits) do + if name:sub(1, #prefix + 1) == prefix..'_' then + if b.map then + b.map[value] = name + b.map[name] = value + end + table.insert(b, name) + end + end + end + end +end + +io.write[[ +/* THIS FILE IS GENERATED, DO NOT EDIT */ + +#ifndef EVENT_NAMES_H +#define EVENT_NAMES_H + +]] +for _, prefix in ipairs(prefixes) do + if prefix ~= 'BTN' then + io.write(string.format('static const char * const %s_map[%s_MAX + 1] = {\n', prefix:lower(), prefix)) + for _, name in ipairs(bits[prefix]) do + io.write(string.format(' [%s] = "%s",\n', name, name)) + end + if prefix == 'KEY' then + for _, name in ipairs(bits.BTN) do + io.write(string.format(' [%s] = "%s",\n', name, name)) + end + end + io.write[[ +}; + +]] + end +end +for _, name in ipairs{'BTN_A', 'BTN_B', 'BTN_X', 'BTN_Y'} do + table.insert(bits.BTN, name) +end +io.write[[ +static const char * const * const event_type_map[EV_MAX + 1] = { +]] +for _, prefix in ipairs(prefixes) do + if not skip[prefix] then + print(string.format(' [EV_%s] = %s_map,', prefix, prefix:lower())) + end +end +io.write[[ +}; + +#if __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winitializer-overrides" +#elif __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Woverride-init" +#endif +static const int ev_max[EV_MAX + 1] = { +]] +for i = 0, bits.EV.map.EV_MAX do + local name = bits.EV.map[i] + if name and bits[name:sub(4)] then + io.write(string.format(' %s_MAX,\n', name:sub(4))) + else + io.write(' -1,\n') + end +end +io.write[[ +}; +#if __clang__ +#pragma clang diagnostic pop /* "-Winitializer-overrides" */ +#elif __GNUC__ +#pragma GCC diagnostic pop /* "-Woverride-init" */ +#endif + +struct name_entry { + const char *name; + unsigned int value; +}; + +static const struct name_entry tool_type_names[] = { +]] +lookuptable('MT_TOOL') +io.write[[ +}; + +static const struct name_entry ev_names[] = { +]] +lookuptable('EV') +io.write[[ +}; + +static const struct name_entry code_names[] = { +]] +lookuptable('ABS') +lookuptable('BTN') +lookuptable('FF') +lookuptable('KEY') +lookuptable('LED') +lookuptable('MSC') +lookuptable('REL') +lookuptable('REP') +lookuptable('SND') +lookuptable('SW') +lookuptable('SYN') +io.write[[ +}; + +static const struct name_entry prop_names[] = { +]] +lookuptable('INPUT_PROP') +io.write[[ +}; + +#endif /* EVENT_NAMES_H */ +]] diff --git a/pkg/libevdev/gen.sh b/pkg/libevdev/gen.sh @@ -0,0 +1,38 @@ +git libevdev-1.12.0 + +cflags " + -I$dir + -I$outdir + -I$srcdir + -I$srcdir/include + -isystem $pkgdir/linux-headers/include + -Wno-pedantic + -Wno-unused-parameter +" + +dep " + linux-headers/headers + $outdir/event-names.h +" + +include --src-prefix libevdev --prefix libevdev " + libevdev.h +" + +rule eventnames 'lua $dir/eventnames.lua $in >$out' +bind description 'EVENTNAMES $out' + +eventnames event-names.h " + include/linux/linux/input.h + include/linux/linux/input-event-codes.h +" + +lib libevdev.a --src-prefix libevdev " + libevdev.c + libevdev-names.c +" + +bin libevdev-events " + tools/libevdev-events.c + libevdev.a +" diff --git a/pkg/libevdev/patch/0001-Revert-switch-to-VLAs-for-multitouch-state.patch b/pkg/libevdev/patch/0001-Revert-switch-to-VLAs-for-multitouch-state.patch @@ -0,0 +1,273 @@ +From 20dd0f459d92805cdd33a7622382f118acf3c07d Mon Sep 17 00:00:00 2001 +From: Michael Forney <mforney@mforney.org> +Date: Tue, 3 Mar 2020 14:17:37 -0800 +Subject: [PATCH libevdev] Revert switch to VLAs for multitouch state + +Signed-off-by: Michael Forney <mforney@mforney.org> +--- + libevdev/libevdev-int.h | 28 +++++++++++++ + libevdev/libevdev.c | 87 +++++++++++++++++++---------------------- + 2 files changed, 68 insertions(+), 47 deletions(-) + +diff --git a/libevdev/libevdev-int.h b/libevdev/libevdev-int.h +index 8e2518e..bc291ea 100644 +--- a/libevdev/libevdev-int.h ++++ b/libevdev/libevdev-int.h +@@ -7,6 +7,7 @@ + #define LIBEVDEV_INT_H + + #include "config.h" ++#include <stdint.h> + #include <stdio.h> + #include <stdlib.h> + #include <stdbool.h> +@@ -38,6 +39,26 @@ enum SyncState { + SYNC_IN_PROGRESS, + }; + ++struct mt_sync_state { ++ uint32_t code; ++ int32_t val[]; ++}; ++ ++/* Keeps a record of touches during SYN_DROPPED */ ++enum touch_state { ++ TOUCH_OFF, ++ TOUCH_STARTED, /* Started during SYN_DROPPED */ ++ TOUCH_STOPPED, /* Stopped during SYN_DROPPED */ ++ TOUCH_ONGOING, /* Existed before, still have same tracking ID */ ++ TOUCH_CHANGED, /* Existed before but have new tracking ID now, so ++ stopped + started in that slot */ ++}; ++ ++struct slot_change_state { ++ enum touch_state state; ++ unsigned long axes[NLONGS(ABS_CNT)]; /* bitmask for updated axes */ ++}; ++ + /** + * Internal only: log data used to send messages to the respective log + * handler. We re-use the same struct for a global and inside +@@ -90,6 +111,13 @@ struct libevdev { + + struct timeval last_event_time; + ++ struct { ++ struct mt_sync_state *mt_state; ++ size_t mt_state_sz; /* in bytes */ ++ struct slot_change_state *changes; ++ size_t changes_sz; /* in bytes */ ++ } mt_sync; ++ + struct logdata log; + }; + +diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c +index b941cfb..1cc912c 100644 +--- a/libevdev/libevdev.c ++++ b/libevdev/libevdev.c +@@ -28,23 +28,7 @@ enum event_filter_status { + EVENT_FILTER_DISCARD, /**< Discard current event */ + }; + +-/* Keeps a record of touches during SYN_DROPPED */ +-enum touch_state { +- TOUCH_OFF, +- TOUCH_STARTED, /* Started during SYN_DROPPED */ +- TOUCH_STOPPED, /* Stopped during SYN_DROPPED */ +- TOUCH_ONGOING, /* Existed before, still have same tracking ID */ +- TOUCH_CHANGED, /* Existed before but have new tracking ID now, so +- stopped + started in that slot */ +-}; +- +-struct slot_change_state { +- enum touch_state state; +- unsigned long axes[NLONGS(ABS_CNT)]; /* bitmask for updated axes */ +-}; +- +-static int sync_mt_state(struct libevdev *dev, +- struct slot_change_state *changes_out); ++static int sync_mt_state(struct libevdev *dev); + static int + update_key_state(struct libevdev *dev, const struct input_event *e); + +@@ -203,6 +187,8 @@ libevdev_reset(struct libevdev *dev) + free(dev->phys); + free(dev->uniq); + free(dev->mt_slot_vals); ++ free(dev->mt_sync.mt_state); ++ free(dev->mt_sync.changes); + memset(dev, 0, sizeof(*dev)); + dev->fd = -1; + dev->initialized = false; +@@ -331,7 +317,11 @@ free_slots(struct libevdev *dev) + { + dev->num_slots = -1; + free(dev->mt_slot_vals); ++ free(dev->mt_sync.changes); ++ free(dev->mt_sync.mt_state); + dev->mt_slot_vals = NULL; ++ dev->mt_sync.changes = NULL; ++ dev->mt_sync.mt_state = NULL; + } + + static int +@@ -341,7 +331,11 @@ init_slots(struct libevdev *dev) + int rc = 0; + + free(dev->mt_slot_vals); ++ free(dev->mt_sync.changes); ++ free(dev->mt_sync.mt_state); + dev->mt_slot_vals = NULL; ++ dev->mt_sync.changes = NULL; ++ dev->mt_sync.mt_state = NULL; + + /* devices with ABS_RESERVED aren't MT devices, + see the documentation for multitouch-related +@@ -365,6 +359,19 @@ init_slots(struct libevdev *dev) + } + dev->current_slot = abs_info->value; + ++ dev->mt_sync.mt_state_sz = sizeof(*dev->mt_sync.mt_state) + ++ dev->num_slots * sizeof(int32_t); ++ dev->mt_sync.mt_state = calloc(1, dev->mt_sync.mt_state_sz); ++ ++ dev->mt_sync.changes_sz = dev->num_slots * ++ sizeof(dev->mt_sync.changes[0]); ++ dev->mt_sync.changes = malloc(dev->mt_sync.changes_sz); ++ ++ if (!dev->mt_sync.changes || !dev->mt_sync.mt_state) { ++ rc = -ENOMEM; ++ goto out; ++ } ++ + reset_tracking_ids(dev); + out: + return rc; +@@ -523,10 +530,8 @@ libevdev_set_fd(struct libevdev* dev, int fd) + if (rc != 0) + goto out; + +- if (dev->num_slots != -1) { +- struct slot_change_state unused[dev->num_slots]; +- sync_mt_state(dev, unused); +- } ++ if (dev->num_slots != -1) ++ sync_mt_state(dev); + + rc = init_event_queue(dev); + if (rc < 0) { +@@ -661,33 +666,27 @@ out: + } + + static int +-sync_mt_state(struct libevdev *dev, +- struct slot_change_state changes_out[dev->num_slots]) ++sync_mt_state(struct libevdev *dev) + { +-#define MAX_SLOTS 256 + int rc = 0; +- struct slot_change_state changes[MAX_SLOTS] = {0}; +- unsigned int nslots = min(MAX_SLOTS, dev->num_slots); ++ struct mt_sync_state *mt_state = dev->mt_sync.mt_state; ++ struct slot_change_state *changes = dev->mt_sync.changes; + +- for (int axis = ABS_MT_MIN; axis <= ABS_MT_MAX; axis++) { +- /* EVIOCGMTSLOTS required format */ +- struct mt_sync_state { +- uint32_t code; +- int32_t val[MAX_SLOTS]; +- } mt_state; ++ memset(dev->mt_sync.changes, 0, dev->mt_sync.changes_sz); + ++ for (int axis = ABS_MT_MIN; axis <= ABS_MT_MAX; axis++) { + if (axis == ABS_MT_SLOT || + !libevdev_has_event_code(dev, EV_ABS, axis)) + continue; + +- mt_state.code = axis; +- rc = ioctl(dev->fd, EVIOCGMTSLOTS(sizeof(mt_state)), &mt_state); ++ mt_state->code = axis; ++ rc = ioctl(dev->fd, EVIOCGMTSLOTS(dev->mt_sync.mt_state_sz), mt_state); + if (rc < 0) + goto out; + +- for (unsigned int slot = 0; slot < nslots; slot++) { ++ for (int slot = 0; slot < dev->num_slots; slot++) { + int val_before = *slot_value(dev, slot, axis), +- val_after = mt_state.val[slot]; ++ val_after = mt_state->val[slot]; + + if (axis == ABS_MT_TRACKING_ID) { + if (val_before == -1 && val_after != -1) { +@@ -716,17 +715,12 @@ sync_mt_state(struct libevdev *dev, + } + } + +- if (dev->num_slots > MAX_SLOTS) +- memset(changes_out, 0, sizeof(*changes) * dev->num_slots); +- +- memcpy(changes_out, changes, sizeof(*changes) * nslots); + out: + return rc; + } + + static void + terminate_slots(struct libevdev *dev, +- const struct slot_change_state changes[dev->num_slots], + int *last_reported_slot) + { + const unsigned int map[] = {BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP, +@@ -734,6 +728,7 @@ terminate_slots(struct libevdev *dev, + BTN_TOOL_QUINTTAP}; + bool touches_stopped = false; + int ntouches_before = 0, ntouches_after = 0; ++ struct slot_change_state *changes = dev->mt_sync.changes; + + /* For BTN_TOOL_* emulation, we need to know how many touches we had + * before and how many we have left once we terminate all the ones +@@ -797,10 +792,10 @@ terminate_slots(struct libevdev *dev, + + static int + push_mt_sync_events(struct libevdev *dev, +- const struct slot_change_state changes[dev->num_slots], + int last_reported_slot) + { + struct input_absinfo abs_info; ++ struct slot_change_state *changes = dev->mt_sync.changes; + int rc; + + for (int slot = 0; slot < dev->num_slots; slot++) { +@@ -909,8 +904,6 @@ sync_state(struct libevdev *dev) + int rc = 0; + bool want_mt_sync = false; + int last_reported_slot = 0; +- struct slot_change_state changes[dev->num_slots > 0 ? dev->num_slots : 1]; +- memset(changes, 0, sizeof(changes)); + + /* see section "Discarding events before synchronizing" in + * libevdev/libevdev.h */ +@@ -928,9 +921,9 @@ sync_state(struct libevdev *dev) + if (dev->num_slots > -1 && + libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT)) { + want_mt_sync = true; +- rc = sync_mt_state(dev, changes); ++ rc = sync_mt_state(dev); + if (rc == 0) +- terminate_slots(dev, changes, &last_reported_slot); ++ terminate_slots(dev, &last_reported_slot); + else + want_mt_sync = false; + } +@@ -944,7 +937,7 @@ sync_state(struct libevdev *dev) + if (rc == 0 && libevdev_has_event_type(dev, EV_ABS)) + rc = sync_abs_state(dev); + if (rc == 0 && want_mt_sync) +- push_mt_sync_events(dev, changes, last_reported_slot); ++ push_mt_sync_events(dev, last_reported_slot); + + dev->queue_nsync = queue_num_elements(dev); + +-- +2.30.0 +