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

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