diff options
author | Sébastien Dailly <sebastien@chimrod.com> | 2016-11-15 13:00:01 +0100 |
---|---|---|
committer | Sébastien Dailly <sebastien@chimrod.com> | 2016-11-15 13:00:01 +0100 |
commit | ef312564ca84a2b49fc291434d8fb2f8501bb618 (patch) | |
tree | 79415fcf225e6da1042c8edaae5e4a74c7a983cb /stub |
Initial commit
Diffstat (limited to 'stub')
-rwxr-xr-x | stub/Makefile | 22 | ||||
-rwxr-xr-x | stub/curses.c | 111 | ||||
-rwxr-xr-x | stub/locale.c | 45 | ||||
-rwxr-xr-x | stub/ocaml.c | 38 | ||||
-rwxr-xr-x | stub/ocaml.h | 28 |
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 |