From ef312564ca84a2b49fc291434d8fb2f8501bb618 Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Tue, 15 Nov 2016 13:00:01 +0100 Subject: Initial commit --- stub/Makefile | 22 ++++++++++++ stub/curses.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ stub/locale.c | 45 ++++++++++++++++++++++++ stub/ocaml.c | 38 ++++++++++++++++++++ stub/ocaml.h | 28 +++++++++++++++ 5 files changed, 244 insertions(+) create mode 100755 stub/Makefile create mode 100755 stub/curses.c create mode 100755 stub/locale.c create mode 100755 stub/ocaml.c create mode 100755 stub/ocaml.h (limited to 'stub') 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 + +#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 +#include +#include +#include + +#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 +#include +#include +#include +#include + +#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 -- cgit v1.2.3