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

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