initial commit

This commit is contained in:
Richard Acayan 2024-04-15 22:11:00 -04:00
commit 1c606d0274
No known key found for this signature in database
GPG key ID: 0346F4894879DB73
36 changed files with 9908 additions and 0 deletions

170
keymap.c Normal file
View file

@ -0,0 +1,170 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* XKB keymap manager.
*
* Copyright (c) 2024, Richard Acayan. All rights reserved.
*/
#include <ctype.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbcommon-keysyms.h>
#include "keymap.h"
#include "layout.h"
#include "ufkbd.h"
static int write_keysym(int fd, xkb_keysym_t sym)
{
char *name;
int len, ret;
len = xkb_keysym_get_name(sym, NULL, 0);
if (len == -1)
return len;
name = malloc((size_t) len + 1);
if (name == NULL)
return -1;
xkb_keysym_get_name(sym, name, (size_t) len + 1);
ret = dprintf(fd, "%s", name);
free(name);
return ret;
}
static int maybe_write_modmap(int fd, int keyid, xkb_keysym_t sym)
{
if (sym == XKB_KEY_Shift_L || sym == XKB_KEY_Shift_R)
return dprintf(fd, " modifier_map Shift { <I%03d> };\n",
keyid);
else if (sym == XKB_KEY_Control_L || sym == XKB_KEY_Control_R)
return dprintf(fd, " modifier_map Control { <I%03d> };\n",
keyid);
else if (sym == XKB_KEY_Alt_L || sym == XKB_KEY_Alt_R)
return dprintf(fd, " modifier_map Mod1 { <I%03d> };\n",
keyid);
return 0;
}
int ufkbd_keymap_add_key(struct ufkbd_keymap *keymap, xkb_keysym_t keysym)
{
xkb_keysym_t upper;
int len;
int keyid;
keyid = keymap->count;
if (keyid >= 256)
return -1;
upper = xkb_keysym_to_upper(keysym);
len = dprintf(keymap->fd, " key <I%03d> { [ ", keyid);
if (len == -1)
return len;
keymap->size += len;
len = write_keysym(keymap->fd, keysym);
if (len == -1)
return len;
keymap->size += len;
len = dprintf(keymap->fd, ", ");
if (len == -1)
return len;
keymap->size += len;
len = write_keysym(keymap->fd, upper);
if (len == -1)
return len;
keymap->size += len;
len = dprintf(keymap->fd, " ] };\n");
if (len == -1)
return len;
keymap->size += len;
len = maybe_write_modmap(keymap->fd, keyid, keysym);
if (len == -1)
return len;
keymap->size += len;
keymap->count++;
return keyid;
}
void ufkbd_keymap_end(struct ufkbd_keymap *keymap)
{
int i;
int fd = keymap->fd;
size_t written;
written = dprintf(fd, " };\n"
"\n"
" xkb_keycodes \"ufkbd\" {\n"
" minimum = 8;\n"
" maximum = 255;\n");
for (i = 8; i < keymap->count; i++)
written += dprintf(fd, " <I%03d> = %d;\n", i, i);
written += dprintf(fd, " indicator 1 = \"Caps Lock\";\n"
" };\n"
"\n"
" xkb_types \"ufkbd\" {\n"
" type \"TWO_LEVEL\" {\n"
" modifiers = Shift;\n"
" map[Shift] = Level2;\n"
" level_name[Level1] = \"Base\";\n"
" level_name[Level2] = \"Shift\";\n"
" };\n"
" };\n"
"\n"
" xkb_compatibility \"ufkbd\" {\n"
" };\n"
"};\n");
keymap->size += written;
}
struct ufkbd_keymap *ufkbd_keymap_init(void)
{
struct ufkbd_keymap *keymap;
intmax_t pid;
keymap = malloc(sizeof(*keymap));
if (keymap == NULL)
return NULL;
pid = getpid();
snprintf(keymap->path, 256, "/tmp/ufkbd-keymap-pid%ju", pid);
keymap->fd = open(keymap->path, O_RDWR | O_CREAT | O_TRUNC, 0644);
if (keymap->fd == -1)
goto err;
keymap->count = 8;
keymap->size = dprintf(keymap->fd, "xkb_keymap {\n"
" xkb_symbols \"ufkbd\" {\n");
return keymap;
err:
free(keymap);
return NULL;
}
void ufkbd_keymap_uninit(struct ufkbd_keymap *keymap)
{
close(keymap->fd);
unlink(keymap->path);
free(keymap);
}