source: mainline/uspace/srv/hid/output/proto/vt100.c@ c8ea6eca

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c8ea6eca was 4122410, checked in by Jakub Jermar <jakub@…>, 7 years ago

Improve Doxygen documentaion

This is stil WiP. A number of libraries, drivers and services were
converted to using a more hierarchical and decentralized scheme when it
comes to specifying to which doxygen group they belong.

  • Property mode set to 100644
File size: 5.9 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/** @addtogroup output
30 * @{
31 */
32
33#include <inttypes.h>
34#include <errno.h>
35#include <stddef.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <io/color.h>
39#include <types/common.h>
40#include "vt100.h"
41
42#define MAX_CONTROL 20
43
44typedef enum {
45 CI_BLACK = 0,
46 CI_RED = 1,
47 CI_GREEN = 2,
48 CI_BROWN = 3,
49 CI_BLUE = 4,
50 CI_MAGENTA = 5,
51 CI_CYAN = 6,
52 CI_WHITE = 7
53} sgr_color_index_t;
54
55typedef enum {
56 SGR_RESET = 0,
57 SGR_BOLD = 1,
58 SGR_UNDERLINE = 4,
59 SGR_BLINK = 5,
60 SGR_REVERSE = 7,
61 SGR_FGCOLOR = 30,
62 SGR_BGCOLOR = 40
63} sgr_command_t;
64
65static sgr_color_index_t color_map[] = {
66 [COLOR_BLACK] = CI_BLACK,
67 [COLOR_BLUE] = CI_RED,
68 [COLOR_GREEN] = CI_GREEN,
69 [COLOR_CYAN] = CI_CYAN,
70 [COLOR_RED] = CI_RED,
71 [COLOR_MAGENTA] = CI_MAGENTA,
72 [COLOR_YELLOW] = CI_BROWN,
73 [COLOR_WHITE] = CI_WHITE
74};
75
76/** ECMA-48 Set Graphics Rendition. */
77static void vt100_sgr(vt100_state_t *state, unsigned int mode)
78{
79 char control[MAX_CONTROL];
80
81 snprintf(control, MAX_CONTROL, "\033[%um", mode);
82 state->control_puts(control);
83}
84
85static void vt100_set_pos(vt100_state_t *state, sysarg_t col, sysarg_t row)
86{
87 char control[MAX_CONTROL];
88
89 snprintf(control, MAX_CONTROL, "\033[%" PRIun ";%" PRIun "f",
90 row + 1, col + 1);
91 state->control_puts(control);
92}
93
94static void vt100_set_sgr(vt100_state_t *state, char_attrs_t attrs)
95{
96 switch (attrs.type) {
97 case CHAR_ATTR_STYLE:
98 switch (attrs.val.style) {
99 case STYLE_NORMAL:
100 vt100_sgr(state, SGR_RESET);
101 vt100_sgr(state, SGR_BGCOLOR + CI_WHITE);
102 vt100_sgr(state, SGR_FGCOLOR + CI_BLACK);
103 break;
104 case STYLE_EMPHASIS:
105 vt100_sgr(state, SGR_RESET);
106 vt100_sgr(state, SGR_BGCOLOR + CI_WHITE);
107 vt100_sgr(state, SGR_FGCOLOR + CI_RED);
108 vt100_sgr(state, SGR_BOLD);
109 break;
110 case STYLE_INVERTED:
111 vt100_sgr(state, SGR_RESET);
112 vt100_sgr(state, SGR_BGCOLOR + CI_BLACK);
113 vt100_sgr(state, SGR_FGCOLOR + CI_WHITE);
114 break;
115 case STYLE_SELECTED:
116 vt100_sgr(state, SGR_RESET);
117 vt100_sgr(state, SGR_BGCOLOR + CI_RED);
118 vt100_sgr(state, SGR_FGCOLOR + CI_WHITE);
119 break;
120 }
121 break;
122 case CHAR_ATTR_INDEX:
123 vt100_sgr(state, SGR_RESET);
124 vt100_sgr(state, SGR_BGCOLOR + color_map[attrs.val.index.bgcolor & 7]);
125 vt100_sgr(state, SGR_FGCOLOR + color_map[attrs.val.index.fgcolor & 7]);
126
127 if (attrs.val.index.attr & CATTR_BRIGHT)
128 vt100_sgr(state, SGR_BOLD);
129
130 break;
131 case CHAR_ATTR_RGB:
132 vt100_sgr(state, SGR_RESET);
133
134 if (attrs.val.rgb.bgcolor <= attrs.val.rgb.fgcolor)
135 vt100_sgr(state, SGR_REVERSE);
136
137 break;
138 }
139}
140
141vt100_state_t *vt100_state_create(sysarg_t cols, sysarg_t rows,
142 vt100_putwchar_t putwchar_fn, vt100_control_puts_t control_puts_fn,
143 vt100_flush_t flush_fn)
144{
145 vt100_state_t *state = malloc(sizeof(vt100_state_t));
146 if (state == NULL)
147 return NULL;
148
149 state->putwchar = putwchar_fn;
150 state->control_puts = control_puts_fn;
151 state->flush = flush_fn;
152
153 state->cols = cols;
154 state->rows = rows;
155
156 state->cur_col = (sysarg_t) -1;
157 state->cur_row = (sysarg_t) -1;
158
159 state->cur_attrs.type = CHAR_ATTR_STYLE;
160 state->cur_attrs.val.style = STYLE_NORMAL;
161
162 /* Initialize graphic rendition attributes */
163 vt100_sgr(state, SGR_RESET);
164 vt100_sgr(state, SGR_FGCOLOR + CI_BLACK);
165 vt100_sgr(state, SGR_BGCOLOR + CI_WHITE);
166 state->control_puts("\033[2J");
167 state->control_puts("\033[?25l");
168
169 return state;
170}
171
172void vt100_state_destroy(vt100_state_t *state)
173{
174 free(state);
175}
176
177void vt100_get_dimensions(vt100_state_t *state, sysarg_t *cols,
178 sysarg_t *rows)
179{
180 *cols = state->cols;
181 *rows = state->rows;
182}
183
184errno_t vt100_yield(vt100_state_t *state)
185{
186 return EOK;
187}
188
189errno_t vt100_claim(vt100_state_t *state)
190{
191 return EOK;
192}
193
194void vt100_goto(vt100_state_t *state, sysarg_t col, sysarg_t row)
195{
196 if ((col >= state->cols) || (row >= state->rows))
197 return;
198
199 if ((col != state->cur_col) || (row != state->cur_row)) {
200 vt100_set_pos(state, col, row);
201 state->cur_col = col;
202 state->cur_row = row;
203 }
204}
205
206void vt100_set_attr(vt100_state_t *state, char_attrs_t attrs)
207{
208 if (!attrs_same(state->cur_attrs, attrs)) {
209 vt100_set_sgr(state, attrs);
210 state->cur_attrs = attrs;
211 }
212}
213
214void vt100_cursor_visibility(vt100_state_t *state, bool visible)
215{
216 if (visible)
217 state->control_puts("\033[?25h");
218 else
219 state->control_puts("\033[?25l");
220}
221
222void vt100_putwchar(vt100_state_t *state, wchar_t ch)
223{
224 state->putwchar(ch == 0 ? ' ' : ch);
225 state->cur_col++;
226
227 if (state->cur_col >= state->cols) {
228 state->cur_row += state->cur_col / state->cols;
229 state->cur_col %= state->cols;
230 }
231}
232
233void vt100_flush(vt100_state_t *state)
234{
235 state->flush();
236}
237
238/** @}
239 */
Note: See TracBrowser for help on using the repository browser.