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

Last change on this file since 2040 was 2040, checked in by Sam Hocevar, 13 years ago
  • Rename _cucul_set_canvas_size into cucul_set_canvas_size to prevent collisions due to symbol mangling.
  • Property svn:keywords set to Id
File size: 7.2 KB
RevLine 
[35]1/*
[672]2 *  libcaca       Colour ASCII-Art library
[527]3 *  Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
[268]4 *                All Rights Reserved
[35]5 *
[769]6 *  $Id: graphics.c 2040 2007-11-23 22:34:35Z sam $
7 *
[1462]8 *  This library is free software. It comes without any warranty, to
[1452]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
[522]12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
[35]13 */
[17]14
[769]15/*
[268]16 *  This file contains character and string drawing functions.
[205]17 */
18
[63]19#include "config.h"
[859]20#include "common.h"
[63]21
[1392]22#if !defined(__KERNEL__)
23#   include <stdio.h>
24#   include <stdlib.h>
25#   include <string.h>
26#endif
27
[185]28#include "caca.h"
29#include "caca_internals.h"
[524]30#include "cucul.h"
31#include "cucul_internals.h"
[17]32
[819]33/** \brief Set the display title.
[343]34 *
35 *  If libcaca runs in a window, try to change its title. This works with
[1391]36 *  the ncurses, S-Lang, OpenGL, X11 and Win32 drivers.
[343]37 *
[1006]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 *
[964]41 *  \param dp The libcaca display context.
[819]42 *  \param title The desired display title.
[1006]43 *  \return 0 upon success, -1 if an error occurred.
[343]44 */
[819]45int caca_set_display_title(caca_display_t *dp, char const *title)
[343]46{
[1006]47    int ret = dp->drv.set_display_title(dp, title);
48
49    if(ret)
[1362]50        seterrno(ENOSYS);
[1006]51
52    return ret;
[343]53}
54
[819]55/** \brief Get the display width.
[352]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
[582]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.
[352]61 *
[1006]62 *  This function never fails.
63 *
[964]64 *  \param dp The libcaca display context.
[819]65 *  \return The display width.
[352]66 */
[819]67unsigned int caca_get_display_width(caca_display_t *dp)
[352]68{
[819]69    return dp->drv.get_display_width(dp);
[352]70}
71
[819]72/** \brief Get the display height.
[352]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 *
[1006]79 *  This function never fails.
80 *
[964]81 *  \param dp The libcaca display context.
[819]82 *  \return The display height.
[352]83 */
[819]84unsigned int caca_get_display_height(caca_display_t *dp)
[352]85{
[819]86    return dp->drv.get_display_height(dp);
[352]87}
88
[268]89/** \brief Set the refresh delay.
[257]90 *
[1231]91 *  Set the refresh delay in microseconds. The refresh delay is used by
92 *  caca_refresh_display() to achieve constant framerate. See the
[819]93 *  caca_refresh_display() documentation for more details.
[268]94 *
95 *  If the argument is zero, constant framerate is disabled. This is the
96 *  default behaviour.
97 *
[1006]98 *  This function never fails.
99 *
[964]100 *  \param dp The libcaca display context.
[268]101 *  \param usec The refresh delay in microseconds.
[1006]102 *  \return This function always returns 0.
[257]103 */
[1006]104int caca_set_display_time(caca_display_t *dp, unsigned int usec)
[227]105{
[811]106    dp->delay = usec;
[1006]107    return 0;
[227]108}
109
[964]110/** \brief Get the display's average rendering time.
[257]111 *
[1231]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.
[268]117 *
[1006]118 *  This function never fails.
119 *
[964]120 *  \param dp The libcaca display context.
[268]121 *  \return The render time in microseconds.
[257]122 */
[964]123unsigned int caca_get_display_time(caca_display_t *dp)
[227]124{
[811]125    return dp->rendertime;
[227]126}
127
[268]128/** \brief Flush pending changes and redraw the screen.
[257]129 *
[1231]130 *  Flush all graphical operations and print them to the display device.
131 *  Nothing will show on the screen until this function is called.
[268]132 *
[964]133 *  If caca_set_display_time() was called with a non-zero value,
[819]134 *  caca_refresh_display() will use that value to achieve constant
[964]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(),
[819]137 *  the second call will be delayed before performing the screen refresh.
[773]138 *
[1006]139 *  This function never fails.
140 *
[964]141 *  \param dp The libcaca display context.
[1006]142 *  \return This function always returns 0.
[257]143 */
[1006]144int caca_refresh_display(caca_display_t *dp)
[227]145{
[322]146#if !defined(_DOXYGEN_SKIP_ME)
[985]147#define IDLE_USEC 5000
[322]148#endif
[811]149    int ticks = dp->lastticks + _caca_getticks(&dp->timer);
[227]150
[811]151    dp->drv.display(dp);
[261]152
[553]153    /* Once the display is finished, we can ack resizes */
[811]154    if(dp->resize.resized)
[349]155    {
[811]156        dp->resize.resized = 0;
157        _caca_handle_resize(dp);
[349]158    }
[347]159
[811]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))
[331]165    {
[335]166        _caca_sleep(IDLE_USEC);
[331]167    }
[227]168
169    /* Update the sliding mean of the render time */
[811]170    dp->rendertime = (7 * dp->rendertime + ticks) / 8;
[227]171
[811]172    dp->lastticks = ticks - dp->delay;
[227]173
174    /* If we drifted too much, it's bad, bad, bad. */
[811]175    if(dp->lastticks > (int)dp->delay)
176        dp->lastticks = 0;
[1006]177
178    return 0;
[227]179}
180
[1430]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
[689]206/** \brief Show or hide the mouse pointer.
[686]207 *
[1839]208 *  Show or hide the mouse pointer. This function works with the ncurses,
209 *  S-Lang and X11 drivers.
[686]210 *
[1006]211 *  If an error occurs, -1 is returned and \b errno is set accordingly:
212 *  - \c ENOSYS Display driver does not support hiding the mouse pointer.
213 *
[964]214 *  \param dp The libcaca display context.
[689]215 *  \param flag 0 hides the pointer, 1 shows the system's default pointer
216 *              (usually an arrow). Other values are reserved for future use.
[1006]217 *  \return 0 upon success, -1 if an error occurred.
[686]218 */
[1006]219int caca_set_mouse(caca_display_t *dp, int flag)
[686]220{
[1006]221    if(!dp->drv.set_mouse)
222    {
[1362]223        seterrno(ENOSYS);
[1006]224        return -1;
225    }
226
227    dp->drv.set_mouse(dp, flag);
228    return 0;
[686]229}
230
[347]231/*
[511]232 * XXX: following functions are local
[347]233 */
[524]234
[811]235void _caca_handle_resize(caca_display_t *dp)
[347]236{
[811]237    dp->drv.handle_resize(dp);
[347]238
[527]239    /* Tell libcucul we changed size */
[811]240    if(dp->resize.w != dp->cv->width || dp->resize.h != dp->cv->height)
[2040]241        __cucul_set_canvas_size(dp->cv, dp->resize.w, dp->resize.h);
[347]242}
243
[1392]244void _caca_set_term_title(char const *str)
245{
246#if defined(HAVE_GETENV)
247    char *term;
248
249    term = getenv("TERM");
250
251    if(!term || !strcmp(term, "linux"))
252        return;
253#endif
254
255    fprintf(stdout, "\x1b]0;%s\x07", str);
256    fflush(stdout);
257}
258
Note: See TracBrowser for help on using the repository browser.