window: Add a cheesy parser for ini-files, use it in desktop-shell
This commit is contained in:
+2
-1
@@ -38,7 +38,8 @@ libtoytoolkit_a_SOURCES = \
|
|||||||
window.c \
|
window.c \
|
||||||
window.h \
|
window.h \
|
||||||
cairo-util.c \
|
cairo-util.c \
|
||||||
cairo-util.h
|
cairo-util.h \
|
||||||
|
config.c
|
||||||
|
|
||||||
toolkit_libs = \
|
toolkit_libs = \
|
||||||
libtoytoolkit.a \
|
libtoytoolkit.a \
|
||||||
|
|||||||
@@ -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 = §ions[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(¤t->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;
|
||||||
|
}
|
||||||
+57
-23
@@ -58,6 +58,30 @@ struct panel_item {
|
|||||||
const char *path;
|
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
|
static void
|
||||||
sigchild_handler(int s)
|
sigchild_handler(int s)
|
||||||
{
|
{
|
||||||
@@ -137,6 +161,16 @@ panel_draw_item(struct item *item, void *data)
|
|||||||
cairo_translate(cr, width + 10, 0);
|
cairo_translate(cr, width + 10, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static void
|
||||||
panel_redraw_handler(struct window *window, void *data)
|
panel_redraw_handler(struct window *window, void *data)
|
||||||
{
|
{
|
||||||
@@ -147,7 +181,7 @@ panel_redraw_handler(struct window *window, void *data)
|
|||||||
surface = window_get_surface(window);
|
surface = window_get_surface(window);
|
||||||
cr = cairo_create(surface);
|
cr = cairo_create(surface);
|
||||||
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
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_paint(cr);
|
||||||
|
|
||||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
||||||
@@ -294,28 +328,26 @@ global_handler(struct wl_display *display, uint32_t id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct {
|
static void
|
||||||
const char *icon;
|
launcher_section_done(void *data)
|
||||||
const char *path;
|
{
|
||||||
} launchers[] = {
|
struct desktop *desktop = data;
|
||||||
{
|
|
||||||
"/usr/share/icons/gnome/24x24/apps/utilities-terminal.png",
|
if (key_launcher_icon == NULL || key_launcher_path == NULL) {
|
||||||
"/usr/bin/gnome-terminal"
|
fprintf(stderr, "invalid launcher section\n");
|
||||||
},
|
return;
|
||||||
{
|
}
|
||||||
"/usr/share/icons/gnome/24x24/apps/utilities-terminal.png",
|
|
||||||
"./clients/terminal"
|
panel_add_item(desktop->panel, key_launcher_icon, key_launcher_path);
|
||||||
},
|
free(key_launcher_icon);
|
||||||
{
|
key_launcher_icon = NULL;
|
||||||
"/usr/share/icons/hicolor/24x24/apps/google-chrome.png",
|
free(key_launcher_path);
|
||||||
"/usr/bin/google-chrome"
|
key_launcher_path = NULL;
|
||||||
},
|
}
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct desktop desktop;
|
struct desktop desktop;
|
||||||
int i;
|
|
||||||
|
|
||||||
desktop.display = display_create(&argc, &argv, NULL);
|
desktop.display = display_create(&argc, &argv, NULL);
|
||||||
if (desktop.display == NULL) {
|
if (desktop.display == NULL) {
|
||||||
@@ -331,9 +363,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
desktop.panel = panel_create(desktop.display);
|
desktop.panel = panel_create(desktop.display);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(launchers); i++)
|
parse_config_file("wayland-desktop-shell.ini",
|
||||||
panel_add_item(desktop.panel,
|
config_sections, ARRAY_LENGTH(config_sections),
|
||||||
launchers[i].icon, launchers[i].path);
|
&desktop);
|
||||||
|
|
||||||
|
printf("panel color: %08x\n", key_panel_color);
|
||||||
|
|
||||||
desktop_shell_set_panel(desktop.shell,
|
desktop_shell_set_panel(desktop.shell,
|
||||||
window_get_wl_surface(desktop.panel->window));
|
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);
|
desktop.background = window_create(desktop.display, 0, 0);
|
||||||
window_set_decoration(desktop.background, 0);
|
window_set_decoration(desktop.background, 0);
|
||||||
window_set_custom(desktop.background);
|
window_set_custom(desktop.background);
|
||||||
desktop.background_path = argv[1];
|
desktop.background_path = key_background_image;
|
||||||
desktop_shell_set_background(desktop.shell,
|
desktop_shell_set_background(desktop.shell,
|
||||||
window_get_wl_surface(desktop.background));
|
window_get_wl_surface(desktop.background));
|
||||||
|
|
||||||
|
|||||||
@@ -322,5 +322,28 @@ input_offers_mime_type(struct input *input, const char *type);
|
|||||||
void
|
void
|
||||||
input_receive_mime_type(struct input *input, const char *type, int fd);
|
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
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user