source: libcaca/trunk/src/caca.c @ 257

Last change on this file since 257 was 257, checked in by Sam Hocevar, 17 years ago
  • src/: + Doxygenated public functions.
  • Property svn:keywords set to Id
File size: 9.3 KB
Line 
1/*
2 *   libcaca       ASCII-Art library
3 *   Copyright (c) 2002, 2003 Sam Hocevar <sam@zoy.org>
4 *                 All Rights Reserved
5 *
6 *   This library is free software; you can redistribute it and/or
7 *   modify it under the terms of the GNU Lesser General Public
8 *   License as published by the Free Software Foundation; either
9 *   version 2 of the License, or (at your option) any later version.
10 *
11 *   This library is distributed in the hope that it will be useful,
12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 *   Lesser General Public License for more details.
15 *
16 *   You should have received a copy of the GNU Lesser General Public
17 *   License along with this library; if not, write to the Free Software
18 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 *   02111-1307  USA
20 */
21
22/**  \file caca.c
23 *   \version \$Id: caca.c 257 2003-12-18 00:11:52Z sam $
24 *   \author Sam Hocevar <sam@zoy.org>
25 *   \brief Main \e libcaca functions
26 *
27 *   This file contains the main functions used by \e libcaca applications to
28 *   initialise the library, get the screen properties, set the framerate and
29 *   so on.
30 */
31
32#include "config.h"
33
34#if defined(USE_SLANG)
35#   include <slang.h>
36#elif defined(USE_NCURSES)
37#   include <curses.h>
38#elif defined(USE_CONIO)
39#   include <dos.h>
40#   include <conio.h>
41#elif defined(USE_X11)
42#   include <X11/Xlib.h>
43#else
44#   error "no graphics library detected"
45#endif
46
47#include <stdlib.h>
48#include <string.h>
49
50#include "caca.h"
51#include "caca_internals.h"
52
53static void caca_init_features(void);
54static void caca_init_terminal(void);
55
56#if defined(USE_NCURSES)
57static mmask_t oldmask;
58#endif
59
60/**
61 * \brief Initialise libcaca.
62 *
63 * \return 0 upon success, a non-zero value if an error occurs.
64 */
65int caca_init(void)
66{
67#if defined(USE_NCURSES)
68    mmask_t newmask;
69#endif
70
71    caca_init_features();
72    caca_init_terminal();
73
74#if defined(USE_SLANG)
75    /* Initialize slang library */
76    SLsig_block_signals();
77    SLtt_get_terminfo();
78
79    if(SLkp_init() == -1)
80    {
81        SLsig_unblock_signals();
82        return -1;
83    }
84
85    SLang_init_tty(-1, 0, 1);
86
87    if(SLsmg_init_smg() == -1)
88    {
89        SLsig_unblock_signals();
90        return -1;
91    }
92
93    SLsig_unblock_signals();
94
95    SLsmg_cls();
96    SLtt_set_cursor_visibility(0);
97    SLkp_define_keysym("\e[M", 1001);
98    SLtt_set_mouse_mode(1, 0);
99    SLsmg_refresh();
100
101    /* Disable scrolling so that hashmap scrolling optimization code
102     * does not cause ugly refreshes due to slow terminals */
103    SLtt_Term_Cannot_Scroll = 1;
104
105#elif defined(USE_NCURSES)
106    initscr();
107    keypad(stdscr, TRUE);
108    nonl();
109    cbreak();
110    noecho();
111    nodelay(stdscr, TRUE);
112    curs_set(0);
113
114    /* Activate mouse */
115    newmask = ALL_MOUSE_EVENTS;
116    mousemask(newmask, &oldmask);
117
118#elif defined(USE_CONIO)
119    _wscroll = 0;
120    _setcursortype(_NOCURSOR);
121    clrscr();
122
123#elif defined(USE_X11)
124    /* Nothing to do */
125
126#endif
127    if(_caca_init_graphics())
128        return -1;
129
130    return 0;
131}
132
133/**
134 * \brief Get the screen width.
135 *
136 * \return The screen width, in character cells.
137 */
138unsigned int caca_get_width(void)
139{
140    return _caca_width;
141}
142
143/**
144 * \brief Get the screen height.
145 *
146 * \return The screen height, in character cells.
147 */
148unsigned int caca_get_height(void)
149{
150    return _caca_height;
151}
152
153/**
154 * \brief Translate a colour value into its name.
155 *
156 * \param color The colour value.
157 * \return A static string containing the colour's name.
158 */
159const char *caca_get_color_name(enum caca_color color)
160{
161    static const char *color_names[] =
162    {
163        "black",
164        "blue",
165        "green",
166        "cyan",
167        "red",
168        "magenta",
169        "brown",
170        "light gray",
171        "dark gray",
172        "light blue",
173        "light green",
174        "light cyan",
175        "light red",
176        "light magenta",
177        "yellow",
178        "white",
179    };
180
181    if(color < 0 || color > 15)
182        return "unknown";
183
184    return color_names[color];
185}
186
187/**
188 * \brief Get the current value of a feature.
189 *
190 * \param feature The requested feature.
191 * \return The current value of the feature.
192 */
193enum caca_feature caca_get_feature(enum caca_feature feature)
194{
195    switch(feature)
196    {
197        case CACA_BACKGROUND:
198            return _caca_background;
199        case CACA_ANTIALIASING:
200            return _caca_antialiasing;
201        case CACA_DITHERING:
202            return _caca_dithering;
203
204        default:
205            return CACA_UNKNOWN_FEATURE;
206    }
207}
208
209/**
210 * \brief Set a feature.
211 *
212 * \param feature The wanted feature.
213 * \return void
214 */
215void caca_set_feature(enum caca_feature feature)
216{
217    switch(feature)
218    {
219        case CACA_BACKGROUND:
220            feature = CACA_BACKGROUND_SOLID;
221        case CACA_BACKGROUND_BLACK:
222        case CACA_BACKGROUND_SOLID:
223            _caca_background = feature;
224            break;
225
226        case CACA_ANTIALIASING:
227            feature = CACA_ANTIALIASING_PREFILTER;
228        case CACA_ANTIALIASING_NONE:
229        case CACA_ANTIALIASING_PREFILTER:
230            _caca_antialiasing = feature;
231            break;
232
233        case CACA_DITHERING:
234            feature = CACA_DITHERING_ORDERED4;
235        case CACA_DITHERING_NONE:
236        case CACA_DITHERING_ORDERED2:
237        case CACA_DITHERING_ORDERED4:
238        case CACA_DITHERING_ORDERED8:
239        case CACA_DITHERING_RANDOM:
240            _caca_dithering = feature;
241            break;
242
243        case CACA_UNKNOWN_FEATURE:
244            break;
245    }
246}
247
248/**
249 * \brief Translate a feature value into its name.
250 *
251 * \param feature The feature value.
252 * \return A static string containing the feature's name.
253 */
254const char *caca_get_feature_name(enum caca_feature feature)
255{
256    switch(feature)
257    {
258        case CACA_BACKGROUND_BLACK: return "black background";
259        case CACA_BACKGROUND_SOLID: return "solid background";
260
261        case CACA_ANTIALIASING_NONE:      return "no antialiasing";
262        case CACA_ANTIALIASING_PREFILTER: return "prefilter antialiasing";
263
264        case CACA_DITHERING_NONE:     return "no dithering";
265        case CACA_DITHERING_ORDERED2: return "2x2 ordered dithering";
266        case CACA_DITHERING_ORDERED4: return "4x4 ordered dithering";
267        case CACA_DITHERING_ORDERED8: return "8x8 ordered dithering";
268        case CACA_DITHERING_RANDOM:   return "random dithering";
269
270        default: return "unknown";
271    }
272}
273
274/**
275 * \brief Uninitialise libcaca.
276 *
277 * \return void
278 */
279void caca_end(void)
280{
281    _caca_end_graphics();
282
283#if defined(USE_SLANG)
284    SLtt_set_mouse_mode(0, 0);
285    SLtt_set_cursor_visibility(1);
286    SLang_reset_tty();
287    SLsmg_reset_smg();
288#elif defined(USE_NCURSES)
289    mousemask(oldmask, NULL);
290    curs_set(1);
291    endwin();
292#elif defined(USE_CONIO)
293    _wscroll = 1;
294    textcolor((enum COLORS)WHITE);
295    textbackground((enum COLORS)BLACK);
296    gotoxy(_caca_width, _caca_height);
297    cputs("\r\n");
298    _setcursortype(_NORMALCURSOR);
299#elif defined(USE_X11)
300    /* Nothing to do */
301#endif
302}
303
304static void caca_init_features(void)
305{
306    /* FIXME: if strcasecmp isn't available, use strcmp */
307#if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP)
308    char *var;
309#endif
310
311    caca_set_feature(CACA_BACKGROUND);
312    caca_set_feature(CACA_ANTIALIASING);
313    caca_set_feature(CACA_DITHERING);
314
315#if defined(HAVE_GETENV) && defined(HAVE_STRCASECMP)
316    if((var = getenv("CACA_BACKGROUND")))
317    {
318        if(!strcasecmp("black", var))
319            caca_set_feature(CACA_BACKGROUND_BLACK);
320        else if(!strcasecmp("solid", var))
321            caca_set_feature(CACA_BACKGROUND_SOLID);
322    }
323
324    if((var = getenv("CACA_ANTIALIASING")))
325    {
326        if(!strcasecmp("none", var))
327            caca_set_feature(CACA_ANTIALIASING_NONE);
328        else if(!strcasecmp("prefilter", var))
329            caca_set_feature(CACA_ANTIALIASING_PREFILTER);
330    }
331
332    if((var = getenv("CACA_DITHERING")))
333    {
334        if(!strcasecmp("none", var))
335            caca_set_feature(CACA_DITHERING_NONE);
336        else if(!strcasecmp("ordered2", var))
337            caca_set_feature(CACA_DITHERING_ORDERED2);
338        else if(!strcasecmp("ordered4", var))
339            caca_set_feature(CACA_DITHERING_ORDERED4);
340        else if(!strcasecmp("ordered8", var))
341            caca_set_feature(CACA_DITHERING_ORDERED8);
342        else if(!strcasecmp("random", var))
343            caca_set_feature(CACA_DITHERING_RANDOM);
344    }
345#endif
346}
347
348static void caca_init_terminal(void)
349{
350#if defined(HAVE_GETENV) && defined(HAVE_PUTENV) \
351     && (defined(USE_SLANG) || defined(USE_NCURSES))
352    char *term, *colorterm, *other;
353
354    term = getenv("TERM");
355    colorterm = getenv("COLORTERM");
356
357    if(term && !strcmp(term, "xterm"))
358    {
359        /* If we are using gnome-terminal, it's really a 16 colour terminal */
360        if(colorterm && !strcmp(colorterm, "gnome-terminal"))
361        {
362#if defined(USE_NCURSES)
363            SCREEN *screen;
364            screen = newterm("xterm-16color", stdout, stdin);
365            if(screen == NULL)
366                return;
367            endwin();
368#endif
369            (void)putenv("TERM=xterm-16color");
370            return;
371        }
372
373        /* Ditto if we are using Konsole */
374        other = getenv("KONSOLE_DCOP_SESSION");
375        if(other)
376        {
377#if defined(USE_NCURSES)
378            SCREEN *screen;
379            screen = newterm("xterm-16color", stdout, stdin);
380            if(screen == NULL)
381                return;
382            endwin();
383#endif
384            (void)putenv("TERM=xterm-16color");
385            return;
386        }
387    }
388#endif
389}
390
Note: See TracBrowser for help on using the repository browser.