make NLIMC the default titlebar layout
[mikachu/openbox.git] / openbox / engine.c
1 #include "engine.h"
2 #include "parse.h"
3
4 #include <glib.h>
5 #include <gmodule.h>
6 #ifdef HAVE_STDLIB_H
7 #  include <stdlib.h>
8 #endif
9
10 char *engine_name;
11 char *engine_theme;
12 char *engine_layout;
13 char *engine_font;
14 gboolean engine_shadow;
15 int engine_shadow_offset;
16 int engine_shadow_tint;
17
18 static GModule *module = NULL;
19 static EngineStartup *estartup = NULL;
20 static EngineShutdown *eshutdown = NULL;
21
22 #define LOADSYM(name, var) \
23     if (!g_module_symbol(module, #name, (gpointer*)&var)) { \
24         g_warning("Failed to load symbol %s from engine", #name); \
25         return FALSE; \
26     }
27
28 static gboolean load(char *name)
29 {
30     char *path;
31
32     g_assert(module == NULL);
33
34     path = g_build_filename(ENGINEDIR, name, NULL);
35     module = g_module_open(path, 0);
36     g_free(path);
37
38     if (module == NULL) {
39         path = g_build_filename(g_get_home_dir(), ".openbox", "engines", name,
40                                 NULL);
41         module = g_module_open(path, 0);
42         g_free(path);
43     }
44
45     if (module == NULL)
46         return FALSE;
47
48     /* load the engine's symbols */
49     LOADSYM(startup, estartup);
50     LOADSYM(shutdown, eshutdown);
51     LOADSYM(frame_new, engine_frame_new);
52     LOADSYM(frame_grab_client, engine_frame_grab_client);
53     LOADSYM(frame_release_client, engine_frame_release_client);
54     LOADSYM(frame_adjust_area, engine_frame_adjust_area);
55     LOADSYM(frame_adjust_shape, engine_frame_adjust_shape);
56     LOADSYM(frame_adjust_state, engine_frame_adjust_state);
57     LOADSYM(frame_adjust_focus, engine_frame_adjust_focus);
58     LOADSYM(frame_adjust_title, engine_frame_adjust_title);
59     LOADSYM(frame_adjust_icon, engine_frame_adjust_icon);
60     LOADSYM(frame_show, engine_frame_show);
61     LOADSYM(frame_hide, engine_frame_hide);
62     LOADSYM(get_context, engine_get_context);
63
64     if (!estartup())
65         return FALSE;
66
67     return TRUE;
68 }
69
70 static void parse_assign(char *name, ParseToken *value)
71 {
72     if (!g_ascii_strcasecmp(name, "engine")) {
73         if (value->type != TOKEN_STRING)
74             yyerror("invalid value");
75         else {
76             g_free(engine_name);
77             engine_name = g_strdup(value->data.string);
78         }
79     } else if (!g_ascii_strcasecmp(name, "theme")) {
80         if (value->type != TOKEN_STRING)
81             yyerror("invalid value");
82         else {
83             g_free(engine_theme);
84             engine_theme = g_strdup(value->data.string);
85         }
86     } else if (!g_ascii_strcasecmp(name, "titlebarlayout")) {
87         if (value->type != TOKEN_STRING)
88             yyerror("invalid value");
89         else {
90             g_free(engine_layout);
91             engine_layout = g_strdup(value->data.string);
92         }
93     } else if (!g_ascii_strcasecmp(name, "font.title")) {
94         if (value->type != TOKEN_STRING)
95             yyerror("invalid value");
96         else {
97             g_free(engine_font);
98             engine_font = g_strdup(value->data.string);
99         }
100     } else if (!g_ascii_strcasecmp(name, "font.title.shadow")) {
101         if (value->type != TOKEN_BOOL)
102             yyerror("invalid value");
103         else {
104             engine_shadow = value->data.bool;
105         }
106     } else if (!g_ascii_strcasecmp(name, "font.title.shadow.offset")) {
107         if (value->type != TOKEN_INTEGER)
108             yyerror("invalid value");
109         else {
110             engine_shadow_offset = value->data.integer;
111         }
112     } else if (!g_ascii_strcasecmp(name, "font.title.shadow.tint")) {
113         if (value->type != TOKEN_INTEGER)
114             yyerror("invalid value");
115         else {
116             engine_shadow_tint = value->data.integer;
117             if (engine_shadow_tint < -100) engine_shadow_tint = -100;
118             else if (engine_shadow_tint > 100) engine_shadow_tint = 100;
119         }
120     } else
121         yyerror("invalid option");
122     parse_free_token(value);
123 }
124
125 void engine_startup()
126 {
127     module = NULL;
128     engine_name = g_strdup(DEFAULT_ENGINE);
129     engine_theme = NULL;
130     engine_layout = g_strdup("NLIMC");
131     engine_font = g_strdup("Sans-7");
132     engine_shadow = FALSE;
133     engine_shadow_offset = 1;
134     engine_shadow_tint = 25;
135
136     parse_reg_section("engine", NULL, parse_assign);
137 }
138
139 void engine_load()
140 {
141     if (load(engine_name))
142         return;
143     g_warning("Failed to load the engine '%s'", engine_name);
144     g_message("Falling back to the default: '%s'", DEFAULT_ENGINE);
145     if (!load(DEFAULT_ENGINE)) {
146         g_critical("Failed to load the engine '%s'. Aborting", DEFAULT_ENGINE);
147         exit(1);
148     }
149 }
150
151 void engine_shutdown()
152 {
153     g_free(engine_name);
154     if (module != NULL) {
155         eshutdown();
156         g_module_close(module);
157     }
158 }