mirror of
https://github.com/labwc/labwc.git
synced 2026-04-12 08:21:13 -04:00
[wip] Support rc.yaml
Tried with:
---
theme:
- name: Adwaita-light
- cornerRadius: 2
...
Needs lots of testing.
This commit is contained in:
parent
6687640665
commit
608246aac8
5 changed files with 173 additions and 8 deletions
11
include/config/yaml2xml.h
Normal file
11
include/config/yaml2xml.h
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
#ifndef LABWC_YAML2XML_H
|
||||||
|
#define LABWC_YAML2XML_H
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct buf;
|
||||||
|
|
||||||
|
bool yaml_to_xml(struct buf *buffer, const char *filename);
|
||||||
|
|
||||||
|
#endif /* LABWC_YAML2XML_H */
|
||||||
|
|
@ -72,6 +72,7 @@ pixman = dependency('pixman-1')
|
||||||
math = cc.find_library('m')
|
math = cc.find_library('m')
|
||||||
png = dependency('libpng')
|
png = dependency('libpng')
|
||||||
svg = dependency('librsvg-2.0', version: '>=2.46', required: false)
|
svg = dependency('librsvg-2.0', version: '>=2.46', required: false)
|
||||||
|
yaml = dependency('yaml-0.1')
|
||||||
|
|
||||||
if get_option('xwayland').enabled() and not wlroots_has_xwayland
|
if get_option('xwayland').enabled() and not wlroots_has_xwayland
|
||||||
error('no wlroots Xwayland support')
|
error('no wlroots Xwayland support')
|
||||||
|
|
@ -119,6 +120,7 @@ labwc_deps = [
|
||||||
pixman,
|
pixman,
|
||||||
math,
|
math,
|
||||||
png,
|
png,
|
||||||
|
yaml,
|
||||||
]
|
]
|
||||||
if have_rsvg
|
if have_rsvg
|
||||||
labwc_deps += [
|
labwc_deps += [
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,5 @@ labwc_sources += files(
|
||||||
'tablet.c',
|
'tablet.c',
|
||||||
'tablet-tool.c',
|
'tablet-tool.c',
|
||||||
'libinput.c',
|
'libinput.c',
|
||||||
|
'yaml2xml.c',
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#include <wlr/util/box.h>
|
#include <wlr/util/box.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "action.h"
|
#include "action.h"
|
||||||
|
#include "common/buf.h"
|
||||||
#include "common/dir.h"
|
#include "common/dir.h"
|
||||||
#include "common/list.h"
|
#include "common/list.h"
|
||||||
#include "common/macros.h"
|
#include "common/macros.h"
|
||||||
|
|
@ -35,6 +36,7 @@
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
#include "window-rules.h"
|
#include "window-rules.h"
|
||||||
#include "workspaces.h"
|
#include "workspaces.h"
|
||||||
|
#include "config/yaml2xml.h"
|
||||||
|
|
||||||
static bool in_regions;
|
static bool in_regions;
|
||||||
static bool in_usable_area_override;
|
static bool in_usable_area_override;
|
||||||
|
|
@ -1651,19 +1653,19 @@ rcxml_read(const char *filename)
|
||||||
{
|
{
|
||||||
rcxml_init();
|
rcxml_init();
|
||||||
|
|
||||||
struct wl_list paths;
|
struct wl_list paths_xml, paths_yaml;
|
||||||
|
|
||||||
if (filename) {
|
if (filename) {
|
||||||
/* Honour command line argument -c <filename> */
|
/* Honour command line argument -c <filename> */
|
||||||
wl_list_init(&paths);
|
wl_list_init(&paths_xml);
|
||||||
struct path *path = znew(*path);
|
struct path *path = znew(*path);
|
||||||
path->string = xstrdup(filename);
|
path->string = xstrdup(filename);
|
||||||
wl_list_append(&paths, &path->link);
|
wl_list_append(&paths_xml, &path->link);
|
||||||
} else {
|
} else {
|
||||||
paths_config_create(&paths, "rc.xml");
|
paths_config_create(&paths_xml, "rc.xml");
|
||||||
|
paths_config_create(&paths_yaml, "rc.yaml");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reading file into buffer before parsing - better for unit tests */
|
|
||||||
bool should_merge_config = rc.merge_config;
|
bool should_merge_config = rc.merge_config;
|
||||||
struct wl_list *(*iter)(struct wl_list *list);
|
struct wl_list *(*iter)(struct wl_list *list);
|
||||||
iter = should_merge_config ? paths_get_prev : paths_get_next;
|
iter = should_merge_config ? paths_get_prev : paths_get_next;
|
||||||
|
|
@ -1677,15 +1679,17 @@ rcxml_read(const char *filename)
|
||||||
*
|
*
|
||||||
* If merging, we iterate backwards (least important XDG Base Dir first)
|
* If merging, we iterate backwards (least important XDG Base Dir first)
|
||||||
* and keep going.
|
* and keep going.
|
||||||
|
*
|
||||||
|
* We start with the XML version if it exists.
|
||||||
*/
|
*/
|
||||||
for (struct wl_list *elm = iter(&paths); elm != &paths; elm = iter(elm)) {
|
for (struct wl_list *elm = iter(&paths_xml); elm != &paths_xml; elm = iter(elm)) {
|
||||||
struct path *path = wl_container_of(elm, path, link);
|
struct path *path = wl_container_of(elm, path, link);
|
||||||
FILE *stream = fopen(path->string, "r");
|
FILE *stream = fopen(path->string, "r");
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_log(WLR_INFO, "read config file %s", path->string);
|
wlr_log(WLR_INFO, "read xml config file %s", path->string);
|
||||||
|
|
||||||
struct buf b = BUF_INIT;
|
struct buf b = BUF_INIT;
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
|
|
@ -1705,7 +1709,26 @@ rcxml_read(const char *filename)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
paths_destroy(&paths);
|
|
||||||
|
/* ...then we do the YAML verion */
|
||||||
|
for (struct wl_list *elm = iter(&paths_yaml); elm != &paths_yaml; elm = iter(elm)) {
|
||||||
|
struct path *path = wl_container_of(elm, path, link);
|
||||||
|
|
||||||
|
wlr_log(WLR_INFO, "read yaml config file %s", path->string);
|
||||||
|
|
||||||
|
struct buf b = BUF_INIT;
|
||||||
|
bool success = yaml_to_xml(&b, path->string);
|
||||||
|
if (success) {
|
||||||
|
rcxml_parse_xml(&b);
|
||||||
|
}
|
||||||
|
buf_reset(&b);
|
||||||
|
if (!should_merge_config) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
paths_destroy(&paths_xml);
|
||||||
|
paths_destroy(&paths_yaml);
|
||||||
post_processing();
|
post_processing();
|
||||||
validate();
|
validate();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
128
src/config/yaml2xml.c
Normal file
128
src/config/yaml2xml.c
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
#include <assert.h>
|
||||||
|
#include <yaml.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
#include "common/buf.h"
|
||||||
|
#include "common/mem.h"
|
||||||
|
#include "config/yaml2xml.h"
|
||||||
|
|
||||||
|
static struct element *elements;
|
||||||
|
static int nr_elements, alloc_elements;
|
||||||
|
|
||||||
|
struct element {
|
||||||
|
char name[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct element *
|
||||||
|
push(const char *name)
|
||||||
|
{
|
||||||
|
if (nr_elements == alloc_elements) {
|
||||||
|
alloc_elements = (alloc_elements + 16) * 2;
|
||||||
|
elements = xrealloc(elements,
|
||||||
|
alloc_elements * sizeof(struct element));
|
||||||
|
}
|
||||||
|
struct element *element = elements + nr_elements;
|
||||||
|
memset(element, 0, sizeof(*element));
|
||||||
|
nr_elements++;
|
||||||
|
strncpy(element->name, name, sizeof(element->name));
|
||||||
|
element->name[sizeof(element->name) - 1] = '\0';
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pop(char *buffer, size_t len)
|
||||||
|
{
|
||||||
|
strncpy(buffer, elements[nr_elements-1].name, len);
|
||||||
|
nr_elements--;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
process_one_event(struct buf *buffer, yaml_event_t *event)
|
||||||
|
{
|
||||||
|
static bool in_scalar;
|
||||||
|
|
||||||
|
switch (event->type) {
|
||||||
|
case YAML_NO_EVENT:
|
||||||
|
case YAML_ALIAS_EVENT:
|
||||||
|
case YAML_MAPPING_START_EVENT:
|
||||||
|
case YAML_MAPPING_END_EVENT:
|
||||||
|
case YAML_STREAM_START_EVENT:
|
||||||
|
case YAML_STREAM_END_EVENT:
|
||||||
|
break;
|
||||||
|
case YAML_DOCUMENT_START_EVENT:
|
||||||
|
buf_add(buffer, "<?xml version=\"1.0\"?>\n");
|
||||||
|
buf_add(buffer, "<labwc_config>\n");
|
||||||
|
break;
|
||||||
|
case YAML_DOCUMENT_END_EVENT:
|
||||||
|
buf_add(buffer, "</labwc_config>\n");
|
||||||
|
break;
|
||||||
|
case YAML_SCALAR_EVENT:
|
||||||
|
if (in_scalar) {
|
||||||
|
char element[64] = { 0 };
|
||||||
|
pop(element, sizeof(element));
|
||||||
|
buf_add(buffer, (char *)event->data.scalar.value);
|
||||||
|
buf_add(buffer, "</");
|
||||||
|
buf_add(buffer, element);
|
||||||
|
buf_add(buffer, ">\n");
|
||||||
|
in_scalar = false;
|
||||||
|
} else {
|
||||||
|
char *value = (char *)event->data.scalar.value;
|
||||||
|
buf_add(buffer, "<");
|
||||||
|
buf_add(buffer, value);
|
||||||
|
buf_add(buffer, ">");
|
||||||
|
push(value);
|
||||||
|
in_scalar = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case YAML_SEQUENCE_START_EVENT:
|
||||||
|
assert(in_scalar);
|
||||||
|
buf_add(buffer, "\n");
|
||||||
|
in_scalar = false;
|
||||||
|
break;
|
||||||
|
case YAML_SEQUENCE_END_EVENT:
|
||||||
|
char element[64] = { 0 };
|
||||||
|
pop(element, sizeof(element));
|
||||||
|
buf_add(buffer, "</");
|
||||||
|
buf_add(buffer, element);
|
||||||
|
buf_add(buffer, ">\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
yaml_to_xml(struct buf *buffer, const char *filename)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
FILE *f = fopen(filename, "r");
|
||||||
|
if (!f) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
yaml_parser_t parser;
|
||||||
|
yaml_parser_initialize(&parser);
|
||||||
|
yaml_parser_set_input_file(&parser, f);
|
||||||
|
|
||||||
|
yaml_event_type_t event_type = 0;
|
||||||
|
while (event_type != YAML_STREAM_END_EVENT) {
|
||||||
|
yaml_event_t event;
|
||||||
|
int success = yaml_parser_parse(&parser, &event);
|
||||||
|
if (!success) {
|
||||||
|
wlr_log(WLR_ERROR, "yaml parse: %s", parser.problem);
|
||||||
|
yaml_parser_delete(&parser);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
process_one_event(buffer, &event);
|
||||||
|
event_type = event.type;
|
||||||
|
yaml_event_delete(&event);
|
||||||
|
}
|
||||||
|
yaml_parser_delete(&parser);
|
||||||
|
free(elements);
|
||||||
|
nr_elements = 0;
|
||||||
|
alloc_elements = 0;
|
||||||
|
ret = true;
|
||||||
|
out:
|
||||||
|
fclose(f);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue