d228227c7dad3c01239bf1e5e27ecbccb4df46e7
[oftp] / src / unix / tgfx.c
1 #include <curses.h>
2 #include "tgfx.h"
3 #include "util.h"
4
5 struct cpair {
6         int pair;
7         int fg, bg;
8 };
9 static struct cpair *colors;
10 static int num_colors;
11
12 static int fgcol, bgcol;
13 static int bgchar;
14 static int cur_pair;
15 static int cur_x, cur_y;
16
17 static int curses_color(int col);
18 static void upd_color(void);
19
20 void tg_init(void)
21 {
22         initscr();
23         cbreak();
24         keypad(stdscr, TRUE);
25         nodelay(stdscr, TRUE);
26         noecho();
27         start_color();
28
29         fgcol = curses_color(TGFX_WHITE);
30         bgcol = curses_color(TGFX_BLACK);
31         bgchar = ' ';
32
33         colors = malloc_nf(COLORS * sizeof *colors);
34         num_colors = 0;
35 }
36
37 void tg_cleanup(void)
38 {
39         endwin();
40 }
41
42 void tg_redraw(void)
43 {
44         move(cur_y, cur_x);
45         refresh();
46 }
47
48 void tg_clear(void)
49 {
50         clear();
51 }
52
53
54 void tg_fgcolor(int col)
55 {
56         fgcol = curses_color(col);
57 }
58
59 void tg_bgcolor(int col)
60 {
61         bgcol = curses_color(col);
62 }
63
64 void tg_color(int col)
65 {
66         fgcol = curses_color(col & 0xf);
67         bgcol = curses_color((col >> 4) & 0xf);
68 }
69
70 void tg_bgchar(int c)
71 {
72         bgchar = c;
73 }
74
75
76 void tg_setcursor(int x, int y)
77 {
78         move(y, x);
79         cur_x = x;
80         cur_y = y;
81 }
82
83
84 void tg_text(int x, int y, const char *fmt, ...)
85 {
86         va_list ap;
87
88         va_start(ap, fmt);
89         tg_vtext(x, y, fmt, ap);
90         va_end(ap);
91 }
92
93 void tg_vtext(int x, int y, const char *fmt, va_list ap)
94 {
95         upd_color();
96         attron(COLOR_PAIR(cur_pair));
97         move(y, x);
98         vw_printw(stdscr, fmt, ap);
99         attroff(COLOR_PAIR(cur_pair));
100 }
101
102
103 void tg_rect(const char *label, int x, int y, int xsz, int ysz, unsigned int flags)
104 {
105         int i;
106
107         upd_color();
108         attron(COLOR_PAIR(cur_pair));
109
110         for(i=0; i<ysz; i++) {
111                 move(y + i, x);
112                 hline(bgchar, xsz);
113         }
114
115         if(flags & TGFX_FRAME) {
116                 move(y, x + 1);
117                 hline(ACS_HLINE, xsz - 2);
118                 move(y + ysz - 1, x + 1);
119                 hline(ACS_HLINE, xsz - 2);
120                 move(y + 1, x);
121                 vline(ACS_VLINE, ysz - 2);
122                 move(y + 1, x + xsz - 1);
123                 vline(ACS_VLINE, ysz - 2);
124
125                 mvaddch(y, x, ACS_ULCORNER);
126                 mvaddch(y, x + xsz - 1, ACS_URCORNER);
127                 mvaddch(y + ysz - 1, x, ACS_LLCORNER);
128                 mvaddch(y + ysz - 1, x + xsz - 1, ACS_LRCORNER);
129         }
130
131         if(label) {
132                 tg_text(x + 2, y, "%s", label);
133         }
134
135         attroff(COLOR_PAIR(cur_pair));
136 }
137
138 static int curses_color(int col)
139 {
140         switch(col) {
141         case TGFX_RED:
142                 return COLOR_RED;
143         case TGFX_BLUE:
144                 return COLOR_BLUE;
145         case TGFX_CYAN:
146                 return COLOR_CYAN;
147         case TGFX_YELLOW:
148                 return COLOR_YELLOW;
149         default:
150                 break;
151         }
152         return col;
153 }
154
155 static void upd_color(void)
156 {
157         int i;
158
159         for(i=0; i<num_colors; i++) {
160                 if(fgcol == colors[i].fg && bgcol == colors[i].bg) {
161                         cur_pair = colors[i].pair;
162                         return;
163                 }
164         }
165
166         /* not found, allocate a new color pair */
167         if(num_colors >= COLORS) {
168                 return;
169         }
170         i = num_colors++;
171         cur_pair = num_colors;
172
173         colors[i].fg = fgcol;
174         colors[i].bg = bgcol;
175         colors[i].pair = cur_pair;
176         init_pair(cur_pair, fgcol, bgcol);
177 }