Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/include/kbd/kbdfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct kbdfile *kbdfile_open(struct kbdfile_ctx *ctx, const char *filename);
void kbdfile_close(struct kbdfile *fp);

int kbdfile_find(const char *fnam, const char *const *dirpath, const char *const *suffixes, struct kbdfile *fp);
int kbdfile_compile(const char *xkb_desc, struct kbdfile *fp);

char *kbdfile_get_pathname(struct kbdfile *fp);
int kbdfile_set_pathname(struct kbdfile *fp, const char *pathname);
Expand Down
62 changes: 62 additions & 0 deletions src/libkbdfile/kbdfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <ctype.h>

#include <kbdfile.h>

Expand Down Expand Up @@ -525,6 +526,67 @@ kbdfile_find(const char *fnam, const char *const *dirpath, const char *const *su
return 1;
}

int
kbdfile_compile(const char *xkb_desc, struct kbdfile *fp)
{
int i;

if (fp->fd != NULL) {
ERR(fp->ctx, "can't compile `%s', because kbdfile already opened: %s", xkb_desc, fp->pathname);
return -1;
}

for (i = 0; xkb_desc[i]; i++)
if (!isalpha((unsigned char) xkb_desc[i]) &&
!isdigit((unsigned char) xkb_desc[i]) &&
/* - and _ in variant names; / in a layout name; : as separator */
!strchr("-/_:", xkb_desc[i]))
break;

if (!xkb_desc[i]) {
char *layout, *variant;
char *colon;
size_t cmdsize;
char *cmd;
int rc = 0;

layout = strdup(xkb_desc);
colon = strchr(layout, ':');
if (colon) {
*colon = '\0';
variant = strdup(colon + 1);
} else
variant = NULL;

cmdsize = sizeof("ckbcomp -model pc105 ");
if (variant) {
cmdsize += strlen(layout) + 1 + strlen(variant);
cmd = malloc(cmdsize);
sprintf(cmd, "ckbcomp -model pc105 %s %s", layout, variant);
} else {
cmdsize += strlen(layout);
cmd = malloc(cmdsize);
sprintf(cmd, "ckbcomp -model pc105 %s", layout);
}

kbdfile_set_pathname(fp, xkb_desc);
fp->fd = popen(cmd, "r");
fp->flags |= KBDFILE_PIPE;
if (!(fp->fd)) {
char buf[200];
strerror_r(errno, buf, sizeof(buf));
ERR(fp->ctx, "popen: %s: %s", cmd, buf);
rc = -1;
}

free(variant);
free(layout);
free(cmd);
return rc;
}
return 1;
}

struct kbdfile *
kbdfile_open(struct kbdfile_ctx *ctx, const char *filename)
{
Expand Down
6 changes: 4 additions & 2 deletions src/loadkeys.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,10 @@ int main(int argc, char *argv[])
kbdfile_set_pathname(fp, "<stdin>");

} else if (kbdfile_find(argv[i], dirpath, suffixes, fp)) {
kbd_warning(0, _("Unable to open file: %s: %m"), argv[i]);
goto fail;
if (kbdfile_compile(argv[i], fp)) {
kbd_warning(0, _("Unable to open file: %s: %m"), argv[i]);
goto fail;
}
}

rc = lk_parse_keymap(ctx, fp);
Expand Down