| [2015] | 1 | /* |
|---|
| 2 | * libcaca Ruby bindings |
|---|
| [4369] | 3 | * Copyright (c) 2007-2010 Pascal Terjan <pterjan@linuxfr.org> |
|---|
| [2015] | 4 | * |
|---|
| 5 | * This library is free software. It comes without any warranty, to |
|---|
| 6 | * the extent permitted by applicable law. You can redistribute it |
|---|
| 7 | * and/or modify it under the terms of the Do What The Fuck You Want |
|---|
| 8 | * To Public License, Version 2, as published by Sam Hocevar. See |
|---|
| 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. |
|---|
| 10 | */ |
|---|
| 11 | |
|---|
| 12 | #include <ruby.h> |
|---|
| 13 | #include <caca.h> |
|---|
| 14 | #include <errno.h> |
|---|
| [2017] | 15 | #include "caca-event.h" |
|---|
| [2821] | 16 | #include "caca-canvas.h" |
|---|
| [2015] | 17 | #include "common.h" |
|---|
| 18 | |
|---|
| 19 | VALUE cDisplay; |
|---|
| 20 | |
|---|
| 21 | void display_free(void *display) |
|---|
| 22 | { |
|---|
| 23 | caca_free_display((caca_display_t *)display); |
|---|
| 24 | } |
|---|
| 25 | |
|---|
| 26 | static VALUE display_alloc(VALUE klass) |
|---|
| 27 | { |
|---|
| 28 | VALUE obj; |
|---|
| [3157] | 29 | obj = Data_Wrap_Struct(klass, 0, display_free, NULL); |
|---|
| [2015] | 30 | return obj; |
|---|
| 31 | } |
|---|
| 32 | |
|---|
| [2092] | 33 | static VALUE display_initialize(int argc, VALUE* argv, VALUE self) |
|---|
| [2015] | 34 | { |
|---|
| 35 | caca_display_t *display; |
|---|
| [2821] | 36 | caca_canvas_t *canvas = NULL; |
|---|
| [2296] | 37 | const char *driver = NULL; |
|---|
| 38 | VALUE cv = Qnil; |
|---|
| 39 | VALUE arg1, arg2; |
|---|
| [2092] | 40 | |
|---|
| [2296] | 41 | rb_scan_args(argc, argv, "02", &arg1, &arg2); |
|---|
| [2092] | 42 | |
|---|
| [2296] | 43 | if(CLASS_OF(arg1) == cCanvas) |
|---|
| [2015] | 44 | { |
|---|
| [2296] | 45 | cv = arg1; |
|---|
| 46 | if(CLASS_OF(arg2) == cCanvas) |
|---|
| 47 | { |
|---|
| [2822] | 48 | rb_raise(rb_eArgError, "Only one argument can be a Caca::Canvas"); |
|---|
| [2296] | 49 | } |
|---|
| [2015] | 50 | } |
|---|
| [2296] | 51 | else if(CLASS_OF(arg2) == cCanvas) |
|---|
| [2092] | 52 | { |
|---|
| [2296] | 53 | cv = arg2; |
|---|
| 54 | } |
|---|
| 55 | |
|---|
| [2298] | 56 | if(TYPE(arg1) == T_STRING) |
|---|
| [2296] | 57 | { |
|---|
| 58 | driver = StringValuePtr(arg1); |
|---|
| [2298] | 59 | if(TYPE(arg2) == T_STRING) |
|---|
| [2092] | 60 | { |
|---|
| [2296] | 61 | rb_raise(rb_eArgError, "Only one argument can be a string"); |
|---|
| [2092] | 62 | } |
|---|
| [2296] | 63 | } |
|---|
| [2298] | 64 | else if(TYPE(arg2) == T_STRING) |
|---|
| [2296] | 65 | { |
|---|
| 66 | driver = StringValuePtr(arg2); |
|---|
| 67 | } |
|---|
| [2015] | 68 | |
|---|
| [2296] | 69 | if(cv != Qnil) |
|---|
| 70 | canvas = DATA_PTR(cv); |
|---|
| 71 | |
|---|
| 72 | if(driver == NULL) |
|---|
| 73 | { |
|---|
| 74 | display = caca_create_display(canvas); |
|---|
| [3582] | 75 | if(display && NIL_P(cv)) |
|---|
| 76 | { |
|---|
| [2296] | 77 | cv = canvas_create(caca_get_canvas(display)); |
|---|
| [3582] | 78 | } |
|---|
| [2092] | 79 | } |
|---|
| [2296] | 80 | else |
|---|
| 81 | { |
|---|
| 82 | display = caca_create_display_with_driver(canvas, driver); |
|---|
| 83 | } |
|---|
| [2092] | 84 | |
|---|
| [2015] | 85 | if(display == NULL) |
|---|
| 86 | { |
|---|
| 87 | rb_raise(rb_eRuntimeError, strerror(errno)); |
|---|
| 88 | } |
|---|
| 89 | |
|---|
| 90 | _SELF = display; |
|---|
| 91 | |
|---|
| [2093] | 92 | rb_iv_set(self, "@canvas", cv); |
|---|
| 93 | |
|---|
| [2015] | 94 | return self; |
|---|
| 95 | } |
|---|
| 96 | |
|---|
| 97 | static VALUE display_refresh(VALUE self) |
|---|
| 98 | { |
|---|
| 99 | caca_refresh_display(_SELF); |
|---|
| 100 | return self; |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | static VALUE set_time(VALUE self, VALUE t) |
|---|
| 104 | { |
|---|
| 105 | caca_set_display_time(_SELF, UINT2NUM(t)); |
|---|
| 106 | return t; |
|---|
| 107 | } |
|---|
| 108 | |
|---|
| 109 | static VALUE set_time2(VALUE self, VALUE t) |
|---|
| 110 | { |
|---|
| 111 | set_time(self, t); |
|---|
| 112 | return self; |
|---|
| 113 | } |
|---|
| 114 | |
|---|
| 115 | static VALUE get_time(VALUE self) |
|---|
| 116 | { |
|---|
| 117 | return NUM2UINT(caca_get_display_time(_SELF)); |
|---|
| 118 | } |
|---|
| 119 | |
|---|
| 120 | static VALUE get_width(VALUE self) |
|---|
| 121 | { |
|---|
| 122 | return NUM2UINT(caca_get_display_width(_SELF)); |
|---|
| 123 | } |
|---|
| 124 | |
|---|
| 125 | static VALUE get_height(VALUE self) |
|---|
| 126 | { |
|---|
| 127 | return NUM2UINT(caca_get_display_height(_SELF)); |
|---|
| 128 | } |
|---|
| 129 | |
|---|
| 130 | static VALUE set_title(VALUE self, VALUE t) |
|---|
| 131 | { |
|---|
| 132 | if(caca_set_display_title(_SELF, StringValuePtr(t))<0) |
|---|
| 133 | { |
|---|
| 134 | rb_raise(rb_eRuntimeError, strerror(errno)); |
|---|
| 135 | } |
|---|
| 136 | return t; |
|---|
| 137 | } |
|---|
| 138 | |
|---|
| 139 | static VALUE set_title2(VALUE self, VALUE t) |
|---|
| 140 | { |
|---|
| 141 | set_title(self, t); |
|---|
| 142 | return self; |
|---|
| 143 | } |
|---|
| 144 | |
|---|
| [2017] | 145 | static VALUE get_mouse_x(VALUE self) |
|---|
| 146 | { |
|---|
| 147 | return NUM2UINT(caca_get_mouse_x(_SELF)); |
|---|
| 148 | } |
|---|
| 149 | |
|---|
| 150 | static VALUE get_mouse_y(VALUE self) |
|---|
| 151 | { |
|---|
| 152 | return NUM2UINT(caca_get_mouse_y(_SELF)); |
|---|
| 153 | } |
|---|
| 154 | |
|---|
| 155 | static VALUE set_mouse(VALUE self, VALUE visible) |
|---|
| 156 | { |
|---|
| 157 | caca_set_display_time(_SELF, visible); |
|---|
| 158 | return visible; |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | static VALUE set_mouse2(VALUE self, VALUE visible) |
|---|
| 162 | { |
|---|
| 163 | set_mouse(self, visible); |
|---|
| 164 | return self; |
|---|
| 165 | } |
|---|
| 166 | |
|---|
| 167 | static VALUE get_event(VALUE self, VALUE event_mask, VALUE timeout) |
|---|
| 168 | { |
|---|
| [2051] | 169 | char utf8[8]; |
|---|
| [2017] | 170 | caca_event_t ev; |
|---|
| [2019] | 171 | VALUE e; |
|---|
| 172 | |
|---|
| [2020] | 173 | event_mask = rb_funcall(event_mask, rb_intern("to_i"), 0); |
|---|
| 174 | |
|---|
| [2017] | 175 | if(caca_get_event(_SELF, NUM2UINT(event_mask), &ev, NUM2INT(timeout)) == 0) |
|---|
| 176 | { |
|---|
| 177 | return Qnil; |
|---|
| 178 | } |
|---|
| [2019] | 179 | |
|---|
| [2051] | 180 | switch(caca_get_event_type(&ev)) |
|---|
| [2019] | 181 | { |
|---|
| 182 | case CACA_EVENT_KEY_PRESS: |
|---|
| [2051] | 183 | caca_get_event_key_utf8(&ev, utf8); |
|---|
| [2019] | 184 | e = rb_funcall(cEventKeyPress, rb_intern("new"), 3, |
|---|
| [2051] | 185 | UINT2NUM(caca_get_event_key_ch(&ev)), |
|---|
| 186 | ULONG2NUM(caca_get_event_key_utf32(&ev)), |
|---|
| 187 | rb_str_new(utf8, 8)); |
|---|
| [2019] | 188 | break; |
|---|
| 189 | case CACA_EVENT_KEY_RELEASE: |
|---|
| [2051] | 190 | caca_get_event_key_utf8(&ev, utf8); |
|---|
| [2019] | 191 | e = rb_funcall(cEventKeyRelease, rb_intern("new"), 3, |
|---|
| [2051] | 192 | UINT2NUM(caca_get_event_key_ch(&ev)), |
|---|
| 193 | ULONG2NUM(caca_get_event_key_utf32(&ev)), |
|---|
| 194 | rb_str_new(utf8, 8)); |
|---|
| [2019] | 195 | break; |
|---|
| 196 | case CACA_EVENT_MOUSE_PRESS: |
|---|
| 197 | e = rb_funcall(cEventMousePress, rb_intern("new"), 3, |
|---|
| [2051] | 198 | UINT2NUM(caca_get_event_mouse_x(&ev)), |
|---|
| 199 | UINT2NUM(caca_get_event_mouse_y(&ev)), |
|---|
| 200 | UINT2NUM(caca_get_event_mouse_button(&ev))); |
|---|
| [2019] | 201 | break; |
|---|
| 202 | case CACA_EVENT_MOUSE_RELEASE: |
|---|
| 203 | e = rb_funcall(cEventMouseRelease, rb_intern("new"), 3, |
|---|
| [2051] | 204 | UINT2NUM(caca_get_event_mouse_x(&ev)), |
|---|
| 205 | UINT2NUM(caca_get_event_mouse_y(&ev)), |
|---|
| 206 | UINT2NUM(caca_get_event_mouse_button(&ev))); |
|---|
| [2019] | 207 | break; |
|---|
| 208 | case CACA_EVENT_MOUSE_MOTION: |
|---|
| 209 | e = rb_funcall(cEventMouseMotion, rb_intern("new"), 3, |
|---|
| [2051] | 210 | UINT2NUM(caca_get_event_mouse_x(&ev)), |
|---|
| 211 | UINT2NUM(caca_get_event_mouse_y(&ev)), |
|---|
| [2019] | 212 | Qnil); |
|---|
| 213 | break; |
|---|
| 214 | case CACA_EVENT_RESIZE: |
|---|
| 215 | e = rb_funcall(cEventResize, rb_intern("new"), 2, |
|---|
| [2051] | 216 | UINT2NUM(caca_get_event_resize_width(&ev)), |
|---|
| 217 | UINT2NUM(caca_get_event_resize_height(&ev))); |
|---|
| [2019] | 218 | break; |
|---|
| 219 | case CACA_EVENT_QUIT: |
|---|
| 220 | e = rb_funcall(cEventQuit, rb_intern("new"), 0); |
|---|
| 221 | break; |
|---|
| 222 | default: |
|---|
| 223 | rb_raise(rb_eRuntimeError, "Invalid event received !"); |
|---|
| 224 | } |
|---|
| 225 | |
|---|
| 226 | return e; |
|---|
| [2017] | 227 | } |
|---|
| 228 | |
|---|
| [2296] | 229 | static VALUE driver_list(void) |
|---|
| 230 | { |
|---|
| 231 | VALUE ary; |
|---|
| 232 | char const* const* list; |
|---|
| [3157] | 233 | |
|---|
| [2296] | 234 | list = caca_get_display_driver_list(); |
|---|
| [3157] | 235 | |
|---|
| 236 | ary = rb_hash_new(); |
|---|
| 237 | while (*list != NULL && *(list+1) != NULL) |
|---|
| [2296] | 238 | { |
|---|
| [3157] | 239 | rb_hash_aset(ary, rb_str_new2(*list), rb_str_new2(*(list+1))); |
|---|
| 240 | list+=2; |
|---|
| [2296] | 241 | } |
|---|
| 242 | |
|---|
| 243 | return ary; |
|---|
| 244 | } |
|---|
| 245 | |
|---|
| 246 | static VALUE get_driver(VALUE self) |
|---|
| 247 | { |
|---|
| 248 | return rb_str_new2(caca_get_display_driver(_SELF)); |
|---|
| 249 | } |
|---|
| 250 | |
|---|
| 251 | static VALUE set_driver(VALUE self, VALUE driver) |
|---|
| 252 | { |
|---|
| 253 | if(caca_set_display_driver(_SELF, StringValuePtr(driver))<0) |
|---|
| 254 | { |
|---|
| 255 | rb_raise(rb_eRuntimeError, strerror(errno)); |
|---|
| 256 | } |
|---|
| 257 | return driver; |
|---|
| 258 | } |
|---|
| 259 | |
|---|
| 260 | static VALUE set_driver2(VALUE self, VALUE driver) |
|---|
| 261 | { |
|---|
| 262 | set_driver(self, driver); |
|---|
| 263 | return self; |
|---|
| 264 | } |
|---|
| 265 | |
|---|
| [4786] | 266 | static VALUE set_cursor(VALUE self, VALUE flag) |
|---|
| 267 | { |
|---|
| 268 | if(caca_set_cursor(_SELF, flag)<0) |
|---|
| 269 | { |
|---|
| 270 | rb_raise(rb_eRuntimeError, strerror(errno)); |
|---|
| 271 | } |
|---|
| 272 | return flag; |
|---|
| 273 | } |
|---|
| 274 | |
|---|
| 275 | static VALUE set_cursor2(VALUE self, VALUE flag) |
|---|
| 276 | { |
|---|
| 277 | set_cursor(self, flag); |
|---|
| 278 | return self; |
|---|
| 279 | } |
|---|
| 280 | |
|---|
| [2015] | 281 | void Init_caca_display(VALUE mCaca) |
|---|
| 282 | { |
|---|
| 283 | cDisplay = rb_define_class_under(mCaca, "Display", rb_cObject); |
|---|
| 284 | rb_define_alloc_func(cDisplay, display_alloc); |
|---|
| 285 | |
|---|
| [2296] | 286 | rb_define_singleton_method(cDisplay, "driver_list", driver_list, 0); |
|---|
| 287 | |
|---|
| [2092] | 288 | rb_define_method(cDisplay, "initialize", display_initialize, -1); |
|---|
| [2015] | 289 | rb_define_method(cDisplay, "refresh", display_refresh, 0); |
|---|
| 290 | rb_define_method(cDisplay, "time=", set_time, 1); |
|---|
| 291 | rb_define_method(cDisplay, "set_time", set_time2, 1); |
|---|
| 292 | rb_define_method(cDisplay, "time", get_time, 0); |
|---|
| 293 | rb_define_method(cDisplay, "width", get_width, 0); |
|---|
| 294 | rb_define_method(cDisplay, "height", get_height, 0); |
|---|
| 295 | rb_define_method(cDisplay, "title=", set_title, 1); |
|---|
| 296 | rb_define_method(cDisplay, "set_title", set_title2, 1); |
|---|
| [2017] | 297 | rb_define_method(cDisplay, "mouse_x", get_mouse_x, 0); |
|---|
| 298 | rb_define_method(cDisplay, "mouse_y", get_mouse_y, 0); |
|---|
| 299 | rb_define_method(cDisplay, "mouse=", set_mouse, 1); |
|---|
| [2296] | 300 | rb_define_method(cDisplay, "driver", get_driver, 0); |
|---|
| 301 | rb_define_method(cDisplay, "set_driver", set_driver2, 1); |
|---|
| 302 | rb_define_method(cDisplay, "driver=", set_driver, 1); |
|---|
| [2017] | 303 | rb_define_method(cDisplay, "set_mouse", set_mouse2, 1); |
|---|
| [2019] | 304 | rb_define_method(cDisplay, "get_event", get_event, 2); |
|---|
| [4786] | 305 | rb_define_method(cDisplay, "cursor=", set_cursor, 1); |
|---|
| 306 | rb_define_method(cDisplay, "set_cursor", set_cursor2, 1); |
|---|
| [2015] | 307 | } |
|---|