diff --git a/Makefile b/Makefile index 24766b4..b5f2e1d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ current_dir := $(shell pwd) CSRCS := $(wildcard tools/xkremap/*.[ch]) -RBSRCS := $(wildcard mrblib/xkremap/*.rb) +MRBSRCS := $(wildcard mrblib/xkremap/*.rb) +MRBCSRCS := $(wildcard src/*.[ch]) .PHONY: all all: xkremap @@ -12,5 +13,5 @@ mruby: curl -L --fail --retry 3 --retry-delay 1 https://github.com/mruby/mruby/archive/1.2.0.tar.gz -s -o - | tar zxf - mv mruby-1.2.0 $@ -mruby/build/host/bin/xkremap: mruby build_config.rb $(CSRCS) $(RBSRCS) +mruby/build/host/bin/xkremap: mruby build_config.rb $(CSRCS) $(MRBSRCS) $(MRBCSRCS) cd mruby && MRUBY_CONFIG="$(current_dir)/build_config.rb" make diff --git a/mrblib/xkremap/event_handler.rb b/mrblib/xkremap/event_handler.rb index 8a6f5a3..fc379ac 100644 --- a/mrblib/xkremap/event_handler.rb +++ b/mrblib/xkremap/event_handler.rb @@ -5,7 +5,7 @@ module Xkremap def initialize(config, display) @config = config @display = display - # grab keys + XlibWrapper.grab_keys(@display) end def handle_key_press(keycode, state) diff --git a/src/display.c b/src/display.c new file mode 100644 index 0000000..904396d --- /dev/null +++ b/src/display.c @@ -0,0 +1,45 @@ +#include +#include "mruby.h" +#include "mruby/data.h" + +struct mrb_display { + Display *display; +}; + +static void +mrb_display_free(mrb_state *mrb, void *ptr) +{ + struct mrb_display *display = (struct mrb_display *)ptr; + if (display != NULL) { + mrb_free(mrb, display); + } +} + +struct mrb_data_type mrb_display_type = { "Display", mrb_display_free }; + +mrb_value +mrb_wrap_x_display(mrb_state *mrb, Display *display) +{ + struct RClass *mXkremap = mrb_module_get(mrb, "Xkremap"); + struct RClass *cDisplay = mrb_class_get_under(mrb, mXkremap, "Display"); + + struct mrb_display *display_ptr = (struct mrb_display *)mrb_malloc(mrb, sizeof(struct mrb_display)); + display_ptr->display = display; + mrb_value display_obj = mrb_obj_value(mrb_data_object_alloc(mrb, cDisplay, NULL, &mrb_display_type)); + DATA_TYPE(display_obj) = &mrb_display_type; + DATA_PTR(display_obj) = display_ptr; + return display_obj; +} + +Display* +extract_x_display(mrb_state *mrb, mrb_value display_obj) +{ + struct mrb_display *display_ptr = (struct mrb_display *)mrb_get_datatype(mrb, display_obj, &mrb_display_type); + return display_ptr->display; +} + +void +mrb_xkremap_display_init(mrb_state *mrb, struct RClass *mXkremap) +{ + mrb_define_class_under(mrb, mXkremap, "Display", mrb->object_class); +} diff --git a/src/xkremap_gem.c b/src/xkremap_gem.c new file mode 100644 index 0000000..5fd8f17 --- /dev/null +++ b/src/xkremap_gem.c @@ -0,0 +1,20 @@ +#include "mruby.h" + +extern void mrb_mruby_xkremap_gem_init(mrb_state *mrb); +extern void mrb_xkremap_xlib_wrapper_init(mrb_state *mrb, struct RClass *mXkremap); +extern void mrb_xkremap_display_init(mrb_state *mrb, struct RClass *mXkremap); + +void +mrb_xkremap_gem_init(mrb_state *mrb) +{ + struct RClass *mXkremap = mrb_define_module(mrb, "Xkremap"); + + mrb_xkremap_xlib_wrapper_init(mrb, mXkremap); + mrb_xkremap_display_init(mrb, mXkremap); + mrb_gc_arena_restore(mrb, 0); +} + +void +mrb_xkremap_gem_final(mrb_state *mrb) +{ +} diff --git a/src/xlib_wrapper.c b/src/xlib_wrapper.c new file mode 100644 index 0000000..7004160 --- /dev/null +++ b/src/xlib_wrapper.c @@ -0,0 +1,25 @@ +#include +#include +#include "mruby.h" + +extern Display* extract_x_display(mrb_state *mrb, mrb_value display_obj); + +mrb_value +mrb_xw_grab_keys(mrb_state *mrb, mrb_value self) +{ + mrb_value display_obj; + mrb_get_args(mrb, "o", &display_obj); + Display *display = extract_x_display(mrb, display_obj); + + Window root = XDefaultRootWindow(display); + XGrabKey(display, XKeysymToKeycode(display, XK_b), ControlMask, root, True, GrabModeAsync, GrabModeAsync); + + return mrb_nil_value(); +} + +void +mrb_xkremap_xlib_wrapper_init(mrb_state *mrb, struct RClass *mXkremap) +{ + struct RClass *cXlibWrapper = mrb_define_class_under(mrb, mXkremap, "XlibWrapper", mrb->object_class); + mrb_define_class_method(mrb, cXlibWrapper, "grab_keys", mrb_xw_grab_keys, MRB_ARGS_REQ(1)); +} diff --git a/tools/xkremap/event_handler.c b/tools/xkremap/event_handler.c index 745dadc..2704bda 100644 --- a/tools/xkremap/event_handler.c +++ b/tools/xkremap/event_handler.c @@ -1,12 +1,15 @@ #include #include +extern mrb_value mrb_wrap_x_display(mrb_state *mrb, Display *display); + mrb_value new_event_handler(mrb_state *mrb, mrb_value config, Display *display) { struct RClass *mXkremap = mrb_module_get(mrb, "Xkremap"); struct RClass *cEventHandler = mrb_class_get_under(mrb, mXkremap, "EventHandler"); - return mrb_funcall(mrb, mrb_obj_value(cEventHandler), "new", 2, config, mrb_nil_value()); + mrb_value display_obj = mrb_wrap_x_display(mrb, display); + return mrb_funcall(mrb, mrb_obj_value(cEventHandler), "new", 2, config, display_obj); } void