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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 57dea62 was 6d5e378, checked in by Martin Decky <martin@…>, 13 years ago

cherrypick GUI implementation (originally by Petr Koupy), with several major changes

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