Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

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