Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

graphics.c 7.3 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * libcaca Colour ASCII-Art library
  3. * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This library is free software. It comes without any warranty, to
  9. * the extent permitted by applicable law. You can redistribute it
  10. * and/or modify it under the terms of the Do What The Fuck You Want
  11. * To Public License, Version 2, as published by Sam Hocevar. See
  12. * http://sam.zoy.org/wtfpl/COPYING for more details.
  13. */
  14. /*
  15. * This file contains character and string drawing functions.
  16. */
  17. #include "config.h"
  18. #include "common.h"
  19. #if !defined(__KERNEL__)
  20. # include <stdio.h>
  21. # include <stdlib.h>
  22. # include <string.h>
  23. #endif
  24. #include "cucul.h"
  25. #include "caca.h"
  26. #include "caca_internals.h"
  27. /** \brief Set the display title.
  28. *
  29. * If libcaca runs in a window, try to change its title. This works with
  30. * the ncurses, S-Lang, OpenGL, X11 and Win32 drivers.
  31. *
  32. * If an error occurs, -1 is returned and \b errno is set accordingly:
  33. * - \c ENOSYS Display driver does not support setting the window title.
  34. *
  35. * \param dp The libcaca display context.
  36. * \param title The desired display title.
  37. * \return 0 upon success, -1 if an error occurred.
  38. */
  39. int caca_set_display_title(caca_display_t *dp, char const *title)
  40. {
  41. int ret = dp->drv.set_display_title(dp, title);
  42. if(ret)
  43. seterrno(ENOSYS);
  44. return ret;
  45. }
  46. /** \brief Get the display width.
  47. *
  48. * If libcaca runs in a window, get the usable window width. This value can
  49. * be used for aspect ratio calculation. If libcaca does not run in a window
  50. * or if there is no way to know the font size, most drivers will assume a
  51. * 6x10 font is being used. Note that the units are not necessarily pixels.
  52. *
  53. * This function never fails.
  54. *
  55. * \param dp The libcaca display context.
  56. * \return The display width.
  57. */
  58. unsigned int caca_get_display_width(caca_display_t const *dp)
  59. {
  60. return dp->drv.get_display_width(dp);
  61. }
  62. /** \brief Get the display height.
  63. *
  64. * If libcaca runs in a window, get the usable window height. This value can
  65. * be used for aspect ratio calculation. If libcaca does not run in a window
  66. * or if there is no way to know the font size, assume a 6x10 font is being
  67. * used. Note that the units are not necessarily pixels.
  68. *
  69. * This function never fails.
  70. *
  71. * \param dp The libcaca display context.
  72. * \return The display height.
  73. */
  74. unsigned int caca_get_display_height(caca_display_t const *dp)
  75. {
  76. return dp->drv.get_display_height(dp);
  77. }
  78. /** \brief Set the refresh delay.
  79. *
  80. * Set the refresh delay in microseconds. The refresh delay is used by
  81. * caca_refresh_display() to achieve constant framerate. See the
  82. * caca_refresh_display() documentation for more details.
  83. *
  84. * If the argument is zero, constant framerate is disabled. This is the
  85. * default behaviour.
  86. *
  87. * This function never fails.
  88. *
  89. * \param dp The libcaca display context.
  90. * \param usec The refresh delay in microseconds.
  91. * \return This function always returns 0.
  92. */
  93. int caca_set_display_time(caca_display_t *dp, unsigned int usec)
  94. {
  95. dp->delay = usec;
  96. return 0;
  97. }
  98. /** \brief Get the display's average rendering time.
  99. *
  100. * Get the average rendering time, which is the average measured time
  101. * between two caca_refresh_display() calls, in microseconds. If constant
  102. * framerate was activated by calling caca_set_display_time(), the average
  103. * rendering time will be close to the requested delay even if the real
  104. * rendering time was shorter.
  105. *
  106. * This function never fails.
  107. *
  108. * \param dp The libcaca display context.
  109. * \return The render time in microseconds.
  110. */
  111. unsigned int caca_get_display_time(caca_display_t const *dp)
  112. {
  113. return dp->rendertime;
  114. }
  115. /** \brief Flush pending changes and redraw the screen.
  116. *
  117. * Flush all graphical operations and print them to the display device.
  118. * Nothing will show on the screen until this function is called.
  119. *
  120. * If caca_set_display_time() was called with a non-zero value,
  121. * caca_refresh_display() will use that value to achieve constant
  122. * framerate: if two consecutive calls to caca_refresh_display() are within
  123. * a time range shorter than the value set with caca_set_display_time(),
  124. * the second call will be delayed before performing the screen refresh.
  125. *
  126. * This function never fails.
  127. *
  128. * \param dp The libcaca display context.
  129. * \return This function always returns 0.
  130. */
  131. int caca_refresh_display(caca_display_t *dp)
  132. {
  133. #if !defined(_DOXYGEN_SKIP_ME)
  134. #define IDLE_USEC 5000
  135. #endif
  136. int ticks = dp->lastticks + _caca_getticks(&dp->timer);
  137. dp->drv.display(dp);
  138. /* Once the display is finished, we can ack resizes */
  139. if(dp->resize.resized)
  140. {
  141. dp->resize.resized = 0;
  142. _caca_handle_resize(dp);
  143. }
  144. /* Wait until dp->delay + time of last call */
  145. ticks += _caca_getticks(&dp->timer);
  146. for(ticks += _caca_getticks(&dp->timer);
  147. ticks + IDLE_USEC < (int)dp->delay;
  148. ticks += _caca_getticks(&dp->timer))
  149. {
  150. _caca_sleep(IDLE_USEC);
  151. }
  152. /* Update the sliding mean of the render time */
  153. dp->rendertime = (7 * dp->rendertime + ticks) / 8;
  154. dp->lastticks = ticks - dp->delay;
  155. /* If we drifted too much, it's bad, bad, bad. */
  156. if(dp->lastticks > (int)dp->delay)
  157. dp->lastticks = 0;
  158. return 0;
  159. }
  160. /** \brief Show or hide the cursor.
  161. *
  162. * Show or hide the cursor, for devices that support such a feature.
  163. *
  164. * If an error occurs, -1 is returned and \b errno is set accordingly:
  165. * - \c ENOSYS Display driver does not support showing the cursor.
  166. *
  167. * \param dp The libcaca display context.
  168. * \param flag 0 hides the cursor, 1 shows the system's default cursor
  169. * (usually a white rectangle). Other values are reserved for
  170. * future use.
  171. * \return 0 upon success, -1 if an error occurred.
  172. */
  173. int caca_set_cursor(caca_display_t *dp, int flag)
  174. {
  175. if(!dp->drv.set_cursor)
  176. {
  177. seterrno(ENOSYS);
  178. return -1;
  179. }
  180. dp->drv.set_cursor(dp, flag);
  181. return 0;
  182. }
  183. /** \brief Show or hide the mouse pointer.
  184. *
  185. * Show or hide the mouse pointer. This function works with the ncurses,
  186. * S-Lang and X11 drivers.
  187. *
  188. * If an error occurs, -1 is returned and \b errno is set accordingly:
  189. * - \c ENOSYS Display driver does not support hiding the mouse pointer.
  190. *
  191. * \param dp The libcaca display context.
  192. * \param flag 0 hides the pointer, 1 shows the system's default pointer
  193. * (usually an arrow). Other values are reserved for future use.
  194. * \return 0 upon success, -1 if an error occurred.
  195. */
  196. int caca_set_mouse(caca_display_t *dp, int flag)
  197. {
  198. if(!dp->drv.set_mouse)
  199. {
  200. seterrno(ENOSYS);
  201. return -1;
  202. }
  203. dp->drv.set_mouse(dp, flag);
  204. return 0;
  205. }
  206. /*
  207. * XXX: following functions are local
  208. */
  209. void _caca_handle_resize(caca_display_t *dp)
  210. {
  211. dp->drv.handle_resize(dp);
  212. /* Tell libcucul we changed size */
  213. if(dp->resize.w != cucul_get_canvas_width(dp->cv)
  214. || dp->resize.h != cucul_get_canvas_height(dp->cv))
  215. {
  216. dp->resize.allow = 1;
  217. cucul_set_canvas_size(dp->cv, dp->resize.w, dp->resize.h);
  218. dp->resize.allow = 0;
  219. }
  220. }
  221. void _caca_set_term_title(char const *str)
  222. {
  223. #if defined(HAVE_GETENV)
  224. char *term;
  225. term = getenv("TERM");
  226. if(!term || !strcmp(term, "linux"))
  227. return;
  228. #endif
  229. fprintf(stdout, "\x1b]0;%s\x07", str);
  230. fflush(stdout);
  231. }