Statistics
| Branch: | Revision:

root / console.c @ ea785922

History | View | Annotate | Download (33.2 kB)

1 e7f0ad58 bellard
/*
2 e7f0ad58 bellard
 * QEMU graphical console
3 e7f0ad58 bellard
 * 
4 e7f0ad58 bellard
 * Copyright (c) 2004 Fabrice Bellard
5 e7f0ad58 bellard
 * 
6 e7f0ad58 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 e7f0ad58 bellard
 * of this software and associated documentation files (the "Software"), to deal
8 e7f0ad58 bellard
 * in the Software without restriction, including without limitation the rights
9 e7f0ad58 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 e7f0ad58 bellard
 * copies of the Software, and to permit persons to whom the Software is
11 e7f0ad58 bellard
 * furnished to do so, subject to the following conditions:
12 e7f0ad58 bellard
 *
13 e7f0ad58 bellard
 * The above copyright notice and this permission notice shall be included in
14 e7f0ad58 bellard
 * all copies or substantial portions of the Software.
15 e7f0ad58 bellard
 *
16 e7f0ad58 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 e7f0ad58 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 e7f0ad58 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 e7f0ad58 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 e7f0ad58 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 e7f0ad58 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 e7f0ad58 bellard
 * THE SOFTWARE.
23 e7f0ad58 bellard
 */
24 e7f0ad58 bellard
#include "vl.h"
25 e7f0ad58 bellard
26 6d6f7c28 pbrook
//#define DEBUG_CONSOLE
27 e7f0ad58 bellard
#define DEFAULT_BACKSCROLL 512
28 e7f0ad58 bellard
#define MAX_CONSOLES 12
29 e7f0ad58 bellard
30 26489844 bellard
#define QEMU_RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
31 26489844 bellard
#define QEMU_RGB(r, g, b) QEMU_RGBA(r, g, b, 0xff)
32 e7f0ad58 bellard
33 6d6f7c28 pbrook
typedef struct TextAttributes {
34 6d6f7c28 pbrook
    uint8_t fgcol:4;
35 6d6f7c28 pbrook
    uint8_t bgcol:4;
36 6d6f7c28 pbrook
    uint8_t bold:1;
37 6d6f7c28 pbrook
    uint8_t uline:1;
38 6d6f7c28 pbrook
    uint8_t blink:1;
39 6d6f7c28 pbrook
    uint8_t invers:1;
40 6d6f7c28 pbrook
    uint8_t unvisible:1;
41 6d6f7c28 pbrook
} TextAttributes;
42 6d6f7c28 pbrook
43 e7f0ad58 bellard
typedef struct TextCell {
44 e7f0ad58 bellard
    uint8_t ch;
45 6d6f7c28 pbrook
    TextAttributes t_attrib;
46 e7f0ad58 bellard
} TextCell;
47 e7f0ad58 bellard
48 e7f0ad58 bellard
#define MAX_ESC_PARAMS 3
49 e7f0ad58 bellard
50 e7f0ad58 bellard
enum TTYState {
51 e7f0ad58 bellard
    TTY_STATE_NORM,
52 e7f0ad58 bellard
    TTY_STATE_ESC,
53 e7f0ad58 bellard
    TTY_STATE_CSI,
54 e7f0ad58 bellard
};
55 e7f0ad58 bellard
56 e15d7371 bellard
typedef struct QEMUFIFO {
57 e15d7371 bellard
    uint8_t *buf;
58 e15d7371 bellard
    int buf_size;
59 e15d7371 bellard
    int count, wptr, rptr;
60 e15d7371 bellard
} QEMUFIFO;
61 e15d7371 bellard
62 e15d7371 bellard
int qemu_fifo_write(QEMUFIFO *f, const uint8_t *buf, int len1)
63 e15d7371 bellard
{
64 e15d7371 bellard
    int l, len;
65 e15d7371 bellard
66 e15d7371 bellard
    l = f->buf_size - f->count;
67 e15d7371 bellard
    if (len1 > l)
68 e15d7371 bellard
        len1 = l;
69 e15d7371 bellard
    len = len1;
70 e15d7371 bellard
    while (len > 0) {
71 e15d7371 bellard
        l = f->buf_size - f->wptr;
72 e15d7371 bellard
        if (l > len)
73 e15d7371 bellard
            l = len;
74 e15d7371 bellard
        memcpy(f->buf + f->wptr, buf, l);
75 e15d7371 bellard
        f->wptr += l;
76 e15d7371 bellard
        if (f->wptr >= f->buf_size)
77 e15d7371 bellard
            f->wptr = 0;
78 e15d7371 bellard
        buf += l;
79 e15d7371 bellard
        len -= l;
80 e15d7371 bellard
    }
81 e15d7371 bellard
    f->count += len1;
82 e15d7371 bellard
    return len1;
83 e15d7371 bellard
}
84 e15d7371 bellard
85 e15d7371 bellard
int qemu_fifo_read(QEMUFIFO *f, uint8_t *buf, int len1)
86 e15d7371 bellard
{
87 e15d7371 bellard
    int l, len;
88 e15d7371 bellard
89 e15d7371 bellard
    if (len1 > f->count)
90 e15d7371 bellard
        len1 = f->count;
91 e15d7371 bellard
    len = len1;
92 e15d7371 bellard
    while (len > 0) {
93 e15d7371 bellard
        l = f->buf_size - f->rptr;
94 e15d7371 bellard
        if (l > len)
95 e15d7371 bellard
            l = len;
96 e15d7371 bellard
        memcpy(buf, f->buf + f->rptr, l);
97 e15d7371 bellard
        f->rptr += l;
98 e15d7371 bellard
        if (f->rptr >= f->buf_size)
99 e15d7371 bellard
            f->rptr = 0;
100 e15d7371 bellard
        buf += l;
101 e15d7371 bellard
        len -= l;
102 e15d7371 bellard
    }
103 e15d7371 bellard
    f->count -= len1;
104 e15d7371 bellard
    return len1;
105 e15d7371 bellard
}
106 e15d7371 bellard
107 95219897 pbrook
/* ??? This is mis-named.
108 95219897 pbrook
   It is used for both text and graphical consoles.  */
109 e7f0ad58 bellard
struct TextConsole {
110 e7f0ad58 bellard
    int text_console; /* true if text console */
111 e7f0ad58 bellard
    DisplayState *ds;
112 95219897 pbrook
    /* Graphic console state.  */
113 95219897 pbrook
    vga_hw_update_ptr hw_update;
114 95219897 pbrook
    vga_hw_invalidate_ptr hw_invalidate;
115 95219897 pbrook
    vga_hw_screen_dump_ptr hw_screen_dump;
116 95219897 pbrook
    void *hw;
117 95219897 pbrook
118 e7f0ad58 bellard
    int g_width, g_height;
119 e7f0ad58 bellard
    int width;
120 e7f0ad58 bellard
    int height;
121 e7f0ad58 bellard
    int total_height;
122 e7f0ad58 bellard
    int backscroll_height;
123 e7f0ad58 bellard
    int x, y;
124 adb47967 ths
    int x_saved, y_saved;
125 e7f0ad58 bellard
    int y_displayed;
126 e7f0ad58 bellard
    int y_base;
127 6d6f7c28 pbrook
    TextAttributes t_attrib_default; /* default text attributes */
128 6d6f7c28 pbrook
    TextAttributes t_attrib; /* currently active text attributes */
129 e7f0ad58 bellard
    TextCell *cells;
130 e7f0ad58 bellard
131 e7f0ad58 bellard
    enum TTYState state;
132 e7f0ad58 bellard
    int esc_params[MAX_ESC_PARAMS];
133 e7f0ad58 bellard
    int nb_esc_params;
134 e7f0ad58 bellard
135 e5b0bc44 pbrook
    CharDriverState *chr;
136 e15d7371 bellard
    /* fifo for key pressed */
137 e15d7371 bellard
    QEMUFIFO out_fifo;
138 e15d7371 bellard
    uint8_t out_fifo_buf[16];
139 e15d7371 bellard
    QEMUTimer *kbd_timer;
140 e7f0ad58 bellard
};
141 e7f0ad58 bellard
142 e7f0ad58 bellard
static TextConsole *active_console;
143 e7f0ad58 bellard
static TextConsole *consoles[MAX_CONSOLES];
144 e7f0ad58 bellard
static int nb_consoles = 0;
145 e7f0ad58 bellard
146 95219897 pbrook
void vga_hw_update(void)
147 95219897 pbrook
{
148 adb47967 ths
    if (active_console && active_console->hw_update)
149 95219897 pbrook
        active_console->hw_update(active_console->hw);
150 95219897 pbrook
}
151 95219897 pbrook
152 95219897 pbrook
void vga_hw_invalidate(void)
153 95219897 pbrook
{
154 95219897 pbrook
    if (active_console->hw_invalidate)
155 95219897 pbrook
        active_console->hw_invalidate(active_console->hw);
156 95219897 pbrook
}
157 95219897 pbrook
158 95219897 pbrook
void vga_hw_screen_dump(const char *filename)
159 95219897 pbrook
{
160 95219897 pbrook
    /* There is currently no was of specifying which screen we want to dump,
161 95219897 pbrook
       so always dump the dirst one.  */
162 95219897 pbrook
    if (consoles[0]->hw_screen_dump)
163 95219897 pbrook
        consoles[0]->hw_screen_dump(consoles[0]->hw, filename);
164 95219897 pbrook
}
165 95219897 pbrook
166 e7f0ad58 bellard
/* convert a RGBA color to a color index usable in graphic primitives */
167 e7f0ad58 bellard
static unsigned int vga_get_color(DisplayState *ds, unsigned int rgba)
168 e7f0ad58 bellard
{
169 e7f0ad58 bellard
    unsigned int r, g, b, color;
170 e7f0ad58 bellard
171 e7f0ad58 bellard
    switch(ds->depth) {
172 e7f0ad58 bellard
#if 0
173 e7f0ad58 bellard
    case 8:
174 e7f0ad58 bellard
        r = (rgba >> 16) & 0xff;
175 e7f0ad58 bellard
        g = (rgba >> 8) & 0xff;
176 e7f0ad58 bellard
        b = (rgba) & 0xff;
177 e7f0ad58 bellard
        color = (rgb_to_index[r] * 6 * 6) + 
178 e7f0ad58 bellard
            (rgb_to_index[g] * 6) + 
179 e7f0ad58 bellard
            (rgb_to_index[b]);
180 e7f0ad58 bellard
        break;
181 e7f0ad58 bellard
#endif
182 e7f0ad58 bellard
    case 15:
183 e7f0ad58 bellard
        r = (rgba >> 16) & 0xff;
184 e7f0ad58 bellard
        g = (rgba >> 8) & 0xff;
185 e7f0ad58 bellard
        b = (rgba) & 0xff;
186 e7f0ad58 bellard
        color = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
187 e7f0ad58 bellard
        break;
188 e7f0ad58 bellard
    case 16:
189 e7f0ad58 bellard
        r = (rgba >> 16) & 0xff;
190 e7f0ad58 bellard
        g = (rgba >> 8) & 0xff;
191 e7f0ad58 bellard
        b = (rgba) & 0xff;
192 e7f0ad58 bellard
        color = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
193 e7f0ad58 bellard
        break;
194 e7f0ad58 bellard
    case 32:
195 e7f0ad58 bellard
    default:
196 e7f0ad58 bellard
        color = rgba;
197 e7f0ad58 bellard
        break;
198 e7f0ad58 bellard
    }
199 e7f0ad58 bellard
    return color;
200 e7f0ad58 bellard
}
201 e7f0ad58 bellard
202 e7f0ad58 bellard
static void vga_fill_rect (DisplayState *ds, 
203 e7f0ad58 bellard
                           int posx, int posy, int width, int height, uint32_t color)
