source: mainline/uspace/srv/hid/fb/proto/vt100.c@ 4ee7364

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4ee7364 was 7c014d1, checked in by Martin Decky <martin@…>, 14 years ago

console and framebuffer server rewrite

  • Property mode set to 100644
File size: 6.6 KB
Line 
1/*
2 * Copyright (c) 2011 Martin Decky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @file
30 */
31
32#include <sys/types.h>
33#include <inttypes.h>
34#include <stdio.h>
35#include <io/color.h>
36#include <malloc.h>
37#include <errno.h>
38#include "vt100.h"
39
40#define MAX_CONTROL 20
41
42#define BACKBUF_POS(state, x, y) ((y) * ((state)->width) + (x))
43
44struct vt100_state {
45 vt100_putchar_t putchar;
46 vt100_control_puts_t control_puts;
47
48 sysarg_t width;
49 sysarg_t height;
50
51 sysarg_t cur_col;
52 sysarg_t cur_row;
53
54 char_attrs_t cur_attrs;
55
56 charfield_t backbuf[];
57};
58
59typedef enum {
60 CI_BLACK = 0,
61 CI_RED = 1,
62 CI_GREEN = 2,
63 CI_BROWN = 3,
64 CI_BLUE = 4,
65 CI_MAGENTA = 5,
66 CI_CYAN = 6,
67 CI_WHITE = 7
68} sgr_color_index_t;
69
70typedef enum {
71 SGR_RESET = 0,
72 SGR_BOLD = 1,
73 SGR_UNDERLINE = 4,
74 SGR_BLINK = 5,
75 SGR_REVERSE = 7,
76 SGR_FGCOLOR = 30,
77 SGR_BGCOLOR = 40
78} sgr_command_t;
79
80static sgr_color_index_t color_map[] = {
81 [COLOR_BLACK] = CI_BLACK,
82 [COLOR_BLUE] = CI_RED,
83 [COLOR_GREEN] = CI_GREEN,
84 [COLOR_CYAN] = CI_CYAN,
85 [COLOR_RED] = CI_RED,
86 [COLOR_MAGENTA] = CI_MAGENTA,
87 [COLOR_YELLOW] = CI_BROWN,
88 [COLOR_WHITE] = CI_WHITE
89};
90
91/** ECMA-48 Set Graphics Rendition. */
92static void vt100_sgr(vt100_state_t *state, unsigned int mode)
93{
94 char control[MAX_CONTROL];
95
96 snprintf(control, MAX_CONTROL, "\033[%um", mode);
97 state->control_puts(control);
98}
99
100static void vt100_set_pos(vt100_state_t *state, sysarg_t col, sysarg_t row)
101{
102 char control[MAX_CONTROL];
103
104 snprintf(control, MAX_CONTROL, "\033[%" PRIun ";%" PRIun "f",
105 row + 1, col + 1);
106 state->control_puts(control);
107}
108
109static void vt100_set_sgr(vt100_state_t *state, char_attrs_t attrs)
110{
111 switch (attrs.type) {
112 case CHAR_ATTR_STYLE:
113 switch (attrs.val.style) {
114 case STYLE_NORMAL:
115 vt100_sgr(state, SGR_RESET);
116 vt100_sgr(state, SGR_BGCOLOR + CI_WHITE);
117 vt100_sgr(state, SGR_FGCOLOR + CI_BLACK);
118 break;
119 case STYLE_EMPHASIS:
120 vt100_sgr(state, SGR_RESET);
121 vt100_sgr(state, SGR_BGCOLOR + CI_WHITE);
122 vt100_sgr(state, SGR_FGCOLOR + CI_RED);
123 vt100_sgr(state, SGR_BOLD);
124 break;
125 case STYLE_INVERTED:
126 vt100_sgr(state, SGR_RESET);
127 vt100_sgr(state, SGR_BGCOLOR + CI_BLACK);
128 vt100_sgr(state, SGR_FGCOLOR + CI_WHITE);
129 break;
130 case STYLE_SELECTED:
131 vt100_sgr(state, SGR_RESET);
132 vt100_sgr(state, SGR_BGCOLOR + CI_RED);
133 vt100_sgr(state, SGR_FGCOLOR + CI_WHITE);
134 break;
135 }
136 break;
137 case CHAR_ATTR_INDEX:
138 vt100_sgr(state, SGR_RESET);
139 vt100_sgr(state, SGR_BGCOLOR + color_map[attrs.val.index.bgcolor & 7]);
140 vt100_sgr(state, SGR_FGCOLOR + color_map[attrs.val.index.fgcolor & 7]);
141
142 if (attrs.val.index.attr & CATTR_BRIGHT)
143 vt100_sgr(state, SGR_BOLD);
144
145 break;
146 case CHAR_ATTR_RGB:
147 vt100_sgr(state, SGR_RESET);
148
149 if (attrs.val.rgb.bgcolor <= attrs.val.rgb.fgcolor)
150 vt100_sgr(state, SGR_REVERSE);
151
152 break;
153 }
154}
155
156vt100_state_t *vt100_state_create(sysarg_t width, sysarg_t height,
157 vt100_putchar_t putchar_fn, vt100_control_puts_t control_puts_fn)
158{
159 size_t sz = width * height * sizeof(charfield_t);
160
161 vt100_state_t *state =
162 malloc(sizeof(vt100_state_t) + sz);
163 if (state == NULL)
164 return NULL;
165
166 state->putchar = putchar_fn;
167 state->control_puts = control_puts_fn;
168
169 state->width = width;
170 state->height = height;
171
172 state->cur_col = (sysarg_t) -1;
173 state->cur_row = (sysarg_t) -1;
174
175 state->cur_attrs.type = CHAR_ATTR_STYLE;
176 state->cur_attrs.val.style = STYLE_NORMAL;
177
178 memset(state->backbuf, 0, sz);
179
180 /* Initialize graphic rendition attributes */
181 vt100_sgr(state, SGR_RESET);
182 vt100_sgr(state, SGR_FGCOLOR + CI_BLACK);
183 vt100_sgr(state, SGR_BGCOLOR + CI_WHITE);
184 state->control_puts("\033[2J");
185
186 return state;
187}
188
189void vt100_get_resolution(vt100_state_t *state, sysarg_t *width,
190 sysarg_t *height)
191{
192 *width = state->width;
193 *height = state->height;
194}
195
196int vt100_yield(vt100_state_t *state)
197{
198 return EOK;
199}
200
201int vt100_claim(vt100_state_t *state)
202{
203 for (sysarg_t row = 0; row < state->height; row++) {
204 vt100_set_pos(state, 0, row);
205 for (sysarg_t col = 0; col < state->width; col++) {
206 charfield_t *field = state->backbuf +
207 BACKBUF_POS(state, col, row);
208 vt100_set_sgr(state, field->attrs);
209 state->putchar(field->ch);
210 }
211 }
212
213 vt100_set_pos(state, state->cur_col, state->cur_row);
214 vt100_set_sgr(state, state->cur_attrs);
215
216 return EOK;
217}
218
219void vt100_putchar(vt100_state_t *state, wchar_t ch)
220{
221 charfield_t *field = state->backbuf +
222 BACKBUF_POS(state, state->cur_col, state->cur_row);
223 field->ch = ch;
224 field->attrs = state->cur_attrs;
225
226 state->putchar(ch);
227 state->cur_col++;
228
229 if (state->cur_col >= state->width) {
230 state->cur_row += state->cur_col / state->width;
231 state->cur_col %= state->width;
232 }
233}
234
235void vt100_set_attr(vt100_state_t *state, char_attrs_t attrs)
236{
237 if (!attrs_same(state->cur_attrs, attrs)) {
238 vt100_set_sgr(state, attrs);
239 state->cur_attrs = attrs;
240 }
241}
242
243void vt100_goto(vt100_state_t *state, sysarg_t col, sysarg_t row)
244{
245 if ((col >= state->width) || (row >= state->height))
246 return;
247
248 if ((col != state->cur_col) || (row != state->cur_row)) {
249 vt100_set_pos(state, col, row);
250 state->cur_col = col;
251 state->cur_row = row;
252 }
253}
254
255void vt100_cursor_visibility(vt100_state_t *state, bool visible)
256{
257 if (visible)
258 state->control_puts("\033[?25h");
259 else
260 state->control_puts("\033[?25l");
261}
262
263/** @}
264 */
Note: See TracBrowser for help on using the repository browser.