~ubuntu-branches/ubuntu/raring/libcaca/raring

« back to all changes in this revision

Viewing changes to caca/driver/slang.c

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hocevar
  • Date: 2010-02-08 01:40:59 UTC
  • mfrom: (1.1.8 upstream) (4.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100208014059-9q4av8pze8p7uw3i
Tags: 0.99.beta17-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *  libcaca       Colour ASCII-Art library
3
 
 *  Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
 
3
 *  Copyright (c) 2002-2009 Sam Hocevar <sam@hocevar.net>
4
4
 *                All Rights Reserved
5
5
 *
6
 
 *  $Id$
7
 
 *
8
6
 *  This library is free software. It comes without any warranty, to
9
7
 *  the extent permitted by applicable law. You can redistribute it
10
8
 *  and/or modify it under the terms of the Do What The Fuck You Want
115
113
struct driver_private
116
114
{
117
115
    char *term;
 
116
    unsigned int sigint_event;
118
117
};
119
118
 
 
119
static void default_sigint (int sig)
 
120
{
 
121
    /* Warn the caller that we got SIGINT. */
 
122
    sigwinch_d->drv.p->sigint_event++;
 
123
}
 
124
 
120
125
static int slang_init_graphics(caca_display_t *dp)
121
126
{
122
127
    dp->drv.p = malloc(sizeof(struct driver_private));
 
128
    dp->drv.p->sigint_event = 0;
123
129
 
124
130
#if defined(HAVE_GETENV) && defined(HAVE_PUTENV)
125
131
    slang_install_terminal(dp);
134
140
 
135
141
    /* Initialise slang library */
136
142
    SLsig_block_signals();
 
143
    /* Disable SLang's own SIGINT on ctrl-c */
 
144
    SLang_set_abort_signal(default_sigint);
 
145
 
137
146
    SLtt_get_terminfo();
138
147
 
139
148
    if(SLkp_init() == -1)
150
159
        return -1;
151
160
    }
152
161
 
153
 
    SLsig_unblock_signals();
154
 
 
155
162
    SLsmg_cls();
156
163
    SLtt_set_cursor_visibility(0);
157
164
    SLkp_define_keysym("\e[M", 1001);
175
182
    SLtt_utf8_enable(1);
176
183
#endif
177
184
 
 
185
    caca_add_dirty_rect(dp->cv, 0, 0, dp->cv->width, dp->cv->height);
178
186
    dp->resize.allow = 1;
179
187
    caca_set_canvas_size(dp->cv, SLtt_Screen_Cols, SLtt_Screen_Rows);
180
188
    dp->resize.allow = 0;
181
189
 
 
190
    SLsig_unblock_signals();
 
191
 
182
192
    return 0;
183
193
}
184
194
 
188
198
    SLtt_set_mouse_mode(0, 0);
189
199
    SLtt_set_cursor_visibility(1);
190
200
    SLang_reset_tty();
 
201
    SLsig_block_signals();
191
202
    SLsmg_reset_smg();
 
203
    SLsig_unblock_signals();
192
204
 
193
205
#if defined HAVE_GETENV && defined HAVE_PUTENV
194
206
    slang_uninstall_terminal(dp);
220
232
 
