]> icculus.org git repositories - dana/openbox.git/blob - openbox/engine.c
add ()'s to the macros for more safety
[dana/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 EngineFrameNew *engine_frame_new;
19 EngineFrameGrabClient *engine_frame_grab_client;
20 EngineFrameReleaseClient *engine_frame_release_client;
21 EngineFrameAdjustArea *engine_frame_adjust_area;
22 EngineFrameAdjustShape *engine_frame_adjust_shape;
23 EngineFrameAdjustState *engine_frame_adjust_state;
24 EngineFrameAdjustFocus *engine_frame_adjust_focus;
25 EngineFrameAdjustTitle *engine_frame_adjust_title;
26 EngineFrameAdjustIcon *engine_frame_adjust_icon;
27 EngineFrameShow *engine_frame_show;
28 EngineFrameHide *engine_frame_hide;
29 EngineGetContext *engine_get_context;
30 EngineRenderLabel *engine_render_label;
31 EngineSizeLabel *engine_size_label;
32
33 static GModule *module = NULL;
34 static EngineStartup *estartup = NULL;
35 static EngineShutdown *eshutdown = NULL;
36
37 #define LOADSYM(name, var) \
38     if (!g_module_symbol(module, #name, (gpointer*)&var)) { \
39         g_warning("Failed to load symbol %s from engine", #name); \
40         return FALSE; \
41     }
42
43 static gboolean load(char *name)
44 {
45     char *path;
46
47     g_assert(module == NULL);
48
49     path = g_build_filename(ENGINEDIR, name, NULL);
50     module = g_module_open(path, 0);
51     g_free(path);
52
53     if (module == NULL) {
54         path = g_build_filename(g_get_home_dir(), ".openbox", "engines", name,
55                                 NULL);
56         module = g_module_open(path, 0);
57         g_free(path);
58     }
59
60     if (module == NULL)
61         return FALSE;
62
63     /* load the engine's symbols */
64     LOADSYM(startup, estartup);
65     LOADSYM(shutdown, eshutdown);
66     LOADSYM(frame_new, engine_frame_new);
67     LOADSYM(frame_grab_client, engine_frame_grab_client);
68     LOADSYM(frame_release_client, engine_frame_release_client);
69     LOADSYM(frame_adjust_area, engine_frame_adjust_area);
70     LOADSYM(frame_adjust_shape, engine_frame_adjust_shape);
71     LOADSYM(frame_adjust_state, engine_frame_adjust_state);
72     LOADSYM(frame_adjust_focus, engine_frame_adjust_focus);
73     LOADSYM(frame_adjust_title, engine_frame_adjust_title);
74     LOADSYM(frame_adjust_icon, engine_frame_adjust_icon);
75     LOADSYM(frame_show, engine_frame_show);
76     LOADSYM(frame_hide, engine_frame_hide);
77     LOADSYM(get_context, engine_get_context);
78     LOADSYM(render_label, engine_render_label);
79     LOADSYM(size_label, engine_size_label);
80
81     if (!estartup())
82         return FALSE;
83
84     return TRUE;
85 }
86
87 static void parse_assign(char *name, ParseToken *value)
88 {
89     if (!g_ascii_strcasecmp(name, "engine")) {
90         if (value->type != TOKEN_STRING)
91             yyerror("invalid value");
92         else {
93             g_free(engine_name);
94             engine_name = g_strdup(value->data.string);
95         }
96     } else if (!g_ascii_strcasecmp(name, "theme")) {
97         if (value->type != TOKEN_STRING)
98             yyerror("invalid value");
99         else {
100             g_free(engine_theme);
101             engine_theme = g_strdup(value->data.string);
102         }
103     } else if (!g_ascii_strcasecmp(name, "titlebarlayout")) {
104         if (value->type != TOKEN_STRING)
105             yyerror("invalid value");
106         else {
107             g_free(engine_layout);
108             engine_layout = g_strdup(value->data.string);
109         }
110     } else if (!g_ascii_strcasecmp(name, "font.title")) {
111         if (value->type != TOKEN_STRING)
112             yyerror("invalid value");
113         else {
114             g_free(engine_font);
115             engine_font = g_strdup(value->data.string);
116         }
117     } else if (!g_ascii_strcasecmp(name, "font.title.shadow")) {
118         if (value->type != TOKEN_BOOL)
119             yyerror("invalid value");
120         else {
121             engine_shadow = value->data.bool;
122         }
123     } else if (!g_ascii_strcasecmp(name, "font.title.shadow.offset")) {
124         if (value->type != TOKEN_INTEGER)
125             yyerror("invalid value");
126         else {
127             engine_shadow_offset = value->data.integer;
128         }
129     } else if (!g_ascii_strcasecmp(name, "font.title.shadow.tint")) {
130         if (value->type != TOKEN_INTEGER)
131             yyerror("invalid value");
132         else {
133             engine_shadow_tint = value->data.integer;
134             if (engine_shadow_tint < -100) engine_shadow_tint = -100;
135             else if (engine_shadow_tint > 100) engine_shadow_tint = 100;
136         }
137     } else
138         yyerror("invalid option");
139     parse_free_token(value);
140 }
141
142 void engine_startup()
143 {
144     module = NULL;
145     engine_name = g_strdup(DEFAULT_ENGINE);
146     engine_theme = NULL;
147     engine_layout = g_strdup("NLIMC");
148     engine_font = g_strdup("Sans-7");
149     engine_shadow = FALSE;
150     engine_shadow_offset = 1;
151     engine_shadow_tint = 25;
152
153     parse_reg_section("engine", NULL, parse_assign);
154 }
155
156 void engine_load()
157 {
158     if (load(engine_name))
159         return;
160     g_warning("Failed to load the engine '%s'", engine_name);
161     g_message("Falling back to the default: '%s'", DEFAULT_ENGINE);
162     if (!load(DEFAULT_ENGINE)) {
163         g_critical("Failed to load the engine '%s'. Aborting", DEFAULT_ENGINE);
164         exit(1);
165     }
166 }
167
168 void engine_shutdown()
169 {
170     g_free(engine_name);
171     if (module != NULL) {
172         eshutdown();
173         g_module_close(module);
174     }
175 }