]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Read rc.xml and begin parsing
authorJohan Malm <jgm323@gmail.com>
Fri, 5 Jun 2020 22:04:54 +0000 (23:04 +0100)
committerJohan Malm <jgm323@gmail.com>
Fri, 5 Jun 2020 22:04:54 +0000 (23:04 +0100)
12 files changed:
data/rc.xml [new file with mode: 0644]
include/labwc.h
include/rcxml.h [new file with mode: 0644]
meson.build
src/config/meson.build [new file with mode: 0644]
src/config/rcxml.c [new file with mode: 0644]
src/main.c
src/meson.build
src/output.c
src/server.c
src/view.c
src/xdg.c

diff --git a/data/rc.xml b/data/rc.xml
new file mode 100644 (file)
index 0000000..032d68a
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<openbox_config xmlns="http://openbox.org/3.4/rc"
+               xmlns:xi="http://www.w3.org/2001/XInclude">
+
+<!-- wlroots specific settings - not part of openbox -->
+<wlroots>
+  <!-- Use client-side decorations for xdg-shell views -->
+  <csd>no</csd>
+</wlroots>
+
+</openbox_config>
index 8885c03d7ea0933349810a5e03c52308cf1556e2..8e1e10d48fc4aacb8ca0fdfe1c50ea6c98200440 100644 (file)
@@ -34,7 +34,6 @@
 #define XCURSOR_MOVE "grabbing"
 #define XWL_TITLEBAR_HEIGHT (10)
 #define XWL_WINDOW_BORDER (3)
