gsl-shell.git - gsl-shell

index : gsl-shell.git
gsl-shell
summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat
-rw-r--r--Makefile 22
-rw-r--r--agg-plot/Makefile 4
-rw-r--r--agg-plot/agg_platform_support_win32.cpp 16
-rw-r--r--agg-plot/agg_platform_support_x11.cpp 23
-rw-r--r--agg-plot/canvas-window-cpp.h 10
-rw-r--r--agg-plot/canvas-window.cpp 22
-rw-r--r--agg-plot/canvas_svg.cpp 2
-rw-r--r--agg-plot/draw_svg.h 4
-rw-r--r--agg-plot/lua-draw.cpp 6
-rw-r--r--agg-plot/lua-draw.h 14
-rw-r--r--agg-plot/lua-graph.cpp (renamed from lua-graph.c)26
-rw-r--r--agg-plot/lua-plot.cpp 32
-rw-r--r--agg-plot/my_list.h 75
-rw-r--r--agg-plot/platform_support_ext.h 117
-rw-r--r--agg-plot/plot-auto.h 7
-rw-r--r--agg-plot/plot.h 16
-rw-r--r--agg-plot/rendering_buffer_utils.h 120
-rw-r--r--agg-plot/sg_object.h 2
-rw-r--r--agg-plot/split-parser.h 2
-rw-r--r--agg-plot/trans.h 4
-rw-r--r--agg-plot/window-cpp.h 5
-rw-r--r--agg-plot/window.cpp 15
-rw-r--r--agg-plot/window_hooks.h 25
-rw-r--r--agg-plot/window_registry.cpp 7
-rw-r--r--cmpl.h 42
-rw-r--r--cpp-utils/list.h 58
-rw-r--r--cpp-utils/pthreadpp.h 54
-rw-r--r--cpp-utils/tree.h (renamed from agg-plot/my_tree.h)17
-rw-r--r--defs.h 3
-rw-r--r--fox-gui/Makefile 62
-rw-r--r--fox-gui/fox_gsl_shell.cpp 36
-rw-r--r--fox-gui/fox_gsl_shell.h 30
-rw-r--r--fox-gui/fx_console.cpp 133
-rw-r--r--fox-gui/fx_console.h 58
-rw-r--r--fox-gui/fx_plot_canvas.cpp 178
-rw-r--r--fox-gui/fx_plot_canvas.h 73
-rw-r--r--fox-gui/fx_plot_window.cpp 31
-rw-r--r--fox-gui/fx_plot_window.h 37
-rw-r--r--fox-gui/gsl-shell-fox.cpp 22
-rw-r--r--fox-gui/gsl_shell_app.cpp 84
-rw-r--r--fox-gui/gsl_shell_app.h 50
-rw-r--r--fox-gui/gsl_shell_interp.cpp 202
-rw-r--r--fox-gui/gsl_shell_interp.h 46
-rw-r--r--fox-gui/gsl_shell_thread.cpp 106
-rw-r--r--fox-gui/gsl_shell_thread.h 60
-rw-r--r--fox-gui/gsl_shell_window.cpp 49
-rw-r--r--fox-gui/gsl_shell_window.h 36
-rw-r--r--fox-gui/image_buf.h 60
-rw-r--r--fox-gui/io_thread.cpp 49
-rw-r--r--fox-gui/io_thread.h 25
-rw-r--r--fox-gui/lua_plot_window.cpp 169
-rw-r--r--fox-gui/lua_plot_window.h 21
-rw-r--r--fox-gui/redirect.cpp 54
-rw-r--r--fox-gui/redirect.h 18
-rw-r--r--gsl-shell-jit.c 53
-rw-r--r--gsl-shell.h 7
-rw-r--r--iter.lua 11
-rw-r--r--lua-graph.h 19
-rw-r--r--lua-gsl.h 23
-rw-r--r--lua-gsl/Makefile 57
-rw-r--r--lua-gsl/fatal.c 13
-rw-r--r--lua-gsl/fatal.h 12
-rw-r--r--lua-gsl/gs-types.c (renamed from gs-types.c)9
-rw-r--r--lua-gsl/gs-types.h (renamed from gs-types.h)3
-rw-r--r--lua-gsl/lua-defs.h (renamed from lua-defs.h)0
-rw-r--r--lua-gsl/lua-gsl.c (renamed from lua-gsl.c)38
-rw-r--r--lua-gsl/lua-utils.c (renamed from lua-utils.c)0
-rw-r--r--lua-gsl/lua-utils.h (renamed from lua-utils.h)0
-rw-r--r--lua-gsl/str.c (renamed from str.c)0
-rw-r--r--lua-gsl/str.h (renamed from str.h)0
-rw-r--r--lua-gsl/strpp.h (renamed from agg-plot/strpp.h)9
-rw-r--r--makedefs 8
-rw-r--r--makepackages 11
73 files changed, 2287 insertions, 425 deletions
diff --git a/Makefile b/Makefile
index 2453c981..73dbddea 100644
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,7 @@ include makedefs
LUADIR = luajit2
-INCLUDES += -I. $(GSL_INCLUDES)
+INCLUDES += -I. $(GSL_INCLUDES) -Iagg-plot -Ilua-gsl
GSL_SHELL = gsl-shell$(EXE_EXT)
LUA_CFLAGS = -I$(LUADIR)/src
@@ -43,9 +43,9 @@ else
endif
endif
-SUBDIRS = $(LUADIR)
+SUBDIRS = $(LUADIR) lua-gsl
-C_SRC_FILES = str.c gs-types.c lua-utils.c lua-graph.c lua-gsl.c
+C_SRC_FILES =
ifeq ($(strip $(USE_READLINE)),yes)
C_SRC_FILES += completion.c
@@ -59,7 +59,8 @@ LUA_TEMPLATES = gauss-kronrod-x-wgs qag rk8pd lmfit qng rkf45 ode-defs rk4 sf-de
LUA_BASE_FILES += $(DEMOS_LIST:%=demos/%.lua)
LUA_BASE_FILES += $(LUA_TEMPLATES:%=templates/%.lua.in)
-LUAGSL_LIBS = $(LUADIR)/src/libluajit.a
+LUAGSL_LIBS += $(LUADIR)/src/libluajit.a
+
C_SRC_FILES += gsl-shell-jit.c
TARGETS = $(GSL_SHELL)
@@ -71,18 +72,13 @@ SUBDIRS += agg-plot
LUAGSL_LIBS += agg-plot/libaggplot.a
LIBS += $(AGG_LIBS) $(FREETYPE_LIBS) $(PTHREADS_LIBS)
-COMPILE = $(CC) $(CFLAGS) $(LUA_CFLAGS) $(DEFS) $(INCLUDES)
-CXXCOMPILE = $(CXX) $(CXXFLAGS) -c
+LUAGSL_LIBS += lua-gsl/libluagsl.a
-ifeq ($(HOST_SYS),Darwin)
- LINK_EXE = $(CXX) $(LDFLAGS)
-else
- LINK_EXE = $(CC) $(LDFLAGS)
-endif
+COMPILE = $(CC) $(CFLAGS) $(LUA_CFLAGS) $(DEFS) $(INCLUDES)
-LUAGSL_OBJ_FILES = $(C_SRC_FILES:%.c=%.o) $(CXX_SRC_FILES:%.cpp=%.o)
+LUAGSL_OBJ_FILES = $(C_SRC_FILES:%.c=%.o)
-DEP_FILES := $(C_SRC_FILES:%.c=.deps/%.P) $(CXX_SRC_FILES:%.cpp=.deps/%.P)
+DEP_FILES := $(C_SRC_FILES:%.c=.deps/%.P)
DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
LIBS_MAGIC := $(shell mkdir .libs > /dev/null 2>&1 || :)
diff --git a/agg-plot/Makefile b/agg-plot/Makefile
index 519d8b5d..e7888409 100644
--- a/agg-plot/Makefile
+++ b/agg-plot/Makefile
@@ -34,9 +34,9 @@ else
PLATSUP_SRC_FILES = support_x11.cpp agg_platform_support_x11.cpp
endif
-INCLUDES += $(AGG_INCLUDES) $(FREETYPE_INCLUDES) -I$(GSH_BASE_DIR) -I$(LUADIR)/src
+INCLUDES += $(FREETYPE_INCLUDES) $(AGG_INCLUDES) -I$(GSH_BASE_DIR) -I$(GSH_BASE_DIR)/lua-gsl -I$(LUADIR)/src -I$(GSH_BASE_DIR)/cpp-utils
-AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) printf_check.cpp fonts.cpp gamma.cpp agg_font_freetype.cpp utils.cpp units.cpp colors.cpp markers.cpp draw_svg.cpp canvas_svg.cpp lua-draw.cpp lua-text.cpp text.cpp agg-parse-trans.cpp window_registry.cpp window.cpp lua-plot.cpp canvas-window.cpp bitmap-plot.cpp
+AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) printf_check.cpp fonts.cpp gamma.cpp agg_font_freetype.cpp utils.cpp units.cpp colors.cpp markers.cpp draw_svg.cpp canvas_svg.cpp lua-draw.cpp lua-text.cpp text.cpp agg-parse-trans.cpp window_registry.cpp window.cpp lua-plot.cpp canvas-window.cpp bitmap-plot.cpp lua-graph.cpp
AGGPLOT_OBJ_FILES := $(AGGPLOT_SRC_FILES:%.cpp=%.o)
diff --git a/agg-plot/agg_platform_support_win32.cpp b/agg-plot/agg_platform_support_win32.cpp
index a4361e69..506f3c5a 100644
--- a/agg-plot/agg_platform_support_win32.cpp
+++ b/agg-plot/agg_platform_support_win32.cpp
@@ -24,8 +24,8 @@
#include <windows.h>
#include <string.h>
-#include <pthread.h>
#include <new>
+#include "pthreadpp.h"
#include "agg-pixfmt-config.h"
#include "platform_support_ext.h"
#include "platform/win32/agg_win32_bmp.h"
@@ -87,7 +87,7 @@ namespace agg
bool m_is_mapped;
bool m_is_ready;
- pthread_mutex_t m_mutex[1];
+ pthread::mutex m_mutex;
static void bitmap_info_resize (BITMAPINFO* bmp, unsigned w, unsigned h);
};
@@ -112,15 +112,11 @@ namespace agg
{
::QueryPerformanceFrequency(&m_sw_freq);
::QueryPerformanceCounter(&m_sw_start);
-
- pthread_mutex_init (m_mutex, NULL);
}
//------------------------------------------------------------------------
platform_specific::~platform_specific()
{
- pthread_mutex_destroy (m_mutex);
-
if (m_bmp_draw)
delete [] (unsigned char*) m_bmp_draw;
}
@@ -461,9 +457,9 @@ namespace agg
if (m_specific->m_is_ready)
{
- pthread_mutex_unlock (m_specific->m_mutex);
+ m_specific->m_mutex.unlock();
status = ::GetMessage(&msg, 0, 0, 0);
- pthread_mutex_lock (m_specific->m_mutex);
+ m_specific->m_mutex.lock();
}
else
{
@@ -628,13 +624,13 @@ platform_support_ext::prepare()
void
platform_support_ext::lock()
{
- pthread_mutex_lock (m_specific->m_mutex);
+ m_specific->m_mutex.lock();
}
void
platform_support_ext::unlock()
{
- pthread_mutex_unlock (m_specific->m_mutex);
+ m_specific->m_mutex.unlock();
}
bool
diff --git a/agg-plot/agg_platform_support_x11.cpp b/agg-plot/agg_platform_support_x11.cpp
index 24f978a7..69181ecd 100644
--- a/agg-plot/agg_platform_support_x11.cpp
+++ b/agg-plot/agg_platform_support_x11.cpp
@@ -32,8 +32,9 @@
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
-#include <pthread.h>
#include <new>
+
+#include "pthreadpp.h"
#include "agg_basics.h"
#include "util/agg_color_conv_rgb8.h"
#include "agg-pixfmt-config.h"
@@ -164,7 +165,7 @@ namespace agg
public:
platform_specific(pix_format_e format, bool flip_y);
- ~platform_specific();
+ ~platform_specific() {};
void free_x_resources();
@@ -199,7 +200,7 @@ namespace agg
bool m_is_mapped;
clock_t m_sw_start;
- pthread_mutex_t m_mutex[1];
+ pthread::mutex m_mutex;
static bool initialized;
};
@@ -252,14 +253,6 @@ namespace agg
break;
}
m_sw_start = clock();
-
- pthread_mutex_init (m_mutex, NULL);
- }
-
- //------------------------------------------------------------------------
- platform_specific::~platform_specific()
- {
- pthread_mutex_destroy (m_mutex);
}
void platform_specific::close_connections()
@@ -728,9 +721,9 @@ namespace agg
XEvent x_event;
if (ps->m_is_mapped)
{
- pthread_mutex_unlock (ps->m_mutex);
+ ps->m_mutex.unlock();
XNextEvent(xc->display, &x_event);
- pthread_mutex_lock (ps->m_mutex);
+ ps->m_mutex.lock();
}
else
{
@@ -1069,13 +1062,13 @@ platform_support_ext::prepare()
void
platform_support_ext::lock()
{
- pthread_mutex_lock (m_specific->m_mutex);
+ m_specific->m_mutex.lock();
}
void
platform_support_ext::unlock()
{
- pthread_mutex_unlock (m_specific->m_mutex);
+ m_specific->m_mutex.unlock();
}
bool
diff --git a/agg-plot/canvas-window-cpp.h b/agg-plot/canvas-window-cpp.h
index d7eb5b77..2d29fef5 100644
--- a/agg-plot/canvas-window-cpp.h
+++ b/agg-plot/canvas-window-cpp.h
@@ -17,6 +17,7 @@ extern "C" {
#include "defs.h"
#include "canvas.h"
#include "utils.h"
+#include "lua-gsl.h"
class canvas_window : public platform_support_ext {
protected:
@@ -26,6 +27,7 @@ protected:
agg::trans_affine m_matrix;
pthread_t m_thread;
+ gsl_shell_state* m_gsl_shell;
public:
@@ -41,9 +43,10 @@ public:
enum win_status_e status;
- canvas_window(agg::rgba8 bgcol) :
- platform_support_ext(gslshell::pixel_format, true),
- m_canvas(NULL), m_bgcolor(bgcol), m_matrix(), status(not_ready)
+ canvas_window(gsl_shell_state* gs, agg::rgba8 bgcol):
+ platform_support_ext(gslshell::pixel_format, true),
+ m_canvas(NULL), m_bgcolor(bgcol), m_matrix(), m_gsl_shell(gs),
+ status(not_ready)
{ };
virtual ~canvas_window()
@@ -56,6 +59,7 @@ public:
virtual void on_resize(int sx, int sy);
void shutdown_close();
+ gsl_shell_state* state() { return m_gsl_shell; }
bool start_new_thread (std::auto_ptr<thread_info>& inf);
diff --git a/agg-plot/canvas-window.cpp b/agg-plot/canvas-window.cpp
index 11270616..bcec7ac7 100644
--- a/agg-plot/canvas-window.cpp
+++ b/agg-plot/canvas-window.cpp
@@ -21,7 +21,7 @@
#include "defs.h"
#include "canvas-window-cpp.h"
#include "resource-manager.h"
-#include "gsl-shell.h"
+#include "lua-gsl.h"
#include "agg-parse-trans.h"
#include "lua-cpp-utils.h"
#include "lua-utils.h"
@@ -105,14 +105,16 @@ canvas_thread_function (void *_inf)
win->unlock();
- pthread_mutex_lock (gsl_shell_shutdown_mutex);
- if (!gsl_shell_shutting_down)
+ gsl_shell_state* gs = win->state();
+
+ pthread_mutex_lock (&gs->shutdown_mutex);
+ if (!gs->is_shutting_down)
{
- GSL_SHELL_LOCK();
- window_index_remove (inf->L, inf->window_id);
- GSL_SHELL_UNLOCK();
+ pthread_mutex_lock(&gs->exec_mutex);
+ window_index_remove (gs->L, inf->window_id);
+ pthread_mutex_unlock(&gs->exec_mutex);
}
- pthread_mutex_unlock (gsl_shell_shutdown_mutex);
+ pthread_mutex_unlock (&gs->shutdown_mutex);
return NULL;
}
@@ -125,9 +127,11 @@ canvas_window::shutdown_close()
{
close_request();
unlock();
- pthread_mutex_unlock (gsl_shell_shutdown_mutex);
+
+ gsl_shell_state* gs = this->m_gsl_shell;
+ pthread_mutex_unlock (&gs->shutdown_mutex);
pthread_join(m_thread, NULL);
- pthread_mutex_lock (gsl_shell_shutdown_mutex);
+ pthread_mutex_lock (&gs->shutdown_mutex);
}
else
{
diff --git a/agg-plot/canvas_svg.cpp b/agg-plot/canvas_svg.cpp
index fc5a859e..e5ef6d88 100644
--- a/agg-plot/canvas_svg.cpp
+++ b/agg-plot/canvas_svg.cpp
@@ -17,6 +17,6 @@ void canvas_svg::draw_outline<sg_object>(sg_object& vs, agg::rgba8 c)
str path;
svg_property_list* ls = vs.svg_path(path, m_height);
str s = svg_stroke_path(path, canvas_svg::default_stroke_width, id, c, ls);
- list::free(ls);
+ svg_property_list::free(ls);
canvas_svg::writeln(m_output, s, " ");
}
diff --git a/agg-plot/draw_svg.h b/agg-plot/draw_svg.h
index 34f6f681..2ceb2169 100644
--- a/agg-plot/draw_svg.h
+++ b/agg-plot/draw_svg.h
@@ -3,7 +3,7 @@
#include "agg_basics.h"
#include "agg_color_rgba.h"
-#include "my_list.h"
+#include "list.h"
#include "strpp.h"
enum svg_path_property_e {
@@ -33,7 +33,7 @@ vertex_flip(VertexSource* vs, double* x, double* y, double h)
return cmd;
}
-typedef pod_list<svg_property_item> svg_property_list;
+typedef list<svg_property_item> svg_property_list;
template <typename VertexSource>
void svg_coords_from_vs(VertexSource* vs, str& s, double h)
diff --git a/agg-plot/lua-draw.cpp b/agg-plot/lua-draw.cpp
index e8fba890..f7a458ae 100644
--- a/agg-plot/lua-draw.cpp
+++ b/agg-plot/lua-draw.cpp
@@ -26,16 +26,14 @@ extern "C" {
}
#include "lua-draw.h"
+#include "lua-graph.h"
#include "text-shape.h"
-#include "gsl-shell.h"
#include "lua-cpp-utils.h"
#include "gs-types.h"
#include "trans.h"
#include "colors.h"
#include "sg_marker.h"
-pthread_mutex_t agg_mutex[1];
-
enum path_cmd_e {
CMD_ERROR = -1,
CMD_MOVE_TO = 0,
@@ -313,8 +311,6 @@ marker_free (lua_State *L)
void
draw_register (lua_State *L)
{
- pthread_mutex_init (agg_mutex, NULL);
-
luaL_newmetatable (L, GS_METATABLE(GS_DRAW_PATH));
luaL_register (L, NULL, agg_path_methods);
lua_pop (L, 1);
diff --git a/agg-plot/lua-draw.h b/agg-plot/lua-draw.h
index 4213a003..a858b73c 100644
--- a/agg-plot/lua-draw.h
+++ b/agg-plot/lua-draw.h
@@ -1,11 +1,8 @@
#ifndef LUA_DRAW_H
#define LUA_DRAW_H
-
#include "defs.h"
-#include <pthread.h>
-
__BEGIN_DECLS
#include "lua.h"
__END_DECLS
@@ -26,17 +23,6 @@ extern draw::path* check_agg_path (lua_State *L, int index);
__BEGIN_DECLS
-extern pthread_mutex_t agg_mutex[1];
-
-#define AGG_LOCK() pthread_mutex_lock (agg_mutex);
-#define AGG_UNLOCK() pthread_mutex_unlock (agg_mutex);
-
-#define AGG_PROTECT(op) { \
- pthread_mutex_lock (agg_mutex); \
- op; \
- pthread_mutex_unlock (agg_mutex); \
- }
-
extern void draw_register (lua_State *L);
__END_DECLS
diff --git a/lua-graph.c b/agg-plot/lua-graph.cpp
index d592b720..c056a10b 100644
--- a/lua-graph.c
+++ b/agg-plot/lua-graph.cpp
@@ -18,18 +18,28 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+extern "C" {
#include <lua.h>
#include <lauxlib.h>
+}
#include "lua-graph.h"
+#include "lua-gsl.h"
#include "window_registry.h"
#include "lua-draw.h"
#include "lua-text.h"
#include "window.h"
#include "lua-plot.h"
+#include "window_hooks.h"
+
+#ifndef MLUA_GRAPHLIBNAME
+#define MLUA_GRAPHLIBNAME "graph"
+#endif
static const struct luaL_Reg methods_dummy[] = {{NULL, NULL}};
+pthread_mutex_t agg_mutex[1];
+
void
graph_close_windows (lua_State *L)
{
@@ -39,16 +49,30 @@ graph_close_windows (lua_State *L)
void
register_graph (lua_State *L)
{
+ pthread_mutex_init (agg_mutex, NULL);
+
window_registry_prepare (L);
luaL_register (L, MLUA_GRAPHLIBNAME, methods_dummy);
draw_register (L);
text_register (L);
- window_register (L);
+ app_window_hooks->register_module (L);
plot_register (L);
initialize_fonts (L);
lua_pop(L, 1);
}
+
+void
+gsl_shell_close_with_graph (struct gsl_shell_state* gs)
+{
+ pthread_mutex_lock (&gs->shutdown_mutex);
+ gs->is_shutting_down = 1;
+ pthread_mutex_lock(&gs->exec_mutex);
+ graph_close_windows(gs->L);
+ lua_close(gs->L);
+ pthread_mutex_unlock(&gs->shutdown_mutex);
+ pthread_mutex_unlock(&gs->exec_mutex);
+}
diff --git a/agg-plot/lua-plot.cpp b/agg-plot/lua-plot.cpp
index 9812668b..9f6ce209 100644
--- a/agg-plot/lua-plot.cpp
+++ b/agg-plot/lua-plot.cpp
@@ -25,10 +25,10 @@ extern "C" {
#include "lua-plot.h"
#include "lua-plot-cpp.h"
+#include "window_hooks.h"
+#include "lua-graph.h"
#include "lua-cpp-utils.h"
#include "bitmap-plot.h"
-#include "window.h"
-#include "window-cpp.h"
#include "gs-types.h"
#include "lua-utils.h"
#include "window_registry.h"
@@ -488,7 +488,7 @@ plot_newindex (lua_State *L)
void
plot_update_raw (lua_State *L, sg_plot *p, int plot_index)
{
- window_refs_lookup_apply (L, plot_index, window_slot_update);
+ window_refs_lookup_apply (L, plot_index, app_window_hooks->update);
p->commit_pending_draw();
}
@@ -504,7 +504,7 @@ int
plot_flush (lua_State *L)
{
sg_plot *p = object_check<sg_plot>(L, 1, GS_PLOT);
- window_refs_lookup_apply (L, 1, window_slot_refresh);
+ window_refs_lookup_apply (L, 1, app_window_hooks->refresh);
p->commit_pending_draw();
return 0;
}
@@ -512,19 +512,11 @@ plot_flush (lua_State *L)
int
plot_show (lua_State *L)
{
- sg_plot* plot = object_check<sg_plot>(L, 1, GS_PLOT);
- window* win = push_new_object<window>(L, GS_WINDOW, colors::white);
-
- int slot_id = win->attach (plot, "");
- assert(slot_id >= 0);
- window_refs_add (L, slot_id, -1, 1);
-
- gslshell::ret_status st;
- win->start(L, st);
-
- if (st.error_msg())
- return luaL_error (L, "%s (reported during %s)", st.error_msg(), st.context());
-
+ lua_pushcfunction (L, app_window_hooks->attach);
+ (*app_window_hooks->create)(L);
+ lua_pushvalue (L, 1);
+ lua_pushstring (L, "");
+ lua_call (L, 3, 0);
return 0;
}
@@ -551,13 +543,13 @@ plot_push_layer (lua_State *L)
{
sg_plot *p = object_check<sg_plot>(L, 1, GS_PLOT);
- window_refs_lookup_apply (L, 1, window_slot_refresh);
+ window_refs_lookup_apply (L, 1, app_window_hooks->refresh);
AGG_LOCK();
p->push_layer();
AGG_UNLOCK();
- window_refs_lookup_apply (L, 1, window_save_slot_image);
+ window_refs_lookup_apply (L, 1, app_window_hooks->save_image);
return 0;
}
@@ -597,7 +589,7 @@ plot_clear (lua_State *L)
p->clear_current_layer();
AGG_UNLOCK();
- window_refs_lookup_apply (L, 1, window_restore_slot_image);
+ window_refs_lookup_apply (L, 1, app_window_hooks->restore_image);
if (p->sync_mode())
plot_update_raw (L, p, 1);
diff --git a/agg-plot/my_list.h b/agg-plot/my_list.h
deleted file mode 100644
index 34e7cf0d..00000000
--- a/agg-plot/my_list.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef AGGPLOT_LIST_H
-#define AGGPLOT_LIST_H
-
-template <class T>
-class pod_list {
- T m_content;
- pod_list *m_next;
-
-public:
- pod_list(const T& c, pod_list* next = 0) : m_content(c), m_next(next) { };
-
- T& content() { return m_content; };
- const T& content() const { return m_content; };
-
- static pod_list* push_back(pod_list* head, pod_list* n)
- {
- pod_list* k = head;
-
- if (! k)
- return n;
-
- while (k->m_next)
- k = k->m_next;
- k->m_next = n;
-
- return head;
- }
-
- pod_list* next() { return m_next; };
-};
-
-namespace list {
-
- template <class T>
- int length(pod_list<T> *ls)
- {
- int n = 0;
- for ( ; ls; ls = ls->next())
- n++;
- return n;
- }
-
- template <class T>
- void free(pod_list<T> *p)
- {
- pod_list<T> *n;
- for (/* */; p; p = n)
- {
- n = p->next();
- delete p;
- }
- }
-
- template <class T>
- pod_list<T> * pop(pod_list<T> *p)
- {
- pod_list<T> *tail = p->next();
- delete p;
- return tail;
- }
-
- template <class T, class f>
- void apply(pod_list<T> *p)
- {
- pod_list<T> *n;
- for ( ; p; p = n)
- {
- n = p->m_next;
- T& val = p->content();
- f::func(val);
- }
- }
-}
-
-#endif
diff --git a/agg-plot/platform_support_ext.h b/agg-plot/platform_support_ext.h
index f58c03f9..8b601763 100644
--- a/agg-plot/platform_support_ext.h
+++ b/agg-plot/platform_support_ext.h
@@ -3,6 +3,7 @@
#include "agg_basics.h"
#include "platform/agg_platform_support.h"
+#include "rendering_buffer_utils.h"
class platform_support_ext : public agg::platform_support {
public:
@@ -24,120 +25,4 @@ public:
agg::pix_format_e src_pixfmt_tag);
};
-template<class RenBufDst, class RenBufSrc, class CopyRow>
-void my_color_conv(RenBufDst* dst, const RenBufSrc* src, CopyRow copy_row_functor)
-{
- unsigned int width = src->width();
- unsigned int height = src->height();
-
- for(unsigned int y = 0; y < height; y++)
- {
- copy_row_functor(dst->row_ptr(0, y, width), src->row_ptr(y), width);
- }
-}
-
-template<class RenBufDst, class RenBufSrc>
-void rendering_buffer_get_region (RenBufDst& dst, RenBufSrc& src, agg::rect_base<int>& r,
- unsigned pixel_width)
-{
- int w = r.x2 - r.x1, h = r.y2 - r.y1;
- for (int y = 0; y < h; y++)
- {
- unsigned char *drow = dst.row_ptr(y);
- unsigned char *srow = src.row_ptr(r.y1 + y);
- srow += r.x1 * pixel_width;
- memcpy (drow, srow, pixel_width * w);
- }
-}
-
-template<class RenBufDst, class RenBufSrc>
-void rendering_buffer_get_const_view (RenBufDst& view, const RenBufSrc& src,
- const agg::rect_base<int>& r,
- unsigned pixel_width, bool flip_y)
-{
- int x = r.x1, y = r.y1, w = r.x2 - r.x1, h = r.y2 - r.y1;
- const unsigned char *buf_start = src.row_ptr(y);
- if (src.stride() < 0)
- buf_start += src.stride() * (h - 1);
- view.attach(buf_start + pixel_width * x, w, h, src.stride());
-}
-
-template<class RenBufDst, class RenBufSrc>
-void rendering_buffer_get_view (RenBufDst& view, RenBufSrc& src,
- const agg::rect_base<int>& r,
- unsigned pixel_width, bool flip_y)
-{
- int x = r.x1, y = r.y1, w = r.x2 - r.x1, h = r.y2 - r.y1;
- unsigned char *buf_start = src.row_ptr(y);
- if (src.stride() < 0)
- buf_start += src.stride() * (h - 1);
- view.attach(buf_start + pixel_width * x, w, h, src.stride());
-}
-
-template<class RenBufDst, class RenBufSrc>
-void rendering_buffer_put_region (RenBufDst& dst, RenBufSrc& src, agg::rect_base<int>& r,
- unsigned pixel_width)
-{
- int w = r.x2 - r.x1, h = r.y2 - r.y1;
- for (int y = 0; y < h; y++)
- {
- unsigned char *drow = dst.row_ptr(r.y1 + y);
- unsigned char *srow = src.row_ptr(y);
- drow += r.x1 * pixel_width;
- memcpy (drow, srow, pixel_width * w);
- }
-}
-
-template<class T> class row_accessor_ro
-{
-public:
- //--------------------------------------------------------------------
- row_accessor_ro() : m_buf(0), m_width(0), m_height(0), m_stride(0), m_start(0) {};
-
- row_accessor_ro(const T* buf, unsigned width, unsigned height, int stride) :
- m_buf(buf), m_width(width), m_height(height), m_stride(stride)
- {
- if(stride < 0)
- m_start = m_buf - int(height - 1) * stride;
- else
- m_start = m_buf;
- }
-
- void attach(const T* buf, unsigned width, unsigned height, int stride)
- {
- m_buf = m_start = buf;
- m_width = width;
- m_height = height;
- m_stride = stride;
- if(stride < 0)
- {
- m_start = m_buf - int(height - 1) * stride;
- }
- };
-
- //--------------------------------------------------------------------
- const T* buf() const { return m_buf; }
- unsigned width() const { return m_width; }
- unsigned height() const { return m_height; }
- int stride() const { return m_stride; }
- unsigned stride_abs() const
- {
- return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride);
- }
-
- //--------------------------------------------------------------------
- const T* row_ptr(int, int y, unsigned) const { return m_start + y * m_stride; }
- const T* row_ptr(int y) const { return m_start + y * m_stride; }
-
-private:
- //--------------------------------------------------------------------
- const T* m_buf; // Pointer to renrdering buffer
- unsigned m_width; // Width in pixels
- unsigned m_height; // Height in pixels
- int m_stride; // Number of bytes per row. Can be < 0
- const T* m_start; // Pointer to first pixel depending on stride
-};
-
-typedef row_accessor_ro<unsigned char> rendering_buffer_ro;
-
#endif
diff --git a/agg-plot/plot-auto.h b/agg-plot/plot-auto.h
index 20b590ad..4701c12f 100644
--- a/agg-plot/plot-auto.h
+++ b/agg-plot/plot-auto.h
@@ -77,8 +77,8 @@ void plot_auto<RM>::add(sg_object* vs, agg::rgba8& color, bool outline)
this->m_enlarged_layer = true;
}
- pod_list<item> *nn = new pod_list<item>(d);
- this->m_drawing_queue = pod_list<item>::push_back(this->m_drawing_queue, nn);
+ list<item> *nn = new list<item>(d);
+ this->m_drawing_queue = list<item>::push_back(this->m_drawing_queue, nn);
RM::acquire(vs);
}
@@ -117,8 +117,7 @@ void plot_auto<RM>::calc_bounding_box()
}
calc_layer_bounding_box(this->get_layer(n-1), box);
-
- for (pod_list<item> *t = this->m_drawing_queue; t; t = t->next())
+ for (list<item> *t = this->m_drawing_queue; t; t = t->next())
{
const item& d = t->content();
agg::rect_base<double> r;
diff --git a/agg-plot/plot.h b/agg-plot/plot.h
index 9abb7444..fbc6707c 100644
--- a/agg-plot/plot.h
+++ b/agg-plot/plot.h
@@ -24,7 +24,7 @@
#include <new>
#include "utils.h"
-#include "my_list.h"
+#include "list.h"
#include "strpp.h"
#include "canvas.h"
#include "units.h"
@@ -106,7 +106,7 @@ protected:
};
public:
- typedef pod_list<item> iterator;
+ typedef list<item> iterator;
typedef virtual_canvas canvas_type;
enum axis_e { x_axis, y_axis };
@@ -326,7 +326,7 @@ protected:
}
agg::trans_affine m_trans;
- pod_list<item> *m_drawing_queue;
+ list<item> *m_drawing_queue;
bool m_clip_flag;
@@ -379,8 +379,8 @@ template <class RM>
void plot<RM>::add(sg_object* vs, agg::rgba8& color, bool outline)
{
item d(vs, color, outline);
- pod_list<item> *new_node = new pod_list<item>(d);
- m_drawing_queue = pod_list<item>::push_back(m_drawing_queue, new_node);
+ list<item> *new_node = new list<item>(d);
+ m_drawing_queue = list<item>::push_back(m_drawing_queue, new_node);
RM::acquire(vs);
}
@@ -388,13 +388,13 @@ template <class RM>
void plot<RM>::push_drawing_queue()
{
item_list* layer = current_layer();
- for (pod_list<item> *c = m_drawing_queue; c != 0; c = c->next())
+ for (list<item> *c = m_drawing_queue; c != 0; c = c->next())
{
layer->add(c->content());
}
while (m_drawing_queue)
- m_drawing_queue = list::pop(m_drawing_queue);
+ m_drawing_queue = list<item>::pop(m_drawing_queue);
}
template <class RM>
@@ -404,7 +404,7 @@ void plot<RM>::clear_drawing_queue()
{
item& d = m_drawing_queue->content();
RM::dispose(d.vs);
- m_drawing_queue = list::pop(m_drawing_queue);
+ m_drawing_queue = list<item>::pop(m_drawing_queue);
}
}
diff --git a/agg-plot/rendering_buffer_utils.h b/agg-plot/rendering_buffer_utils.h
new file mode 100644
index 00000000..56103e4a
--- /dev/null
+++ b/agg-plot/rendering_buffer_utils.h
@@ -0,0 +1,120 @@
+#ifndef AGGPLOT_RBUF_UTILS_H
+#define AGGPLOT_RBUF_UTILS_H
+
+template<class RenBufDst, class RenBufSrc, class CopyRow>
+void my_color_conv(RenBufDst* dst, const RenBufSrc* src, CopyRow copy_row_functor)
+{
+ unsigned int width = src->width();
+ unsigned int height = src->height();
+
+ for(unsigned int y = 0; y < height; y++)
+ {
+ copy_row_functor(dst->row_ptr(0, y, width), src->row_ptr(y), width);
+ }
+}
+
+template<class RenBufDst, class RenBufSrc>
+void rendering_buffer_get_region (RenBufDst& dst, RenBufSrc& src, agg::rect_base<int>& r,
+ unsigned pixel_width)
+{
+ int w = r.x2 - r.x1, h = r.y2 - r.y1;
+ for (int y = 0; y < h; y++)
+ {
+ unsigned char *drow = dst.row_ptr(y);
+ unsigned char *srow = src.row_ptr(r.y1 + y);
+ srow += r.x1 * pixel_width;
+ memcpy (drow, srow, pixel_width * w);
+ }
+}
+
+template<class RenBufDst, class RenBufSrc>
+void rendering_buffer_get_const_view (RenBufDst& view, const RenBufSrc& src,
+ const agg::rect_base<int>& r,
+ unsigned pixel_width, bool flip_y)
+{
+ int x = r.x1, y = r.y1, w = r.x2 - r.x1, h = r.y2 - r.y1;
+ const unsigned char *buf_start = src.row_ptr(y);
+ if (src.stride() < 0)
+ buf_start += src.stride() * (h - 1);
+ view.attach(buf_start + pixel_width * x, w, h, src.stride());
+}
+
+template<class RenBufDst, class RenBufSrc>
+void rendering_buffer_get_view (RenBufDst& view, RenBufSrc& src,
+ const agg::rect_base<int>& r,
+ unsigned pixel_width, bool flip_y)
+{
+ int x = r.x1, y = r.y1, w = r.x2 - r.x1, h = r.y2 - r.y1;
+ unsigned char *buf_start = src.row_ptr(y);
+ if (src.stride() < 0)
+ buf_start += src.stride() * (h - 1);
+ view.attach(buf_start + pixel_width * x, w, h, src.stride());
+}
+
+template<class RenBufDst, class RenBufSrc>
+void rendering_buffer_put_region (RenBufDst& dst, RenBufSrc& src, agg::rect_base<int>& r,
+ unsigned pixel_width)
+{
+ int w = r.x2 - r.x1, h = r.y2 - r.y1;
+ for (int y = 0; y < h; y++)
+ {
+ unsigned char *drow = dst.row_ptr(r.y1 + y);
+ unsigned char *srow = src.row_ptr(y);
+ drow += r.x1 * pixel_width;
+ memcpy (drow, srow, pixel_width * w);
+ }
+}
+
+template<class T> class row_accessor_ro
+{
+public:
+ //--------------------------------------------------------------------
+ row_accessor_ro() : m_buf(0), m_width(0), m_height(0), m_stride(0), m_start(0) {};
+
+ row_accessor_ro(const T* buf, unsigned width, unsigned height, int stride) :
+ m_buf(buf), m_width(width), m_height(height), m_stride(stride)
+ {
+ if(stride < 0)
+ m_start = m_buf - int(height - 1) * stride;
+ else
+ m_start = m_buf;
+ }
+
+ void attach(const T* buf, unsigned width, unsigned height, int stride)
+ {
+ m_buf = m_start = buf;
+ m_width = width;
+ m_height = height;
+ m_stride = stride;
+ if(stride < 0)
+ {
+ m_start = m_buf - int(height - 1) * stride;
+ }
+ };
+
+ //--------------------------------------------------------------------
+ const T* buf() const { return m_buf; }
+ unsigned width() const { return m_width; }
+ unsigned height() const { return m_height; }
+ int stride() const { return m_stride; }
+ unsigned stride_abs() const
+ {
+ return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride);
+ }
+
+ //--------------------------------------------------------------------
+ const T* row_ptr(int, int y, unsigned) const { return m_start + y * m_stride; }
+ const T* row_ptr(int y) const { return m_start + y * m_stride; }
+
+private:
+ //--------------------------------------------------------------------
+ const T* m_buf; // Pointer to renrdering buffer
+ unsigned m_width; // Width in pixels
+ unsigned m_height; // Height in pixels
+ int m_stride; // Number of bytes per row. Can be < 0
+ const T* m_start; // Pointer to first pixel depending on stride
+};
+
+typedef row_accessor_ro<unsigned char> rendering_buffer_ro;
+
+#endif
diff --git a/agg-plot/sg_object.h b/agg-plot/sg_object.h
index 4b3b4b8d..6001ca95 100644
--- a/agg-plot/sg_object.h
+++ b/agg-plot/sg_object.h
@@ -52,7 +52,7 @@ struct sg_object : public vertex_source {
str path;
svg_property_list* ls = this->svg_path(path, h);
str s = svg_fill_path(path, id, c, ls);
- list::free(ls);
+ svg_property_list::free(ls);
return s;
}
diff --git a/agg-plot/split-parser.h b/agg-plot/split-parser.h
index bbc9044d..feb44dd6 100644
--- a/agg-plot/split-parser.h
+++ b/agg-plot/split-parser.h
@@ -1,7 +1,7 @@
#ifndef AGGPLOT_SPLIT_PARSER_H
#define AGGPLOT_SPLIT_PARSER_H
-#include "my_tree.h"
+#include "tree.h"
enum direction_e { along_x, along_y };
diff --git a/agg-plot/trans.h b/agg-plot/trans.h
index c3aa60c2..e0aa9ecb 100644
--- a/agg-plot/trans.h
+++ b/agg-plot/trans.h
@@ -39,7 +39,7 @@ struct trans {
str path;
svg_property_list* ls = this->m_source->svg_path(path, h);
str s = svg_stroke_path(path, m_width, id, c, ls);
- list::free(ls);
+ svg_property_list::free(ls);
return s;
}
@@ -179,7 +179,7 @@ struct trans {
ls = new svg_property_list(item3, ls);
str svg = svg_marker_path(path, m_size, id, ls);
- list::free(ls);
+ svg_property_list::free(ls);
return str::print("%s\n %s", marker_def.cstr(), svg.cstr());
}
diff --git a/agg-plot/window-cpp.h b/agg-plot/window-cpp.h
index 4e8faa7e..20ba4744 100644
--- a/agg-plot/window-cpp.h
+++ b/agg-plot/window-cpp.h
@@ -10,7 +10,7 @@ extern "C" {
#include "lua-cpp-utils.h"
#include "plot.h"
#include "rect.h"
-#include "my_list.h"
+#include "list.h"
#include "agg_color_rgba.h"
#include "agg_trans_affine.h"
@@ -60,7 +60,8 @@ private:
ref::node* m_tree;
public:
- window(agg::rgba8 bgcol) : canvas_window(bgcol), m_tree(0)
+ window(gsl_shell_state* gs, agg::rgba8 bgcol= colors::white):
+ canvas_window(gs, bgcol), m_tree(0)
{
this->split(".");
};
diff --git a/agg-plot/window.cpp b/agg-plot/window.cpp
index 71560795..4c6de7c5 100644
--- a/agg-plot/window.cpp
+++ b/agg-plot/window.cpp
@@ -8,6 +8,7 @@ extern "C" {
#include "window-cpp.h"
#include "window_registry.h"
#include "lua-draw.h"
+#include "lua-graph.h"
#include "lua-cpp-utils.h"
#include "gs-types.h"
#include "colors.h"
@@ -64,14 +65,14 @@ int window::ref::calculate(window::ref::node* t, const bmatrix& m, int id)
r->matrix = m;
}
- int nb = list::length(t->tree());
+ int nb = list<ref::node*>::length(t->tree());
if (nb > 0)
{
double frac = 1 / (double) nb;
direction_e dir;
- ref::node::list *ls = t->tree(dir);
+ list<ref::node*> *ls = t->tree(dir);
if (ls)
{
bmatrix lm;
@@ -117,7 +118,7 @@ window::ref::save_image (agg::rendering_buffer& win_buf,
void
window::draw_rec(ref::node *n)
{
- ref::node::list *ls;
+ list<ref::node*> *ls;
for (ls = n->tree(); ls != NULL; ls = ls->next())
draw_rec(ls->content());
@@ -130,7 +131,7 @@ window::draw_rec(ref::node *n)
window::ref* window::ref_lookup (ref::node *p, int slot_id)
{
- ref::node::list *t = p->tree();
+ list<ref::node*> *t = p->tree();
for (/* */; t; t = t->next())
{
ref *ref = window::ref_lookup(t->content(), slot_id);
@@ -274,7 +275,7 @@ window::on_resize(int sx, int sy)
void
window::cleanup_tree_rec (lua_State *L, int window_index, ref::node* n)
{
- for (ref::node::list *ls = n->tree(); ls != NULL; ls = ls->next())
+ for (list<ref::node*> *ls = n->tree(); ls != NULL; ls = ls->next())
cleanup_tree_rec(L, window_index, ls->content());
ref *ref = n->content();
@@ -332,7 +333,7 @@ int window::attach(sg_plot* plot, const char *spec)
for (ptr = next_int (spec, k); ptr; ptr = next_int (ptr, k))
{
- ref::node::list* list = n->tree();
+ list<ref::node*>* list = n->tree();
if (! list)
return -1;
@@ -420,7 +421,7 @@ void window::start (lua_State *L, gslshell::ret_status& st)
int
window_new (lua_State *L)
{
- window *win = push_new_object<window>(L, GS_WINDOW, colors::white);
+ window *win = push_new_object<window>(L, GS_WINDOW, global_state);
const char *spec = lua_tostring (L, 1);
gslshell::ret_status st;
diff --git a/agg-plot/window_hooks.h b/agg-plot/window_hooks.h
new file mode 100644
index 00000000..e39350eb
--- /dev/null
+++ b/agg-plot/window_hooks.h
@@ -0,0 +1,25 @@
+#ifndef AGGPLOT_WINDOW_HOOKS_H
+#define AGGPLOT_WINDOW_HOOKS_H
+
+#include "defs.h"
+
+__BEGIN_DECLS
+
+#include "lua.h"
+
+struct window_hooks {
+ int (*create)(lua_State* L);
+ int (*attach)(lua_State* L);
+ int (*update)(lua_State* L);
+ int (*refresh)(lua_State* L);
+ int (*save_image)(lua_State* L);
+ int (*restore_image)(lua_State* L);
+
+ void (*register_module)(lua_State* L);
+};
+
+extern struct window_hooks app_window_hooks[1];
+
+__END_DECLS
+
+#endif
diff --git a/agg-plot/window_registry.cpp b/agg-plot/window_registry.cpp
index 4f324ea8..c2e6f1f1 100644
--- a/agg-plot/window_registry.cpp
+++ b/agg-plot/window_registry.cpp
@@ -18,14 +18,11 @@ window_registry_prepare (lua_State *L)
int
window_index_add(lua_State *L, int index)
{
- int n;
-
- if (index < 0)
- index = lua_gettop (L) - (index+1);
+ INDEX_SET_ABS(L, index);
lua_getfield (L, LUA_REGISTRYINDEX, registry_tname);
- n = lua_objlen (L, -1);
+ int n = lua_objlen (L, -1);
lua_pushvalue (L, index);
lua_rawseti (L, -2, n+1);
diff --git a/cmpl.h b/cmpl.h
deleted file mode 100644
index 10f1750e..00000000
--- a/cmpl.h
+++ /dev/null
@@ -1,42 +0,0 @@
-
-/* cmpl.h
- *
- * Copyright (C) 2009 Francesco Abbate
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef CMPL_VECTOR_H
-#define CMPL_VECTOR_H
-
-#include <math.h>
-
-#ifdef __cplusplus
-#define complex _Complex
-#else
-#include <complex.h>
-#endif /* C++ */
-
-#include "defs.h"
-
-__BEGIN_DECLS
-
-#define CSQABS(z) (creal(z)*creal(z) + cimag(z)*cimag(z))
-
-typedef double complex cmpl;
-
-__END_DECLS
-
-#endif
diff --git a/cpp-utils/list.h b/cpp-utils/list.h
new file mode 100644
index 00000000..95b9cb1c
--- /dev/null
+++ b/cpp-utils/list.h
@@ -0,0 +1,58 @@
+#ifndef CPP_LIST_H
+#define CPP_LIST_H
+
+template <class T>
+class list {
+ T m_content;
+ list* m_next;
+
+public:
+ list(const T& c, list* next = 0) : m_content(c), m_next(next) { };
+ list( T& c, list* next = 0) : m_content(c), m_next(next) { };
+
+ T& content() { return m_content; };
+ const T& content() const { return m_content; };
+
+ static list* push_back(list* head, list* n)
+ {
+ list* k = head;
+
+ if (! k)
+ return n;
+
+ while (k->m_next)
+ k = k->m_next;
+ k->m_next = n;
+
+ return head;
+ }
+
+ static int length(list* ls)
+ {
+ int n = 0;
+ for ( ; ls; ls = ls->next())
+ n++;
+ return n;
+ }
+
+ static void free(list* p)
+ {
+ list* n;
+ for (/* */; p; p = n)
+ {
+ n = p->m_next;
+ delete p;
+ }
+ }
+
+ static list* pop(list* p)
+ {
+ list* tail = p->next();
+ delete p;
+ return tail;
+ }
+
+ list* next() { return m_next; };
+};
+
+#endif
diff --git a/cpp-utils/pthreadpp.h b/cpp-utils/pthreadpp.h
new file mode 100644
index 00000000..876cc1fd
--- /dev/null
+++ b/cpp-utils/pthreadpp.h
@@ -0,0 +1,54 @@
+#ifndef CPP_PTHREADPP_H
+#define CPP_PTHREADPP_H
+
+#include <pthread.h>
+
+/* Simple C++ wrapper around basic mutex/condition operations.
+ The added value of the wrapper is more clean C++ code with automatic
+ initialization/deallocation of resources. */
+
+namespace pthread {
+
+ class mutex {
+ public:
+ mutex() { pthread_mutex_init(&m_mutex, NULL); }
+ ~mutex() { pthread_mutex_destroy(&m_mutex); }
+
+ void lock() { pthread_mutex_lock(&m_mutex); }
+ void unlock() { pthread_mutex_unlock(&m_mutex); }
+
+ pthread_mutex_t* mutex_ptr() { return &m_mutex; }
+
+ private:
+ mutex(const mutex&);
+ mutex& operator= (const mutex&);
+
+ pthread_mutex_t m_mutex;
+ };
+
+ class auto_lock {
+ public:
+ auto_lock(mutex& m): m_mutex(m) { m_mutex.lock(); }
+ ~auto_lock() { m_mutex.unlock(); }
+ private:
+ mutex& m_mutex;
+ };
+
+ /* Since the official documentation recommend to use pthread conditions
+ always in pair with a mutex we let a condtion inherit from a mutex.
+ In this way a C++ "cond" instance can perform both mutex and condition
+ operations. */
+ class cond : public mutex {
+ public:
+ cond() { pthread_cond_init(&m_cond, NULL); }
+ ~cond() { pthread_cond_destroy(&m_cond); }
+
+ void signal() { pthread_cond_signal(&m_cond); }
+ void wait() { pthread_cond_wait(&m_cond, mutex_ptr()); }
+
+ private:
+ pthread_cond_t m_cond;
+ };
+}
+
+#endif
diff --git a/agg-plot/my_tree.h b/cpp-utils/tree.h
index 97bc65a9..4d546615 100644
--- a/agg-plot/my_tree.h
+++ b/cpp-utils/tree.h
@@ -1,16 +1,14 @@
-#ifndef AGGPLOT_MY_TREE_H
-#define AGGPLOT_MY_TREE_H
+#ifndef CPP_TREE_H
+#define CPP_TREE_H
-#include "my_list.h"
+#include "list.h"
namespace tree {
template <class base_type, class tree_data_type>
struct node {
- typedef pod_list<node*> list;
-
- virtual list* tree() { return 0; };
- virtual list* tree(tree_data_type& data) { return 0; };
+ virtual list<node*>* tree() { return 0; };
+ virtual list<node*>* tree(tree_data_type& data) { return 0; };
virtual base_type* content() = 0;
virtual void content(const base_type& src) = 0;
@@ -33,7 +31,7 @@ namespace tree {
class tree_node : public node<base_type, tree_data_type> {
typedef node<base_type, tree_data_type> node_type;
- typedef typename node<base_type, tree_data_type>::list node_list;
+ typedef list<node_type*> node_list;
node_list *m_head;
tree_data_type m_data;
@@ -79,7 +77,8 @@ namespace tree {
if (c)
f::func(*c);
- typename node<base_type, tree_data_type>::list *ls = t->tree();
+ typedef node<base_type, tree_data_type> node_type;
+ list<node_type*>* ls = t->tree();
if (ls)
{
for ( ; ls; ls = ls->next())
diff --git a/defs.h b/defs.h
index 35c6e51f..f0e56161 100644
--- a/defs.h
+++ b/defs.h
@@ -46,4 +46,7 @@ typedef int bool;
#include <stdbool.h>
#endif
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+
#endif
diff --git a/fox-gui/Makefile b/fox-gui/Makefile
new file mode 100644
index 00000000..c1c9fbbb
--- /dev/null
+++ b/fox-gui/Makefile
@@ -0,0 +1,62 @@
+
+# Makefile
+#
+# Copyright (C) 2009 Francesco Abbate
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+GSH_BASE_DIR = ..
+
+include $(GSH_BASE_DIR)/makeconfig
+include $(GSH_BASE_DIR)/make-system-detect
+include $(GSH_BASE_DIR)/makepackages
+include $(GSH_BASE_DIR)/makedefs
+
+GSL_SHELL_GUI = gsl-shell-fox.exe
+
+LUADIR = $(GSH_BASE_DIR)/luajit2
+
+INCLUDES += $(AGG_INCLUDES) $(FOX_INCLUDES) -I$(GSH_BASE_DIR) -I$(GSH_BASE_DIR)/lua-gsl -I$(GSH_BASE_DIR)/agg-plot -I$(LUADIR)/src -I$(GSH_BASE_DIR)/cpp-utils
+LIBS += $(LUADIR)/src/libluajit.a $(GSH_BASE_DIR)/agg-plot/libaggplot.a $(GSH_BASE_DIR)/lua-gsl/libluagsl.a $(FOX_LIBS) $(PTHREADS_LIBS) -lsupc++
+
+INCLUDES += $(FREETYPE_INCLUDES) $(PTHREADS_CFLAGS)
+LIBS += $(AGG_LIBS) $(FREETYPE_LIBS) $(PTHREADS_LIBS) $(GSL_LIBS)
+
+FOXGUI_SRC_FILES = io_thread.cpp fx_console.cpp redirect.cpp gsl_shell_interp.cpp gsl_shell_thread.cpp fox_gsl_shell.cpp gsl_shell_window.cpp fx_plot_canvas.cpp fx_plot_window.cpp lua_plot_window.cpp gsl_shell_app.cpp gsl-shell-fox.cpp
+FOXGUI_OBJ_FILES := $(FOXGUI_SRC_FILES:%.cpp=%.o)
+
+DEP_FILES := $(FOXGUI_SRC_FILES:%.cpp=.deps/%.P)
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+CXXCOMPILE = $(CC) $(CXXFLAGS) $(DEFS) $(INCLUDES)
+
+TARGETS = $(GSL_SHELL_GUI)
+
+all: $(TARGETS)
+
+$(GSL_SHELL_GUI): $(FOXGUI_OBJ_FILES)
+ @echo Linking $@
+ @$(LINK_EXE) -o $@ $(FOXGUI_OBJ_FILES) $(LIBS)
+
+include $(GSH_BASE_DIR)/makerules
+
+.PHONY: clean all
+
+clean:
+ $(HOST_RM) *.o *.lo *.la *.so *.dll $(TARGETS)
+
+-include $(DEP_FILES)
diff --git a/fox-gui/fox_gsl_shell.cpp b/fox-gui/fox_gsl_shell.cpp
new file mode 100644
index 00000000..46a985df
--- /dev/null
+++ b/fox-gui/fox_gsl_shell.cpp
@@ -0,0 +1,36 @@
+
+#include "fox_gsl_shell.h"
+#include "lua_plot_window.h"
+#include "window_registry.h"
+
+void fox_gsl_shell::init()
+{
+ gsl_shell_thread::init();
+}
+
+void
+fox_gsl_shell::before_eval()
+{
+ unsigned n = m_window_close_queue.size();
+ for (unsigned k = 0; k < n; k++)
+ {
+ window_index_remove (L, m_window_close_queue[k]);
+ }
+ m_window_close_queue.clear();
+}
+
+void
+fox_gsl_shell::quit_callback()
+{
+ if (m_close)
+ m_close->signal();
+}
+
+void
+fox_gsl_shell::window_close_notify(int window_id)
+{
+ pthread::mutex& eval = eval_mutex();
+ eval.lock();
+ m_window_close_queue.add(window_id);
+ eval.unlock();
+}
diff --git a/fox-gui/fox_gsl_shell.h b/fox-gui/fox_gsl_shell.h
new file mode 100644
index 00000000..66379665
--- /dev/null
+++ b/fox-gui/fox_gsl_shell.h
@@ -0,0 +1,30 @@
+#ifndef FOX_GSL_SHELL_H
+#define FOX_GSL_SHELL_H
+
+#include <fx.h>
+#include "agg_array.h"
+
+#include "gsl_shell_thread.h"
+
+class fox_gsl_shell : public gsl_shell_thread
+{
+public:
+ fox_gsl_shell(FXApp* app): m_app(app), m_close(0) { }
+
+ ~fox_gsl_shell() { delete m_close; }
+
+ virtual void init();
+ virtual void before_eval();
+ virtual void quit_callback();
+
+ void set_closing_signal(FXGUISignal* s) { m_close = s; }
+
+ void window_close_notify(int window_id);
+
+private:
+ FXApp* m_app;
+ FXGUISignal* m_close;
+ agg::pod_bvector<int> m_window_close_queue;
+};
+
+#endif
diff --git a/fox-gui/fx_console.cpp b/fox-gui/fx_console.cpp
new file mode 100644
index 00000000..fe30fc75
--- /dev/null
+++ b/fox-gui/fx_console.cpp
@@ -0,0 +1,133 @@
+
+#include <fxkeys.h>
+
+#include "luajit.h"
+
+#include "fx_console.h"
+#include "gsl_shell_app.h"
+#include "gsl_shell_thread.h"
+#include "fx_plot_window.h"
+
+FXDEFMAP(fx_console) fx_console_map[]=
+{
+ FXMAPFUNC(SEL_KEYPRESS, 0, fx_console::on_key_press),
+ FXMAPFUNC(SEL_IO_READ, fx_console::ID_LUA_OUTPUT, fx_console::on_lua_output),
+};
+
+FXIMPLEMENT(fx_console,FXText,fx_console_map,ARRAYNUMBER(fx_console_map))
+
+char const * const fx_console::prompt = "> ";
+
+fx_console::fx_console(gsl_shell_thread* gs, FXComposite *p, FXObject* tgt, FXSelector sel, FXuint opts, FXint x, FXint y, FXint w, FXint h, FXint pl, FXint pr, FXint pt, FXint pb):
+ FXText(p, tgt, sel, opts, x, y, w, h, pl, pr, pt, pb),
+ m_status(not_ready), m_engine(gs)
+{
+ FXApp* app = getApp();
+ m_lua_io_signal = new FXGUISignal(app, this, ID_LUA_OUTPUT);
+ m_lua_io_thread = new lua_io_thread(m_engine, m_lua_io_signal, &m_lua_io_mutex, &m_lua_io_buffer);
+}
+
+fx_console::~fx_console()
+{
+ delete m_lua_io_thread;
+ delete m_lua_io_signal;
+}
+
+void fx_console::prepare_input()
+{
+ appendText(prompt, strlen(prompt));
+ m_status = input_mode;
+ m_input_begin = getCursorPos();
+}
+
+void fx_console::show_errors()
+{
+ if (m_engine->eval_status() == gsl_shell::eval_error)
+ {
+ appendText("Error reported: ");
+ appendText(m_engine->error_msg());
+ appendText("\n");
+ makePositionVisible(getCursorPos());
+ }
+}
+
+void fx_console::create()
+{
+ FXText::create();
+ FXString msg;
+ msg.format("GSL Shell %s, Copyright (C) 2009-2012 Francesco Abbate\n"
+ "GNU Scientific Library, Copyright (C) The GSL Team\n"
+ "%s -- %s\n",
+ GSL_SHELL_RELEASE, LUAJIT_VERSION, LUAJIT_COPYRIGHT);
+ init(msg);
+ setFocus();
+ m_lua_io_thread->start();
+}
+
+void fx_console::init(const FXString& greeting)
+{
+ appendText(greeting);
+ prepare_input();
+}
+
+long fx_console::on_key_press(FXObject* obj, FXSelector sel, void* ptr)
+{
+ FXEvent* event = (FXEvent*)ptr;
+ if (event->code == KEY_Return && m_status == input_mode)
+ {
+ FXint pos = getCursorPos();
+ FXint line_end = lineEnd(pos), line_start = m_input_begin;
+ extractText(m_input, line_start, line_end - line_start);
+ appendText("\n");
+
+ this->m_status = output_mode;
+ m_engine->input(m_input.text());
+
+ return 1;
+ }
+
+ return FXText::onKeyPress(obj, sel, ptr);
+}
+
+long fx_console::on_lua_output(FXObject* obj, FXSelector sel, void* ptr)
+{
+ bool eot = false;
+
+ m_lua_io_mutex.lock();
+ FXint len = m_lua_io_buffer.length();
+ if (len > 0)
+ {
+ if (m_lua_io_buffer[len-1] == gsl_shell_thread::eot_character)
+ {
+ eot = true;
+ m_lua_io_buffer.trunc(len-1);
+ }
+ }
+ appendText(m_lua_io_buffer);
+ makePositionVisible(getCursorPos());
+
+ m_lua_io_buffer.clear();
+ m_lua_io_mutex.unlock();
+
+ if (eot)
+ {
+ int status = m_engine->eval_status();
+
+ if (status == gsl_shell::incomplete_input)
+ {
+ m_status = input_mode;
+ }
+ else if (status == gsl_shell::exit_request)
+ {
+ FXApp* app = getApp();
+ app->handle(this, FXSEL(SEL_COMMAND,FXApp::ID_QUIT), NULL);
+ }
+ else
+ {
+ show_errors();
+ prepare_input();
+ }
+ }
+
+ return 1;
+}
diff --git a/fox-gui/fx_console.h b/fox-gui/fx_console.h
new file mode 100644
index 00000000..4c40cb22
--- /dev/null
+++ b/fox-gui/fx_console.h
@@ -0,0 +1,58 @@
+#ifndef FOXGUI_FX_CONSOLE_H
+#define FOXGUI_FX_CONSOLE_H
+
+#include <new>
+#include <fx.h>
+#include <FXArray.h>
+
+#include "gsl_shell_thread.h"
+#include "io_thread.h"
+
+class fx_console : public FXText
+{
+ FXDECLARE(fx_console)
+
+private:
+ enum status_e { not_ready, input_mode, output_mode };
+
+ static char const * const prompt;
+
+public:
+ fx_console(gsl_shell_thread* gs, FXComposite *p,FXObject* tgt=NULL,FXSelector sel=0,FXuint opts=0,FXint x=0,FXint y=0,FXint w=0,FXint h=0,FXint pl=3,FXint pr=3,FXint pt=2,FXint pb=2);
+
+ ~fx_console();
+
+ // prepare to accept input
+ void init(const FXString& greeting);
+ void prepare_input();
+ void show_errors();
+
+public:
+ virtual void create();
+
+ long on_key_press(FXObject*,FXSelector,void*);
+ long on_lua_output(FXObject*,FXSelector,void*);
+
+ enum
+ {
+ ID_READ_INPUT = FXText::ID_LAST,
+ ID_LUA_OUTPUT,
+ ID_LAST,
+ };
+
+protected:
+ fx_console() {}
+
+private:
+ FXint m_input_begin;
+ FXString m_input;
+ status_e m_status;
+ gsl_shell_thread* m_engine;
+
+ lua_io_thread* m_lua_io_thread;
+ FXGUISignal* m_lua_io_signal;
+ FXMutex m_lua_io_mutex;
+ FXString m_lua_io_buffer;
+};
+
+#endif
diff --git a/fox-gui/fx_plot_canvas.cpp b/fox-gui/fx_plot_canvas.cpp
new file mode 100644
index 00000000..f7ecf21e
--- /dev/null
+++ b/fox-gui/fx_plot_canvas.cpp
@@ -0,0 +1,178 @@
+#include "util/agg_color_conv_rgb8.h"
+
+#include "fx_plot_canvas.h"
+#include "rendering_buffer_utils.h"
+#include "fatal.h"
+#include "lua-graph.h"
+
+FXDEFMAP(fx_plot_canvas) fx_plot_canvas_map[]=
+{
+ FXMAPFUNC(SEL_PAINT, 0, fx_plot_canvas::on_cmd_paint),
+ FXMAPFUNC(SEL_UPDATE, 0, fx_plot_canvas::on_update),
+};
+
+FXIMPLEMENT(fx_plot_canvas,FXCanvas,fx_plot_canvas_map,ARRAYNUMBER(fx_plot_canvas_map));
+
+fx_plot_canvas::fx_plot_canvas(FXComposite* p, FXObject* tgt, FXSelector sel, FXuint opts, FXint x, FXint y, FXint w, FXint h):
+ FXCanvas(p, tgt, sel, opts, x, y, w, h),
+ m_plot(0), m_canvas(0), m_dirty_flag(true), m_dirty_img(true)
+{
+}
+
+fx_plot_canvas::~fx_plot_canvas()
+{
+ delete m_canvas;
+}
+
+void fx_plot_canvas::prepare_image_buffer(unsigned ww, unsigned hh)
+{
+ m_img.resize(ww, hh);
+ m_canvas = new canvas(m_img, ww, hh, colors::white);
+ m_dirty_img = true;
+}
+
+void fx_plot_canvas::ensure_canvas_size(unsigned ww, unsigned hh)
+{
+ if (m_img.width() != ww || m_img.height() != hh)
+ {
+ m_area_mtx.sx = ww;
+ m_area_mtx.sy = hh;
+ prepare_image_buffer(ww, hh);
+ }
+}
+
+void fx_plot_canvas::plot_render(agg::trans_affine& m)
+{
+ m_canvas->clear(colors::white);
+ AGG_LOCK();
+ m_plot->draw(*m_canvas, m);
+ AGG_UNLOCK();
+ m_dirty_img = false;
+}
+
+void fx_plot_canvas::plot_draw(agg::trans_affine& m)
+{
+ FXDCWindow dc(this);
+ int ww = getWidth(), hh = getHeight();
+
+ ensure_canvas_size(ww, hh);
+
+ if (m_canvas && m_plot)
+ {
+ if (m_dirty_img)
+ plot_render(m);
+
+ FXImage img(getApp(), NULL, IMAGE_OWNED|IMAGE_SHMI|IMAGE_SHMP, ww, hh);
+ agg::int8u* data = (agg::int8u*) img.getData();
+ agg::rendering_buffer rbuf_tmp(data, ww, hh, - ww * 4);
+ my_color_conv(&rbuf_tmp, &m_img, color_conv_rgb24_to_rgba32());
+ img.create();
+
+ dc.drawImage(&img, 0, 0);
+ }
+ else
+ {
+ dc.setForeground(FXRGB(255,255,255));
+ dc.fillRectangle(0, 0, ww, hh);
+ }
+
+ m_dirty_flag = false;
+}
+
+void fx_plot_canvas::update_region(const agg::rect_base<int>& _r)
+{
+ int iw = m_img.width(), ih = m_img.height();
+ const agg::rect_base<int> b(0, 0, iw, ih);
+ agg::rect_base<int> r = agg::intersect_rectangles(_r, b);
+
+ FXshort ww = r.x2 - r.x1, hh= r.y2 - r.y1;
+ FXImage img(getApp(), NULL, IMAGE_OWNED|IMAGE_SHMI|IMAGE_SHMP, ww, hh);
+
+ const unsigned bpp = 32;
+ const unsigned pixel_size = bpp / 8;
+
+ agg::rendering_buffer dest;
+ dest.attach((agg::int8u*) img.getData(), ww, hh, -ww * pixel_size);
+
+ rendering_buffer_ro src;
+ rendering_buffer_get_const_view(src, m_img, r, gslshell::bpp / 8, true);
+
+ my_color_conv(&dest, &src, color_conv_rgb24_to_rgba32());
+
+ img.create();
+
+ FXDCWindow dc(this);
+ dc.drawImage(&img, r.x1, getHeight() - r.y2);
+}
+
+opt_rect<double> fx_plot_canvas::plot_render_queue(agg::trans_affine& m)
+{
+ opt_rect<double> r, draw_rect;
+ AGG_LOCK();
+ m_plot->draw_queue(*m_canvas, m, draw_rect);
+ AGG_UNLOCK();
+ r.add<rect_union>(draw_rect);
+ r.add<rect_union>(m_dirty_rect);
+ m_dirty_rect = draw_rect;
+ return r;
+}
+
+void fx_plot_canvas::plot_draw_queue(agg::trans_affine& m, bool draw_all)
+{
+ if (!m_canvas || !m_plot) return;
+
+ opt_rect<double> rect = plot_render_queue(m);
+
+ if (draw_all)
+ {
+ const agg::rect_base<int> ri(0, 0, getWidth(), getHeight());
+ update_region(ri);
+ }
+ else if (rect.is_defined())
+ {
+ const int pd = 4;
+ const agg::rect_base<double>& r = rect.rect();
+ const agg::rect_base<int> ri(r.x1 - pd, r.y1 - pd, r.x2 + pd, r.y2 + pd);
+ update_region(ri);
+ }
+}
+
+bool fx_plot_canvas::save_image()
+{
+ int ww = getWidth(), hh = getHeight();
+ if (!m_img.defined() || !m_save_img.resize(ww, hh)) return false;
+ if (m_dirty_img)
+ plot_render(m_area_mtx);
+ m_save_img.copy_from(m_img);
+ return true;
+}
+
+bool fx_plot_canvas::restore_image()
+{
+ if (!image::match(m_img, m_save_img))
+ return false;
+ m_img.copy_from(m_save_img);
+ return true;
+}
+
+void fx_plot_canvas::attach(plot_type* p)
+{
+ m_plot = p;
+ m_dirty_flag = true;
+ m_dirty_img = true;
+}
+
+long fx_plot_canvas::on_cmd_paint(FXObject *, FXSelector, void *ptr)
+{
+ FXEvent* ev = (FXEvent*) ptr;
+ plot_draw(m_area_mtx);
+ return 1;
+}
+
+long fx_plot_canvas::on_update(FXObject *, FXSelector, void *)
+{
+ bool need_upd = m_dirty_flag;
+ if (need_upd)
+ plot_draw(m_area_mtx);
+ return (need_upd ? 1 : 0);
+}
diff --git a/fox-gui/fx_plot_canvas.h b/fox-gui/fx_plot_canvas.h
new file mode 100644
index 00000000..5a0d3524
--- /dev/null
+++ b/fox-gui/fx_plot_canvas.h
@@ -0,0 +1,73 @@
+#ifndef FOXGUI_FX_PLOT_CANVAS_H
+#define FOXGUI_FX_PLOT_CANVAS_H
+
+#include <new>
+#include <fx.h>
+#include <agg_rendering_buffer.h>
+
+#include "image_buf.h"
+#include "sg_object.h"
+#include "plot-auto.h"
+#include "canvas.h"
+#include "rect.h"
+
+class fx_plot_canvas : public FXCanvas
+{
+ FXDECLARE(fx_plot_canvas)
+
+ typedef image_gen<3, true> image;
+
+public:
+ typedef plot<manage_owner> plot_type;
+
+ fx_plot_canvas(FXComposite* p, FXObject* tgt=NULL, FXSelector sel=0,
+ FXuint opts=FRAME_NORMAL,
+ FXint x=0, FXint y=0, FXint w=0, FXint h=0);
+
+ ~fx_plot_canvas();
+
+ void attach(plot_type* p);
+ void update_region(const agg::rect_base<int>& r);
+
+ plot_type* get_plot()
+ {
+ return m_plot;
+ }
+
+ void plot_render(agg::trans_affine& m);
+ void plot_draw(agg::trans_affine& m);
+ opt_rect<double> plot_render_queue(agg::trans_affine& m);
+ void plot_draw_queue(agg::trans_affine& m, bool draw_all);
+
+ agg::trans_affine& plot_matrix()
+ {
+ return m_area_mtx;
+ }
+ bool is_ready() const
+ {
+ return m_canvas && m_plot;
+ }
+
+ bool save_image();
+ bool restore_image();
+
+ long on_cmd_paint(FXObject *, FXSelector, void *);
+ long on_update(FXObject *, FXSelector, void *);
+
+protected:
+ fx_plot_canvas() {}
+
+private:
+ void prepare_image_buffer(unsigned ww, unsigned hh);
+ void ensure_canvas_size(unsigned ww, unsigned hh);
+
+ image m_img;
+ image m_save_img;
+ plot_type* m_plot;
+ canvas* m_canvas;
+ bool m_dirty_flag, m_dirty_img;
+ opt_rect<double> m_dirty_rect;
+ agg::trans_affine m_area_mtx;
+};
+
+#endif
diff --git a/fox-gui/fx_plot_window.cpp b/fox-gui/fx_plot_window.cpp
new file mode 100644
index 00000000..b75e42d4
--- /dev/null
+++ b/fox-gui/fx_plot_window.cpp
@@ -0,0 +1,31 @@
+
+#include "fx_plot_window.h"
+
+FXDEFMAP(fx_plot_window) fx_plot_window_map[]=
+{
+};
+
+FXIMPLEMENT(fx_plot_window,FXMainWindow,fx_plot_window_map,ARRAYNUMBER(fx_plot_window_map))
+
+fx_plot_window::fx_plot_window(FXApp* app, const FXString& name, FXIcon *ic, FXIcon *mi, FXint w, FXint h):
+ FXMainWindow(app, name, ic, mi, DECOR_ALL, 0, 0, w, h)
+{
+ m_menu_bar = new FXMenuBar(this, LAYOUT_SIDE_TOP|LAYOUT_FILL_X);
+
+ m_plot_menu = new FXMenuPane(this);
+ new FXMenuCommand(m_plot_menu, "&Close\tCtl-C", NULL, app, FXApp::ID_QUIT);
+ new FXMenuTitle(m_menu_bar, "&Plot", NULL, m_plot_menu);
+
+ FXVerticalFrame* frame = new FXVerticalFrame(this, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);
+
+ // Sunken border for text widget
+ FXHorizontalFrame *cbox = new FXHorizontalFrame(frame, FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0);
+
+ m_canvas = new fx_plot_canvas(cbox, NULL, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y);
+}
+
+fx_plot_window::~fx_plot_window()
+{
+ delete m_canvas;
+ delete m_plot_menu;
+}
diff --git a/fox-gui/fx_plot_window.h b/fox-gui/fx_plot_window.h
new file mode 100644
index 00000000..a016b248
--- /dev/null
+++ b/fox-gui/fx_plot_window.h
@@ -0,0 +1,37 @@
+#ifndef FOXGUI_FX_PLOT_WINDOW_H
+#define FOXGUI_FX_PLOT_WINDOW_H
+
+#include <fx.h>
+
+#include "gsl_shell_app.h"
+#include "fx_plot_canvas.h"
+
+class fx_plot_window : public FXMainWindow
+{
+ FXDECLARE(fx_plot_window)
+public:
+ fx_plot_window(FXApp* a, const FXString& name, FXIcon *ic=NULL, FXIcon *mi=NULL, FXint w=0, FXint h=0);
+
+ ~fx_plot_window();
+
+ fx_plot_canvas* canvas()
+ {
+ return m_canvas;
+ }
+ gsl_shell_app* get_app()
+ {
+ return (gsl_shell_app*) getApp();
+ }
+
+ int lua_id; // the following is used by Lua to keep trace of the window
+
+protected:
+ fx_plot_window() {}
+
+private:
+ FXMenuBar* m_menu_bar;
+ FXMenuPane* m_plot_menu;
+ fx_plot_canvas* m_canvas;
+};
+
+#endif
diff --git a/fox-gui/gsl-shell-fox.cpp b/fox-gui/gsl-shell-fox.cpp
new file mode 100644
index 00000000..1064819c
--- /dev/null
+++ b/fox-gui/gsl-shell-fox.cpp
@@ -0,0 +1,22 @@
+#include <fx.h>
+#include "gsl_shell_window.h"
+#include "gsl_shell_app.h"
+#include "window_hooks.h"
+#include "lua_plot_window.h"
+
+struct window_hooks app_window_hooks[1] = {{
+ fox_window_new, fox_window_attach,
+ fox_window_slot_update, fox_window_slot_refresh,
+ fox_window_save_slot_image, fox_window_restore_slot_image,
+ fox_window_register,
+ }
+};
+
+int
+main (int argc, char *argv[])
+{
+ gsl_shell_app app;
+ app.init(argc, argv);
+ app.create();
+ return app.run();
+}
diff --git a/fox-gui/gsl_shell_app.cpp b/fox-gui/gsl_shell_app.cpp
new file mode 100644
index 00000000..b32d2878
--- /dev/null
+++ b/fox-gui/gsl_shell_app.cpp
@@ -0,0 +1,84 @@
+
+#include <unistd.h>
+
+#include "gsl_shell_app.h"
+#include "gsl_shell_window.h"
+#include "fx_plot_window.h"
+#include "lua_plot_window.h"
+#include "fatal.h"
+
+FXDEFMAP(gsl_shell_app) gsl_shell_app_map[]=
+{
+ FXMAPFUNC(SEL_IO_READ, gsl_shell_app::ID_LUA_REQUEST, gsl_shell_app::on_lua_request),
+ FXMAPFUNC(SEL_IO_READ, gsl_shell_app::ID_LUA_QUIT, gsl_shell_app::on_lua_quit),
+ FXMAPFUNC(SEL_COMMAND, gsl_shell_app::ID_CONSOLE_CLOSE, gsl_shell_app::on_console_close),
+ FXMAPFUNC(SEL_CLOSE, 0, gsl_shell_app::on_window_close),
+};
+
+FXIMPLEMENT(gsl_shell_app,FXApp,gsl_shell_app_map,ARRAYNUMBER(gsl_shell_app_map))
+
+gsl_shell_app* global_app;
+
+gsl_shell_app::gsl_shell_app() : FXApp("GSL Shell", "GSL Shell"),
+ m_engine(this)
+{
+ m_lua_request = new FXGUISignal(this, this, ID_LUA_REQUEST);
+
+ FXGUISignal* quit = new FXGUISignal(this, this, ID_LUA_QUIT);
+ m_engine.set_closing_signal(quit);
+
+ global_app = this;
+ m_engine.start();
+
+ new gsl_shell_window(&m_engine, this, "GSL Shell Console", NULL, NULL, 600, 500);
+}
+
+gsl_shell_app::~gsl_shell_app()
+{
+ delete m_lua_request;
+}
+
+long gsl_shell_app::on_lua_request(FXObject*, FXSelector, void*)
+{
+ for (unsigned k = 0; k < m_win_queue.size(); k++)
+ {
+ FXMainWindow* win = m_win_queue[k];
+ win->create();
+ win->show(PLACEMENT_SCREEN);
+ }
+ m_win_queue.clear();
+ m_window_mapping.signal();
+ return 1;
+}
+
+long gsl_shell_app::on_lua_quit(FXObject*, FXSelector, void*)
+{
+ m_engine.close();
+ exit(0);
+ return 1;
+}
+
+void gsl_shell_app::window_create_request(FXMainWindow* win)
+{
+ m_win_queue.add(win);
+ m_lua_request->signal();
+}
+
+long gsl_shell_app::on_console_close(FXObject* sender, FXSelector, void*)
+{
+ m_engine.stop();
+ return 1;
+}
+
+long gsl_shell_app::on_window_close(FXObject* sender, FXSelector, void*)
+{
+ fx_plot_window* win = (fx_plot_window*) sender;
+ m_engine.window_close_notify(win->lua_id);
+ return 0;
+}
+
+void gsl_shell_app::wait_window_mapping()
+{
+ FXMutex& app_mutex = mutex();
+ m_window_mapping.wait(app_mutex);
+}
diff --git a/fox-gui/gsl_shell_app.h b/fox-gui/gsl_shell_app.h
new file mode 100644
index 00000000..f33e9a77
--- /dev/null
+++ b/fox-gui/gsl_shell_app.h
@@ -0,0 +1,50 @@
+#ifndef FOXGUI_GSL_SHELL_APP_H
+#define FOXGUI_GSL_SHELL_APP_H
+
+#include <fx.h>
+
+#include "agg_array.h"
+#include "fox_gsl_shell.h"
+
+class gsl_shell_app : public FXApp
+{
+ FXDECLARE(gsl_shell_app)
+public:
+ gsl_shell_app();
+ ~gsl_shell_app();
+
+ void lock()
+ {
+ mutex().lock();
+ }
+ void unlock()
+ {
+ mutex().unlock();
+ }
+
+ void window_create_request(FXMainWindow* win);
+ void wait_window_mapping();
+
+ long on_lua_request(FXObject*,FXSelector,void*);
+ long on_window_close(FXObject*,FXSelector,void*);
+ long on_console_close(FXObject*,FXSelector,void*);
+ long on_lua_quit(FXObject*,FXSelector,void*);
+
+ enum
+ {
+ ID_LUA_REQUEST = FXApp::ID_LAST,
+ ID_CONSOLE_CLOSE,
+ ID_LUA_QUIT,
+ ID_LAST
+ };
+
+private:
+ fox_gsl_shell m_engine;
+ FXGUISignal* m_lua_request;
+ agg::pod_bvector<FXMainWindow*> m_win_queue;
+ FXCondition m_window_mapping;
+};
+
+extern gsl_shell_app* global_app;
+
+#endif
diff --git a/fox-gui/gsl_shell_interp.cpp b/fox-gui/gsl_shell_interp.cpp
new file mode 100644
index 00000000..6cd077e5
--- /dev/null
+++ b/fox-gui/gsl_shell_interp.cpp
@@ -0,0 +1,202 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define luajit_c
+
+extern "C" {
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+#include "luajit.h"
+}
+
+#include "gsl_shell_interp.h"
+#include "lua-gsl.h"
+#include "lua-graph.h"
+#include "fatal.h"
+
+static void stderr_message(const char *pname, const char *msg)
+{
+ if (pname) fprintf(stderr, "%s: ", pname);
+ fprintf(stderr, "%s\n", msg);
+ fflush(stderr);
+}
+
+static int stderr_report(lua_State *L, int status)
+{
+ if (status && !lua_isnil(L, -1))
+ {
+ const char *msg = lua_tostring(L, -1);
+ if (msg == NULL) msg = "(error object is not a string)";
+ stderr_message("gsl-shell", msg);
+ lua_pop(L, 1);
+ }
+ return status;
+}
+
+static int traceback(lua_State *L)
+{
+ if (!lua_isstring(L, 1)) /* 'message' not a string? */
+ return 1; /* keep it intact */
+ lua_getfield(L, LUA_GLOBALSINDEX, "debug");
+ if (!lua_istable(L, -1))
+ {
+ lua_pop(L, 1);
+ return 1;
+ }
+ lua_getfield(L, -1, "traceback");
+ if (!lua_isfunction(L, -1))
+ {
+ lua_pop(L, 2);
+ return 1;
+ }
+ lua_pushvalue(L, 1); /* pass error message */
+ lua_pushinteger(L, 2); /* skip this function and traceback */
+ lua_call(L, 2, 1); /* call debug.traceback */
+ return 1;
+}
+
+static int docall(lua_State *L, int narg, int clear)
+{
+ int status;
+ int base = lua_gettop(L) - narg; /* function index */
+ lua_pushcfunction(L, traceback); /* push traceback function */
+ lua_insert(L, base); /* put it under chunk and args */
+ status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
+ lua_remove(L, base); /* remove traceback function */
+ /* force a complete garbage collection in case of errors */
+ if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
+ return status;
+}
+
+static int dolibrary(lua_State *L, const char *name)
+{
+ lua_getglobal(L, "require");
+ lua_pushstring(L, name);
+ return stderr_report(L, docall(L, 1, 1));
+}
+
+static int pinit(lua_State *L)
+{
+ LUAJIT_VERSION_SYM(); /* linker-enforced version check */
+ lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */
+ luaL_openlibs(L); /* open libraries */
+ luaopen_gsl (L);
+ register_graph (L);
+ lua_gc(L, LUA_GCRESTART, -1);
+ dolibrary (L, "gslext");
+ return 0;
+}
+
+/* If the input is an expression we load it preceded by "return" so
+ that the value is returned as a result of the evaluation.
+ If the value is not an expression leave the stack as before and
+ returns a non zero value. */
+static int yield_expr(lua_State* L, const char* line, size_t len)
+{
+ const char *p;
+ int status;
+
+ for (p = line + len - 1; p >= line; p--)
+ {
+ const char c = *p;
+ if (c == ';')
+ return 1;
+ if (c != ' ')
+ break;
+ }
+
+ str mline = str::print("return %s", line);
+ status = luaL_loadbuffer(L, mline.cstr(), len+7, "=stdin");
+ if (status != 0) lua_pop(L, 1); // remove the error message
+ return status;
+}
+
+static int incomplete(lua_State *L, int status)
+{
+ if (status == LUA_ERRSYNTAX)
+ {
+ size_t lmsg;
+ const char *msg = lua_tolstring(L, -1, &lmsg);
+ const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
+ if (strstr(msg, LUA_QL("<eof>")) == tp)
+ {
+ lua_pop(L, 1);
+ return 1;
+ }
+ }
+ return 0; /* else... */
+}
+
+void gsl_shell::init()
+{
+ gsl_shell_open(this);
+
+ int status = lua_cpcall(this->L, pinit, NULL);
+
+ if (unlikely(stderr_report(this->L, status)))
+ {
+ lua_close(this->L);
+ fatal_exception("cannot initialize Lua state");
+ }
+}
+
+void gsl_shell::close()
+{
+ lua_close(this->L);
+ this->L = NULL;
+}
+
+int gsl_shell::error_report(int status)
+{
+ lua_State* L = this->L;
+ if (status && !lua_isnil(L, -1))
+ {
+ const char *msg = lua_tostring(L, -1);
+ if (msg == NULL) msg = "(error object is not a string)";
+ m_error_msg = msg;
+ lua_pop(L, 1);
+ }
+ return status;
+}
+
+int gsl_shell::exec(const char *line)
+{
+ lua_State* L = this->L;
+ size_t len = strlen(line);
+
+ if (strcmp (line, "exit") == 0)
+ return exit_request;
+
+ /* try to load the string as an expression */
+ int status = yield_expr(L, line, len);
+
+ if (status != 0)
+ {
+ status = luaL_loadbuffer(L, line, len, "=<user input>");
+
+ if (incomplete(L, status))
+ return incomplete_input;
+ }
+
+ if (status == 0)
+ {
+ status = docall(L, 0, 0);
+ error_report(status);
+ if (status == 0 && lua_gettop(L) > 0) /* any result to print? */
+ {
+ lua_pushvalue(L, -1);
+ lua_setfield(L, LUA_GLOBALSINDEX, "_");
+
+ lua_getglobal(L, "print");
+ lua_insert(L, 1);
+ if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
+ fprintf(stderr, "error calling print function");
+ }
+ }
+
+ error_report(status);
+
+ return (status == 0 ? eval_success : eval_error);
+}
diff --git a/fox-gui/gsl_shell_interp.h b/fox-gui/gsl_shell_interp.h
new file mode 100644
index 00000000..c61a5373
--- /dev/null
+++ b/fox-gui/gsl_shell_interp.h
@@ -0,0 +1,46 @@
+#ifndef GSL_SHELL_INTERP_H
+#define GSL_SHELL_INTERP_H
+
+extern "C" {
+#include <lua.h>
+}
+
+#include "defs.h"
+#include "pthreadpp.h"
+#include "lua-gsl.h"
+#include "strpp.h"
+#include "fatal.h"
+
+class gsl_shell : public gsl_shell_state
+{
+public:
+ enum eval_result_e { eval_success, eval_error, incomplete_input, exit_request };
+
+ gsl_shell()
+ {
+ gsl_shell_init(this);
+ }
+
+ virtual ~gsl_shell()
+ {
+ if (unlikely(this->L != NULL))
+ fatal_exception("warning: attempt to dispose an open Lua state");
+ gsl_shell_free(this);
+ }
+
+ virtual void init();
+ virtual void close();
+
+ int exec(const char* line);
+ const char* error_msg() const
+ {
+ return m_error_msg.cstr();
+ }
+
+private:
+ int error_report(int status);
+
+ str m_error_msg;
+};
+
+#endif
diff --git a/fox-gui/gsl_shell_thread.cpp b/fox-gui/gsl_shell_thread.cpp
new file mode 100644
index 00000000..1d2a452d
--- /dev/null
+++ b/fox-gui/gsl_shell_thread.cpp
@@ -0,0 +1,106 @@
+#include <pthread.h>
+#include <stdio.h>
+
+#include "gsl_shell_thread.h"
+
+extern "C" void * luajit_eval_thread (void *userdata);
+
+void *
+luajit_eval_thread (void *userdata)
+{
+ gsl_shell_thread* eng = (gsl_shell_thread*) userdata;
+ eng->lock();
+ eng->init();
+ eng->run();
+ pthread_exit(NULL);
+ return NULL;
+}
+
+gsl_shell_thread::gsl_shell_thread():
+ m_status(starting), m_redirect(4096), m_exit_request(false)
+{
+}
+
+gsl_shell_thread::~gsl_shell_thread()
+{
+ m_redirect.stop();
+}
+
+void gsl_shell_thread::start()
+{
+ m_redirect.start();
+
+ pthread_attr_t attr[1];
+
+ pthread_attr_init (attr);
+ pthread_attr_setdetachstate (attr, PTHREAD_CREATE_DETACHED);
+
+ if (pthread_create (&m_thread, attr, luajit_eval_thread, (void*)this))
+ {
+ fprintf(stderr, "error creating thread");
+ }
+}
+
+void
+gsl_shell_thread::run()
+{
+ while (!m_exit_request)
+ {
+ m_eval.lock();
+ m_status = ready;
+
+ this->unlock();
+ m_eval.wait();
+ this->lock();
+
+ before_eval();
+
+ if (m_exit_request)
+ {
+ m_eval.unlock();
+ break;
+ }
+
+ m_status = busy;
+ m_eval.unlock();
+
+ // here m_line_pending cannot be modified by the other thread
+ // because we declared above m_status to "busy" befor unlocking m_eval
+ const char* line = m_line_pending.cstr();
+ m_eval_status = this->exec(line);
+
+ fputc(eot_character, stdout);
+ fflush(stdout);
+ }
+
+ this->unlock();
+ quit_callback();
+}
+
+void
+gsl_shell_thread::stop()
+{
+ m_eval.lock();
+ m_exit_request = true;
+ m_eval.signal();
+ m_eval.unlock();
+ sched_yield();
+}
+
+void
+gsl_shell_thread::input(const char* line)
+{
+ pthread::auto_lock lock(m_eval);
+
+ if (m_status == ready)
+ {
+ m_line_pending = line;
+ m_eval.signal();
+ }
+}
+
+int
+gsl_shell_thread::read(char* buffer, unsigned buffer_size)
+{
+ return m_redirect.read(buffer, buffer_size);
+}
diff --git a/fox-gui/gsl_shell_thread.h b/fox-gui/gsl_shell_thread.h
new file mode 100644
index 00000000..06678183
--- /dev/null
+++ b/fox-gui/gsl_shell_thread.h
@@ -0,0 +1,60 @@
+#ifndef FOXGUI_LUA_ENGINE_H
+#define FOXGUI_LUA_ENGINE_H
+
+extern "C" {
+#include "lua.h"
+}
+
+#include "gsl_shell_interp.h"
+#include "pthreadpp.h"
+#include "redirect.h"
+#include "str.h"
+
+class gsl_shell_thread : public gsl_shell
+{
+public:
+ enum engine_status_e { starting, ready, busy, terminated };
+ enum { eot_character = 0x04 };
+
+ gsl_shell_thread();
+ ~gsl_shell_thread();
+
+ void input(const char* line);
+ void start();
+ void run();
+ void stop();
+
+ virtual void before_eval() { }
+ virtual void quit_callback() { }
+
+ void lock()
+ {
+ pthread_mutex_lock(&this->exec_mutex);
+ }
+ void unlock()
+ {
+ pthread_mutex_unlock(&this->exec_mutex);
+ }
+
+ int read(char* buffer, unsigned buffer_size);
+
+ int eval_status() const
+ {
+ return m_eval_status;
+ }
+ pthread::mutex& eval_mutex()
+ {
+ return m_eval;
+ }
+
+private:
+ pthread_t m_thread;
+ engine_status_e m_status;
+ stdout_redirect m_redirect;
+ pthread::cond m_eval;
+ str m_line_pending;
+ int m_eval_status;
+ bool m_exit_request;
+};
+
+#endif
diff --git a/fox-gui/gsl_shell_window.cpp b/fox-gui/gsl_shell_window.cpp
new file mode 100644
index 00000000..49e69db1
--- /dev/null
+++ b/fox-gui/gsl_shell_window.cpp
@@ -0,0 +1,49 @@
+#include "gsl_shell_window.h"
+#include "gsl_shell_app.h"
+
+#ifdef WIN32
+#define CONSOLE_FONT "lucida console"
+#else
+#define CONSOLE_FONT "monospace"
+#endif
+
+FXDEFMAP(gsl_shell_window) gsl_shell_window_map[]=
+{
+ FXMAPFUNC(SEL_CLOSE, 0, gsl_shell_window::on_close),
+ FXMAPFUNC(SEL_COMMAND, FXTopWindow::ID_CLOSE, gsl_shell_window::on_close),
+};
+
+FXIMPLEMENT(gsl_shell_window,FXMainWindow,gsl_shell_window_map,ARRAYNUMBER(gsl_shell_window_map))
+
+gsl_shell_window::gsl_shell_window(gsl_shell_thread* gs, FXApp* app, const FXString& name, FXIcon *ic, FXIcon *mi, FXint w, FXint h):
+ FXMainWindow(app, name, ic, mi, DECOR_ALL, 0, 0, w, h)
+{
+ m_menu_bar = new FXMenuBar(this, LAYOUT_SIDE_TOP|LAYOUT_FILL_X);
+ m_status_bar = new FXStatusBar(this, LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|FRAME_RAISED|STATUSBAR_WITH_DRAGCORNER);
+
+ m_file_menu = new FXMenuPane(this);
+ new FXMenuCommand(m_file_menu, "&Quit\tCtl-Q", NULL, this, FXTopWindow::ID_CLOSE);
+ new FXMenuTitle(m_menu_bar, "&File", NULL, m_file_menu);
+
+ FXVerticalFrame* frame = new FXVerticalFrame(this, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y);
+
+ // Sunken border for text widget
+ FXHorizontalFrame *textbox = new FXHorizontalFrame(frame, FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y,0,0,0,0, 0,0,0,0);
+
+ m_text_font = new FXFont(app, CONSOLE_FONT, 10);
+ m_text = new fx_console(gs, textbox, NULL, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y);
+ m_text->setFont(m_text_font);
+}
+
+void gsl_shell_window::create()
+{
+ FXMainWindow::create();
+ show(PLACEMENT_SCREEN);
+}
+
+long gsl_shell_window::on_close(FXObject* obj, FXSelector sel, void* ptr)
+{
+ FXApp* app = getApp();
+ app->handle(this, FXSEL(SEL_COMMAND, gsl_shell_app::ID_CONSOLE_CLOSE), NULL);
+ return 0;
+}
diff --git a/fox-gui/gsl_shell_window.h b/fox-gui/gsl_shell_window.h
new file mode 100644
index 00000000..c9d5c1e3
--- /dev/null
+++ b/fox-gui/gsl_shell_window.h
@@ -0,0 +1,36 @@
+#ifndef FOXGUI_GSL_SHELL_WINDOW_H
+#define FOXGUI_GSL_SHELL_WINDOW_H
+
+#include <fx.h>
+
+#include "gsl_shell_thread.h"
+#include "fx_console.h"
+
+class gsl_shell_window : public FXMainWindow
+{
+ FXDECLARE(gsl_shell_window)
+public:
+ gsl_shell_window(gsl_shell_thread* gs, FXApp* a, const FXString& name, FXIcon *ic=NULL, FXIcon *mi=NULL, FXint w=0, FXint h=0);
+
+ virtual ~gsl_shell_window()
+ {
+ delete m_file_menu;
+ delete m_text_font;
+ }
+
+ virtual void create();
+
+ long on_close(FXObject* obj, FXSelector sel, void* ptr);
+
+protected:
+ gsl_shell_window() {}
+
+private:
+ fx_console* m_text;
+ FXStatusBar* m_status_bar;
+ FXMenuBar* m_menu_bar;
+ FXMenuPane* m_file_menu;
+ FXFont* m_text_font;
+};
+
+#endif
diff --git a/fox-gui/image_buf.h b/fox-gui/image_buf.h
new file mode 100644
index 00000000..ecca662d
--- /dev/null
+++ b/fox-gui/image_buf.h
@@ -0,0 +1,60 @@
+#ifndef FOXGUI_IMAGE_BUF_H
+#define FOXGUI_IMAGE_BUF_H
+
+#include <agg_rendering_buffer.h>
+
+template <unsigned PixelSize, bool FlipY>
+struct image_gen : agg::rendering_buffer
+{
+ image_gen() { }
+ image_gen(unsigned w, unsigned h)
+ {
+ init(w, h);
+ }
+
+ ~image_gen()
+ {
+ dispose();
+ }
+
+ bool defined() const
+ {
+ return (buf() != 0);
+ }
+
+ bool resize(unsigned w, unsigned h)
+ {
+ dispose();
+ return init(w, h);
+ }
+
+ void clear()
+ {
+ dispose();
+ attach(NULL, 0, 0, 0);
+ }
+
+ static bool match(const image_gen& a, const image_gen& b)
+ {
+ if (!a.defined() || !b.defined())
+ return false;
+ return (a.width() == b.width() && a.height() == b.height());
+ }
+
+private:
+ bool init(unsigned w, unsigned h)
+ {
+ agg::int8u* data = new(std::nothrow) agg::int8u[w * h * PixelSize];
+ int stride = (FlipY ? - w * PixelSize : w * PixelSize);
+ attach(data, w, h, stride);
+ return (data != 0);
+ }
+
+ void dispose()
+ {
+ agg::int8u* data = buf();
+ delete[] data;
+ }
+};
+
+#endif
diff --git a/fox-gui/io_thread.cpp b/fox-gui/io_thread.cpp
new file mode 100644
index 00000000..f9b4062f
--- /dev/null
+++ b/fox-gui/io_thread.cpp
@@ -0,0 +1,49 @@
+#include <pthread.h>
+#include <errno.h>
+
+#include "io_thread.h"
+
+static void* io_thread_run(void* data)
+{
+ lua_io_thread* thread = (lua_io_thread*) data;
+ thread->run();
+ return 0;
+}
+
+void lua_io_thread::run()
+{
+ char buffer[128];
+
+ while (1)
+ {
+ int nr = m_engine->read(buffer, 127);
+ if (nr < 0)
+ {
+ fprintf(stderr, "ERROR on read: %d.\n", errno);
+ break;
+ }
+ if (nr == 0)
+ break;
+
+ buffer[nr] = 0;
+
+ m_io_protect->lock();
+ m_io_buffer->append((const FXchar*)buffer);
+ m_io_protect->unlock();
+
+ m_io_ready->signal();
+ }
+}
+
+void lua_io_thread::start()
+{
+ pthread_attr_t attr[1];
+
+ pthread_attr_init (attr);
+ pthread_attr_setdetachstate (attr, PTHREAD_CREATE_DETACHED);
+
+ if (pthread_create (&m_thread, attr, io_thread_run, (void*)this))
+ {
+ fprintf(stderr, "error creating thread");
+ }
+}
diff --git a/fox-gui/io_thread.h b/fox-gui/io_thread.h
new file mode 100644
index 00000000..682999f7
--- /dev/null
+++ b/fox-gui/io_thread.h
@@ -0,0 +1,25 @@
+#ifndef FOXGUI_IO_THREAD_H
+#define FOXGUI_IO_THREAD_H
+
+#include <fx.h>
+
+#include "gsl_shell_thread.h"
+
+class lua_io_thread {
+public:
+ lua_io_thread(gsl_shell_thread* eng, FXGUISignal* sig, FXMutex* mut, FXString* buf):
+ m_engine(eng), m_io_ready(sig), m_io_protect(mut), m_io_buffer(buf)
+ { }
+
+ void run();
+ void start();
+
+private:
+ pthread_t m_thread;
+ gsl_shell_thread* m_engine;
+ FXGUISignal* m_io_ready;
+ FXMutex* m_io_protect;
+ FXString* m_io_buffer;
+};
+
+#endif
diff --git a/fox-gui/lua_plot_window.cpp b/fox-gui/lua_plot_window.cpp
new file mode 100644
index 00000000..9a3d3230
--- /dev/null
+++ b/fox-gui/lua_plot_window.cpp
@@ -0,0 +1,169 @@
+
+extern "C" {
+#include "lua.h"
+#include "lauxlib.h"
+}
+
+#include "lua_plot_window.h"
+#include "gsl_shell_app.h"
+#include "window_registry.h"
+#include "fx_plot_window.h"
+#include "lua-cpp-utils.h"
+#include "lua-graph.h"
+#include "gs-types.h"
+#include "plot.h"
+
+__BEGIN_DECLS
+
+static int fox_window_close (lua_State *L);
+
+static const struct luaL_Reg fox_window_functions[] =
+{
+ {"window", fox_window_new},
+ {NULL, NULL}
+};
+
+static const struct luaL_Reg fox_window_methods[] =
+{
+ {"attach", fox_window_attach },
+ {"close", fox_window_close },
+ {"refresh", fox_window_slot_refresh },
+ {"update", fox_window_slot_update },
+ {NULL, NULL}
+};
+
+
+struct lua_fox_window
+{
+ fx_plot_window* window;
+};
+
+__END_DECLS
+
+typedef plot<manage_owner> sg_plot;
+
+int
+fox_window_new (lua_State *L)
+{
+ gsl_shell_app* app = global_app;
+ app->lock();
+
+ lua_fox_window* bwin = new(L, GS_FOX_WINDOW) lua_fox_window();
+ fx_plot_window* win = new fx_plot_window(app, "GSL Shell FX plot", NULL, NULL, 480, 480);
+ bwin->window = win;
+
+ win->setTarget(app);
+ app->window_create_request(win);
+
+ win->lua_id = window_index_add (L, -1);
+
+ do
+ app->wait_window_mapping();
+ while (!win->shown());
+
+ app->unlock();
+ return 1;
+}
+
+int
+fox_window_attach (lua_State *L)
+{
+ fx_plot_window *win = object_check<lua_fox_window>(L, 1, GS_FOX_WINDOW)->window;
+ sg_plot* p = object_check<sg_plot>(L, 2, GS_PLOT);
+ gsl_shell_app* app = win->get_app();
+ app->lock();
+ win->canvas()->attach(p);
+ app->unlock();
+ int slot_id = 1;
+ window_refs_add (L, slot_id, 1, 2);
+ return 0;
+}
+
+int
+fox_window_close (lua_State *L)
+{
+ return 0;
+}
+
+int
+fox_window_slot_refresh (lua_State *L)
+{
+ fx_plot_window *win = object_check<lua_fox_window>(L, 1, GS_FOX_WINDOW)->window;
+ fx_plot_canvas* canvas = win->canvas();
+ gsl_shell_app* app = win->get_app();
+
+ app->lock();
+
+ if (canvas->is_ready())
+ {
+ agg::trans_affine& m = canvas->plot_matrix();
+ bool redraw = canvas->get_plot()->need_redraw();
+ if (redraw)
+ canvas->plot_render(m);
+ canvas->plot_draw_queue(m, redraw);
+ }
+
+ app->unlock();
+ return 0;
+}
+
+int
+fox_window_slot_update (lua_State *L)
+{
+ fx_plot_window *win = object_check<lua_fox_window>(L, 1, GS_FOX_WINDOW)->window;
+ fx_plot_canvas* canvas = win->canvas();
+ gsl_shell_app* app = win->get_app();
+
+ app->lock();
+
+ if (canvas->is_ready())
+ {
+ agg::trans_affine& m = canvas->plot_matrix();
+ canvas->plot_render(m);
+ canvas->plot_draw_queue(m, true);
+ }
+
+ app->unlock();
+ return 0;
+}
+
+int
+fox_window_save_slot_image (lua_State *L)
+{
+ fx_plot_window *win = object_check<lua_fox_window>(L, 1, GS_FOX_WINDOW)->window;
+ fx_plot_canvas* canvas = win->canvas();
+ gsl_shell_app* app = win->get_app();
+ app->lock();
+ canvas->save_image();
+ app->unlock();
+ return 0;
+}
+
+int
+fox_window_restore_slot_image (lua_State *L)
+{
+ fx_plot_window *win = object_check<lua_fox_window>(L, 1, GS_FOX_WINDOW)->window;
+ fx_plot_canvas* canvas = win->canvas();
+ gsl_shell_app* app = win->get_app();
+ app->lock();
+ if (!canvas->restore_image())
+ {
+ agg::trans_affine& m = canvas->plot_matrix();
+ canvas->plot_render(m);
+ canvas->save_image();
+ }
+ app->unlock();
+ return 0;
+}
+
+void
+fox_window_register (lua_State *L)
+{
+ luaL_newmetatable (L, GS_METATABLE(GS_FOX_WINDOW));
+ lua_pushvalue (L, -1);
+ lua_setfield (L, -2, "__index");
+ luaL_register (L, NULL, fox_window_methods);
+ lua_pop (L, 1);
+
+ luaL_register (L, NULL, fox_window_functions);
+}
diff --git a/fox-gui/lua_plot_window.h b/fox-gui/lua_plot_window.h
new file mode 100644
index 00000000..3ae8d18c
--- /dev/null
+++ b/fox-gui/lua_plot_window.h
@@ -0,0 +1,21 @@
+#ifndef FOXGUI_FOX_WINDOW_H
+#define FOXGUI_FOX_WINDOW_H
+
+#include "defs.h"
+
+__BEGIN_DECLS
+
+#include "lua.h"
+
+extern void fox_window_register (lua_State *L);
+
+extern int fox_window_new (lua_State *L);
+extern int fox_window_attach (lua_State *L);
+extern int fox_window_slot_refresh (lua_State *L);
+extern int fox_window_slot_update (lua_State *L);
+extern int fox_window_save_slot_image (lua_State *L);
+extern int fox_window_restore_slot_image (lua_State *L);
+
+__END_DECLS
+
+#endif
diff --git a/fox-gui/redirect.cpp b/fox-gui/redirect.cpp
new file mode 100644
index 00000000..3df2c94b
--- /dev/null
+++ b/fox-gui/redirect.cpp
@@ -0,0 +1,54 @@
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "redirect.h"
+
+#define READ_FD 0
+#define WRITE_FD 1
+
+#define CHECK(a) if ((a)!= 0) return -1;
+
+stdout_redirect::stdout_redirect(int bufferSize)
+{
+ int status;
+
+#ifdef WIN32
+ status = _pipe(fd_pipe, bufferSize, O_TEXT);
+#else
+ status = pipe(fd_pipe);
+#endif
+
+ assert(status == 0);
+
+ fd_stdout = dup(fileno(stdout));
+}
+
+int stdout_redirect::start()
+{
+ fflush(stdout);
+ CHECK(dup2(fd_pipe[WRITE_FD], fileno(stdout)));
+ setvbuf( stdout, NULL, _IONBF, 0 ); // absolutely needed
+ return 0;
+}
+
+int stdout_redirect::stop()
+{
+ CHECK(dup2(fd_stdout, fileno(stdout)));
+ close(fd_stdout);
+ close(fd_pipe[WRITE_FD]);
+ close(fd_pipe[READ_FD]);
+ return 0;
+}
+
+int stdout_redirect::read(char *buffer, int size)
+{
+ int nOutRead = ::read(fd_pipe[READ_FD], buffer, size);
+ return nOutRead;
+}
diff --git a/fox-gui/redirect.h b/fox-gui/redirect.h
new file mode 100644
index 00000000..eef56343
--- /dev/null
+++ b/fox-gui/redirect.h
@@ -0,0 +1,18 @@
+#ifndef FOXGUI_REDIRECT_H
+#define FOXGUI_REDIRECT_H
+
+class stdout_redirect
+{
+public:
+ stdout_redirect(int buffer_size);
+
+ int start();
+ int stop();
+ int read(char *buffer, int size);
+
+private:
+ int fd_pipe[2];
+ int fd_stdout;
+};
+
+#endif
diff --git a/gsl-shell-jit.c b/gsl-shell-jit.c
index bea6611a..7def3915 100644
--- a/gsl-shell-jit.c
+++ b/gsl-shell-jit.c
@@ -41,6 +41,8 @@
#include "gsl-shell.h"
#include "completion.h"
#include "lua-graph.h"
+#include "window_hooks.h"
+#include "window.h"
#if defined(USE_READLINE)
#include <stdio.h>
@@ -98,15 +100,21 @@ static void my_freeline (lua_State *L, char *b) { }
#endif
lua_State *globalL = NULL;
+struct gsl_shell_state gsl_shell[1];
static const char *progname = LUA_PROGNAME;
-pthread_mutex_t gsl_shell_mutex[1];
-pthread_mutex_t gsl_shell_shutdown_mutex[1];
-volatile int gsl_shell_shutting_down = 0;
+struct window_hooks app_window_hooks[1] = {{
+ window_new, window_attach,
+ window_slot_update, window_slot_refresh,
+ window_save_slot_image, window_restore_slot_image,
+ window_register,
+ }
+};
static void gsl_shell_openlibs(lua_State *L)
{
luaopen_gsl (L);
+ register_graph (L);
}
static void lstop(lua_State *L, lua_Debug *ar)
@@ -289,9 +297,9 @@ static int pushline (lua_State *L, int firstline) {
size_t l;
const char *prmt = get_prompt(L, firstline);
- GSL_SHELL_UNLOCK();
+ pthread_mutex_unlock(&gsl_shell->exec_mutex);
b = my_readline(L, buffer, prmt);
- GSL_SHELL_LOCK();
+ pthread_mutex_lock(&gsl_shell->exec_mutex);
if (b == NULL)
return 0; /* no input */
@@ -654,31 +662,20 @@ int main(int argc, char **argv)
#ifdef USE_READLINE
initialize_readline();
#endif
- pthread_mutex_init (gsl_shell_mutex, NULL);
- pthread_mutex_init (gsl_shell_shutdown_mutex, NULL);
-
- GSL_SHELL_LOCK();
- lua_State *L = lua_open(); /* create state */
- if (L == NULL) {
- l_message(argv[0], "cannot create state: not enough memory");
- return EXIT_FAILURE;
- }
+ gsl_shell_init(gsl_shell);
+ gsl_shell_open(gsl_shell);
+
+ pthread_mutex_lock(&gsl_shell->exec_mutex);
+
s.argc = argc;
s.argv = argv;
- status = lua_cpcall(L, pmain, &s);
- report(L, status);
-
- GSL_SHELL_UNLOCK();
- pthread_mutex_lock (gsl_shell_shutdown_mutex);
- gsl_shell_shutting_down = 1;
- GSL_SHELL_LOCK();
- graph_close_windows(L);
- lua_close(L);
- pthread_mutex_unlock (gsl_shell_shutdown_mutex);
- GSL_SHELL_UNLOCK();
-
- pthread_mutex_destroy (gsl_shell_mutex);
- pthread_mutex_destroy (gsl_shell_shutdown_mutex);
+ status = lua_cpcall(gsl_shell->L, pmain, &s);
+ report(gsl_shell->L, status);
+
+ pthread_mutex_unlock(&gsl_shell->exec_mutex);
+
+ gsl_shell_close_with_graph(gsl_shell);
+ gsl_shell_free(gsl_shell);
return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/gsl-shell.h b/gsl-shell.h
index 67058d30..92a1d8a5 100644
--- a/gsl-shell.h
+++ b/gsl-shell.h
@@ -2,19 +2,12 @@
#define GSL_SHELL_INCLUDED
#include "defs.h"
-#include <pthread.h>
#include <lua.h>
__BEGIN_DECLS
extern lua_State *globalL;
-extern pthread_mutex_t gsl_shell_mutex[1];
-extern pthread_mutex_t gsl_shell_shutdown_mutex[1];
-extern volatile int gsl_shell_shutting_down;
__END_DECLS
-#define GSL_SHELL_LOCK() pthread_mutex_lock (gsl_shell_mutex)
-#define GSL_SHELL_UNLOCK() pthread_mutex_unlock (gsl_shell_mutex)
-
#endif
diff --git a/iter.lua b/iter.lua
index d28d9bd7..a6c537ff 100644
--- a/iter.lua
+++ b/iter.lua
@@ -20,7 +20,12 @@
local cat = table.concat
local fmt = string.format
-local gsl_type = gslsh.type
+
+local gsl_type
+do
+ local reg = debug.getregistry()
+ gsl_typename = reg.__gsl_type
+end
function math.divmod(n, p)
local r = n % p
@@ -61,8 +66,8 @@ tos = function (t, maxdepth)
local mt = getmetatable(t)
local ftostr = mt and mt.__tostring
if ftostr then return ftostr(t) else
- if gsl_type then
- return fmt('<%s: %p>', gsl_type(t), t)
+ if gsl_typename then
+ return fmt('<%s: %p>', gsl_typename(t), t)
else
return fmt('<userdata: %p>', t)
end
diff --git a/lua-graph.h b/lua-graph.h
index 636f3f76..f7477a8b 100644
--- a/lua-graph.h
+++ b/lua-graph.h
@@ -1,12 +1,25 @@
#ifndef LUA_GRAPH_H
#define LUA_GRAPH_H
-#ifndef MLUA_GRAPHLIBNAME
-#define MLUA_GRAPHLIBNAME "graph"
-#endif
+#include <pthread.h>
+
+#include "defs.h"
+
+__BEGIN_DECLS
+
+#include <lua.h>
extern void graph_close_windows (lua_State *L);
extern void register_graph (lua_State *L);
+extern void gsl_shell_close_with_graph (struct gsl_shell_state* gs);
+
extern int initialize_fonts(lua_State* L);
+extern pthread_mutex_t agg_mutex[1];
+
+#define AGG_LOCK() pthread_mutex_lock (agg_mutex);
+#define AGG_UNLOCK() pthread_mutex_unlock (agg_mutex);
+
+__END_DECLS
+
#endif
diff --git a/lua-gsl.h b/lua-gsl.h
index 70a4b3cb..9fada7a1 100644
--- a/lua-gsl.h
+++ b/lua-gsl.h
@@ -1,6 +1,29 @@
#ifndef LUA_GSL_H
#define LUA_GSL_H
+#include <pthread.h>
+
+#include "defs.h"
+
+__BEGIN_DECLS
+
+#include <lua.h>
+
+struct gsl_shell_state {
+ lua_State *L;
+ pthread_mutex_t exec_mutex;
+ pthread_mutex_t shutdown_mutex;
+ int is_shutting_down;
+};
+
+extern void gsl_shell_open (struct gsl_shell_state *gs);
+extern void gsl_shell_free (struct gsl_shell_state *gs);
+extern void gsl_shell_init (struct gsl_shell_state *gs);
+
extern int luaopen_gsl (lua_State *L);
+extern struct gsl_shell_state* global_state;
+
+__END_DECLS
+
#endif
diff --git a/lua-gsl/Makefile b/lua-gsl/Makefile
new file mode 100644
index 00000000..386803f8
--- /dev/null
+++ b/lua-gsl/Makefile
@@ -0,0 +1,57 @@
+
+# Makefile
+#
+# Copyright (C) 2009 Francesco Abbate
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+GSH_BASE_DIR = ..
+
+include $(GSH_BASE_DIR)/makeconfig
+include $(GSH_BASE_DIR)/make-system-detect
+include $(GSH_BASE_DIR)/makepackages
+include $(GSH_BASE_DIR)/makedefs
+
+LUADIR = $(GSH_BASE_DIR)/luajit2
+
+INCLUDES += -I$(LUADIR)/src -I$(GSH_BASE_DIR)
+
+LUAGSL_SRC_FILES = gs-types.c lua-utils.c lua-gsl.c str.c fatal.c
+LUAGSL_OBJ_FILES := $(LUAGSL_SRC_FILES:%.c=%.o)
+
+DEP_FILES := $(LUAGSL_SRC_FILES:%.c=.deps/%.P)
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+COMPILE = $(CC) $(CFLAGS) $(LUA_CFLAGS) $(DEFS) $(INCLUDES)
+
+TARGETS = libluagsl.a
+
+all: $(TARGETS)
+
+libluagsl.a: $(LUAGSL_OBJ_FILES)
+ @echo Archive $@
+ @$(AR) $@ $?
+ @$(RANLIB) $@
+
+include $(GSH_BASE_DIR)/makerules
+
+.PHONY: clean all
+
+clean:
+ $(HOST_RM) *.o *.lo *.la *.so *.dll $(TARGETS)
+
+-include $(DEP_FILES)
diff --git a/lua-gsl/fatal.c b/lua-gsl/fatal.c
new file mode 100644
index 00000000..da739527
--- /dev/null
+++ b/lua-gsl/fatal.c
@@ -0,0 +1,13 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "fatal.h"
+
+void
+fatal_exception(const char* msg)
+{
+ fputs(msg, stderr);
+ fputs("\n", stderr);
+ abort();
+}
diff --git a/lua-gsl/fatal.h b/lua-gsl/fatal.h
new file mode 100644
index 00000000..27814349
--- /dev/null
+++ b/lua-gsl/fatal.h
@@ -0,0 +1,12 @@
+#ifndef MY_FATAL_H
+#define MY_FATAL_H
+
+#include "defs.h"
+
+__BEGIN_DECLS
+
+extern void fatal_exception(const char* msg) __attribute__ ((noreturn));
+
+__END_DECLS
+
+#endif
diff --git a/gs-types.c b/lua-gsl/gs-types.c
index e6167fca..3f6b68a6 100644
--- a/gs-types.c
+++ b/lua-gsl/gs-types.c
@@ -8,9 +8,8 @@
#include <gsl/gsl_errno.h>
#include <math.h>
-static int gs_type_string (lua_State *L);
-
#define GS_WINDOW_NAME_DEF "GSL.window"
+#define GS_FOX_WINDOW_NAME_DEF "GSL.FOXwindow"
#define GS_DRAW_SCALABLE_NAME_DEF NULL
#define GS_DRAW_PATH_NAME_DEF "GSL.path"
#define GS_DRAW_ELLIPSE_NAME_DEF "GSL.ellipse"
@@ -29,6 +28,7 @@ static int gs_type_string (lua_State *L);
#define MY_EXPAND_DER(NM,DESCR,BASE) {MYCAT2(GS,NM), MYCAT3(GS,NM,NAME_DEF), DESCR, MYCAT2(GS,BASE)}
const struct gs_type gs_type_table[] = {
+ MY_EXPAND(FOX_WINDOW, "FOX graphical window"),
MY_EXPAND(WINDOW, "graphical window"),
MY_EXPAND(DRAW_SCALABLE, "graphical object"),
MY_EXPAND_DER(DRAW_PATH, "geometric line", DRAW_SCALABLE),
@@ -48,11 +48,6 @@ const struct gs_type gs_type_table[] = {
#undef MY_EXPAND
#undef MY_EXPAND_DER
-const struct luaL_Reg gs_type_functions[] = {
- {"type", gs_type_string},
- {NULL, NULL}
-};
-
const char *
type_qualified_name (int typeid)
{
diff --git a/gs-types.h b/lua-gsl/gs-types.h
index 94e961f6..5437696f 100644
--- a/gs-types.h
+++ b/lua-gsl/gs-types.h
@@ -11,6 +11,7 @@ __BEGIN_DECLS
enum gs_type_e {
GS_NO_TYPE = -1,
GS_WINDOW = 0,
+ GS_FOX_WINDOW,
GS_DRAW_SCALABLE, /* derived types are declared only after their base class */
GS_DRAW_PATH,
GS_DRAW_ELLIPSE,
@@ -48,7 +49,7 @@ extern const struct gs_type gs_type_table[];
#define GS_METATABLE(id) gs_type_table[(id)].mt_name
-extern const struct luaL_Reg gs_type_functions[];
+extern int gs_type_string (lua_State *L);
__END_DECLS
diff --git a/lua-defs.h b/lua-gsl/lua-defs.h
index a637aada..a637aada 100644
--- a/lua-defs.h
+++ b/lua-gsl/lua-defs.h
diff --git a/lua-gsl.c b/lua-gsl/lua-gsl.c
index 98d979cc..004dba16 100644
--- a/lua-gsl.c
+++ b/lua-gsl/lua-gsl.c
@@ -27,18 +27,44 @@
#include "lua-gsl.h"
#include "gs-types.h"
#include "lua-utils.h"
+#include "fatal.h"
-#include "lua-graph.h"
+struct gsl_shell_state* global_state;
+
+void
+gsl_shell_open (struct gsl_shell_state *gs)
+{
+ gs->L = lua_open(); /* create state */
+
+ if (unlikely(gs->L == NULL))
+ fatal_exception("cannot create state: not enough memory");
+
+ global_state = gs;
+}
+
+void
+gsl_shell_init (struct gsl_shell_state *gs)
+{
+ pthread_mutex_init (&gs->exec_mutex, NULL);
+ pthread_mutex_init (&gs->shutdown_mutex, NULL);
+ gs->is_shutting_down = 0;
+ gs->L = NULL;
+}
+
+void
+gsl_shell_free (struct gsl_shell_state *gs)
+{
+ pthread_mutex_destroy (&gs->exec_mutex);
+ pthread_mutex_destroy (&gs->shutdown_mutex);
+}
int
luaopen_gsl (lua_State *L)
{
gsl_set_error_handler_off ();
- luaL_register (L, "gslsh", gs_type_functions);
- lua_pop (L, 1);
-
- register_graph (L);
+ lua_pushcfunction (L, gs_type_string);
+ lua_setfield (L, LUA_REGISTRYINDEX, "__gsl_type");
- return 1;
+ return 0;
}
diff --git a/lua-utils.c b/lua-gsl/lua-utils.c
index 095cac89..095cac89 100644
--- a/lua-utils.c
+++ b/lua-gsl/lua-utils.c
diff --git a/lua-utils.h b/lua-gsl/lua-utils.h
index 333b7a49..333b7a49 100644
--- a/lua-utils.h
+++ b/lua-gsl/lua-utils.h
diff --git a/str.c b/lua-gsl/str.c
index e3fb42ac..e3fb42ac 100644
--- a/str.c
+++ b/lua-gsl/str.c
diff --git a/str.h b/lua-gsl/str.h
index 7182edb6..7182edb6 100644
--- a/str.h
+++ b/lua-gsl/str.h
diff --git a/agg-plot/strpp.h b/lua-gsl/strpp.h
index bcc54a73..9bd9e67d 100644
--- a/agg-plot/strpp.h
+++ b/lua-gsl/strpp.h
@@ -11,11 +11,18 @@ public:
~str() { str_free(this); }
- const str& operator = (const str& s) {
+ const str& operator= (const str& s)
+ {
str_copy(this, &s);
return *this;
}
+ const str& operator= (const char* s)
+ {
+ str_copy_c(this, s);
+ return *this;
+ }
+
const char* cstr() const { return CSTR(this); }
unsigned len() const { return this->length; }
diff --git a/makedefs b/makedefs
index 2718df41..eda224a3 100644
--- a/makedefs
+++ b/makedefs
@@ -15,6 +15,12 @@ RANLIB= ranlib
CC = gcc
CXX = g++
+ifeq ($(HOST_SYS),Darwin)
+ LINK_EXE = $(CXX) $(LDFLAGS)
+else
+ LINK_EXE = $(CC) $(LDFLAGS)
+endif
+
ifeq ($(strip $(LUA_BUILD)), yes)
PACKAGE_NAME = lua
PACKAGE_VERSION = 5.1
@@ -39,6 +45,8 @@ ifeq ($(HOST_SYS),Windows)
EXE_EXT = .exe
else
EXE_EXT =
+ DEFS += -pthread
+ LIBS += -pthread
endif
ifeq ($(strip $(DEBUG)), yes)
diff --git a/makepackages b/makepackages
index 7c9dc4b8..a21da6ec 100644
--- a/makepackages
+++ b/makepackages
@@ -9,13 +9,17 @@
ifeq ($(HOST_SYS),Windows)
USER_LIBS_HOME = C:/fra/sviluppo
+ USER_INCLUDE = $(USER_LIBS_HOME)/include
- INCLUDES += -I$(USER_LIBS_HOME)/include
+ INCLUDES += -I$(USER_INCLUDE)
LIBS += -L$(USER_LIBS_HOME)/lib
- AGG_INCLUDES = -I$(USER_LIBS_HOME)/include/agg2
+ AGG_INCLUDES = -I$(USER_INCLUDE)/agg2
AGG_LIBS = -lagg -lgdi32
+ FOX_INCLUDES = -I$(USER_INCLUDE)/fox-1.6
+ FOX_LIBS = -lfox -lgdi32
+
GSL_INCLUDES =
GSL_LIBS = -lgsl -lgslcblas -lm
@@ -30,6 +34,9 @@ else
GSL_INCLUDES =
GSL_LIBS = -lgsl -lgslcblas -lm
+ FOX_INCLUDES := $(shell pkg-config fox --cflags)
+ FOX_LIBS = $(shell pkg-config fox --libs)
+
FREETYPE_INCLUDES = -I/usr/include/freetype2
FREETYPE_LIBS = -lfreetype
generated by cgit v1.2.3 (git 2.39.1) at 2025年09月16日 23:35:19 +0000

AltStyle によって変換されたページ (->オリジナル) /