]> Dogcows Code - chaz/openbox/blob - openbox/engine.c
clean up the module if load() fails
[chaz/openbox] / 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 (module != NULL) {
163 g_module_close(module);
164 module = NULL;
165 }
166 if (!load(DEFAULT_ENGINE)) {
167 g_critical("Failed to load the engine '%s'. Aborting", DEFAULT_ENGINE);
168 exit(1);
169 }
170 }
171
172 void engine_shutdown()
173 {
174 g_free(engine_name);
175 if (module != NULL) {
176 eshutdown();
177 g_module_close(module);
178 }
179 }
This page took 0.042221 seconds and 5 git commands to generate.