-#define LAB_DISABLE_CSD (0)
 
 enum cursor_mode {
        LAB_CURSOR_PASSTHROUGH,
diff --git a/include/rcxml.h b/include/rcxml.h
new file mode 100644 (file)
index 0000000..4e0c643
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef RCXML_H
+#define RCXML_H
+
+#include <stdio.h>
+#include <stdbool.h>
+
+struct rcxml {
+       bool client_side_decorations;
+};
+
+extern struct rcxml rc;
+
+void rcxml_init(struct rcxml *rc);
+void rcxml_read(const char *filename);
+void rcxml_set_verbose(void);
+
+#endif /* RCXML_H */
index 01d0d94142c19f70a87a00ff3656fa046cb66363..9c2d8a5ebb1067864a121c9f5be13caedf2aa8df 100644 (file)
@@ -40,13 +40,16 @@ endif
 wayland_server  = dependency('wayland-server')
 wayland_protos  = dependency('wayland-protocols')
 xkbcommon       = dependency('xkbcommon')
+xml2            = dependency('libxml-2.0')
 
 labwc_inc       = include_directories('include')
 
 subdir('protocols')
 subdir('src')
 
-labwc_deps      = [ server_protos, wayland_server, wlroots, xkbcommon, ]
+labwc_deps      = [
+  server_protos, wayland_server, wlroots, xkbcommon, xml2
+]
 
 executable(
   meson.project_name(),
diff --git a/src/config/meson.build b/src/config/meson.build
new file mode 100644 (file)
index 0000000..19872e9
--- /dev/null
@@ -0,0 +1,3 @@
+labwc_sources += files(
+  'rcxml.c',
+)
diff --git a/src/config/rcxml.c b/src/config/rcxml.c
new file mode 100644 (file)
index 0000000..495e528
--- /dev/null
@@ -0,0 +1,174 @@
+#define _POSIX_C_SOURCE 200112L
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "rcxml.h"
+
+static bool in_keybind = false;
+static bool is_attribute = false;
+static bool verbose = false;
+
+static void rstrip(char *buf, const char *pattern)
+{
+       char *p = strstr(buf, pattern);
+       if (!p)
+               return;
+       *p = '\0';
+}
+
+static void fill_keybind(xmlNode *n, char *nodename, char *content)
+{
+       rstrip(nodename, ".keybind.keyboard");
+       if (!strcmp(nodename, "name.action")) {
+               ; /* TODO: populate keybind with stuff */
+       }
+}
+
+static bool get_bool(const char *s)
+{
+       if (!s)
+               return false;
+       if (!strcasecmp(s, "yes"))
+               return true;
+       if (!strcasecmp(s, "true"))
+               return true;
+       return false;
+}
+
+static void entry(xmlNode *node, char *nodename, char *content)
+{
+       if (!nodename)
+               return;
+       rstrip(nodename, ".openbox_config");
+       if (verbose) {
+               if (is_attribute)
+                       printf("@");
+               printf("%s: %s\n", nodename, content);
+       }
+       if (!content)
+               return;
+       if (in_keybind)
+               fill_keybind(node, nodename, content);
+       if (!strcmp(nodename, "csd.wlroots"))
+               rc.client_side_decorations = get_bool(content);
+}
+
+static void keybind_begin(void)
+{
+       /* TODO: xcalloc struct keybind */
+       in_keybind = true;
+}
+
+static void keybind_end(void)
+{
+       in_keybind = false;
+       /* TODO: wl_list_add keybind */
+}
+
+static char *nodename(xmlNode *node, char *buf, int len)
+{
+       if (!node || !node->name)
+               return NULL;
+
+       /* Ignore superflous 'text.' in node name */
+       if (node->parent && !strcmp((char *)node->name, "text"))
+               node = node->parent;
+
+       buf += len;
+       *--buf = 0;
+       len--;
+
+       char *p = buf;
+       p[--len] = 0;
+       for (;;) {
+               const char *name = (char *)node->name;
+               char c;
+               while ((c = *name++) != 0) {
+                       *p++ = tolower(c);
+                       if (!--len)
+                               return buf;
+               }
+               *p = 0;
+               node = node->parent;
+               if (!node || !node->name)
+                       return buf;
+               *p++ = '.';
+               if (!--len)
+                       return buf;
+       }
+}
+
+static void process_node(xmlNode *node)
+{
+       char *content;
+       static char buffer[256];
+       char *name;
+
+       content = (char *)node->content;
+       if (xmlIsBlankNode(node))
+               return;
+       name = nodename(node, buffer, sizeof(buffer));
+       entry(node, name, content);
+}
+
+static void xml_tree_walk(xmlNode *node);
+
+static void traverse(xmlNode *n)
+{
+       process_node(n);
+       is_attribute = true;
+       for (xmlAttr *attr = n->properties; attr; attr = attr->next)
+               xml_tree_walk(attr->children);
+       is_attribute = false;
+       xml_tree_walk(n->children);
+}
+
+static void xml_tree_walk(xmlNode *node)
+{
+       for (xmlNode *n = node; n && n->name; n = n->next) {
+               if (!strcasecmp((char *)n->name, "comment"))
+                       continue;
+               if (!strcasecmp((char *)n->name, "keybind")) {
+                       keybind_begin();
+                       traverse(n);
+                       keybind_end();
+                       continue;
+               }
+               traverse(n);
+       }
+}
+
+static void parse_xml(const char *filename)
+{
+       xmlDoc *d = xmlReadFile(filename, NULL, 0);
+       if (!d) {
+               fprintf(stderr, "fatal: error reading file '%s'\n", filename);
+               exit(EXIT_FAILURE);
+       }
+       printf("info: reading config file '%s'\n", filename);
+       xml_tree_walk(xmlDocGetRootElement(d));
+       xmlFreeDoc(d);
+       xmlCleanupParser();
+}
+
+void rcxml_init(struct rcxml *rc)
+{
+       LIBXML_TEST_VERSION
+}
+
+void rcxml_read(const char *filename)
+{
+       parse_xml(filename);
+}
+
+void rcxml_set_verbose(void)
+{
+       verbose = true;
+}
index c43c5c9b0ad1cada9b9a7519ceeb3df1b7813db0..616b0babcc54fde53ce0def6e80ddc234e08adb0 100644 (file)
@@ -1,6 +1,8 @@
 #include "labwc.h"
+#include "rcxml.h"
 
 struct server server = { 0 };
+struct rcxml rc = { 0 };
 
 int main(int argc, char *argv[])
 {
@@ -23,6 +25,10 @@ int main(int argc, char *argv[])
                return 0;
        }
 
+       rcxml_init(&rc);
+       rcxml_set_verbose();
+       rcxml_read("data/rc.xml");
+
        /* Wayland requires XDG_RUNTIME_DIR to be set */
        if (!getenv("XDG_RUNTIME_DIR")) {
                wlr_log(WLR_ERROR, "XDG_RUNTIME_DIR is not set");
index e68751fefa5f1c01423a91af038cfbea7e22d068..478f34ff532c243cdcb6d2e5652ba59259822e15 100644 (file)
@@ -11,4 +11,5 @@ labwc_sources = files(
   'xwl.c',
 )
 
+subdir('config')
 subdir('debug')
index 8e577fa60a25b804150f9eaf54cd578510b3bd58..e5a23bcf2f7b14cea48df351c53361e934362bf9 100644 (file)
@@ -1,4 +1,5 @@
 #include "labwc.h"
+#include "rcxml.h"
 
 static float window_active_title_bg[] = { 0.29, 0.55, 0.78, 1.0 };
 static float window_active_handle_bg[] = { 0.21, 0.49, 0.71, 1.0 };
@@ -23,7 +24,8 @@ static void render_cycle_box(struct output *output)
                if (view != output->server->cycle_view)
                        continue;
                struct wlr_box box;
-               if ((view->type == LAB_XWAYLAND_VIEW) || LAB_DISABLE_CSD) {
+               if ((view->type == LAB_XWAYLAND_VIEW) ||
+                   !rc.client_side_decorations) {
                        box = deco_max_extents(view);
                } else {
                        box = view_get_surface_geometry(view);
index babf0937601de392d3ee423cc3fc222bc16b0ad7..e496a5340764736e84edcc475a8d4dbafda6f2e5 100644 (file)
@@ -1,4 +1,5 @@
 #include "labwc.h"
+#include "rcxml.h"
 
 #include <wlr/types/wlr_export_dmabuf_v1.h>
 #include <wlr/types/wlr_screencopy_v1.h>
@@ -222,7 +223,7 @@ void server_init(struct server *server)
                exit(EXIT_FAILURE);
        }
        wlr_server_decoration_manager_set_default_mode(
-               deco_mgr, LAB_DISABLE_CSD ?
+               deco_mgr, !rc.client_side_decorations ?
                                  WLR_SERVER_DECORATION_MANAGER_MODE_SERVER :
                                  WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT);
 
index 1107724c1e8ac800e508053c332ba25f0ea52d4a..87d395eabb36fbfb0e98b794857a02533c841b6b 100644 (file)
@@ -1,4 +1,5 @@
 #include "labwc.h"
+#include "rcxml.h"
 
 static bool is_toplevel(struct view *view)
 {
@@ -19,7 +20,7 @@ void view_init_position(struct view *view)
        if (!is_toplevel(view))
                return;
        struct wlr_box box;
-       if (view->type == LAB_XDG_SHELL_VIEW && !LAB_DISABLE_CSD) {
+       if (view->type == LAB_XDG_SHELL_VIEW && rc.client_side_decorations) {
                /* CSD */
                wlr_xdg_surface_get_geometry(view->xdg_surface, &box);
        } else if (!view_want_deco(view)) {
@@ -88,7 +89,7 @@ bool view_want_deco(struct view *view)
 {
        if (!is_toplevel(view))
                return false;
-       if (view->type == LAB_XDG_SHELL_VIEW && !LAB_DISABLE_CSD)
+       if (view->type == LAB_XDG_SHELL_VIEW && rc.client_side_decorations)
                return false;
        if (view->type == LAB_XDG_SHELL_VIEW)
                return true;
index 526493296f29e3676e9f692e1842f347904d1eec..e8ea18a6927ba488d5209c873906e21c0232aae0 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -1,4 +1,5 @@
 #include "labwc.h"
+#include "rcxml.h"
 
 struct xdg_deco {
        struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration;
@@ -22,7 +23,7 @@ static void xdg_deco_request_mode(struct wl_listener *listener, void *data)
        struct xdg_deco *xdg_deco;
        xdg_deco = wl_container_of(listener, xdg_deco, request_mode);
        enum wlr_xdg_toplevel_decoration_v1_mode mode;
-       if (LAB_DISABLE_CSD)
+       if (!rc.client_side_decorations)
                mode = WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;
        else
                mode = WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;