diff --git a/src/config.c b/src/config.c index bc3f1e4..68183a8 100644 --- a/src/config.c +++ b/src/config.c @@ -163,6 +163,16 @@ static char *read_file(const char *path) return data; } +static struct layer *config_add_layer(struct config *config, + const char *name, + uint16_t mods) +{ + struct layer *layer = create_layer(name, mods); + config->layers[config->nr_layers++] = layer; + + return layer; +} + static struct layer *lookup_layer(const char *name, void *_config) { struct config *config = (struct config *) (_config); @@ -178,14 +188,48 @@ static struct layer *lookup_layer(const char *name, void *_config) /* Autovivify modifier layers as required. */ - if (!parse_modset(name, &mods)) { - struct layer *layer = create_layer(name, mods, 0); + if (!parse_modset(name, &mods)) + return config_add_layer(config, name, mods); + + return NULL; +} + + +static struct layer *config_add_layout(struct config *config, const char *name) +{ + uint16_t code; + size_t i; - config->layers[config->nr_layers++] = layer; - return layer; + struct layer *layout = config_add_layer(config, name, 0); + layout->is_layout = 1; + + for (code = 0; code < KEY_MAX; code++) { + struct descriptor d; + + d.op = OP_KEYSEQ; + d.args[0].sequence.code = code; + d.args[0].sequence.mods = 0; + + layer_set_descriptor(layout, code, &d); } - return NULL; + for (i = 0; i < sizeof(modifier_table)/sizeof(modifier_table[0]); i++) { + struct modifier_table_ent *m = &modifier_table[i]; + + struct layer *layer; + struct descriptor d; + + layer = lookup_layer(m->name, (void*)config); + assert(layer); + + d.op = OP_LAYER; + d.args[0].layer = layer; + + layer_set_descriptor(layout, m->code1, &d); + layer_set_descriptor(layout, m->code2, &d); + } + + return layout; } static int parse_header(const char *s, @@ -267,34 +311,19 @@ static void parse_id_section(struct config *config, struct ini_section *section) struct config *create_config(const char *name) { size_t i; - struct layer *main; struct config *config; config = calloc(1, sizeof(struct config)); strncpy(config->name, name, sizeof(config->name)-1); - main = create_layer("main", 0, 1); - - config->nr_layers = 0; - config->layers[config->nr_layers++] = main; - for (i = 0; i < sizeof(modifier_table)/sizeof(modifier_table[0]); i++) { struct modifier_table_ent *m = &modifier_table[i]; - struct layer *layer; - struct descriptor d; - - layer = create_layer(m->name, m->mask, 0); - - d.op = OP_LAYER; - d.args[0].layer = layer; - - layer_set_descriptor(main, m->code1, &d); - layer_set_descriptor(main, m->code2, &d); - - config->layers[config->nr_layers++] = layer; + config_add_layer(config, m->name, m->mask); } + config->default_layout = config_add_layout(config, "main"); + return config; } @@ -346,9 +375,9 @@ static int parse_config(struct config *config, char *str) if (!layer) { /* If the layer doesn't exist, create it. */ if (!strcmp(type, "layout")) - layer = create_layer(name, 0, 1); + layer = config_add_layout(config, name); else if (!parse_modset(type, &mods)) - layer = create_layer(name, mods, 0); + layer = config_add_layer(config, name, mods); else if (strcmp(type, "")) { fprintf(stderr, "WARNING %s:%zu: \"%s\" is not a valid layer type " @@ -356,8 +385,6 @@ static int parse_config(struct config *config, char *str) config->name, section->lnum, type); continue; } - - config->layers[config->nr_layers++] = layer; } layers[n] = layer; @@ -423,7 +450,6 @@ static int parse_config(struct config *config, char *str) } layer_set_descriptor(layer, code, &desc); - } } diff --git a/src/config.h b/src/config.h index b05c460..164c585 100644 --- a/src/config.h +++ b/src/config.h @@ -13,6 +13,7 @@ struct config { /* The first two layers are the default main and modifier layouts. */ struct layer *layers[MAX_LAYERS]; + struct layer *default_layout; size_t nr_device_ids; size_t nr_layers; diff --git a/src/keyd.c b/src/keyd.c index e6fbd83..4d5b928 100644 --- a/src/keyd.c +++ b/src/keyd.c @@ -358,7 +358,7 @@ static int manage_keyboard(const char *devnode) kbd = calloc(1, sizeof(struct keyboard)); kbd->fd = fd; - kbd->layout = config->layers[0]; + kbd->layout = config->default_layout; strcpy(kbd->devnode, devnode); diff --git a/src/layer.c b/src/layer.c index bcf8be8..22ea6da 100644 --- a/src/layer.c +++ b/src/layer.c @@ -67,27 +67,15 @@ void layer_set_descriptor(struct layer *layer, layer->_keymap = ent; } -struct layer *create_layer(const char *name, uint16_t mods, int is_layout) +struct layer *create_layer(const char *name, uint16_t mods) { uint16_t code; struct layer *layer; layer = calloc(1, sizeof(struct layer)); layer->mods = mods; - layer->is_layout = is_layout; strcpy(layer->name, name); - if (is_layout) { - for (code = 0; code < KEY_MAX; code++) { - struct descriptor d; - - d.op = OP_KEYSEQ; - d.args[0].sequence.code = code; - d.args[0].sequence.mods = 0; - - layer_set_descriptor(layer, code, &d); - } - } return layer; } diff --git a/src/layer.h b/src/layer.h index c76eeaa..a5c4c89 100644 --- a/src/layer.h +++ b/src/layer.h @@ -29,7 +29,7 @@ struct layer { struct keymap_entry *_keymap; }; -struct layer *create_layer(const char *name, uint16_t mods, int populate); +struct layer *create_layer(const char *name, uint16_t mods); void free_layer(struct layer *layer); struct descriptor *layer_get_descriptor(const struct layer *layer, uint16_t code); diff --git a/t/layout2.t b/t/layout2.t new file mode 100644 index 0000000..7364952 --- /dev/null +++ b/t/layout2.t @@ -0,0 +1,19 @@ +- down +- up +a down +a up +control down +a down +a up +control up +- down +- up + +c down +c up +control down +control up +b down +b up +control down +control up diff --git a/t/test.conf b/t/test.conf index f7fc30a..8ba2b1f 100644 --- a/t/test.conf +++ b/t/test.conf @@ -22,6 +22,12 @@ r = reset() l = layer(test) t = overload(o, esc, 2) m = macro(C-h one) +- = layout(layout2) + +[layout2:layout] + +a = c +- = layout(main) [control]