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.
 
 
 
 
 
 

259 regels
7.2 KiB

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