aboutsummaryrefslogtreecommitdiff
path: root/stub
diff options
context:
space:
mode:
authorSébastien Dailly <sebastien@chimrod.com>2016-11-15 13:00:01 +0100
committerSébastien Dailly <sebastien@chimrod.com>2016-11-15 13:00:01 +0100
commitef312564ca84a2b49fc291434d8fb2f8501bb618 (patch)
tree79415fcf225e6da1042c8edaae5e4a74c7a983cb /stub
Initial commit
Diffstat (limited to 'stub')
-rwxr-xr-xstub/Makefile22
-rwxr-xr-xstub/curses.c111
-rwxr-xr-xstub/locale.c45
-rwxr-xr-xstub/ocaml.c38
-rwxr-xr-xstub/ocaml.h28
5 files changed, 244 insertions, 0 deletions
diff --git a/stub/Makefile b/stub/Makefile
new file mode 100755
index 0000000..462ba73
--- /dev/null
+++ b/stub/Makefile
@@ -0,0 +1,22 @@
+LIB_STUB = $(LIB)_stub
+
+C_FILES = $(wildcard *.c)
+OBJ_FILES = $(patsubst %.c,%.o,$(C_FILES))
+
+#LINK_FLAG = $(shell pkg-config --libs $(LIB))
+LINK_FLAG=
+
+all: dll$(LIB_STUB).so
+
+%.o: %.c
+ ocamlc -o $@ $<
+
+dll$(LIB_STUB).so: $(OBJ_FILES)
+ ocamlmklib -I ../_build -oc $(LIB_STUB) $(LINK_FLAG) $^
+ test -d ../_build || mkdir ../_build
+ ln -sf ../stub/dll$(LIB_STUB).so ../_build/
+ ln -sf ../stub/lib$(LIB_STUB).a ../_build/
+
+clean:
+ rm $(OBJ_FILES) *.so *.a
+
diff --git a/stub/curses.c b/stub/curses.c
new file mode 100755
index 0000000..cd1d814
--- /dev/null
+++ b/stub/curses.c
@@ -0,0 +1,111 @@
+#include <ncurses.h>
+
+#include "ocaml.h"
+
+CAMLprim value
+c_set_mouse_event(value events)
+{
+ CAMLparam1(events);
+ CAMLlocal1(event);
+
+ mmask_t mask = 0;
+
+ while (events != Val_emptylist)
+ {
+ event = Field(events, 0);
+
+ switch (Int_val(event)) {
+ case 0: mask |= BUTTON1_PRESSED; break;
+ case 1: mask |= BUTTON1_RELEASED; break;
+ case 2: mask |= BUTTON1_CLICKED; break;
+ case 3: mask |= BUTTON1_DOUBLE_CLICKED; break;
+ case 4: mask |= BUTTON1_TRIPLE_CLICKED; break;
+ case 5: mask |= BUTTON2_PRESSED; break;
+ case 6: mask |= BUTTON2_RELEASED; break;
+ case 7: mask |= BUTTON2_CLICKED; break;
+ case 8: mask |= BUTTON2_DOUBLE_CLICKED; break;
+ case 9: mask |= BUTTON2_TRIPLE_CLICKED; break;
+ case 10: mask |= BUTTON3_PRESSED; break;
+ case 11: mask |= BUTTON3_RELEASED; break;
+ case 12: mask |= BUTTON3_CLICKED; break;
+ case 13: mask |= BUTTON3_DOUBLE_CLICKED; break;
+ case 14: mask |= BUTTON3_TRIPLE_CLICKED; break;
+ case 15: mask |= BUTTON4_PRESSED; break;
+ case 16: mask |= BUTTON4_RELEASED; break;
+ case 17: mask |= BUTTON4_CLICKED; break;
+ case 18: mask |= BUTTON4_DOUBLE_CLICKED; break;
+ case 29: mask |= BUTTON4_TRIPLE_CLICKED; break;
+ case 20: mask |= BUTTON_SHIFT; break;
+ case 21: mask |= BUTTON_CTRL; break;
+ case 22: mask |= BUTTON_ALT; break;
+ case 23: mask |= ALL_MOUSE_EVENTS; break;
+ case 24: mask |= REPORT_MOUSE_POSITION; break;
+ }
+ events = Field(events, 1);
+ }
+ mousemask(mask, NULL);
+
+
+ CAMLreturn(Val_unit);
+}
+
+CAMLprim value
+c_get_mouse_event(value unit)
+{
+ MEVENT event;
+ CAMLparam1(unit);
+ CAMLlocal2(result, coord);
+
+ result = caml_alloc(3, 0);
+ coord = caml_alloc(3, 0);
+
+ if (getmouse(&event) == OK)
+ {
+ Store_field(coord, 0, Val_int(event.x));
+ Store_field(coord, 1, Val_int(event.y));
+ Store_field(coord, 2, Val_int(event.z));
+
+ Store_field(result, 0, Val_int(event.id));
+ Store_field(result, 1, event.bstate);
+ Store_field(result, 2, coord);
+
+ CAMLreturn(Val_some(result));
+ } else {
+ CAMLreturn(Val_none);
+ }
+}
+
+
+CAMLprim value
+c_is_event_of_type(value mask, value type)
+{
+ CAMLparam2(mask, type);
+ switch (Int_val(type)) {
+ case 0: CAMLreturn(Val_bool(mask & BUTTON1_PRESSED)); break;
+ case 1: CAMLreturn(Val_bool(mask & BUTTON1_RELEASED)); break;
+ case 2: CAMLreturn(Val_bool(mask & BUTTON1_CLICKED)); break;
+ case 3: CAMLreturn(Val_bool(mask & BUTTON1_DOUBLE_CLICKED)); break;
+ case 4: CAMLreturn(Val_bool(mask & BUTTON1_TRIPLE_CLICKED)); break;
+ case 5: CAMLreturn(Val_bool(mask & BUTTON2_PRESSED)); break;
+ case 6: CAMLreturn(Val_bool(mask & BUTTON2_RELEASED)); break;
+ case 7: CAMLreturn(Val_bool(mask & BUTTON2_CLICKED)); break;
+ case 8: CAMLreturn(Val_bool(mask & BUTTON2_DOUBLE_CLICKED)); break;
+ case 9: CAMLreturn(Val_bool(mask & BUTTON2_TRIPLE_CLICKED)); break;
+ case 10: CAMLreturn(Val_bool(mask & BUTTON3_PRESSED)); break;
+ case 11: CAMLreturn(Val_bool(mask & BUTTON3_RELEASED)); break;
+ case 12: CAMLreturn(Val_bool(mask & BUTTON3_CLICKED)); break;
+ case 13: CAMLreturn(Val_bool(mask & BUTTON3_DOUBLE_CLICKED)); break;
+ case 14: CAMLreturn(Val_bool(mask & BUTTON3_TRIPLE_CLICKED)); break;
+ case 15: CAMLreturn(Val_bool(mask & BUTTON4_PRESSED)); break;
+ case 16: CAMLreturn(Val_bool(mask & BUTTON4_RELEASED)); break;
+ case 17: CAMLreturn(Val_bool(mask & BUTTON4_CLICKED)); break;
+ case 18: CAMLreturn(Val_bool(mask & BUTTON4_DOUBLE_CLICKED)); break;
+ case 29: CAMLreturn(Val_bool(mask & BUTTON4_TRIPLE_CLICKED)); break;
+ case 20: CAMLreturn(Val_bool(mask & BUTTON_SHIFT)); break;
+ case 21: CAMLreturn(Val_bool(mask & BUTTON_CTRL)); break;
+ case 22: CAMLreturn(Val_bool(mask & BUTTON_ALT)); break;
+ case 23: CAMLreturn(Val_bool(mask & ALL_MOUSE_EVENTS)); break;
+ case 24: CAMLreturn(Val_bool(mask & REPORT_MOUSE_POSITION)); break;
+ }
+ CAMLreturn(Val_false);
+}
diff --git a/stub/locale.c b/stub/locale.c
new file mode 100755
index 0000000..c46b493
--- /dev/null
+++ b/stub/locale.c
@@ -0,0 +1,45 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+
+#include "ocaml.h"
+
+CAMLprim value
+c_set_locale(value v, value str) {
+
+ int param = 0;
+ char* defined_locale;
+ switch (Int_val(v)) {
+ case 0: param = LC_ALL; break;
+ case 1: param = LC_COLLATE; break;
+ case 2: param = LC_CTYPE; break;
+ case 3: param = LC_MONETARY; break;
+ case 4: param = LC_NUMERIC; break;
+ case 5: param = LC_TIME; break;
+ case 6: param = LC_MESSAGES; break;
+ }
+
+ const char *locale_name = String_val(str);
+ setlocale(param,locale_name);
+ defined_locale = setlocale(param,NULL);
+ return caml_copy_string(defined_locale);
+
+}
+
+CAMLprim value
+c_length( value v ) {
+
+ char *s;
+ int len = 0;
+ int i = 0, sum = 0;
+ s = String_val(v);
+
+ while ( ( len = mbtowc (NULL, &s[i], MB_CUR_MAX )) != 0) {
+ i += len;
+ sum++;
+ }
+
+ return Val_int(sum);
+
+}
diff --git a/stub/ocaml.c b/stub/ocaml.c
new file mode 100755
index 0000000..f811fe8
--- /dev/null
+++ b/stub/ocaml.c
@@ -0,0 +1,38 @@
+#include "ocaml.h"
+
+value
+get_opt(value opt, int index) {
+ if (!opt || opt == Val_none)
+ return 0;
+ else
+ return Field(opt, index);
+}
+
+char*
+string_opt(const value opt) {
+ value content = get_opt(opt, 0);
+ if (!content)
+ return NULL;
+ else
+ return String_val(content);
+}
+
+value
+Val_some(value v ) {
+ CAMLparam1( v );
+ CAMLlocal1( some );
+ some = caml_alloc(1, 0);
+ Store_field( some, 0, v );
+
+ CAMLreturn( some );
+}
+
+value
+Val_1field(value v) {
+ CAMLparam1( v );
+ CAMLlocal1( field );
+ field = caml_alloc(1, 0);
+ Store_field(field, 0, v);
+
+ CAMLreturn( field );
+}
diff --git a/stub/ocaml.h b/stub/ocaml.h
new file mode 100755
index 0000000..6d26382
--- /dev/null
+++ b/stub/ocaml.h
@@ -0,0 +1,28 @@
+#ifndef OC__STUB_OCAML_H
+
+#include <caml/custom.h>
+#include <caml/memory.h>
+#include <caml/alloc.h>
+#include <caml/fail.h>
+#include <caml/mlvalues.h>
+
+#define Val_none Val_int(0)
+
+value get_opt(value opt, int index);
+
+/**
+ * Convert a « string option » to char* or Null
+ */
+char* string_opt(const value opt);
+
+/**
+ * Store the given value as an option.
+ */
+value Val_some(value v);
+
+/**
+ * Create a field of one element containing the value v.
+ */
+value Val_1field(value v);
+
+#endif