From patchwork Wed Jan 29 11:54:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Young X-Patchwork-Id: 11355925 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 980DE188B for ; Wed, 29 Jan 2020 11:54:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7CF1C20720 for ; Wed, 29 Jan 2020 11:54:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726622AbgA2LyW (ORCPT ); Wed, 29 Jan 2020 06:54:22 -0500 Received: from gofer.mess.org ([88.97.38.141]:35395 "EHLO gofer.mess.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726140AbgA2LyV (ORCPT ); Wed, 29 Jan 2020 06:54:21 -0500 Received: by gofer.mess.org (Postfix, from userid 1000) id 34F5CC643D; Wed, 29 Jan 2020 11:54:19 +0000 (GMT) From: Sean Young To: linux-media@vger.kernel.org Cc: Frank Wunderlich Subject: [PATCH v4l-utils 1/4] keytable: support 64 bit scancodes Date: Wed, 29 Jan 2020 11:54:15 +0000 Message-Id: <20200129115419.8456-1-sean@mess.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Signed-off-by: Sean Young --- utils/common/keymap.c | 4 +- utils/common/keymap.h | 4 +- utils/keytable/keytable.c | 80 +++++++++++++++++++++++++++------------ 3 files changed, 59 insertions(+), 29 deletions(-) diff --git a/utils/common/keymap.c b/utils/common/keymap.c index d06deb59..15c31c76 100644 --- a/utils/common/keymap.c +++ b/utils/common/keymap.c @@ -162,7 +162,7 @@ static error_t parse_plain_keymap(char *fname, struct keymap **keymap, bool verb return ENOMEM; } - se->scancode = strtoul(scancode, NULL, 0); + se->scancode = strtoull(scancode, NULL, 0); se->keycode = strdup(keycode); se->next = map->scancode; map->scancode = se; @@ -442,7 +442,7 @@ static error_t parse_toml_protocol(const char *fname, struct toml_table_t *proot return ENOMEM; } - se->scancode = strtoul(scancode, NULL, 0); + se->scancode = strtoull(scancode, NULL, 0); se->keycode = keycode; *next = se; next = &se->next; diff --git a/utils/common/keymap.h b/utils/common/keymap.h index f2b29632..99833827 100644 --- a/utils/common/keymap.h +++ b/utils/common/keymap.h @@ -20,13 +20,13 @@ struct protocol_param { struct scancode_entry { struct scancode_entry *next; - u_int32_t scancode; + u_int64_t scancode; char *keycode; }; struct raw_entry { struct raw_entry *next; - u_int32_t scancode; + u_int64_t scancode; u_int32_t raw_length; char *keycode; u_int32_t raw[1]; diff --git a/utils/keytable/keytable.c b/utils/keytable/keytable.c index e2a1bfe1..cc1b5217 100644 --- a/utils/keytable/keytable.c +++ b/utils/keytable/keytable.c @@ -76,7 +76,8 @@ struct input_keymap_entry_v2 { #endif struct keytable_entry { - u_int32_t scancode; + // 64 bit int which can printed with %llx + unsigned long long scancode; u_int32_t keycode; struct keytable_entry *next; }; @@ -400,7 +401,7 @@ static int add_keymap(struct keymap *map, const char *fname) if (value == -1) { value = strtol(se->keycode, &p, 0); if (errno || *p) { - fprintf(stderr, _("%s: keycode `%s' not recognised, no mapping for scancode %d\n"), fname, se->keycode, se->scancode); + fprintf(stderr, _("%s: keycode `%s' not recognised, no mapping for scancode %llx\n"), fname, se->keycode, (unsigned long long)se->scancode); continue; } } @@ -589,7 +590,7 @@ static error_t parse_opt(int k, char *arg, struct argp_state *state) return ENOMEM; } - ke->scancode = strtoul(p, NULL, 0); + ke->scancode = strtoull(p, NULL, 0); if (errno) { free(ke); argp_error(state, _("Invalid scancode: %s"), p); @@ -616,7 +617,7 @@ static error_t parse_opt(int k, char *arg, struct argp_state *state) ke->keycode = key; if (debug) - fprintf(stderr, _("scancode 0x%04x=%u\n"), + fprintf(stderr, _("scancode 0x%04llx=%u\n"), ke->scancode, ke->keycode); ke->next = keytable; @@ -722,21 +723,21 @@ static struct argp argp = { .doc = doc, }; -static void prtcode(int *codes) +static void prtcode(unsigned long long scancode, int keycode) { struct parse_event *p; for (p = key_events; p->name != NULL; p++) { - if (p->value == (unsigned)codes[1]) { - printf(_("scancode 0x%04x = %s (0x%02x)\n"), codes[0], p->name, codes[1]); + if (p->value == keycode) { + printf(_("scancode 0x%04llx = %s (0x%02x)\n"), scancode, p->name, keycode); return; } } - if (isprint (codes[1])) - printf(_("scancode 0x%04x = '%c' (0x%02x)\n"), codes[0], codes[1], codes[1]); + if (isprint (keycode)) + printf(_("scancode 0x%04llx = '%c' (0x%02x)\n"), scancode, keycode, keycode); else - printf(_("scancode 0x%04x = 0x%02x\n"), codes[0], codes[1]); + printf(_("scancode 0x%04llx = 0x%02x\n"), scancode, keycode); } static void free_names(struct sysfs_names *names) @@ -1399,17 +1400,34 @@ static int add_keys(int fd) for (ke = keytable; ke; ke = ke->next) { write_cnt++; if (debug) - fprintf(stderr, "\t%04x=%04x\n", + fprintf(stderr, "\t%04llx=%04x\n", ke->scancode, ke->keycode); codes[0] = ke->scancode; codes[1] = ke->keycode; - if (ioctl(fd, EVIOCSKEYCODE, codes)) { - fprintf(stderr, - _("Setting scancode 0x%04x with 0x%04x via "), - ke->scancode, ke->keycode); - perror("EVIOCSKEYCODE"); + if (codes[0] != ke->scancode) { + // 64 bit scancode + struct input_keymap_entry_v2 entry = { + .keycode = ke->keycode, + .len = sizeof(ke->scancode) + }; + + memcpy(entry.scancode, &ke->scancode, sizeof(ke->scancode)); + + if (ioctl(fd, EVIOCSKEYCODE_V2, &entry)) { + fprintf(stderr, + _("Setting scancode 0x%04llx with 0x%04x via "), + ke->scancode, ke->keycode); + perror("EVIOCSKEYCODE"); + } + } else { + if (ioctl(fd, EVIOCSKEYCODE, codes)) { + fprintf(stderr, + _("Setting scancode 0x%04llx with 0x%04x via "), + ke->scancode, ke->keycode); + perror("EVIOCSKEYCODE"); + } } } @@ -1596,7 +1614,7 @@ static void display_table_v1(struct rc_device *rc_dev, int fd) if (ioctl(fd, EVIOCGKEYCODE, codes) == -1) perror("EVIOCGKEYCODE"); else if (codes[1] != KEY_RESERVED) - prtcode(codes); + prtcode(codes[0], codes[1]); } } display_proto(rc_dev); @@ -1604,25 +1622,37 @@ static void display_table_v1(struct rc_device *rc_dev, int fd) static void display_table_v2(struct rc_device *rc_dev, int fd) { + struct input_keymap_entry_v2 entry = {}; + unsigned long long scancode; int i; - struct input_keymap_entry_v2 entry; - int codes[2]; - memset(&entry, '\0', sizeof(entry)); i = 0; do { entry.flags = KEYMAP_BY_INDEX; entry.index = i; - entry.len = sizeof(u_int32_t); + entry.len = sizeof(scancode); if (ioctl(fd, EVIOCGKEYCODE_V2, &entry) == -1) break; - /* FIXME: Extend it to support scancodes > 32 bits */ - memcpy(&codes[0], entry.scancode, sizeof(codes[0])); - codes[1] = entry.keycode; + if (entry.len == sizeof(u_int32_t)) { + u_int32_t temp; + + memcpy(&temp, entry.scancode, sizeof(temp)); + + scancode = temp; + } else if (entry.len == sizeof(u_int64_t)) { + u_int64_t temp; + + memcpy(&temp, entry.scancode, sizeof(temp)); + + scancode = temp; + } else { + printf("error: unknown scancode length %d\n", entry.len); + continue; + } - prtcode(codes); + prtcode(scancode, entry.keycode); i++; } while (1); display_proto(rc_dev); From patchwork Wed Jan 29 11:54:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Young X-Patchwork-Id: 11355921 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 008FD1395 for ; Wed, 29 Jan 2020 11:54:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DD44220732 for ; Wed, 29 Jan 2020 11:54:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726632AbgA2LyW (ORCPT ); Wed, 29 Jan 2020 06:54:22 -0500 Received: from gofer.mess.org ([88.97.38.141]:53595 "EHLO gofer.mess.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726599AbgA2LyV (ORCPT ); Wed, 29 Jan 2020 06:54:21 -0500 Received: by gofer.mess.org (Postfix, from userid 1000) id 709F1C645D; Wed, 29 Jan 2020 11:54:19 +0000 (GMT) From: Sean Young To: linux-media@vger.kernel.org Cc: Frank Wunderlich Subject: [PATCH v4l-utils 2/4] keytable: new samsung36 bpf decoder Date: Wed, 29 Jan 2020 11:54:17 +0000 Message-Id: <20200129115419.8456-3-sean@mess.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200129115419.8456-1-sean@mess.org> References: <20200129115419.8456-1-sean@mess.org> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Signed-off-by: Sean Young --- utils/keytable/bpf_protocols/Makefile.am | 2 +- utils/keytable/bpf_protocols/samsung36.c | 136 +++++++++++++++++++++++ 2 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 utils/keytable/bpf_protocols/samsung36.c diff --git a/utils/keytable/bpf_protocols/Makefile.am b/utils/keytable/bpf_protocols/Makefile.am index 3423aba1..13be2794 100644 --- a/utils/keytable/bpf_protocols/Makefile.am +++ b/utils/keytable/bpf_protocols/Makefile.am @@ -10,7 +10,7 @@ CLANG_SYS_INCLUDES := $(shell $(CLANG) -v -E - &1 \ %.o: %.c bpf_helpers.h $(CLANG) $(CLANG_SYS_INCLUDES) -D__linux__ -I$(top_srcdir)/include -target bpf -O2 -c $< -PROTOCOLS = grundig.o pulse_distance.o pulse_length.o rc_mm.o manchester.o xbox-dvd.o imon_rsc.o raw.o +PROTOCOLS = grundig.o pulse_distance.o pulse_length.o rc_mm.o manchester.o xbox-dvd.o imon_rsc.o raw.o samsung36.o all: $(PROTOCOLS) diff --git a/utils/keytable/bpf_protocols/samsung36.c b/utils/keytable/bpf_protocols/samsung36.c new file mode 100644 index 00000000..1b09365f --- /dev/null +++ b/utils/keytable/bpf_protocols/samsung36.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Remote protocol used by some Samsung remotes. It has 36 bits and the +// 16th bit is not really a bit, but a marker to distinguish it from +// shorter samsung protocols. +// +// http://www.hifi-remote.com/wiki/index.php/DecodeIR#Samsung36 +// Copyright (C) 2020 Sean Young + +#include +#include + +#include "bpf_helpers.h" + +enum state { + STATE_INACTIVE, + STATE_HEADER_SPACE, + STATE_BITS_SPACE, + STATE_BITS_PULSE, + STATE_TRAILER, +}; + +struct decoder_state { + unsigned long bits; + enum state state; + unsigned int count; +}; + +struct bpf_map_def SEC("maps") decoder_state_map = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(unsigned int), + .value_size = sizeof(struct decoder_state), + .max_entries = 1, +}; + +// These values can be overridden in the rc_keymap toml +// +// We abuse elf relocations. We cast the address of these variables to +// an int, so that the compiler emits a mov immediate for the address +// but uses it as an int. The bpf loader replaces the relocation with the +// actual value (either overridden or taken from the data segment). +int margin = 300; +int rc_protocol = 69; + +#define BPF_PARAM(x) (int)(&(x)) + +static inline int eq_margin(unsigned d1, unsigned d2) +{ + return ((d1 > (d2 - BPF_PARAM(margin))) && (d1 < (d2 + BPF_PARAM(margin)))); +} + +SEC("samsung36") +int bpf_decoder(unsigned int *sample) +{ + unsigned int key = 0; + struct decoder_state *s = bpf_map_lookup_elem(&decoder_state_map, &key); + + if (!s) + return 0; + + switch (*sample & LIRC_MODE2_MASK) { + case LIRC_MODE2_SPACE: + case LIRC_MODE2_PULSE: + case LIRC_MODE2_TIMEOUT: + break; + default: + // not a timing events + return 0; + } + + int duration = LIRC_VALUE(*sample); + int pulse = LIRC_IS_PULSE(*sample); + + switch (s->state) { + case STATE_INACTIVE: + if (pulse && eq_margin(duration, 4500)) { + s->bits = 0; + s->state = STATE_HEADER_SPACE; + s->count = 0; + } + break; + case STATE_HEADER_SPACE: + if (!pulse && eq_margin(duration, 4500)) + s->state = STATE_BITS_PULSE; + else + s->state = STATE_INACTIVE; + break; + case STATE_BITS_PULSE: + if (pulse && eq_margin(duration, 500)) + s->state = STATE_BITS_SPACE; + else + s->state = STATE_INACTIVE; + break; + case STATE_BITS_SPACE: + if (pulse) { + s->state = STATE_INACTIVE; + break; + } + + s->count++; + + if (s->count == 17) { + if (eq_margin(duration, 4450)) { + s->state = STATE_BITS_PULSE; + } else { + s->state = STATE_INACTIVE; + } + break; + } + + s->bits <<= 1; + + if (eq_margin(duration, 1600)) { + s->bits |= 1; + } else if (!eq_margin(duration, 500)) { + s->state = STATE_INACTIVE; + break; + } + + if (s->count == 37) + s->state = STATE_TRAILER; + else + s->state = STATE_BITS_PULSE; + break; + case STATE_TRAILER: + if (pulse && eq_margin(duration, 500)) { + bpf_rc_keydown(sample, BPF_PARAM(rc_protocol), s->bits, 0); + } + + s->state = STATE_INACTIVE; + } + + return 0; +} + +char _license[] SEC("license") = "GPL"; From patchwork Wed Jan 29 11:54:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Young X-Patchwork-Id: 11355929 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4011F1395 for ; Wed, 29 Jan 2020 11:54:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1EBC420732 for ; Wed, 29 Jan 2020 11:54:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726668AbgA2LyY (ORCPT ); Wed, 29 Jan 2020 06:54:24 -0500 Received: from gofer.mess.org ([88.97.38.141]:37937 "EHLO gofer.mess.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726604AbgA2LyV (ORCPT ); Wed, 29 Jan 2020 06:54:21 -0500 Received: by gofer.mess.org (Postfix, from userid 1000) id 9AC90C6460; Wed, 29 Jan 2020 11:54:19 +0000 (GMT) From: Sean Young To: linux-media@vger.kernel.org Cc: Frank Wunderlich Subject: [PATCH v4l-utils 3/4] Add keymap for Samsung AK59-00125A remote Date: Wed, 29 Jan 2020 11:54:18 +0000 Message-Id: <20200129115419.8456-4-sean@mess.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200129115419.8456-1-sean@mess.org> References: <20200129115419.8456-1-sean@mess.org> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Signed-off-by: Sean Young --- .../samsung_ak59_00125a.toml | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 utils/keytable/rc_keymaps_userspace/samsung_ak59_00125a.toml diff --git a/utils/keytable/rc_keymaps_userspace/samsung_ak59_00125a.toml b/utils/keytable/rc_keymaps_userspace/samsung_ak59_00125a.toml new file mode 100644 index 00000000..5d068f7c --- /dev/null +++ b/utils/keytable/rc_keymaps_userspace/samsung_ak59_00125a.toml @@ -0,0 +1,69 @@ +[[protocols]] +name = 'Samsung AK59-00125A' +protocol = 'pulse_distance' +header_pulse = 4500 +header_space = 4500 +bit_pulse = 600 +bit_0_space = 500 +bit_1_space = 1600 +bits = 32 +margin = 300 +trailer_pulse = 600 +[protocols.scancodes] +0xe0e040bf = "KEY_POWER2" +# input +0xe0e0807f = "KEY_VIDEO" +0xe0e0e01f = "KEY_VOLUMEUP" +0xe0e0d02f = "KEY_VOLUMEDOWN" +0xe0e0f00f = "KEY_MUTE" +0xe0e048b7 = "KEY_CHANNELUP" +0xe0e008f7 = "KEY_CHANNELDOWN" +[[protocols]] +protocol = 'samsung36' +[protocols.scancodes] +0x400e00ff = "KEY_POWER" +# bonus view +0x400ecc33 = "KEY_VENDOR" +0x400e807f = "KEY_EJECTCD" +0x400e40bf = "KEY_NUMERIC_1" +0x400ec03f = "KEY_NUMERIC_2" +0x400e20df = "KEY_NUMERIC_3" +0x400ea05f = "KEY_NUMERIC_4" +0x400e609f = "KEY_NUMERIC_5" +0x400ee01f = "KEY_NUMERIC_6" +0x400e10ef = "KEY_NUMERIC_7" +0x400e906f = "KEY_NUMERIC_8" +0x400e50af = "KEY_NUMERIC_9" +0x400ed02f = "KEY_NUMERIC_0" +0x400ea45b = "KEY_AUDIO" +0x400e649b = "KEY_SUBTITLE" +0x400eb04f = "KEY_PREVIOUS" +0x400e8877 = "KEY_NEXT" +0x400e48b7 = "KEY_FASTREVERSE" +0x400ea857 = "KEY_FASTFORWARD" +0x400ec837 = "KEY_STOP" +0x400e28d7 = "KEY_PLAY" +0x400e4cb3 = "KEY_PAUSE" +# disc menu +0x400eb847 = "KEY_ROOT_MENU" +0x400e6897 = "KEY_MENU" +# title menu/popup +0x400e04fb = "KEY_TITLE" +# tools +0x400e5ca3 = "KEY_CONFIG" +0x400e7887 = "KEY_INFO" +0x400e18e7 = "KEY_UP" +0x400ed827 = "KEY_LEFT" +0x400e58a7 = "KEY_RIGHT" +0x400e9867 = "KEY_DOWN" +0x400e38c7 = "KEY_ENTER" +0x400ee817 = "KEY_ESC" +0x400ed42b = "KEY_EXIT" +0x400e847b = "KEY_RED" +0x400e44bb = "KEY_GREEN" +0x400ec43b = "KEY_YELLOW" +0x400e24db = "KEY_BLUE" +# smart/hub +0x400e1ce3 = "KEY_VENDOR" +0x400ebc43 = "KEY_SEARCH" +0x400ee41b = "KEY_MEDIA_REPEAT" From patchwork Wed Jan 29 11:54:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Young X-Patchwork-Id: 11355927 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E4BEA1395 for ; Wed, 29 Jan 2020 11:54:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CCCCD20720 for ; Wed, 29 Jan 2020 11:54:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726620AbgA2LyV (ORCPT ); Wed, 29 Jan 2020 06:54:21 -0500 Received: from gofer.mess.org ([88.97.38.141]:60379 "EHLO gofer.mess.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726618AbgA2LyV (ORCPT ); Wed, 29 Jan 2020 06:54:21 -0500 Received: by gofer.mess.org (Postfix, from userid 1000) id AA688C6461; Wed, 29 Jan 2020 11:54:19 +0000 (GMT) From: Sean Young To: linux-media@vger.kernel.org Cc: Frank Wunderlich Subject: [PATCH v4l-utils 4/4] keytable: a bpf protocol can have parameters and no scancodes Date: Wed, 29 Jan 2020 11:54:19 +0000 Message-Id: <20200129115419.8456-5-sean@mess.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200129115419.8456-1-sean@mess.org> References: <20200129115419.8456-1-sean@mess.org> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Currently a protocol without scancodes does not get its parameters parsed. Signed-off-by: Sean Young --- utils/common/keymap.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/utils/common/keymap.c b/utils/common/keymap.c index 15c31c76..a3c1349e 100644 --- a/utils/common/keymap.c +++ b/utils/common/keymap.c @@ -384,13 +384,6 @@ static error_t parse_toml_protocol(const char *fname, struct toml_table_t *proot return EINVAL; } - scancodes = toml_table_in(proot, "scancodes"); - if (!scancodes) { - if (verbose) - fprintf(stderr, _("%s: no [protocols.scancodes] section\n"), fname); - return 0; - } - for (i = 0; (key = toml_key_in(proot, i)) != NULL; i++) { int64_t value; @@ -408,6 +401,13 @@ static error_t parse_toml_protocol(const char *fname, struct toml_table_t *proot } } + scancodes = toml_table_in(proot, "scancodes"); + if (!scancodes) { + if (verbose) + fprintf(stderr, _("%s: no [protocols.scancodes] section\n"), fname); + return 0; + } + struct scancode_entry **next = &map->scancode; i = 0;