204 e7f0ad58 bellard
{
205 e7f0ad58 bellard
    uint8_t *d, *d1;
206 e7f0ad58 bellard
    int x, y, bpp;
207 e7f0ad58 bellard
    
208 e7f0ad58 bellard
    bpp = (ds->depth + 7) >> 3;
209 e7f0ad58 bellard
    d1 = ds->data + 
210 e7f0ad58 bellard
        ds->linesize * posy + bpp * posx;
211 e7f0ad58 bellard
    for (y = 0; y < height; y++) {
212 e7f0ad58 bellard
        d = d1;
213 e7f0ad58 bellard
        switch(bpp) {
214 e7f0ad58 bellard
        case 1:
215 e7f0ad58 bellard
            for (x = 0; x < width; x++) {
216 e7f0ad58 bellard
                *((uint8_t *)d) = color;
217 e7f0ad58 bellard
                d++;
218 e7f0ad58 bellard
            }
219 e7f0ad58 bellard
            break;
220 e7f0ad58 bellard
        case 2:
221 e7f0ad58 bellard
            for (x = 0; x < width; x++) {
222 e7f0ad58 bellard
                *((uint16_t *)d) = color;
223 e7f0ad58 bellard
                d += 2;
224 e7f0ad58 bellard
            }
225 e7f0ad58 bellard
            break;
226 e7f0ad58 bellard
        case 4:
227 e7f0ad58 bellard
            for (x = 0; x < width; x++) {
228 e7f0ad58 bellard
                *((uint32_t *)d) = color;
229 e7f0ad58 bellard
                d += 4;
230 e7f0ad58 bellard
            }
231 e7f0ad58 bellard
            break;
232 e7f0ad58 bellard
        }
233 e7f0ad58 bellard
        d1 += ds->linesize;
234 e7f0ad58 bellard
    }
235 e7f0ad58 bellard
}
236 e7f0ad58 bellard
237 e7f0ad58 bellard
/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */
238 e7f0ad58 bellard
static void vga_bitblt(DisplayState *ds, int xs, int ys, int xd, int yd, int w, int h)
239 e7f0ad58 bellard
{
240 e7f0ad58 bellard
    const uint8_t *s;
241 e7f0ad58 bellard
    uint8_t *d;
242 e7f0ad58 bellard
    int wb, y, bpp;
243 e7f0ad58 bellard
244 e7f0ad58 bellard
    bpp = (ds->depth + 7) >> 3;
245 e7f0ad58 bellard
    wb = w * bpp;
246 e7f0ad58 bellard
    if (yd <= ys) {
247 e7f0ad58 bellard
        s = ds->data + 
248 e7f0ad58 bellard
            ds->linesize * ys + bpp * xs;
249 e7f0ad58 bellard
        d = ds->data + 
250 e7f0ad58 bellard
            ds->linesize * yd + bpp * xd;
251 e7f0ad58 bellard
        for (y = 0; y < h; y++) {
252 e7f0ad58 bellard
            memmove(d, s, wb);
253 e7f0ad58 bellard
            d += ds->linesize;
254 e7f0ad58 bellard
            s += ds->linesize;
255 e7f0ad58 bellard
        }
256 e7f0ad58 bellard
    } else {
257 e7f0ad58 bellard
        s = ds->data + 
258 e7f0ad58 bellard
            ds->linesize * (ys + h - 1) + bpp * xs;
259 e7f0ad58 bellard
        d = ds->data + 
260 e7f0ad58 bellard
            ds->linesize * (yd + h - 1) + bpp * xd;
261 e7f0ad58 bellard
       for (y = 0; y < h; y++) {
262 e7f0ad58 bellard
            memmove(d, s, wb);
263 e7f0ad58 bellard
            d -= ds->linesize;
264 e7f0ad58 bellard
            s -= ds->linesize;
265 e7f0ad58 bellard
        }
266 e7f0ad58 bellard
    }
267 e7f0ad58 bellard
}
268 e7f0ad58 bellard
269 e7f0ad58 bellard
/***********************************************************/
270 e7f0ad58 bellard
/* basic char display */
271 e7f0ad58 bellard
272 e7f0ad58 bellard
#define FONT_HEIGHT 16
273 e7f0ad58 bellard
#define FONT_WIDTH 8
274 e7f0ad58 bellard
275 e7f0ad58 bellard
#include "vgafont.h"
276 e7f0ad58 bellard
277 e7f0ad58 bellard
#define cbswap_32(__x) \
278 e7f0ad58 bellard
((uint32_t)( \
279 e7f0ad58 bellard
                (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
280 e7f0ad58 bellard
                (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
281 e7f0ad58 bellard
                (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
282 e7f0ad58 bellard
                (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
283 e7f0ad58 bellard
284 e7f0ad58 bellard
#ifdef WORDS_BIGENDIAN
285 e7f0ad58 bellard
#define PAT(x) x
286 e7f0ad58 bellard
#else
287 e7f0ad58 bellard
#define PAT(x) cbswap_32(x)
288 e7f0ad58 bellard
#endif
289 e7f0ad58 bellard
290 e7f0ad58 bellard
static const uint32_t dmask16[16] = {
291 e7f0ad58 bellard
    PAT(0x00000000),
292 e7f0ad58 bellard
    PAT(0x000000ff),
293 e7f0ad58 bellard
    PAT(0x0000ff00),
294 e7f0ad58 bellard
    PAT(0x0000ffff),
295 e7f0ad58 bellard
    PAT(0x00ff0000),
296 e7f0ad58 bellard
    PAT(0x00ff00ff),
297 e7f0ad58 bellard
    PAT(0x00ffff00),
298 e7f0ad58 bellard
    PAT(0x00ffffff),
299 e7f0ad58 bellard
    PAT(0xff000000),
300 e7f0ad58 bellard
    PAT(0xff0000ff),
301 e7f0ad58 bellard
    PAT(0xff00ff00),
302 e7f0ad58 bellard
    PAT(0xff00ffff),
303 e7f0ad58 bellard
    PAT(0xffff0000),
304 e7f0ad58 bellard
    PAT(0xffff00ff),
305 e7f0ad58 bellard
    PAT(0xffffff00),
306 e7f0ad58 bellard
    PAT(0xffffffff),
307 e7f0ad58 bellard
};
308 e7f0ad58 bellard
309 e7f0ad58 bellard
static const uint32_t dmask4[4] = {
310 e7f0ad58 bellard
    PAT(0x00000000),
311 e7f0ad58 bellard
    PAT(0x0000ffff),
312 e7f0ad58 bellard
    PAT(0xffff0000),
313 e7f0ad58 bellard
    PAT(0xffffffff),
314 e7f0ad58 bellard
};
315 e7f0ad58 bellard
316 6d6f7c28 pbrook
static uint32_t color_table[2][8];
317 6d6f7c28 pbrook
318 6d6f7c28 pbrook
enum color_names {
319 6d6f7c28 pbrook
    COLOR_BLACK   = 0,
320 6d6f7c28 pbrook
    COLOR_RED     = 1,
321 6d6f7c28 pbrook
    COLOR_GREEN   = 2,
322 6d6f7c28 pbrook
    COLOR_YELLOW  = 3,
323 6d6f7c28 pbrook
    COLOR_BLUE    = 4,
324 6d6f7c28 pbrook
    COLOR_MAGENTA = 5,
325 6d6f7c28 pbrook
    COLOR_CYAN    = 6,
326 6d6f7c28 pbrook
    COLOR_WHITE   = 7
327 6d6f7c28 pbrook
};
328 6d6f7c28 pbrook
329 6d6f7c28 pbrook
static const uint32_t color_table_rgb[2][8] = {
330 6d6f7c28 pbrook
    {   /* dark */
331 26489844 bellard
        QEMU_RGB(0x00, 0x00, 0x00),  /* black */
332 26489844 bellard
        QEMU_RGB(0xaa, 0x00, 0x00),  /* red */
333 26489844 bellard
        QEMU_RGB(0x00, 0xaa, 0x00),  /* green */
334 26489844 bellard
        QEMU_RGB(0xaa, 0xaa, 0x00),  /* yellow */
335 26489844 bellard
        QEMU_RGB(0x00, 0x00, 0xaa),  /* blue */
336 26489844 bellard
        QEMU_RGB(0xaa, 0x00, 0xaa),  /* magenta */
337 26489844 bellard
        QEMU_RGB(0x00, 0xaa, 0xaa),  /* cyan */
338 26489844 bellard
        QEMU_RGB(0xaa, 0xaa, 0xaa),  /* white */
339 6d6f7c28 pbrook
    },
340 6d6f7c28 pbrook
    {   /* bright */
341 26489844 bellard
        QEMU_RGB(0x00, 0x00, 0x00),  /* black */
342 26489844 bellard
        QEMU_RGB(0xff, 0x00, 0x00),  /* red */
343 26489844 bellard
        QEMU_RGB(0x00, 0xff, 0x00),  /* green */
344 26489844 bellard
        QEMU_RGB(0xff, 0xff, 0x00),  /* yellow */
345 26489844 bellard
        QEMU_RGB(0x00, 0x00, 0xff),  /* blue */
346 26489844 bellard
        QEMU_RGB(0xff, 0x00, 0xff),  /* magenta */
347 26489844 bellard
        QEMU_RGB(0x00, 0xff, 0xff),  /* cyan */
348 26489844 bellard
        QEMU_RGB(0xff, 0xff, 0xff),  /* white */
349 6d6f7c28 pbrook
    }
350 e7f0ad58 bellard
};
351 e7f0ad58 bellard
352 e7f0ad58 bellard
static inline unsigned int col_expand(DisplayState *ds, unsigned int col)
353 e7f0ad58 bellard
{
354 e7f0ad58 bellard
    switch(ds->depth) {
355 e7f0ad58 bellard
    case 8:
356 e7f0ad58 bellard
        col |= col << 8;
357 e7f0ad58 bellard
        col |= col << 16;
358 e7f0ad58 bellard
        break;
359 e7f0ad58 bellard
    case 15:
360 e7f0ad58 bellard
    case 16:
361 e7f0ad58 bellard
        col |= col << 16;
362 e7f0ad58 bellard
        break;
363 e7f0ad58 bellard
    default:
364 e7f0ad58 bellard
        break;
365 e7f0ad58 bellard
    }
366 e7f0ad58 bellard
367 e7f0ad58 bellard
    return col;
368 e7f0ad58 bellard
}
369 6d6f7c28 pbrook
#ifdef DEBUG_CONSOLE
370 6d6f7c28 pbrook
static void console_print_text_attributes(TextAttributes *t_attrib, char ch)
371 6d6f7c28 pbrook
{
372 6d6f7c28 pbrook
    if (t_attrib->bold) {
373 6d6f7c28 pbrook
        printf("b");
374 6d6f7c28 pbrook
    } else {
375 6d6f7c28 pbrook
        printf(" ");
376 6d6f7c28 pbrook
    }
377 6d6f7c28 pbrook
    if (t_attrib->uline) {
378 6d6f7c28 pbrook
        printf("u");
379 6d6f7c28 pbrook
    } else {
380 6d6f7c28 pbrook
        printf(" ");
381 6d6f7c28 pbrook
    }
382 6d6f7c28 pbrook
    if (t_attrib->blink) {
383 6d6f7c28 pbrook
        printf("l");
384 6d6f7c28 pbrook
    } else {
385 6d6f7c28 pbrook
        printf(" ");
386 6d6f7c28 pbrook
    }
387 6d6f7c28 pbrook
    if (t_attrib->invers) {
388 6d6f7c28 pbrook
        printf("i");
389 6d6f7c28 pbrook
    } else {
390 6d6f7c28 pbrook
        printf(" ");
391 6d6f7c28 pbrook
    }
392 6d6f7c28 pbrook
    if (t_attrib->unvisible) {
393 6d6f7c28 pbrook
        printf("n");
394 6d6f7c28 pbrook
    } else {
395 6d6f7c28 pbrook
        printf(" ");
396 6d6f7c28 pbrook
    }
397 6d6f7c28 pbrook
398 6d6f7c28 pbrook
    printf(" fg: %d bg: %d ch:'%2X' '%c'\n", t_attrib->fgcol, t_attrib->bgcol, ch, ch);
399 6d6f7c28 pbrook
}
400 6d6f7c28 pbrook
#endif
401 e7f0ad58 bellard
402 e7f0ad58 bellard
static void vga_putcharxy(DisplayState *ds, int x, int y, int ch, 
403 6d6f7c28 pbrook
                          TextAttributes *t_attrib)
404 e7f0ad58 bellard
{
405 e7f0ad58 bellard
    uint8_t *d;
406 e7f0ad58 bellard
    const uint8_t *font_ptr;
407 e7f0ad58 bellard
    unsigned int font_data, linesize, xorcol, bpp;
408 e7f0ad58 bellard
    int i;
409 6d6f7c28 pbrook
    unsigned int fgcol, bgcol;
410 6d6f7c28 pbrook
411 6d6f7c28 pbrook
#ifdef DEBUG_CONSOLE
412 6d6f7c28 pbrook
    printf("x: %2i y: %2i", x, y);
413 6d6f7c28 pbrook
    console_print_text_attributes(t_attrib, ch);
414 6d6f7c28 pbrook
#endif
415 6d6f7c28 pbrook
416 6d6f7c28 pbrook
    if (t_attrib->invers) {
417 6d6f7c28 pbrook
        bgcol = color_table[t_attrib->bold][t_attrib->fgcol];
418 6d6f7c28 pbrook
        fgcol = color_table[t_attrib->bold][t_attrib->bgcol];
419 6d6f7c28 pbrook
    } else {
420 6d6f7c28 pbrook
        fgcol = color_table[t_attrib->bold][t_attrib->fgcol];
421 6d6f7c28 pbrook
        bgcol = color_table[t_attrib->bold][t_attrib->bgcol];
422 6d6f7c28 pbrook
    }
423 e7f0ad58 bellard
424 e7f0ad58 bellard
    bpp = (ds->depth + 7) >> 3;
425 e7f0ad58 bellard
    d = ds->data + 
426 e7f0ad58 bellard
        ds->linesize * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;
427 e7f0ad58 bellard
    linesize = ds->linesize;
428 e7f0ad58 bellard
    font_ptr = vgafont16 + FONT_HEIGHT * ch;
429 e7f0ad58 bellard
    xorcol = bgcol ^ fgcol;
430 e7f0ad58 bellard
    switch(ds->depth) {
431 e7f0ad58 bellard
    case 8:
432 e7f0ad58 bellard
        for(i = 0; i < FONT_HEIGHT; i++) {
433 e7f0ad58 bellard
            font_data = *font_ptr++;
434 6d6f7c28 pbrook
            if (t_attrib->uline
435 6d6f7c28 pbrook
                && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
436 6d6f7c28 pbrook
                font_data = 0xFFFF;
437 6d6f7c28 pbrook
            }
438 e7f0ad58 bellard
            ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
439 e7f0ad58 bellard
            ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
440 e7f0ad58 bellard
            d += linesize;
441 e7f0ad58 bellard
        }
442 e7f0ad58 bellard
        break;
443 e7f0ad58 bellard
    case 16:
444 e7f0ad58 bellard
    case 15:
445 e7f0ad58 bellard
        for(i = 0; i < FONT_HEIGHT; i++) {
446 e7f0ad58 bellard
            font_data = *font_ptr++;
447 6d6f7c28 pbrook
            if (t_attrib->uline
448 6d6f7c28 pbrook
                && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
449 6d6f7c28 pbrook
                font_data = 0xFFFF;
450 6d6f7c28 pbrook
            }
451 e7f0ad58 bellard
            ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
452 e7f0ad58 bellard
            ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
453 e7f0ad58 bellard
            ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
454 e7f0ad58 bellard
            ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
455 e7f0ad58 bellard
            d += linesize;
456 e7f0ad58 bellard
        }
457 e7f0ad58 bellard
        break;
458 e7f0ad58 bellard
    case 32:
459 e7f0ad58 bellard
        for(i = 0; i < FONT_HEIGHT; i++) {
460 e7f0ad58 bellard
            font_data = *font_ptr++;
461 6d6f7c28 pbrook
            if (t_attrib->uline && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
462 6d6f7c28 pbrook
                font_data = 0xFFFF;
463 6d6f7c28 pbrook
            }
464 e7f0ad58 bellard
            ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
465 e7f0ad58 bellard
            ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
466 e7f0ad58 bellard
            ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
467 e7f0ad58 bellard
            ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
468 e7f0ad58 bellard
            ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
469 e7f0ad58 bellard
            ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
470 e7f0ad58 bellard
            ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
471 e7f0ad58 bellard
            ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
472 e7f0ad58 bellard
            d += linesize;
473 e7f0ad58 bellard
        }
474 e7f0ad58 bellard
        break;
475 e7f0ad58 bellard
    }
476 e7f0ad58 bellard
}
477 e7f0ad58 bellard
478 e7f0ad58 bellard
static void text_console_resize(TextConsole *s)
479 e7f0ad58 bellard
{
480 e7f0ad58 bellard
    TextCell *cells, *c, *c1;
481 e7f0ad58 bellard
    int w1, x, y, last_width;
482 e7f0ad58 bellard
483 e7f0ad58 bellard
    last_width = s->width;
484 e7f0ad58 bellard
    s->width = s->g_width / FONT_WIDTH;
485 e7f0ad58 bellard
    s->height = s->g_height / FONT_HEIGHT;
486 e7f0ad58 bellard
487 e7f0ad58 bellard
    w1 = last_width;
488 e7f0ad58 bellard
    if (s->width < w1)
489 e7f0ad58 bellard
        w1 = s->width;
490 e7f0ad58 bellard
491 e7f0ad58 bellard
    cells = qemu_malloc(s->width * s->total_height * sizeof(TextCell));
492 e7f0ad58 bellard
    for(y = 0; y < s->total_height; y++) {
493 e7f0ad58 bellard
        c = &cells[y * s->width];
494 e7f0ad58 bellard
        if (w1 > 0) {
495 e7f0ad58 bellard
            c1 = &s->cells[y * last_width];
496 e7f0ad58 bellard
            for(x = 0; x < w1; x++) {
497 e7f0ad58 bellard
                *c++ = *c1++;
498 e7f0ad58 bellard
            }
499 e7f0ad58 bellard
        }
500 e7f0ad58 bellard
        for(x = w1; x < s->width; x++) {
501 e7f0ad58 bellard
            c->ch = ' ';
502 6d6f7c28 pbrook
            c->t_attrib = s->t_attrib_default;
503 e7f0ad58 bellard
            c++;
504 e7f0ad58 bellard
        }
505 e7f0ad58 bellard
    }
506 e7f0ad58 bellard
    free(s->cells);
507 e7f0ad58 bellard
    s->cells = cells;
508 e7f0ad58 bellard
}
509 e7f0ad58 bellard
510 e7f0ad58 bellard
static void update_xy(TextConsole *s, int x, int y)
511 e7f0ad58 bellard
{
512 e7f0ad58 bellard
    TextCell *c;
513 e7f0ad58 bellard
    int y1, y2;
514 e7f0ad58 bellard
515 e7f0ad58 bellard
    if (s == active_console) {
516 e7f0ad58 bellard
        y1 = (s->y_base + y) % s->total_height;
517 e7f0ad58 bellard
        y2 = y1 - s->y_displayed;
518 e7f0ad58 bellard
        if (y2 < 0)
519 e7f0ad58 bellard
            y2 += s->total_height;
520 e7f0ad58 bellard
        if (y2 < s->height) {
521 e7f0ad58 bellard
            c = &s->cells[y1 * s->width + x];
522 e7f0ad58 bellard
            vga_putcharxy(s->ds, x, y2, c->ch, 
523 6d6f7c28 pbrook
                          &(c->t_attrib));
524 e7f0ad58 bellard
            dpy_update(s->ds, x * FONT_WIDTH, y2 * FONT_HEIGHT, 
525 e7f0ad58 bellard
                       FONT_WIDTH, FONT_HEIGHT);
526 e7f0ad58 bellard
        }
527 e7f0ad58 bellard
    }
528 e7f0ad58 bellard
}
529 e7f0ad58 bellard
530 e7f0ad58 bellard
static void console_show_cursor(TextConsole *s, int show)
531 e7f0ad58 bellard
{
532 e7f0ad58 bellard
    TextCell *c;
533 e7f0ad58 bellard
    int y, y1;
534 e7f0ad58 bellard
535 e7f0ad58 bellard
    if (s == active_console) {
536 e7f0ad58 bellard
        y1 = (s->y_base + s->y) % s->total_height;
537 e7f0ad58 bellard
        y = y1 - s->y_displayed;
538 e7f0ad58 bellard
        if (y < 0)
539 e7f0ad58 bellard
            y += s->total_height;
540 e7f0ad58 bellard
        if (y < s->height) {
541 e7f0ad58 bellard
            c = &s->cells[y1 * s->width + s->x];
542 e7f0ad58 bellard
            if (show) {
543 6d6f7c28 pbrook
                TextAttributes t_attrib = s->t_attrib_default;
544 6d6f7c28 pbrook
                t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
545 6d6f7c28 pbrook
                vga_putcharxy(s->ds, s->x, y, c->ch, &t_attrib);
546 e7f0ad58 bellard
            } else {
547 e7f0ad58 bellard
                vga_putcharxy(s->ds, s->x, y, c->ch, 
548 6d6f7c28 pbrook
                              &(c->t_attrib));
549 e7f0ad58 bellard
            }
550 e7f0ad58 bellard
            dpy_update(s->ds, s->x * FONT_WIDTH, y * FONT_HEIGHT, 
551 e7f0ad58 bellard
                       FONT_WIDTH, FONT_HEIGHT);
552 e7f0ad58 bellard
        }
553 e7f0ad58 bellard
    }
554 e7f0ad58 bellard
}
555 e7f0ad58 bellard
556 e7f0ad58 bellard
static void console_refresh(TextConsole *s)
557 e7f0ad58 bellard
{
558 e7f0ad58 bellard
    TextCell *c;
559 e7f0ad58 bellard
    int x, y, y1;
560 e7f0ad58 bellard
561 e7f0ad58 bellard
    if (s != active_console) 
562 e7f0ad58 bellard
        return;
563 e7f0ad58 bellard
564 e7f0ad58 bellard
    vga_fill_rect(s->ds, 0, 0, s->ds->width, s->ds->height,
565 6d6f7c28 pbrook
                  color_table[0][COLOR_BLACK]);
566 e7f0ad58 bellard
    y1 = s->y_displayed;
567 e7f0ad58 bellard
    for(y = 0; y < s->height; y++) {
568 e7f0ad58 bellard
        c = s->cells + y1 * s->width;
569 e7f0ad58 bellard
        for(x = 0; x < s->width; x++) {
570 e7f0ad58 bellard
            vga_putcharxy(s->ds, x, y, c->ch, 
571 6d6f7c28 pbrook
                          &(c->t_attrib));
572 e7f0ad58 bellard
            c++;
573 e7f0ad58 bellard
        }
574 e7f0ad58 bellard
        if (++y1 == s->total_height)
575 e7f0ad58 bellard
            y1 = 0;
576 e7f0ad58 bellard
    }
577 e7f0ad58 bellard
    dpy_update(s->ds, 0, 0, s->ds->width, s->ds->height);
578 e7f0ad58 bellard
    console_show_cursor(s, 1);
579 e7f0ad58 bellard
}
580 e7f0ad58 bellard
581 e7f0ad58 bellard
static void console_scroll(int ydelta)
582 e7f0ad58 bellard
{
583 e7f0ad58 bellard
    TextConsole *s;
584 e7f0ad58 bellard
    int i, y1;
585 e7f0ad58 bellard
    
586 e7f0ad58 bellard
    s = active_console;
587 e7f0ad58 bellard
    if (!s || !s->text_console)
588 e7f0ad58 bellard
        return;
589 e7f0ad58 bellard
590 e7f0ad58 bellard
    if (ydelta > 0) {
591 e7f0ad58 bellard
        for(i = 0; i < ydelta; i++) {
592 e7f0ad58 bellard
            if (s->y_displayed == s->y_base)
593 e7f0ad58 bellard
                break;
594 e7f0ad58 bellard
            if (++s->y_displayed == s->total_height)
595 e7f0ad58 bellard
                s->y_displayed = 0;
596 e7f0ad58 bellard
        }
597 e7f0ad58 bellard
    } else {
598 e7f0ad58 bellard
        ydelta = -ydelta;
599 e7f0ad58 bellard
        i = s->backscroll_height;
600 e7f0ad58 bellard
        if (i > s->total_height - s->height)
601 e7f0ad58 bellard
            i = s->total_height - s->height;
602 e7f0ad58 bellard
        y1 = s->y_base - i;
603 e7f0ad58 bellard
        if (y1 < 0)
604 e7f0ad58 bellard
            y1 += s->total_height;
605 e7f0ad58 bellard
        for(i = 0; i < ydelta; i++) {
606 e7f0ad58 bellard
            if (s->y_displayed == y1)
607 e7f0ad58 bellard
                break;
608 e7f0ad58 bellard
            if (--s->y_displayed < 0)
609 e7f0ad58 bellard
                s->y_displayed = s->total_height - 1;
610 e7f0ad58 bellard
        }
611 e7f0ad58 bellard
    }
612 e7f0ad58 bellard
    console_refresh(s);
613 e7f0ad58 bellard
}
614 e7f0ad58 bellard
615 e7f0ad58 bellard
static void console_put_lf(TextConsole *s)
616 e7f0ad58 bellard
{
617 e7f0ad58 bellard
    TextCell *c;
618 e7f0ad58 bellard
    int x, y1;
619 e7f0ad58 bellard
620 e7f0ad58 bellard
    s->y++;
621 e7f0ad58 bellard
    if (s->y >= s->height) {
622 e7f0ad58 bellard
        s->y = s->height - 1;
623 6d6f7c28 pbrook
624 e7f0ad58 bellard
        if (s->y_displayed == s->y_base) {
625 e7f0ad58 bellard
            if (++s->y_displayed == s->total_height)
626 e7f0ad58 bellard
                s->y_displayed = 0;
627 e7f0ad58 bellard
        }
628 e7f0ad58 bellard
        if (++s->y_base == s->total_height)
629 e7f0ad58 bellard
            s->y_base = 0;
630 e7f0ad58 bellard
        if (s->backscroll_height < s->total_height)
631 e7f0ad58 bellard
            s->backscroll_height++;
632 e7f0ad58 bellard
        y1 = (s->y_base + s->height - 1) % s->total_height;
633 e7f0ad58 bellard
        c = &s->cells[y1 * s->width];
634 e7f0ad58 bellard
        for(x = 0; x < s->width; x++) {
635 e7f0ad58 bellard
            c->ch = ' ';
636 6d6f7c28 pbrook
            c->t_attrib = s->t_attrib_default;
637 e7f0ad58 bellard
            c++;
638 e7f0ad58 bellard
        }
639 e7f0ad58 bellard
        if (s == active_console && s->y_displayed == s->y_base) {
640 e7f0ad58 bellard
            vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0, 
641 e7f0ad58 bellard
                       s->width * FONT_WIDTH, 
642 e7f0ad58 bellard
                       (s->height - 1) * FONT_HEIGHT);
643 e7f0ad58 bellard
            vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT,
644 e7f0ad58 bellard
                          s->width * FONT_WIDTH, FONT_HEIGHT, 
645 6d6f7c28 pbrook
                          color_table[0][s->t_attrib_default.bgcol]);
646 e7f0ad58 bellard
            dpy_update(s->ds, 0, 0, 
647 e7f0ad58 bellard
                       s->width * FONT_WIDTH, s->height * FONT_HEIGHT);
648 e7f0ad58 bellard
        }
649 e7f0ad58 bellard
    }
650 e7f0ad58 bellard
}
651 e7f0ad58 bellard
652 6d6f7c28 pbrook
/* Set console attributes depending on the current escape codes.
653 6d6f7c28 pbrook
 * NOTE: I know this code is not very efficient (checking every color for it
654 6d6f7c28 pbrook
 * self) but it is more readable and better maintainable.
655 6d6f7c28 pbrook
 */
656 6d6f7c28 pbrook
static void console_handle_escape(TextConsole *s)
657 6d6f7c28 pbrook
{
658 6d6f7c28 pbrook
    int i;
659 6d6f7c28 pbrook
660 6d6f7c28 pbrook
    for (i=0; i<s->nb_esc_params; i++) {
661 6d6f7c28 pbrook
        switch (s->esc_params[i]) {
662 6d6f7c28 pbrook
            case 0: /* reset all console attributes to default */
663 6d6f7c28 pbrook
                s->t_attrib = s->t_attrib_default;
664 6d6f7c28 pbrook
                break;
665 6d6f7c28 pbrook
            case 1:
666 6d6f7c28 pbrook
                s->t_attrib.bold = 1;
667 6d6f7c28 pbrook
                break;
668 6d6f7c28 pbrook
            case 4:
669 6d6f7c28 pbrook
                s->t_attrib.uline = 1;
670 6d6f7c28 pbrook
                break;
671 6d6f7c28 pbrook
            case 5:
672 6d6f7c28 pbrook
                s->t_attrib.blink = 1;
673 6d6f7c28 pbrook
                break;
674 6d6f7c28 pbrook
            case 7:
675 6d6f7c28 pbrook
                s->t_attrib.invers = 1;
676 6d6f7c28 pbrook
                break;
677 6d6f7c28 pbrook
            case 8:
678 6d6f7c28 pbrook
                s->t_attrib.unvisible = 1;
679 6d6f7c28 pbrook
                break;
680 6d6f7c28 pbrook
            case 22:
681 6d6f7c28 pbrook
                s->t_attrib.bold = 0;
682 6d6f7c28 pbrook
                break;
683 6d6f7c28 pbrook
            case 24:
684 6d6f7c28 pbrook
                s->t_attrib.uline = 0;
685 6d6f7c28 pbrook
                break;
686 6d6f7c28 pbrook
            case 25:
687 6d6f7c28 pbrook
                s->t_attrib.blink = 0;
688 6d6f7c28 pbrook
                break;
689 6d6f7c28 pbrook
            case 27:
690 6d6f7c28 pbrook
                s->t_attrib.invers = 0;
691 6d6f7c28 pbrook
                break;
692 6d6f7c28 pbrook
            case 28:
693 6d6f7c28 pbrook
                s->t_attrib.unvisible = 0;
694 6d6f7c28 pbrook
                break;
695 6d6f7c28 pbrook
            /* set foreground color */
696 6d6f7c28 pbrook
            case 30:
697 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_BLACK;
698 6d6f7c28 pbrook
                break;
699 6d6f7c28 pbrook
            case 31:
700 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_RED;
701 6d6f7c28 pbrook
                break;
702 6d6f7c28 pbrook
            case 32:
703 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_GREEN;
704 6d6f7c28 pbrook
                break;
705 6d6f7c28 pbrook
            case 33:
706 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_YELLOW;
707 6d6f7c28 pbrook
                break;
708 6d6f7c28 pbrook
            case 34:
709 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_BLUE;
710 6d6f7c28 pbrook
                break;
711 6d6f7c28 pbrook
            case 35:
712 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_MAGENTA;
713 6d6f7c28 pbrook
                break;
714 6d6f7c28 pbrook
            case 36:
715 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_CYAN;
716 6d6f7c28 pbrook
                break;
717 6d6f7c28 pbrook
            case 37:
718 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_WHITE;
719 6d6f7c28 pbrook
                break;
720 6d6f7c28 pbrook
            /* set background color */
721 6d6f7c28 pbrook
            case 40:
722 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_BLACK;
723 6d6f7c28 pbrook
                break;
724 6d6f7c28 pbrook
            case 41:
725 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_RED;
726 6d6f7c28 pbrook
                break;
727 6d6f7c28 pbrook
            case 42:
728 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_GREEN;
729 6d6f7c28 pbrook
                break;
730 6d6f7c28 pbrook
            case 43:
731 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_YELLOW;
732 6d6f7c28 pbrook
                break;
733 6d6f7c28 pbrook
            case 44:
734 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_BLUE;
735 6d6f7c28 pbrook
                break;
736 6d6f7c28 pbrook
            case 45:
737 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_MAGENTA;
738 6d6f7c28 pbrook
                break;
739 6d6f7c28 pbrook
            case 46:
740 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_CYAN;
741 6d6f7c28 pbrook
                break;
742 6d6f7c28 pbrook
            case 47:
743 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_WHITE;
744 6d6f7c28 pbrook
                break;
745 6d6f7c28 pbrook
        }
746 6d6f7c28 pbrook
    }
747 6d6f7c28 pbrook
}
748 6d6f7c28 pbrook
749 adb47967 ths
static void console_clear_xy(TextConsole *s, int x, int y)
750 adb47967 ths
{
751 adb47967 ths
    int y1 = (s->y_base + y) % s->total_height;
752 adb47967 ths
    TextCell *c = &s->cells[y1 * s->width + x];
753 adb47967 ths
    c->ch = ' ';
754 adb47967 ths
    c->t_attrib = s->t_attrib_default;
755 adb47967 ths
    c++;
756 adb47967 ths
    update_xy(s, x, y);
757 adb47967 ths
}
758 adb47967 ths
759 e7f0ad58 bellard
static void console_putchar(TextConsole *s, int ch)
760 e7f0ad58 bellard
{
761 e7f0ad58 bellard
    TextCell *c;
762 adb47967 ths
    int y1, i;
763 adb47967 ths
    int x, y;
764 e7f0ad58 bellard
765 e7f0ad58 bellard
    switch(s->state) {
766 e7f0ad58 bellard
    case TTY_STATE_NORM:
767 e7f0ad58 bellard
        switch(ch) {
768 6d6f7c28 pbrook
        case '\r':  /* carriage return */
769 e7f0ad58 bellard
            s->x = 0;
770 e7f0ad58 bellard
            break;
771 6d6f7c28 pbrook
        case '\n':  /* newline */
772 e7f0ad58 bellard
            console_put_lf(s);
773 e7f0ad58 bellard
            break;
774 6d6f7c28 pbrook
        case '\b':  /* backspace */
775 e15d7371 bellard
            if (s->x > 0) 
776 e15d7371 bellard
                s->x--;
777 6d6f7c28 pbrook
            break;
778 6d6f7c28 pbrook
        case '\t':  /* tabspace */
779 6d6f7c28 pbrook
            if (s->x + (8 - (s->x % 8)) > s->width) {
780 bd468840 bellard
                s->x = 0;
781 6d6f7c28 pbrook
                console_put_lf(s);
782 6d6f7c28 pbrook
            } else {
783 6d6f7c28 pbrook
                s->x = s->x + (8 - (s->x % 8));
784 6d6f7c28 pbrook
            }
785 6d6f7c28 pbrook
            break;
786 6d6f7c28 pbrook
        case '\a':  /* alert aka. bell */
787 6d6f7c28 pbrook
            /* TODO: has to be implemented */
788 6d6f7c28 pbrook
            break;
789 adb47967 ths
        case 14:
790 adb47967 ths
            /* SI (shift in), character set 0 (ignored) */
791 adb47967 ths
            break;
792 adb47967 ths
        case 15:
793 adb47967 ths
            /* SO (shift out), character set 1 (ignored) */
794 adb47967 ths
            break;
795 6d6f7c28 pbrook
        case 27:    /* esc (introducing an escape sequence) */
796 e7f0ad58 bellard
            s->state = TTY_STATE_ESC;
797 e7f0ad58 bellard
            break;
798 e7f0ad58 bellard
        default:
799 adb47967 ths
            if (s->x >= s->width - 1) {
800 adb47967 ths
                break;
801 adb47967 ths
            }
802 e7f0ad58 bellard
            y1 = (s->y_base + s->y) % s->total_height;
803 e7f0ad58 bellard
            c = &s->cells[y1 * s->width + s->x];
804 e7f0ad58 bellard
            c->ch = ch;
805 6d6f7c28 pbrook
            c->t_attrib = s->t_attrib;
806 e7f0ad58 bellard
            update_xy(s, s->x, s->y);
807 e7f0ad58 bellard
            s->x++;
808 adb47967 ths
#if 0 /* line wrap disabled */
809 bd468840 bellard
            if (s->x >= s->width) {
810 bd468840 bellard
                s->x = 0;
811 e7f0ad58 bellard
                console_put_lf(s);
812 bd468840 bellard
            }
813 adb47967 ths
#endif
814 e7f0ad58 bellard
            break;
815 e7f0ad58 bellard
        }
816 e7f0ad58 bellard
        break;
817 6d6f7c28 pbrook
    case TTY_STATE_ESC: /* check if it is a terminal escape sequence */
818 e7f0ad58 bellard
        if (ch == '[') {
819 e7f0ad58 bellard
            for(i=0;i<MAX_ESC_PARAMS;i++)
820 e7f0ad58 bellard
                s->esc_params[i] = 0;
821 e7f0ad58 bellard
            s->nb_esc_params = 0;
822 e7f0ad58 bellard
            s->state = TTY_STATE_CSI;
823 e7f0ad58 bellard
        } else {
824 e7f0ad58 bellard
            s->state = TTY_STATE_NORM;
825 e7f0ad58 bellard
        }
826 e7f0ad58 bellard
        break;
827 6d6f7c28 pbrook
    case TTY_STATE_CSI: /* handle escape sequence parameters */
828 e7f0ad58 bellard
        if (ch >= '0' && ch <= '9') {
829 e7f0ad58 bellard
            if (s->nb_esc_params < MAX_ESC_PARAMS) {
830 e7f0ad58 bellard
                s->esc_params[s->nb_esc_params] = 
831 e7f0ad58 bellard
                    s->esc_params[s->nb_esc_params] * 10 + ch - '0';
832 e7f0ad58 bellard
            }
833 e7f0ad58 bellard
        } else {
834 e7f0ad58 bellard
            s->nb_esc_params++;
835 e7f0ad58 bellard
            if (ch == ';')
836 e7f0ad58 bellard
                break;
837 adb47967 ths
#ifdef DEBUG_CONSOLE
838 adb47967 ths
            fprintf(stderr, "escape sequence CSI%d;%d%c, %d parameters\n",
839 adb47967 ths
                    s->esc_params[0], s->esc_params[1], ch, s->nb_esc_params);
840 adb47967 ths
#endif
841 e7f0ad58 bellard
            s->state = TTY_STATE_NORM;
842 e7f0ad58 bellard
            switch(ch) {
843 adb47967 ths
            case 'A':
844 adb47967 ths
                /* move cursor up */
845 adb47967 ths
                if (s->esc_params[0] == 0) {
846 adb47967 ths
                    s->esc_params[0] = 1;
847 adb47967 ths
                }
848 adb47967 ths
                s->y -= s->esc_params[0];
849 adb47967 ths
                if (s->y < 0) {
850 adb47967 ths
                    s->y = 0;
851 adb47967 ths
                }
852 adb47967 ths
                break;
853 adb47967 ths
            case 'B':
854 adb47967 ths
                /* move cursor down */
855 adb47967 ths
                if (s->esc_params[0] == 0) {
856 adb47967 ths
                    s->esc_params[0] = 1;
857 adb47967 ths
                }
858 adb47967 ths
                s->y += s->esc_params[0];
859 adb47967 ths
                if (s->y >= s->height) {
860 adb47967 ths
                    s->y = s->height - 1;
861 adb47967 ths
                }
862 e7f0ad58 bellard
                break;
863 e7f0ad58 bellard
            case 'C':
864 adb47967 ths
                /* move cursor right */
865 adb47967 ths
                if (s->esc_params[0] == 0) {
866 adb47967 ths
                    s->esc_params[0] = 1;
867 adb47967 ths
                }
868 adb47967 ths
                s->x += s->esc_params[0];
869 adb47967 ths
                if (s->x >= s->width) {
870 adb47967 ths
                    s->x = s->width - 1;
871 adb47967 ths
                }
872 e7f0ad58 bellard
                break;
873 adb47967 ths
            case 'D':
874 adb47967 ths
                /* move cursor left */
875 adb47967 ths
                if (s->esc_params[0] == 0) {
876 adb47967 ths
                    s->esc_params[0] = 1;
877 adb47967 ths
                }
878 adb47967 ths
                s->x -= s->esc_params[0];
879 adb47967 ths
                if (s->x < 0) {
880 adb47967 ths
                    s->x = 0;
881 adb47967 ths
                }
882 adb47967 ths
                break;
883 adb47967 ths
            case 'G':
884 adb47967 ths
                /* move cursor to column */
885 adb47967 ths
                s->x = s->esc_params[0] - 1;
886 adb47967 ths
                if (s->x < 0) {
887 adb47967 ths
                    s->x = 0;
888 adb47967 ths
                }
889 adb47967 ths
                break;
890 adb47967 ths
            case 'f':
891 adb47967 ths
            case 'H':
892 adb47967 ths
                /* move cursor to row, column */
893 adb47967 ths
                s->x = s->esc_params[1] - 1;
894 adb47967 ths
                if (s->x < 0) {
895 adb47967 ths
                    s->x = 0;
896 adb47967 ths
                }
897 adb47967 ths
                s->y = s->esc_params[0] - 1;
898 adb47967 ths
                if (s->y < 0) {
899 adb47967 ths
                    s->y = 0;
900 adb47967 ths
                }
901 adb47967 ths
                break;
902 adb47967 ths
            case 'J':
903 adb47967 ths
                switch (s->esc_params[0]) {
904 adb47967 ths
                case 0:
905 adb47967 ths
                    /* clear to end of screen */
906 adb47967 ths
                    for (y = s->y; y < s->height; y++) {
907 adb47967 ths
                        for (x = 0; x < s->width; x++) {
908 adb47967 ths
                            if (y == s->y && x < s->x) {
909 adb47967 ths
                                continue;
910 adb47967 ths
                            }
911 adb47967 ths
                            console_clear_xy(s, x, y);
912 adb47967 ths
                        }
913 adb47967 ths
                    }
914 adb47967 ths
                    break;
915 adb47967 ths
                case 1:
916 adb47967 ths
                    /* clear from beginning of screen */
917 adb47967 ths
                    for (y = 0; y <= s->y; y++) {
918 adb47967 ths
                        for (x = 0; x < s->width; x++) {
919 adb47967 ths
                            if (y == s->y && x > s->x) {
920 adb47967 ths
                                break;
921 adb47967 ths
                            }
922 adb47967 ths
                            console_clear_xy(s, x, y);
923 adb47967 ths
                        }
924 adb47967 ths
                    }
925 adb47967 ths
                    break;
926 adb47967 ths
                case 2:
927 adb47967 ths
                    /* clear entire screen */
928 adb47967 ths
                    for (y = 0; y <= s->height; y++) {
929 adb47967 ths
                        for (x = 0; x < s->width; x++) {
930 adb47967 ths
                            console_clear_xy(s, x, y);
931 adb47967 ths
                        }
932 adb47967 ths
                    }
933 adb47967 ths
                break;
934 adb47967 ths
                }
935 e7f0ad58 bellard
            case 'K':
936 adb47967 ths
                switch (s->esc_params[0]) {
937 adb47967 ths
                case 0:
938 e7f0ad58 bellard
                /* clear to eol */
939 e7f0ad58 bellard
                for(x = s->x; x < s->width; x++) {
940 adb47967 ths
                        console_clear_xy(s, x, s->y);
941 e7f0ad58 bellard
                }
942 e7f0ad58 bellard
                break;
943 adb47967 ths
                case 1:
944 adb47967 ths
                    /* clear from beginning of line */
945 adb47967 ths
                    for (x = 0; x <= s->x; x++) {
946 adb47967 ths
                        console_clear_xy(s, x, s->y);
947 adb47967 ths
                    }
948 adb47967 ths
                    break;
949 adb47967 ths
                case 2:
950 adb47967 ths
                    /* clear entire line */
951 adb47967 ths
                    for(x = 0; x < s->width; x++) {
952 adb47967 ths
                        console_clear_xy(s, x, s->y);
953 adb47967 ths
                    }
954 e7f0ad58 bellard
                break;
955 e7f0ad58 bellard
            }
956 adb47967 ths
                break;
957 adb47967 ths
            case 'm':
958 6d6f7c28 pbrook
            console_handle_escape(s);
959 e7f0ad58 bellard
            break;
960 adb47967 ths
            case 'n':
961 adb47967 ths
                /* report cursor position */
962 adb47967 ths
                /* TODO: send ESC[row;colR */
963 adb47967 ths
                break;
964 adb47967 ths
            case 's':
965 adb47967 ths
                /* save cursor position */
966 adb47967 ths
                s->x_saved = s->x;
967 adb47967 ths
                s->y_saved = s->y;
968 adb47967 ths
                break;
969 adb47967 ths
            case 'u':
970 adb47967 ths
                /* restore cursor position */
971 adb47967 ths
                s->x = s->x_saved;
972 adb47967 ths
                s->y = s->y_saved;
973 adb47967 ths
                break;
974 adb47967 ths
            default:
975 adb47967 ths
#ifdef DEBUG_CONSOLE
976 adb47967 ths
                fprintf(stderr, "unhandled escape character '%c'\n", ch);
977 adb47967 ths
#endif
978 adb47967 ths
                break;
979 adb47967 ths
            }
980 adb47967 ths
            break;
981 e7f0ad58 bellard
        }
982 e7f0ad58 bellard
    }
983 e7f0ad58 bellard
}
984 e7f0ad58 bellard
985 e7f0ad58 bellard
void console_select(unsigned int index)
986 e7f0ad58 bellard
{
987 e7f0ad58 bellard
    TextConsole *s;
988 6d6f7c28 pbrook
989 e7f0ad58 bellard
    if (index >= MAX_CONSOLES)
990 e7f0ad58 bellard
        return;
991 e7f0ad58 bellard
    s = consoles[index];
992 e7f0ad58 bellard
    if (s) {
993 e7f0ad58 bellard
        active_console = s;
994 e7f0ad58 bellard
        if (s->text_console) {
995 e7f0ad58 bellard
            if (s->g_width != s->ds->width ||
996 8e3a9fd2 bellard
                s->g_height != s->ds->height) {
997 6d6f7c28 pbrook
                s->g_width = s->ds->width;
998 6d6f7c28 pbrook
                s->g_height = s->ds->height;
999 e7f0ad58 bellard
                text_console_resize(s);
1000 95219897 pbrook
            }
1001 e7f0ad58 bellard
            console_refresh(s);
1002 95219897 pbrook
        } else {
1003 95219897 pbrook
            vga_hw_invalidate();
1004 e7f0ad58 bellard
        }
1005 e7f0ad58 bellard
    }
1006 e7f0ad58 bellard
}
1007 e7f0ad58 bellard
1008 e7f0ad58 bellard
static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
1009 e7f0ad58 bellard
{
1010 e7f0ad58 bellard
    TextConsole *s = chr->opaque;
1011 e7f0ad58 bellard
    int i;
1012 e7f0ad58 bellard
1013 e7f0ad58 bellard
    console_show_cursor(s, 0);
1014 e7f0ad58 bellard
    for(i = 0; i < len; i++) {
1015 e7f0ad58 bellard
        console_putchar(s, buf[i]);
1016 e7f0ad58 bellard
    }
1017 e7f0ad58 bellard
    console_show_cursor(s, 1);
1018 e7f0ad58 bellard
    return len;
1019 e7f0ad58 bellard
}
1020 e7f0ad58 bellard
1021 6fcfafb7 bellard
static void console_send_event(CharDriverState *chr, int event)
1022 6fcfafb7 bellard
{
1023 6fcfafb7 bellard
    TextConsole *s = chr->opaque;
1024 6fcfafb7 bellard
    int i;
1025 6fcfafb7 bellard
1026 6fcfafb7 bellard
    if (event == CHR_EVENT_FOCUS) {
1027 6fcfafb7 bellard
        for(i = 0; i < nb_consoles; i++) {
1028 6fcfafb7 bellard
            if (consoles[i] == s) {
1029 6fcfafb7 bellard
                console_select(i);
1030 6fcfafb7 bellard
                break;
1031 6fcfafb7 bellard
            }
1032 6fcfafb7 bellard
        }
1033 6fcfafb7 bellard
    }
1034 6fcfafb7 bellard
}
1035 6fcfafb7 bellard
1036 e15d7371 bellard
static void kbd_send_chars(void *opaque)
1037 e15d7371 bellard
{
1038 e15d7371 bellard
    TextConsole *s = opaque;
1039 e15d7371 bellard
    int len;
1040 e15d7371 bellard
    uint8_t buf[16];
1041 e15d7371 bellard
    
1042 e5b0bc44 pbrook
    len = qemu_chr_can_read(s->chr);
1043 e15d7371 bellard
    if (len > s->out_fifo.count)
1044 e15d7371 bellard
        len = s->out_fifo.count;
1045 e15d7371 bellard
    if (len > 0) {
1046 e15d7371 bellard
        if (len > sizeof(buf))
1047 e15d7371 bellard
            len = sizeof(buf);
1048 e15d7371 bellard
        qemu_fifo_read(&s->out_fifo, buf, len);
1049 e5b0bc44 pbrook
        qemu_chr_read(s->chr, buf, len);
1050 e15d7371 bellard
    }
1051 e15d7371 bellard
    /* characters are pending: we send them a bit later (XXX:
1052 e15d7371 bellard
       horrible, should change char device API) */
1053 e15d7371 bellard
    if (s->out_fifo.count > 0) {
1054 e15d7371 bellard
        qemu_mod_timer(s->kbd_timer, qemu_get_clock(rt_clock) + 1);
1055 e15d7371 bellard
    }
1056 e15d7371 bellard
}
1057 e15d7371 bellard
1058 e7f0ad58 bellard
/* called when an ascii key is pressed */
1059 e7f0ad58 bellard
void kbd_put_keysym(int keysym)
1060 e7f0ad58 bellard
{
1061 e7f0ad58 bellard
    TextConsole *s;
1062 e7f0ad58 bellard
    uint8_t buf[16], *q;
1063 e7f0ad58 bellard
    int c;
1064 e7f0ad58 bellard
1065 e7f0ad58 bellard
    s = active_console;
1066 e7f0ad58 bellard
    if (!s || !s->text_console)
1067 e7f0ad58 bellard
        return;
1068 e7f0ad58 bellard
1069 e7f0ad58 bellard
    switch(keysym) {
1070 e7f0ad58 bellard
    case QEMU_KEY_CTRL_UP:
1071 e7f0ad58 bellard
        console_scroll(-1);
1072 e7f0ad58 bellard
        break;
1073 e7f0ad58 bellard
    case QEMU_KEY_CTRL_DOWN:
1074 e7f0ad58 bellard
        console_scroll(1);
1075 e7f0ad58 bellard
        break;
1076 e7f0ad58 bellard
    case QEMU_KEY_CTRL_PAGEUP:
1077 e7f0ad58 bellard
        console_scroll(-10);
1078 e7f0ad58 bellard
        break;
1079 e7f0ad58 bellard
    case QEMU_KEY_CTRL_PAGEDOWN:
1080 e7f0ad58 bellard
        console_scroll(10);
1081 e7f0ad58 bellard
        break;
1082 e7f0ad58 bellard
    default:
1083 e15d7371 bellard
        /* convert the QEMU keysym to VT100 key string */
1084 e15d7371 bellard
        q = buf;
1085 e15d7371 bellard
        if (keysym >= 0xe100 && keysym <= 0xe11f) {
1086 e15d7371 bellard
            *q++ = '\033';
1087 e15d7371 bellard
            *q++ = '[';
1088 e15d7371 bellard
            c = keysym - 0xe100;
1089 e15d7371 bellard
            if (c >= 10)
1090 e15d7371 bellard
                *q++ = '0' + (c / 10);
1091 e15d7371 bellard
            *q++ = '0' + (c % 10);
1092 e15d7371 bellard
            *q++ = '~';
1093 e15d7371 bellard
        } else if (keysym >= 0xe120 && keysym <= 0xe17f) {
1094 e15d7371 bellard
            *q++ = '\033';
1095 e15d7371 bellard
            *q++ = '[';
1096 e15d7371 bellard
            *q++ = keysym & 0xff;
1097 e15d7371 bellard
        } else {
1098 e7f0ad58 bellard
                *q++ = keysym;
1099 e15d7371 bellard
        }
1100 e5b0bc44 pbrook
        if (s->chr->chr_read) {
1101 e15d7371 bellard
            qemu_fifo_write(&s->out_fifo, buf, q - buf);
1102 e15d7371 bellard
            kbd_send_chars(s);
1103 e7f0ad58 bellard
        }
1104 e7f0ad58 bellard
        break;
1105 e7f0ad58 bellard
    }
1106 e7f0ad58 bellard
}
1107 e7f0ad58 bellard
1108 95219897 pbrook
static TextConsole *new_console(DisplayState *ds, int text)
1109 e7f0ad58 bellard
{
1110 e7f0ad58 bellard
    TextConsole *s;
1111 95219897 pbrook
    int i;
1112 e7f0ad58 bellard
1113 e7f0ad58 bellard
    if (nb_consoles >= MAX_CONSOLES)
1114 e7f0ad58 bellard
        return NULL;
1115 e7f0ad58 bellard
    s = qemu_mallocz(sizeof(TextConsole));
1116 e7f0ad58 bellard
    if (!s) {
1117 e7f0ad58 bellard
        return NULL;
1118 e7f0ad58 bellard
    }
1119 95219897 pbrook
    if (!active_console || (active_console->text_console && !text))
1120 e7f0ad58 bellard
        active_console = s;
1121 e7f0ad58 bellard
    s->ds = ds;
1122 95219897 pbrook
    s->text_console = text;
1123 95219897 pbrook
    if (text) {
1124 95219897 pbrook
        consoles[nb_consoles++] = s;
1125 95219897 pbrook
    } else {
1126 95219897 pbrook
        /* HACK: Put graphical consoles before text consoles.  */
1127 95219897 pbrook
        for (i = nb_consoles; i > 0; i--) {
1128 95219897 pbrook
            if (!consoles[i - 1]->text_console)
1129 95219897 pbrook
                break;
1130 95219897 pbrook
            consoles[i] = consoles[i - 1];
1131 95219897 pbrook
        }
1132 95219897 pbrook
        consoles[i] = s;
1133 95219897 pbrook
    }
1134 95219897 pbrook
    return s;
1135 95219897 pbrook
}
1136 95219897 pbrook
1137 95219897 pbrook
TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update,
1138 95219897 pbrook
                                  vga_hw_invalidate_ptr invalidate,
1139 95219897 pbrook
                                  vga_hw_screen_dump_ptr screen_dump,
1140 95219897 pbrook
                                  void *opaque)
1141 95219897 pbrook
{
1142 95219897 pbrook
    TextConsole *s;
1143 95219897 pbrook
1144 95219897 pbrook
    s = new_console(ds, 0);
1145 95219897 pbrook
    if (!s)
1146 95219897 pbrook
      return NULL;
1147 95219897 pbrook
    s->hw_update = update;
1148 95219897 pbrook
    s->hw_invalidate = invalidate;
1149 95219897 pbrook
    s->hw_screen_dump = screen_dump;
1150 95219897 pbrook
    s->hw = opaque;
1151 e7f0ad58 bellard
    return s;
1152 e7f0ad58 bellard
}
1153 e7f0ad58 bellard
1154 95219897 pbrook
int is_graphic_console(void)
1155 e7f0ad58 bellard
{
1156 95219897 pbrook
    return !active_console->text_console;
1157 e7f0ad58 bellard
}
1158 e7f0ad58 bellard
1159 e7f0ad58 bellard
CharDriverState *text_console_init(DisplayState *ds)
1160 e7f0ad58 bellard
{
1161 e7f0ad58 bellard
    CharDriverState *chr;
1162 e7f0ad58 bellard
    TextConsole *s;
1163 6d6f7c28 pbrook
    int i,j;
1164 e7f0ad58 bellard
    static int color_inited;
1165 6d6f7c28 pbrook
1166 e7f0ad58 bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
1167 e7f0ad58 bellard
    if (!chr)
1168 e7f0ad58 bellard
        return NULL;
1169 95219897 pbrook
    s = new_console(ds, 1);
1170 e7f0ad58 bellard
    if (!s) {
1171 e7f0ad58 bellard
        free(chr);
1172 e7f0ad58 bellard
        return NULL;
1173 e7f0ad58 bellard
    }
1174 e7f0ad58 bellard
    chr->opaque = s;
1175 e7f0ad58 bellard
    chr->chr_write = console_puts;
1176 6fcfafb7 bellard
    chr->chr_send_event = console_send_event;
1177 6fcfafb7 bellard
1178 e5b0bc44 pbrook
    s->chr = chr;
1179 e15d7371 bellard
    s->out_fifo.buf = s->out_fifo_buf;
1180 e15d7371 bellard
    s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
1181 e15d7371 bellard
    s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);
1182 e15d7371 bellard
    
1183 e7f0ad58 bellard
    if (!color_inited) {
1184 e7f0ad58 bellard
        color_inited = 1;
1185 6d6f7c28 pbrook
        for(j = 0; j < 2; j++) {
1186 6d6f7c28 pbrook
            for(i = 0; i < 8; i++) {
1187 6d6f7c28 pbrook
                color_table[j][i] = col_expand(s->ds, 
1188 6d6f7c28 pbrook
                        vga_get_color(s->ds, color_table_rgb[j][i]));
1189 6d6f7c28 pbrook
            }
1190 e7f0ad58 bellard
        }
1191 e7f0ad58 bellard
    }
1192 e7f0ad58 bellard
    s->y_displayed = 0;
1193 e7f0ad58 bellard
    s->y_base = 0;
1194 e7f0ad58 bellard
    s->total_height = DEFAULT_BACKSCROLL;
1195 e7f0ad58 bellard
    s->x = 0;
1196 e7f0ad58 bellard
    s->y = 0;
1197 e7f0ad58 bellard
    s->g_width = s->ds->width;
1198 e7f0ad58 bellard
    s->g_height = s->ds->height;
1199 6d6f7c28 pbrook
1200 6d6f7c28 pbrook
    /* Set text attribute defaults */
1201 6d6f7c28 pbrook
    s->t_attrib_default.bold = 0;
1202 6d6f7c28 pbrook
    s->t_attrib_default.uline = 0;
1203 6d6f7c28 pbrook
    s->t_attrib_default.blink = 0;
1204 6d6f7c28 pbrook
    s->t_attrib_default.invers = 0;
1205 6d6f7c28 pbrook
    s->t_attrib_default.unvisible = 0;
1206 6d6f7c28 pbrook
    s->t_attrib_default.fgcol = COLOR_WHITE;
1207 6d6f7c28 pbrook
    s->t_attrib_default.bgcol = COLOR_BLACK;
1208 6d6f7c28 pbrook
1209 6d6f7c28 pbrook
    /* set current text attributes to default */
1210 6d6f7c28 pbrook
    s->t_attrib = s->t_attrib_default;
1211 e7f0ad58 bellard
    text_console_resize(s);
1212 e7f0ad58 bellard
1213 86e94dea ths
    qemu_chr_reset(chr);
1214 86e94dea ths
1215 e7f0ad58 bellard
    return chr;
1216 e7f0ad58 bellard
}