source: libcaca/trunk/caca/graphics.c @ 4333

Last change on this file since 4333 was 4333, checked in by Sam Hocevar, 10 years ago

Large source code cleanup, getting rid of spaces, tabs, and svn keywords.

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