1
2 /*
3 * geanylua.c - Lua scripting plugin for the Geany IDE
4 * Copyright 2007-2008 Jeff Pohlmeyer <yetanothergeek(at)gmail(dot)com>
5 *
6 * Portions copyright Enrico Tröger <enrico.troeger(at)uvena(dot)de>
7 * Portions copyright Nick Treleaven <nick.treleaven(at)btinternet(dot)com>
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 *
25 *
26 * Some portions of this code were adapted from the Lua standalone
27 * interpreter sources, and may be subject to the terms and conditions
28 * specified under the Lua license. See the file COPYRIGHT.LUA for more
29 * information, or visit http://www.lua.org/license.html .
30 */
31
32
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
36
37
38 #include <geanyplugin.h>
39
40 #include "glspi_ver.h"
41
42 #define SUPPORT_LIB "libgeanylua." G_MODULE_SUFFIX
43
44 #define CB_COPY(field) plugin_callbacks[i].field=glspi_geany_callbacks[i].field;
45
46 #define GETSYM(name,ptr) ( g_module_symbol(libgeanylua, name, (gpointer) &ptr) && ptr )
47
48
49 PLUGIN_EXPORT
50 PLUGIN_VERSION_CHECK(MY_GEANY_API_VER)
51
52 PLUGIN_EXPORT
53 PLUGIN_SET_INFO(PLUGIN_NAME, PLUGIN_DESC, PLUGIN_VER, PLUGIN_AUTHOR)
54
55 PLUGIN_EXPORT
56 GeanyPlugin *geany_plugin;
57
58
59
60 typedef void (*InitFunc) (GeanyData *data, GeanyPlugin *plugin);
61 typedef void (*ConfigFunc) (GtkWidget *parent);
62 typedef void (*CleanupFunc) (void);
63
64
65 static gchar **glspi_version = NULL;
66 static guint *glspi_abi = NULL;
67 static InitFunc glspi_init = NULL;
68 static ConfigFunc glspi_configure = NULL;
69 static CleanupFunc glspi_cleanup = NULL;
70 static PluginCallback *glspi_geany_callbacks = NULL;
71
72
73
74 /*
75 It seems to me like we could simply pass the callbacks pointer directly
76 from the support library to the application. But for some reason that
77 doesn't work at all. So we make a copy of the callbacks array here,
78 and all is well...
79 */
80 PLUGIN_EXPORT
81 PluginCallback plugin_callbacks[8] = {
82 {NULL, NULL, FALSE, NULL},
83 {NULL, NULL, FALSE, NULL},
84 {NULL, NULL, FALSE, NULL},
85 {NULL, NULL, FALSE, NULL},
86 {NULL, NULL, FALSE, NULL},
87 {NULL, NULL, FALSE, NULL},
88 {NULL, NULL, FALSE, NULL},
89 {NULL, NULL, FALSE, NULL}
90 };
91
copy_callbacks(void)92 static void copy_callbacks(void)
93 {
94 gint i;
95 for (i=0; glspi_geany_callbacks[i].signal_name; i++) {
96 CB_COPY(signal_name);
97 CB_COPY(callback);
98 CB_COPY(after);
99 CB_COPY(user_data);
100 }
101 }
102
103
104
105 static GModule *libgeanylua = NULL;
106
107
fail_init(void)108 static void fail_init(void) {
109 if (libgeanylua) { g_module_close(libgeanylua); }
110 libgeanylua = NULL;
111 glspi_version = NULL;
112 glspi_abi = NULL;
113 glspi_init = NULL;
114 glspi_configure = NULL;
115 glspi_cleanup = NULL;
116 glspi_geany_callbacks = NULL;
117 plugin_callbacks[0].signal_name=NULL;
118 plugin_callbacks[0].callback=NULL;
119 plugin_callbacks[0].after=FALSE;
120 plugin_callbacks[0].user_data=NULL;
121 }
122
123 static GeanyData *geany_data=NULL;
124
125
get_lib_dir(void)126 static gchar *get_lib_dir(void)
127 {
128 #ifdef G_OS_WIN32
129 gchar *install_dir, *result;
130 # if GLIB_CHECK_VERSION(2, 16, 0)
131 install_dir = g_win32_get_package_installation_directory_of_module(NULL);
132 # else
133 install_dir = g_win32_get_package_installation_directory(NULL, NULL);
134 # endif
135 result = g_strconcat(install_dir, "\\lib", NULL);
136 g_free(install_dir);
137 return result;
138 #else
139 return g_strdup(LIBDIR);
140 #endif
141 }
142
143
144
load_support_lib(const gchar * libname)145 static gboolean load_support_lib(const gchar *libname)
146 {
147 if ( !g_file_test(libname,G_FILE_TEST_IS_REGULAR) ) {
148 return FALSE;
149 }
150 libgeanylua=g_module_open(libname,0);
151 if (!libgeanylua) {
152 g_printerr("%s\n", g_module_error());
153 g_printerr(_("%s: Can't load support library %s!\n"), PLUGIN_NAME, libname);
154 return FALSE;
155 }
156 if ( !(
157 GETSYM("glspi_version", glspi_version) &&
158 GETSYM("glspi_abi", glspi_abi) &&
159 GETSYM("glspi_init", glspi_init) &&
160 GETSYM("glspi_configure", glspi_configure) &&
161 GETSYM("glspi_cleanup", glspi_cleanup) &&
162 GETSYM("glspi_geany_callbacks", glspi_geany_callbacks)
163 )) {
164 g_printerr("%s\n", g_module_error());
165 g_printerr(_("%s: Failed to initialize support library %s!\n"), PLUGIN_NAME, libname);
166 fail_init();
167 return FALSE;
168 }
169 if (!g_str_equal(*glspi_version, VERSION)) {
170 g_printerr(_("%s: Support library version mismatch: %s for %s (should be %s)!\n"),
171 PLUGIN_NAME, *glspi_version, libname, VERSION);
172 fail_init();
173 return FALSE;
174 }
175 if (*glspi_abi != GEANY_ABI_VERSION) {
176 g_printerr(_("%s: Support library ABI mismatch: %d for %s (should be %d)!\n"),
177 PLUGIN_NAME, *glspi_abi, libname, GEANY_ABI_VERSION);
178 fail_init();
179 return FALSE;
180 }
181 if (geany->app->debug_mode) {
182 g_printerr("%s: Using support library path: %s\n", PLUGIN_NAME, libname);
183 }
184 return TRUE;
185 }
186
187
188 PLUGIN_EXPORT
plugin_init(GeanyData * data)189 void plugin_init(GeanyData *data)
190 {
191 gchar *libname=NULL;
192
193 main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
194
195 geany_data=data;
196 /* first try the user config path */
197 libname=g_build_path(G_DIR_SEPARATOR_S, data->app->configdir, "plugins", "geanylua", SUPPORT_LIB, NULL);
198 if (!load_support_lib(libname)) {
199 /* try the system path */
200 gchar *libdir=get_lib_dir();
201 g_free(libname);
202 libname=g_build_path(G_DIR_SEPARATOR_S, libdir, "geany-plugins", "geanylua", SUPPORT_LIB, NULL);
203 g_free(libdir);
204 if (!load_support_lib(libname)) {
205 g_printerr(_("%s: Can't find support library %s!\n"), PLUGIN_NAME, libname);
206 g_free(libname);
207 return;
208 }
209 }
210 g_free(libname);
211 copy_callbacks();
212
213 glspi_init(data, geany_plugin);
214 }
215
216
217 PLUGIN_EXPORT
plugin_configure_single(GtkWidget * parent)218 void plugin_configure_single(GtkWidget *parent)
219 {
220 if (glspi_configure) {
221 glspi_configure(parent);
222 } else {
223 dialogs_show_msgbox(GTK_MESSAGE_ERROR,
224 _("The %s plugin failed to load properly.\n"
225 "Please check your installation."), PLUGIN_NAME );
226 }
227 }
228
229
230 PLUGIN_EXPORT
plugin_cleanup(void)231 void plugin_cleanup(void)
232 {
233 if (glspi_cleanup) { glspi_cleanup(); }
234 if (libgeanylua) { g_module_close(libgeanylua); }
235 }
236