You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

308 line
7.8 KiB

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