~siretart/lcd4linux/debian

« back to all changes in this revision

Viewing changes to drv_Curses.c

  • Committer: Reinhard Tartler
  • Date: 2011-04-27 17:24:15 UTC
  • mto: This revision was merged to the branch mainline in revision 750.
  • Revision ID: siretart@tauware.de-20110427172415-6n4aptmvmz0eztvm
Tags: upstream-0.11.0~svn1143
ImportĀ upstreamĀ versionĀ 0.11.0~svn1143

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: drv_Curses.c 975 2009-01-18 11:16:20Z michael $
 
2
 * $URL: https://ssl.bulix.org/svn/lcd4linux/trunk/drv_Curses.c $
 
3
 *
 
4
 * pure ncurses based text driver
 
5
 *
 
6
 * Copyright (C) 2004 Michael Reinelt <michael@reinelt.co.at>
 
7
 * Copyright (C) 2004 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
 
8
 *
 
9
 * based on the old Curses/Text driver which is
 
10
 * Copyright (C) 2001 Leopold Toetsch <lt@toetsch.at>
 
11
 *
 
12
 * This file is part of LCD4Linux.
 
13
 *
 
14
 * LCD4Linux is free software; you can redistribute it and/or modify
 
15
 * it under the terms of the GNU General Public License as published by
 
16
 * the Free Software Foundation; either version 2, or (at your option)
 
17
 * any later version.
 
18
 *
 
19
 * LCD4Linux is distributed in the hope that it will be useful,
 
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
22
 * GNU General Public License for more details.
 
23
 *
 
24
 * You should have received a copy of the GNU General Public License
 
25
 * along with this program; if not, write to the Free Software
 
26
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
27
 *
 
28
 */
 
29
 
 
30
/* 
 
31
 *
 
32
 * exported fuctions:
 
33
 *
 
34
 * struct DRIVER drv_Curses
 
35
 *
 
36
 */
 
37
 
 
38
#include "config.h"
 
39
 
 
40
#include <stdlib.h>
 
41
#include <stdio.h>
 
42
#include <string.h>
 
43
#include <unistd.h>
 
44
 
 
45
#include <curses.h>
 
46
 
 
47
#include "debug.h"
 
48
#include "cfg.h"
 
49
#include "qprintf.h"
 
50
#include "timer.h"
 
51
#include "plugin.h"
 
52
#include "widget.h"
 
53
#include "widget_text.h"
 
54
#include "widget_bar.h"
 
55
#include "widget_keypad.h"
 
56
#include "drv.h"
 
57
#include "drv_generic_text.h"
 
58
#include "drv_generic_keypad.h"
 
59
 
 
60
 
 
61
static char Name[] = "Curses";
 
62
 
 
63
static WINDOW *w = NULL;
 
64
static WINDOW *e = NULL;
 
65
 
 
66
static int EROWS;
 
67
 
 
68
 
 
69
/****************************************/
 
70
/***  hardware dependant functions    ***/
 
71
/****************************************/
 
72
 
 
73
static void drv_Curs_clear(void)
 
74
{
 
75
    werase(w);
 
76
    box(w, 0, 0);
 
77
    wrefresh(w);
 
78
}
 
79
 
 
80
 
 
81
static void drv_Curs_write(const int row, const int col, const char *data, const int len)
 
82
{
 
83
    int l = len;
 
84
    char *p;
 
85
 
 
86
    while ((p = strpbrk(data, "\r\n")) != NULL) {
 
87
        *p = '\0';
 
88
    }
 
89
 
 
90
    if (col < DCOLS) {
 
91
        if (DCOLS - col < l)
 
92
            l = DCOLS - col;
 
93
        mvwprintw(w, row + 1, col + 1, "%.*s", l, data);
 
94
        wmove(w, DROWS + 1, 0);
 
95
        wrefresh(w);
 
96
    }
 
97
}
 
98
 
 
99
 
 
100
static void drv_Curs_defchar(const __attribute__ ((unused))
 
101
                             int ascii, const __attribute__ ((unused))
 
102
                             unsigned char *buffer)
 
103
{
 
104
    /* empty */
 
105
}
 
106
 
 
107
 
 
108
/* ncures scroll SIGSEGVs on my system, so this is a workaroud */
 
109
 
 
110
int curses_error(char *buffer)
 
