summaryrefslogtreecommitdiffstats
path: root/src/livecode/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/livecode/api')
-rw-r--r--src/livecode/api/api.h34
-rw-r--r--src/livecode/api/context.cpp21
-rw-r--r--src/livecode/api/input.cpp113
-rw-r--r--src/livecode/api/point.cpp298
4 files changed, 466 insertions, 0 deletions
diff --git a/src/livecode/api/api.h b/src/livecode/api/api.h
new file mode 100644
index 000000000..94694ca56
--- /dev/null
+++ b/src/livecode/api/api.h
@@ -0,0 +1,34 @@
+#ifndef JANET_2GEOM_POINT_INCLUDED
+#define JANET_2GEOM_POINT_INCLUDED
+
+#include <janet.h>
+#include <2geom/point.h>
+#include "livecode/context.h"
+#include "livecode/input.h"
+
+namespace Inkscape {
+namespace Livecode {
+
+/* context.cpp */
+void janet_lib_context(JanetTable *env, Context &context);
+
+Context &ctx();
+
+/* point.cpp */
+void janet_lib_geom_point(JanetTable *env);
+
+extern const JanetAbstractType geom_point_type;
+
+Janet janet_wrap_point(Geom::Point const &x);
+Janet janet_wrap_point(Geom::IntPoint const &x);
+Geom::Point janet_unwrap_point(Janet x);
+
+/* input.cpp */
+void janet_lib_input(JanetTable *env);
+
+Janet janet_wrap_inputstate(InputState const &state);
+
+}
+}
+
+#endif // JANET_2GEOM_POINT_INCLUDED
diff --git a/src/livecode/api/context.cpp b/src/livecode/api/context.cpp
new file mode 100644
index 000000000..43c6881d1
--- /dev/null
+++ b/src/livecode/api/context.cpp
@@ -0,0 +1,21 @@
+#include "livecode/api/api.h"
+
+namespace Inkscape {
+namespace Livecode {
+
+static Context *_context = nullptr;
+
+Context &ctx() {
+ if (!_context) {
+ janet_panic("Livecode Context uninitialized!!");
+ }
+
+ return *_context;
+}
+
+void janet_lib_context(JanetTable *env, Context &context) {
+ _context = &context;
+}
+
+}
+}
diff --git a/src/livecode/api/input.cpp b/src/livecode/api/input.cpp
new file mode 100644
index 000000000..0fc820bbd
--- /dev/null
+++ b/src/livecode/api/input.cpp
@@ -0,0 +1,113 @@
+#include "livecode/api/api.h"
+
+#include <sstream>
+
+namespace Inkscape {
+namespace Livecode {
+
+extern "C" Janet cfun_mouse_pos(int32_t argc, Janet *argv) {
+ janet_fixarity(argc, 0);
+ return janet_wrap_point(ctx().mouse().pos());
+}
+
+extern "C" Janet cfun_mouse_delta(int32_t argc, Janet *argv) {
+ janet_fixarity(argc, 0);
+ return janet_wrap_point(ctx().mouse().delta());
+}
+
+extern "C" Janet cfun_mouse_ui_pos(int32_t argc, Janet *argv) {
+ janet_fixarity(argc, 0);
+ return janet_wrap_point(ctx().mouse().ui_pos());
+}
+
+extern "C" Janet cfun_mouse_ui_delta(int32_t argc, Janet *argv) {
+ janet_fixarity(argc, 0);
+ return janet_wrap_point(ctx().mouse().ui_delta());
+}
+
+Janet janet_wrap_inputstate(InputState const &state) {
+ switch (state) {
+ case INPUTSTATE_NONE:
+ return janet_wrap_nil();
+ case INPUTSTATE_HOVER:
+ return janet_ckeywordv("hover");
+ case INPUTSTATE_PRESSED:
+ return janet_ckeywordv("pressed");
+ case INPUTSTATE_HELD:
+ return janet_ckeywordv("held");
+ case INPUTSTATE_RELEASED:
+ return janet_ckeywordv("released");
+ default:
+ janet_panic("unexpected event value");
+ }
+}
+
+extern "C" Janet cfun_mouse_event(int32_t argc, Janet *argv) {
+ janet_arity(argc, 0, 1);
+
+ guint button = janet_getsize(argv, 1);
+ if (button < 1 || button > 5) {
+ janet_panic("expected button to be between 1 and 5");
+ }
+
+ return janet_wrap_inputstate(ctx().mouse().event(button));
+}
+
+#define BUTTONMETHOD(name) \
+extern "C" Janet cfun_mouse_##name(int32_t argc, Janet *argv) { \
+ janet_arity(argc, 0, 1); \
+ guint button = janet_getsize(argv, 1); \
+ if (button < 1 || button > 5) { \
+ janet_panic("expected button to be between 1 and 5"); \
+ } \
+ return janet_wrap_boolean(ctx().mouse().name(button)); \
+}
+
+BUTTONMETHOD(pressed)
+BUTTONMETHOD(held)
+BUTTONMETHOD(released)
+
+const JanetReg it_cfuns[] = {
+ {
+ "mouse/pos", cfun_mouse_pos,
+ "(mouse/pos)\n\nGet the current mouse position as a geom/point."
+ },
+ {
+ "mouse/delta", cfun_mouse_delta,
+ "(mouse/pos)\n\nGet the mouse motion since last frame as a geom/point."
+ },
+ {
+ "mouse/ui-pos", cfun_mouse_ui_pos,
+ "(mouse/pos)\n\nGet the current mouse position as a geom/point, in UI space."
+ },
+ {
+ "mouse/ui-delta", cfun_mouse_ui_delta,
+ "(mouse/pos)\n\nGet the mouse motion since last frame as a geom/point, in UI space."
+ },
+ {
+ "mouse/event", cfun_mouse_event,
+ "(mouse/event [button])\n\nGet the current event/status for a mouse button.\n"
+ "Returns either nil, :pressed, :held or :released."
+ },
+ {
+ "mouse/pressed", cfun_mouse_pressed,
+ "(mouse/pressed [button])\n\nCheck whether a mouse button was pressed this frame.\n"
+ },
+ {
+ "mouse/held", cfun_mouse_held,
+ "(mouse/held [button])\n\nCheck whether a mouse button was held down this frame.\n"
+ },
+ {
+ "mouse/released", cfun_mouse_released,
+ "(mouse/released [button])\n\nCheck whether a mouse button was released this frame.\n"
+ },
+ {NULL, NULL, NULL}
+};
+
+
+void janet_lib_input(JanetTable *env) {
+ janet_cfuns(env, NULL, it_cfuns);
+}
+
+}
+}
diff --git a/src/livecode/api/point.cpp b/src/livecode/api/point.cpp
new file mode 100644
index 000000000..6eab6af1d
--- /dev/null
+++ b/src/livecode/api/point.cpp
@@ -0,0 +1,298 @@
+#include "livecode/api/api.h"
+
+#include <sstream>
+
+namespace Inkscape {
+namespace Livecode {
+
+extern "C" Janet geom_point_get(void *p, Janet key);
+extern "C" void geom_point_set(void *p, Janet key, Janet value);
+
+extern "C" void geom_point_tostring(void *p, JanetBuffer *buffer) {
+ std::stringstream stream;
+ stream << "<2geom/point " << *static_cast<Geom::Point *>(p) << ">";
+ janet_buffer_push_cstring(buffer, stream.str().c_str());
+}
+
+
+const JanetAbstractType geom_point_type = {
+ "2geom/point",
+ NULL,
+ NULL,
+ geom_point_get,
+ geom_point_set,
+ NULL,
+ NULL,
+ geom_point_tostring
+};
+
+
+Janet janet_wrap_point(Geom::Point const &x) {
+ Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point));
+ *box = Geom::Point(x);
+ return janet_wrap_abstract(box);
+}
+
+Janet janet_wrap_point(Geom::IntPoint const &x) {
+ Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point));
+ *box = Geom::Point(x);
+ return janet_wrap_abstract(box);
+}
+
+Geom::Point janet_unwrap_point(Janet x) {
+ if (janet_checktype(x, JANET_ABSTRACT)) {
+ void *abst = janet_unwrap_abstract(x);
+ if (janet_abstract_type(abst) == &geom_point_type)
+ return *(Geom::Point *)abst;
+ }
+
+ janet_panic("expected a geom/point");
+}
+
+Geom::Point janet_unwrap_point_or_scalar(Janet x) {
+ if (janet_checktype(x, JANET_ABSTRACT)) {
+ void *abst = janet_unwrap_abstract(x);
+ if (janet_abstract_type(abst) == &geom_point_type)
+ return *(Geom::Point *)abst;
+ } else if (janet_checktype(x, JANET_NUMBER)) {
+ double val = janet_unwrap_number(x);
+ return Geom::Point(val, val);
+ }
+
+ janet_panic("expected a geom/point");
+}
+
+
+Geom::Point& janet_unwrap_point_ref(Janet x) {
+ if (janet_checktype(x, JANET_ABSTRACT)) {
+ void *abst = janet_unwrap_abstract(x);
+ if (janet_abstract_type(abst) == &geom_point_type)
+ return *(Geom::Point *)abst;
+ }
+
+ janet_panic("expected a geom/point");
+}
+
+extern "C" Janet cfun_geom_point_new(int32_t argc, Janet *argv) {
+ janet_arity(argc, 0, 2);
+ double x = 0;
+ double y = 0;
+ if (argc == 2) {
+ x = janet_getnumber(argv, 0);
+ y = janet_getnumber(argv, 1);
+ } else if (argc == 1) {
+ x = janet_getnumber(argv, 0);
+ y = x;
+ }
+ return janet_wrap_point(Geom::Point(x, y));
+}
+
+const JanetReg it_cfuns[] = {
+ {
+ "point", cfun_geom_point_new,
+ "(geom/point x y)\n\nCreate a Point from x/y coordinate values."
+ },
+ {NULL, NULL, NULL}
+};
+
+static Janet cfun_geom_point_add(int32_t argc, Janet *argv) {
+ janet_arity(argc, 2, -1);
+ Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point));
+ *box = janet_unwrap_point(argv[0]);
+ for (int i = 1; i < argc; i++)
+ *box += janet_unwrap_point(argv[i]);
+ return janet_wrap_abstract(box);
+}
+
+static Janet cfun_geom_point_add_mut(int32_t argc, Janet *argv) {
+ janet_arity(argc, 2, -1);
+ Geom::Point *box = (Geom::Point *)janet_getabstract(argv, 0, &geom_point_type);
+ for (int i = 1; i < argc; i++)
+ *box += janet_unwrap_point(argv[i]);
+ return janet_wrap_abstract(box);
+}
+
+static Janet cfun_geom_point_sub(int32_t argc, Janet *argv) {
+ janet_arity(argc, 2, -1);
+ Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point));
+ *box = janet_unwrap_point(argv[0]);
+ for (int i = 1; i < argc; i++)
+ *box -= janet_unwrap_point(argv[i]);
+ return janet_wrap_abstract(box);
+}
+
+static Janet cfun_geom_point_sub_mut(int32_t argc, Janet *argv) {
+ janet_arity(argc, 2, -1);
+ Geom::Point *box = (Geom::Point *)janet_getabstract(argv, 0, &geom_point_type);
+ for (int i = 1; i < argc; i++)
+ *box -= janet_unwrap_point(argv[i]);
+ return janet_wrap_abstract(box);
+}
+
+static Janet cfun_geom_point_mul(int32_t argc, Janet *argv) {
+ janet_arity(argc, 2, -1);
+ Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point));
+ *box = janet_unwrap_point(argv[0]);
+ for (int i = 1; i < argc; i++) {
+ Geom::Point arg = janet_unwrap_point_or_scalar(argv[i]);
+ (*box)[0] *= arg[0];
+ (*box)[1] *= arg[1];
+ }
+ return janet_wrap_abstract(box);
+}
+
+static Janet cfun_geom_point_mul_mut(int32_t argc, Janet *argv) {
+ janet_arity(argc, 2, -1);
+ Geom::Point *box = (Geom::Point *)janet_getabstract(argv, 0, &geom_point_type);
+ for (int i = 1; i < argc; i++) {
+ Geom::Point arg = janet_unwrap_point_or_scalar(argv[i]);
+ (*box)[0] *= arg[0];
+ (*box)[1] *= arg[1];
+ }
+ return janet_wrap_abstract(box);
+}
+
+static Janet cfun_geom_point_div(int32_t argc, Janet *argv) {
+ janet_arity(argc, 2, -1);
+ Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point));
+ *box = janet_unwrap_point(argv[0]);
+ for (int i = 1; i < argc; i++) {
+ Geom::Point arg = janet_unwrap_point_or_scalar(argv[i]);
+ (*box)[0] /= arg[0];
+ (*box)[1] /= arg[1];
+ }
+ return janet_wrap_abstract(box);
+}
+
+static Janet cfun_geom_point_div_mut(int32_t argc, Janet *argv) {
+ janet_arity(argc, 2, -1);
+ Geom::Point *box = (Geom::Point *)janet_getabstract(argv, 0, &geom_point_type);
+ for (int i = 1; i < argc; i++) {
+ Geom::Point arg = janet_unwrap_point_or_scalar(argv[i]);
+ (*box)[0] /= arg[0];
+ (*box)[1] /= arg[1];
+ }
+ return janet_wrap_abstract(box);
+}
+
+static Janet cfun_geom_point_eq(int32_t argc, Janet *argv) {
+ janet_fixarity(argc, 2);
+ Geom::Point& v1 = janet_unwrap_point_ref(argv[0]);
+ Geom::Point& v2 = janet_unwrap_point_ref(argv[1]);
+ return janet_wrap_boolean(v1 == v2);
+}
+
+static Janet cfun_geom_point_lt(int32_t argc, Janet *argv) {
+ janet_fixarity(argc, 2);
+ Geom::Point& v1 = janet_unwrap_point_ref(argv[0]);
+ Geom::Point& v2 = janet_unwrap_point_ref(argv[1]);
+ return janet_wrap_boolean(v1 < v2);
+}
+
+#define CONSTMETHOD(name, method, type) \
+static Janet cfun_geom_point_##name(int32_t argc, Janet *argv) { \
+ janet_fixarity(argc, 1); \
+ Geom::Point *box = (Geom::Point *)janet_getabstract(argv, 0, &geom_point_type); \
+ return janet_wrap_##type(box->method()); \
+}
+
+CONSTMETHOD(is_zero, isZero, boolean)
+CONSTMETHOD(is_finite, isFinite, boolean)
+CONSTMETHOD(is_normalized, isNormalized, boolean)
+
+CONSTMETHOD(x, x, number)
+CONSTMETHOD(y, y, number)
+CONSTMETHOD(length, length, number)
+
+CONSTMETHOD(cw, cw, point)
+CONSTMETHOD(ccw, ccw, point)
+CONSTMETHOD(round, round, point)
+CONSTMETHOD(floor, floor, point)
+CONSTMETHOD(ceil, ceil, point)
+CONSTMETHOD(normalize, normalized, point)
+
+static Janet cfun_geom_point_normalize_mut(int32_t argc, Janet *argv) {
+ janet_fixarity(argc, 1);
+ Geom::Point *box = (Geom::Point *)janet_getabstract(argv, 0, &geom_point_type);
+ box->normalize();
+ return janet_wrap_point(*box);
+}
+
+static JanetMethod geom_point_methods[] = {
+ {"+", cfun_geom_point_add},
+ {"-", cfun_geom_point_sub},
+ {"*", cfun_geom_point_mul},
+ {"/", cfun_geom_point_div},
+ {"<", cfun_geom_point_lt},
+ {"==", cfun_geom_point_eq},
+
+ {"+!", cfun_geom_point_add_mut},
+ {"-!", cfun_geom_point_sub_mut},
+ {"*!", cfun_geom_point_mul_mut},
+ {"/!", cfun_geom_point_div_mut},
+
+ {"zero?", cfun_geom_point_is_zero},
+ {"finite?", cfun_geom_point_is_finite},
+ {"normalized?", cfun_geom_point_is_normalized},
+
+ {"x", cfun_geom_point_x},
+ {"y", cfun_geom_point_y},
+ {"length", cfun_geom_point_length},
+
+ {"cw", cfun_geom_point_cw},
+ {"ccw", cfun_geom_point_ccw},
+ {"round", cfun_geom_point_round},
+ {"floor", cfun_geom_point_floor},
+ {"ceil", cfun_geom_point_ceil},
+ {"normalize", cfun_geom_point_normalize},
+
+ {"normalize!", cfun_geom_point_normalize_mut},
+
+ {NULL, NULL}
+};
+
+extern "C" Janet geom_point_get(void *p, Janet key) {
+ Geom::Point *box = (Geom::Point *)p;
+
+ if (janet_checktype(key, JANET_KEYWORD))
+ return janet_getmethod(janet_unwrap_keyword(key), geom_point_methods);
+
+ if (!janet_checksize(key)) janet_panic("expected size as key");
+
+ size_t const index = (size_t) janet_unwrap_number(key);
+ switch (index) {
+ case 0:
+ return janet_wrap_number((*box)[0]);
+ case 1:
+ return janet_wrap_number((*box)[1]);
+ default:
+ return janet_wrap_nil();
+ }
+}
+
+extern "C" void geom_point_set(void *p, Janet key, Janet value) {
+ Geom::Point *box = (Geom::Point *)p;
+
+ if (!janet_checksize(key)) janet_panic("expected size as key");
+ if (!janet_checktype(key, JANET_NUMBER)) janet_panic("expected number as value");
+
+ size_t const index = (size_t) janet_unwrap_number(key);
+ switch (index) {
+ case 0:
+ (*box)[0] = janet_unwrap_number(value);
+ break;
+ case 1:
+ (*box)[1] = janet_unwrap_number(value);
+ break;
+ default:
+ janet_panic("index out of bounds");
+ }
+}
+
+void janet_lib_geom_point(JanetTable *env) {
+ janet_cfuns(env, NULL, it_cfuns);
+ janet_register_abstract_type(&geom_point_type);
+}
+
+}
+}