window: Add a cheesy parser for ini-files, use it in desktop-shell
authorKristian Høgsberg <krh@bitplanet.net>
Tue, 15 Nov 2011 03:43:37 +0000 (22:43 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 15 Nov 2011 03:51:02 +0000 (22:51 -0500)
clients/Makefile.am
clients/config.c [new file with mode: 0644]
clients/desktop-shell.c
clients/window.h

index 9c14eb9..bae9f3f 100644 (file)
@@ -38,7 +38,8 @@ libtoytoolkit_a_SOURCES =                     \
        window.c                                \
        window.h                                \
        cairo-util.c                            \
-       cairo-util.h
+       cairo-util.h                            \
+       config.c
 
 toolkit_libs =                                 \
        libtoytoolkit.a                         \
diff --git a/clients/config.c b/clients/config.c
new file mode 100644 (file)
index 0000000..f389b69
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <window.h>
+
+static int
+handle_key(const struct config_key *key, const char *value)
+{
+       char *end, *s;
+       int i, len;
+       
+       switch (key->type) {
+       case CONFIG_KEY_INTEGER:
+               i = strtol(value, &end, 0);
+               if (*end != '\n') {
+                       fprintf(stderr, "invalid integer: %s\n", value);
+                       return -1;
+               }
+               *(int *)key->data = i;
+               return 0;
+
+       case CONFIG_KEY_STRING:
+               len = strlen(value);
+               s = malloc(len);
+               if (s == NULL)
+                       return -1;
+               memcpy(s, value, len - 1);
+               s[len - 1] = '\0';
+               *(char **)key->data = s;
+               return 0;
+
+       case CONFIG_KEY_BOOL:
+               if (strcmp(value, "false") == 0)
+                       *(int *)key->data = 0;
+               else if (strcmp(value, "true") == 0)
+                       *(int *)key->data = 1;
+               else {
+                       fprintf(stderr, "invalid bool: %s\n", value);
+                       return -1;
+               }
+               return 0;
+
+       default:
+               assert(0);
+               break;
+       }
+}
+
+int
+parse_config_file(const char *path,
+                 const struct config_section *sections, int num_sections,
+                 void *data)
+{
+       FILE *fp;
+       char line[512], *p;
+       const struct config_section *current = NULL;
+       int i;
+
+       fp = fopen(path, "r");
+       if (fp == NULL) {
+               fprintf(stderr, "couldn't open %s\n", path);
+               return -1;
+       }
+
+       while (fgets(line, sizeof line, fp)) {
+               if (line[0] == '#' || line[0] == '\n') {
+                       continue;
+               } if (line[0] == '[') {
+                       p = strchr(&line[1], ']');
+                       if (!p || p[1] != '\n') {
+                               fprintf(stderr, "malformed "
+                                       "section header: %s\n", line);
+                               fclose(fp);
+                               return -1;
+                       }
+                       if (current && current->done)
+                               current->done(data);
+                       p[0] = '\0';
+                       for (i = 0; i < num_sections; i++) {
+                               if (strcmp(sections[i].name, &line[1]) == 0) {
+                                       current = &sections[i];
+                                       break;
+                               }
+                       }
+                       if (i == num_sections)
+                               current = NULL;
+               } else if (p = strchr(line, '='), p != NULL) {
+                       if (current == NULL)
+                               continue;
+                       p[0] = '\0';
+                       for (i = 0; i < current->num_keys; i++) {
+                               if (strcmp(current->keys[i].name, line) == 0) {
+                                       if (handle_key(&current->keys[i], &p[1]) < 0) {
+                                               fclose(fp);
+                                               return -1;
+                                       }
+                                       break;
+                               }
+                       }
+               } else {
+                       fprintf(stderr, "malformed config line: %s\n", line);
+                       fclose(fp);
+                       return -1;
+               }
+       }
+
+       if (current && current->done)
+               current->done(data);
+
+       fclose(fp);
+
+       return 0;
+}
index b915723..33ea677 100644 (file)
@@ -58,6 +58,30 @@ struct panel_item {
        const char *path;
 };
 
+static char *key_background_image;
+static uint32_t key_panel_color;
+static char *key_launcher_icon;
+static char *key_launcher_path;
+static void launcher_section_done(void *data);
+
+static const struct config_key shell_config_keys[] = {
+       { "background-image", CONFIG_KEY_STRING, &key_background_image },
+       { "panel-color", CONFIG_KEY_INTEGER, &key_panel_color },
+};
+
+static const struct config_key launcher_config_keys[] = {
+       { "icon", CONFIG_KEY_STRING, &key_launcher_icon },
+       { "path", CONFIG_KEY_STRING, &key_launcher_path },
+};
+
+static const struct config_section config_sections[] = {
+       { "wayland-desktop-shell",
+         shell_config_keys, ARRAY_LENGTH(shell_config_keys) },
+       { "launcher",
+         launcher_config_keys, ARRAY_LENGTH(launcher_config_keys),
+         launcher_section_done }
+};
+
 static void
 sigchild_handler(int s)
 {
@@ -138,6 +162,16 @@ panel_draw_item(struct item *item, void *data)
 }
 
 static void
+set_hex_color(cairo_t *cr, uint32_t color)
+{
+       cairo_set_source_rgba(cr, 
+                             ((color >> 16) & 0xff) / 255.0,
+                             ((color >>  8) & 0xff) / 255.0,
+                             ((color >>  0) & 0xff) / 255.0,
+                             ((color >> 24) & 0xff) / 255.0);
+}
+
+static void
 panel_redraw_handler(struct window *window, void *data)
 {
        cairo_surface_t *surface;
@@ -147,7 +181,7 @@ panel_redraw_handler(struct window *window, void *data)
        surface = window_get_surface(window);
        cr = cairo_create(surface);
        cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
-       cairo_set_source_rgba(cr, 0.1, 0.1, 0.1, 0.9);
+       set_hex_color(cr, key_panel_color);
        cairo_paint(cr);
 
        cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
@@ -294,28 +328,26 @@ global_handler(struct wl_display *display, uint32_t id,
        }
 }
 
-static const struct {
-       const char *icon;
-       const char *path;
-} launchers[] = {
-       {
-               "/usr/share/icons/gnome/24x24/apps/utilities-terminal.png",
-               "/usr/bin/gnome-terminal"
-       },
-       {
-               "/usr/share/icons/gnome/24x24/apps/utilities-terminal.png",
-               "./clients/terminal"
-       },
-       {
-               "/usr/share/icons/hicolor/24x24/apps/google-chrome.png",
-               "/usr/bin/google-chrome"
-       },
-};
+static void
+launcher_section_done(void *data)
+{
+       struct desktop *desktop = data;
+
+       if (key_launcher_icon == NULL || key_launcher_path == NULL) {
+               fprintf(stderr, "invalid launcher section\n");
+               return;
+       }
+
+       panel_add_item(desktop->panel, key_launcher_icon, key_launcher_path);
+       free(key_launcher_icon);
+       key_launcher_icon = NULL;
+       free(key_launcher_path);
+       key_launcher_path = NULL;
+}
 
 int main(int argc, char *argv[])
 {
        struct desktop desktop;
-       int i;
 
        desktop.display = display_create(&argc, &argv, NULL);
        if (desktop.display == NULL) {
@@ -331,9 +363,11 @@ int main(int argc, char *argv[])
 
        desktop.panel = panel_create(desktop.display);
 
-       for (i = 0; i < ARRAY_LENGTH(launchers); i++)
-               panel_add_item(desktop.panel,
-                              launchers[i].icon, launchers[i].path);
+       parse_config_file("wayland-desktop-shell.ini",
+                         config_sections, ARRAY_LENGTH(config_sections),
+                         &desktop);
+
+       printf("panel color: %08x\n", key_panel_color);
 
        desktop_shell_set_panel(desktop.shell,
                                window_get_wl_surface(desktop.panel->window));
@@ -341,7 +375,7 @@ int main(int argc, char *argv[])
        desktop.background = window_create(desktop.display, 0, 0);
        window_set_decoration(desktop.background, 0);
        window_set_custom(desktop.background);
-       desktop.background_path = argv[1];
+       desktop.background_path = key_background_image;
        desktop_shell_set_background(desktop.shell,
                                     window_get_wl_surface(desktop.background));
 
index 290c6b9..40bf102 100644 (file)
@@ -322,5 +322,28 @@ input_offers_mime_type(struct input *input, const char *type);
 void
 input_receive_mime_type(struct input *input, const char *type, int fd);
 
+enum {
+       CONFIG_KEY_INTEGER,
+       CONFIG_KEY_STRING,
+       CONFIG_KEY_BOOL
+};
+
+struct config_key {
+       const char *name;
+       int type;
+       void *data;
+};
+
+struct config_section {
+       const char *name;
+       const struct config_key *keys;
+       int num_keys;
+       void (*done)(void *data);
+};
+
+int
+parse_config_file(const char *path,
+                 const struct config_section *sections, int num_sections,
+                 void *data);
 
 #endif