221
233
static void slang_display(caca_display_t *dp)
222
234
{
223
 
    uint32_t const *cvchars = (uint32_t const *)caca_get_canvas_chars(dp->cv);
224
 
    uint32_t const *cvattrs = (uint32_t const *)caca_get_canvas_attrs(dp->cv);
225
 
    int width = caca_get_canvas_width(dp->cv);
226
 
    int height = caca_get_canvas_height(dp->cv);
227
 
    int x, y;
 
235
    int x, y, i;
228
236
 
229
 
    for(y = 0; y < (int)height; y++)
 
237
    SLsig_block_signals();
 
238
    for(i = 0; i < caca_get_dirty_rect_count(dp->cv); i++)
230
239
    {
231
 
        SLsmg_gotorc(y, 0);
232
 
        for(x = width; x--; )
 
240
        uint32_t const *cvchars, *cvattrs;
 
241
        int dx, dy, dw, dh;
 
242
 
 
243
        caca_get_dirty_rect(dp->cv, i, &dx, &dy, &dw, &dh);
 
244
 
 
245
        cvchars = caca_get_canvas_chars(dp->cv) + dx + dy * dp->cv->width;
 
246
        cvattrs = caca_get_canvas_attrs(dp->cv) + dx + dy * dp->cv->width;
 
247
 
 
248
        for(y = dy; y < dy + dh; y++)
233
249
        {
234
 
            uint32_t ch = *cvchars++;
 
250
            SLsmg_gotorc(y, dx);
 
251
            for(x = dx; x < dx + dw; x++)
 
252
            {
 
253
                uint32_t ch = *cvchars++;
235
254
 
236
255
#if defined(OPTIMISE_SLANG_PALETTE)
237
 
            /* If foreground == background, just don't use this colour
238
 
             * pair, and print a space instead of the real character.
239
 
             * XXX: disabled, because I can't remember what it was
240
 
             * here for, and in cases where SLang does not render
241
 
             * bright backgrounds, it's just fucked up. */
 
256
                /* If foreground == background, just don't use this colour
 
257
                 * pair, and print a space instead of the real character. */
 
258
                /* XXX: disabled, because I can't remember what it was
 
259
                 * here for, and in cases where SLang does not render
 
260
                 * bright backgrounds, it's just fucked up. */
242
261
#if 0
243
 
            uint8_t fgcolor = caca_attr_to_ansi_fg(*cvattrs);
244
 
            uint8_t bgcolor = caca_attr_to_ansi_bg(*cvattrs);
245
 
 
246
 
            if(fgcolor >= 0x10)
247
 
                fgcolor = CACA_LIGHTGRAY;
248
 
 
249
 
            if(bgcolor >= 0x10)
250
 
                bgcolor = CACA_BLACK; /* FIXME: handle transparency */
251
 
 
252
 
            if(fgcolor == bgcolor)
253
 
            {
254
 
                if(fgcolor == CACA_BLACK)
255
 
                    fgcolor = CACA_WHITE;
256
 
                else if(fgcolor == CACA_WHITE
257
 
                         || fgcolor <= CACA_LIGHTGRAY)
258
 
                    fgcolor = CACA_BLACK;
 
262
                uint8_t fgcolor = caca_attr_to_ansi_fg(*cvattrs);
 
263
                uint8_t bgcolor = caca_attr_to_ansi_bg(*cvattrs);
 
264
 
 
265
                if(fgcolor >= 0x10)
 
266
                    fgcolor = CACA_LIGHTGRAY;
 
267
 
 
268
                if(bgcolor >= 0x10)
 
269
                    bgcolor = CACA_BLACK; /* FIXME: handle transparency */
 
270
 
 
271
                if(fgcolor == bgcolor)
 
272
                {
 
273
                    if(fgcolor == CACA_BLACK)
 
274
                        fgcolor = CACA_WHITE;
 
275
                    else if(fgcolor == CACA_WHITE
 
276
                             || fgcolor <= CACA_LIGHTGRAY)
 
277
                        fgcolor = CACA_BLACK;
 
278
                    else
 
279
                        fgcolor = CACA_WHITE;
 
280
                    SLsmg_set_color(slang_assoc[fgcolor + 16 * bgcolor]);
 
281
                    SLsmg_write_char(' ');
 
282
                    cvattrs++;
 
283
                }
259
284
                else
260
 
                    fgcolor = CACA_WHITE;
261
 
                SLsmg_set_color(slang_assoc[fgcolor + 16 * bgcolor]);
262
 
                SLsmg_write_char(' ');
263
 
                cvattrs++;
264
 
            }
265
 
            else
266
285
#endif
267
 
            {
268
 
                SLsmg_set_color(slang_assoc[caca_attr_to_ansi(*cvattrs++)]);
 
286
                {
 
287
                    SLsmg_set_color(slang_assoc[caca_attr_to_ansi(*cvattrs++)]);
 
288
                    slang_write_utf32(ch);
 
289
                }
 
290
#else
 
291
                SLsmg_set_color(caca_attr_to_ansi(*cvattrs++));
269
292
                slang_write_utf32(ch);
 
293
#endif
270
294
            }
271
 
#else
272
 
            SLsmg_set_color(caca_attr_to_ansi(*cvattrs++));
273
 
            slang_write_utf32(ch);
274
 
#endif
 
295
 
 
296
            cvchars += dp->cv->width - dw;
 
297
            cvattrs += dp->cv->width - dw;
275
298
        }
276
299
    }
277
 
    SLsmg_gotorc(caca_get_cursor_y(dp->cv), caca_get_cursor_x(dp->cv));
 
300
    SLsmg_gotorc(caca_wherey(dp->cv), caca_wherex(dp->cv));
278
301
    SLsmg_refresh();
 
302
    SLsig_unblock_signals();
279
303
}
280
304
 
281
305
static void slang_handle_resize(caca_display_t *dp)
284
308
    dp->resize.w = SLtt_Screen_Cols;
285
309
    dp->resize.h = SLtt_Screen_Rows;
286
310
 
 
311
    SLsig_block_signals();
287
312
    if(dp->resize.w != caca_get_canvas_width(dp->cv)
288
313
        || dp->resize.h != caca_get_canvas_height(dp->cv))
289
314
        SLsmg_reinit_smg();
 
315
    SLsig_unblock_signals();
290
316
}
291
317
 
292
318
static int slang_get_event(caca_display_t *dp, caca_privevent_t *ev)
293
319
{
294
320
    int intkey;
295
321
 
 
322
    /* If SIGINT was caught, we pass it to the application as Ctrl-C. */
 
323
    if(dp->drv.p->sigint_event > 0)
 
324
    {
 
325
        ev->type = CACA_EVENT_KEY_PRESS;
 
326
        ev->data.key.ch = CACA_KEY_CTRL_C;
 
327
        ev->data.key.utf32 = 0x03;
 
328
        ev->data.key.utf8[0] = 0x03;
 
329
        ev->data.key.utf8[1] = 0;
 
330
        dp->drv.p->sigint_event--;
 
331
        return 1;
 
332
    }
 
333
 
296
334
    if(!SLang_input_pending(0))
297
335
    {
298
336
        ev->type = CACA_EVENT_NONE;