1 // --------------------------------------------------------------------
2 // Common code for all platforms
3 // --------------------------------------------------------------------
4
5 #include <cstdio>
6 #include <cstdlib>
7
8 // for version info only
9 #include "ipefonts.h"
10 #include <zlib.h>
11
12 extern int luaopen_ipeui(lua_State *L);
13 extern int luaopen_appui(lua_State *L);
14
15 // --------------------------------------------------------------------
16
ipeIconDirectory()17 String ipeIconDirectory()
18 {
19 static String iconDir;
20 if (iconDir.empty()) {
21 const char *p = getenv("IPEICONDIR");
22 #ifdef IPEBUNDLE
23 String s(p ? p : Platform::ipeDir("icons"));
24 #else
25 String s(p ? p : IPEICONDIR);
26 #endif
27 if (s.right(1) != "/")
28 s += IPESEP;
29 iconDir = s;
30 }
31 return iconDir;
32 }
33
traceback(lua_State * L)34 static int traceback (lua_State *L)
35 {
36 if (!lua_isstring(L, 1)) /* 'message' not a string? */
37 return 1; /* keep it intact */
38 lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);
39 lua_getfield(L, -1, "debug");
40 if (!lua_istable(L, -1)) {
41 lua_pop(L, 2);
42 return 1;
43 }
44 lua_getfield(L, -1, "traceback");
45 if (!lua_isfunction(L, -1)) {
46 lua_pop(L, 3);
47 return 1;
48 }
49 lua_pushvalue(L, 1); // pass error message
50 lua_pushinteger(L, 2); // skip this function and traceback
51 luacall(L, 2, 1); // call debug.traceback
52 return 1;
53 }
54
setup_config(lua_State * L,const char * var,const char * env,const char * conf)55 static void setup_config(lua_State *L, const char *var,
56 const char *env, const char *conf)
57 {
58 const char *p = env ? getenv(env) : nullptr;
59 #ifdef IPEBUNDLE
60 push_string(L, p ? p : Platform::ipeDir(conf));
61 #else
62 lua_pushstring(L, p ? p : conf);
63 #endif
64 lua_setfield(L, -2, var);
65 }
66
setup_common_config(lua_State * L)67 static void setup_common_config(lua_State *L)
68 {
69 push_string(L, Fonts::freetypeVersion());
70 lua_setfield(L, -2, "freetype_version");
71 lua_pushfstring(L, "%s / %s", CAIRO_VERSION_STRING, cairo_version_string());
72 lua_setfield(L, -2, "cairo_version");
73 lua_pushliteral(L, ZLIB_VERSION);
74 lua_setfield(L, -2, "zlib_version");
75 push_string(L, Platform::spiroVersion());
76 lua_setfield(L, -2, "spiro_version");
77 push_string(L, Platform::gslVersion());
78 lua_setfield(L, -2, "gsl_version");
79
80 push_string(L, Platform::latexDirectory());
81 lua_setfield(L, -2, "latexdir");
82 push_string(L, Platform::latexPath());
83 lua_setfield(L, -2, "latexpath");
84 push_string(L, ipeIconDirectory());
85 lua_setfield(L, -2, "icons");
86
87 lua_pushfstring(L, "Ipe %d.%d.%d",
88 IPELIB_VERSION / 10000,
89 (IPELIB_VERSION / 100) % 100,
90 IPELIB_VERSION % 100);
91 lua_setfield(L, -2, "version");
92
93 push_string(L, Platform::ipeDrive());
94 lua_setfield(L, -2, "ipedrive");
95 }
96
97 // --------------------------------------------------------------------
98
99 /* Replacement for Lua's tonumber function,
100 which is locale-dependent. */
ipe_tonumber(lua_State * L)101 static int ipe_tonumber(lua_State *L)
102 {
103 const char *s = luaL_checklstring(L, 1, nullptr);
104 int iValue;
105 double dValue;
106 int result = Platform::toNumber(s, iValue, dValue);
107 switch (result) {
108 case 2:
109 lua_pushnumber(L, dValue);
110 break;
111 case 1:
112 lua_pushinteger(L, iValue);
113 break;
114 case 0:
115 default:
116 lua_pushnil(L);
117 }
118 return 1;
119 }
120
setup_lua()121 static lua_State *setup_lua()
122 {
123 lua_State *L = luaL_newstate();
124 luaL_openlibs(L);
125 luaopen_ipe(L);
126 luaopen_ipeui(L);
127 luaopen_appui(L);
128 return L;
129 }
130
lua_run_ipe(lua_State * L,lua_CFunction fn)131 static bool lua_run_ipe(lua_State *L, lua_CFunction fn)
132 {
133 lua_pushcfunction(L, fn);
134 lua_setglobal(L, "mainloop");
135
136 // run Ipe
137 lua_pushcfunction(L, traceback);
138 assert(luaL_loadstring(L, "require \"main\"") == 0);
139
140 if (lua_pcallk(L, 0, 0, -2, 0, nullptr)) {
141 const char *errmsg = lua_tolstring(L, -1, nullptr);
142 fprintf(stderr, "%s\n", errmsg);
143 return false;
144 }
145 return true;
146 }
147
148 // --------------------------------------------------------------------
149