111
{
 
112
    static int lines = 0;
 
113
    static char *lb[100];
 
114
    int start, i;
 
115
    char *p;
 
116
 
 
117
    if (e == NULL)
 
118
        return 0;
 
119
 
 
120
    /* replace \r, \n with underscores */
 
121
    while ((p = strpbrk(buffer, "\r\n")) != NULL) {
 
122
        *p = '_';
 
123
    }
 
124
 
 
125
    if (lines >= EROWS) {
 
126
        free(lb[0]);
 
127
        for (i = 1; i <= EROWS; i++) {
 
128
            lb[i - 1] = lb[i];
 
129
        }
 
130
        start = 0;
 
131
    } else {
 
132
        start = lines;
 
133
    }
 
134
 
 
135
    lb[lines] = strdup(buffer);
 
136
    for (i = start; i <= lines; i++) {
 
137
        mvwprintw(e, i + 1, 1, "%s", lb[i]);
 
138
        wclrtoeol(e);
 
139
    }
 
140
 
 
141
    box(e, 0, 0);
 
142
    mvwprintw(e, 0, 3, "Stderr:");
 
143
    wrefresh(e);
 
144
 
 
145
    if (lines < EROWS)
 
146
        lines++;
 
147
 
 
148
    return 1;
 
149
}
 
150
 
 
151
 
 
152
static int drv_Curs_start(const char *section, const int quiet)
 
153
{
 
154
    char *s;
 
155
 
 
156
    if (!running_foreground) {
 
157
        error("%s: You want me to display on /dev/null? Sorry, I can't ...", Name);
 
158
        error("%s: Maybe you want me to run in foreground? Try '-F'", Name);
 
159
        return -1;
 
160
    }
 
161
 
 
162
    s = cfg_get(section, "Size", "20x4");
 
163
    if (s == NULL || *s == '\0') {
 
164
        error("%s: no '%s.Size' entry from %s", Name, section, cfg_source());
 
165
        free(s);
 
166
        return -1;
 
167
    }
 
168
    if (sscanf(s, "%dx%d", &DCOLS, &DROWS) != 2 || DROWS < 1 || DCOLS < 1) {
 
169
        error("%s: bad %s.Size '%s' from %s", Name, section, s, cfg_source());
 
170
        free(s);
 
171
        return -1;
 
172
    }
 
173
    free(s);
 
174
 
 
175
    initscr();
 
176
    noecho();
 
177
    debug("%s: curses thinks that COLS=%d LINES=%d", Name, COLS, LINES);
 
178
    w = newwin(DROWS + 2, DCOLS + 2, 0, 0);
 
179
    keypad(w, TRUE);
 
180
    nodelay(w, TRUE);
 
181
 
 
182
    EROWS = LINES - DROWS - 3;
 
183
    if (EROWS > 99)
 
184
        EROWS = 99;
 
185
    debug("EROWS=%d", EROWS);
 
186
 
 
187
    if (EROWS >= 4) {
 
188
        e = newwin(EROWS, COLS, DROWS + 3, 0);
 
189
        EROWS -= 3;
 
190
        box(e, 0, 0);
 
191
        mvwprintw(e, 0, 3, "Stderr:");
 
192
        wmove(e, 1, 0);
 
193
        wrefresh(e);
 
194
    }
 
195
 
 
196
    drv_Curs_clear();
 
197
 
 
198
    if (!quiet) {
 
199
        char buffer[40];
 
200
        qprintf(buffer, sizeof(buffer), "%s %dx%d", Name, DCOLS, DROWS);
 
201
        if (drv_generic_text_greet(buffer, NULL)) {
 
202
            sleep(3);
 
203
            drv_Curs_clear();
 
204
        }
 
205
    }
 
206
 
 
207
    return 0;
 
208
}
 
209
 
 
210
static void drv_Curs_timer(void __attribute__ ((unused)) * notused)
 
211
{
 
212
    int c;
 
213
    while (1) {
 
214
        c = wgetch(w);
 
215
        if (c <= 0)
 
216
            break;
 
217
        drv_generic_keypad_press(c);
 
218
    }
 
219
}
 
220
 
 
221
static int drv_Curs_keypad(const int num)
 
222
{
 
223
    int val = 0;
 
224
 
 
225
    switch (num) {
 
226
    case KEY_UP:
 
227
        debug("Key Up");
 
228
        val += WIDGET_KEY_PRESSED;
 
229
        val += WIDGET_KEY_UP;
 
230
        break;
 
231
    case KEY_DOWN:
 
232
        debug("Key Down");
 
233
        val += WIDGET_KEY_PRESSED;
 
234
        val += WIDGET_KEY_DOWN;
 
235
        break;
 
236
    case KEY_LEFT:
 
237
        debug("Key Left");
 
238
        val += WIDGET_KEY_PRESSED;
 
239
        val += WIDGET_KEY_LEFT;
 
240
        break;
 
241
    case KEY_RIGHT:
 
242
        debug("Key Right");
 
243
        val += WIDGET_KEY_PRESSED;
 
244
        val += WIDGET_KEY_RIGHT;
 
245
        break;
 
246
    default:
 
247
        debug("Unbound Key '%d'", num);
 
248
        break;
 
249
    }
 
250
 
 
251
    return val;
 
252
}
 
253
 
 
254
 
 
255
/****************************************/
 
256
/***            plugins               ***/
 
257
/****************************************/
 
258
 
 
259
/* none at the moment... */
 
260
 
 
261
 
 
262
/****************************************/
 
263
/***        widget callbacks          ***/
 
264
/****************************************/
 
265
 
 
266
/* using drv_generic_text_draw(W) */
 
267
/* using drv_generic_text_bar_draw(W) */
 
268
/* using drv_generic_keypad_draw(W) */
 
269
 
 
270
 
 
271
/****************************************/
 
272
/***        exported functions        ***/
 
273
/****************************************/
 
274
 
 
275
 
 
276
/* list models */
 
277
int drv_Curs_list(void)
 
278
{
 
279
    printf("pure ncurses based text driver");
 
280
    return 0;
 
281
}
 
282
 
 
283
 
 
284
/* initialize driver & display */
 
285
int drv_Curs_init(const char *section, const int quiet)
 
286
{
 
287
    WIDGET_CLASS wc;
 
288
    int ret;
 
289
 
 
290
    info("%s: %s", Name, "$Rev: 975 $");
 
291
 
 
292
    /* display preferences */
 
293
    XRES = 1;                   /* pixel width of one char  */
 
294
    YRES = 1;                   /* pixel height of one char  */
 
295
    CHARS = 0;                  /* number of user-defineable characters */
 
296
    CHAR0 = 0;                  /* ASCII of first user-defineable char */
 
297
    GOTO_COST = 0;              /* number of bytes a goto command requires */
 
298
 
 
299
    /* real worker functions */
 
300
    drv_generic_text_real_write = drv_Curs_write;
 
301
    drv_generic_text_real_defchar = drv_Curs_defchar;
 
302
    drv_generic_keypad_real_press = drv_Curs_keypad;
 
303
 
 
304
    /* regularly process display answers */
 
305
    timer_add(drv_Curs_timer, NULL, 100, 0);
 
306
 
 
307
    /* start display */
 
308
    if ((ret = drv_Curs_start(section, quiet)) != 0) {
 
309
        return ret;
 
310
    }
 
311
 
 
312
    /* initialize generic text driver */
 
313
    if ((ret = drv_generic_text_init(section, Name)) != 0)
 
314
        return ret;
 
315
 
 
316
    /* initialize generic bar driver */
 
317
    if ((ret = drv_generic_text_bar_init(1)) != 0)
 
318
        return ret;
 
319
 
 
320
    /* initialize generic key pad driver */
 
321
    if ((ret = drv_generic_keypad_init(section, Name)) != 0)
 
322
        return ret;
 
323
 
 
324
    /* add fixed chars to the bar driver */
 
325
    drv_generic_text_bar_add_segment(0, 0, 255, 32);    /* ASCII  32 = blank */
 
326
    drv_generic_text_bar_add_segment(255, 255, 255, '*');       /* asterisk */
 
327
 
 
328
    /* register text widget */
 
329
    wc = Widget_Text;
 
330
    wc.draw = drv_generic_text_draw;
 
331
    widget_register(&wc);
 
332
 
 
333
    /* register bar widget */
 
334
    wc = Widget_Bar;
 
335
    wc.draw = drv_generic_text_bar_draw;
 
336
    widget_register(&wc);
 
337
 
 
338
    /* register plugins */
 
339
    /* none at the moment... */
 
340
 
 
341
    return 0;
 
342
}
 
343
 
 
344
 
 
345
/* close driver & display */
 
346
int drv_Curs_quit(const int quiet)
 
347
{
 
348
 
 
349
    info("%s: shutting down.", Name);
 
350
 
 
351
    drv_generic_text_quit();
 
352
    drv_generic_keypad_quit();
 
353
 
 
354
    /* clear display */
 
355
    drv_Curs_clear();
 
356
 
 
357
    /* say goodbye... */
 
358
    if (!quiet) {
 
359
        drv_generic_text_greet("goodbye!", NULL);
 
360
    }
 
361
 
 
362
    endwin();
 
363
 
 
364
    return (0);
 
365
}
 
366
 
 
367
 
 
368
DRIVER drv_Curses = {
 
369
    .name = Name,
 
370
    .list = drv_Curs_list,
 
371
    .init = drv_Curs_init,
 
372
    .quit = drv_Curs_quit,
 
373
};