Statistics
| Branch: | Revision:

root / console.c @ ffe8b821

History | View | Annotate | Download (46.8 kB)

1 e7f0ad58 bellard
/*
2 e7f0ad58 bellard
 * QEMU graphical console
3 5fafdf24 ths
 *
4 e7f0ad58 bellard
 * Copyright (c) 2004 Fabrice Bellard
5 5fafdf24 ths
 *
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 87ecb68b pbrook
#include "qemu-common.h"
25 87ecb68b pbrook
#include "console.h"
26 87ecb68b pbrook
#include "qemu-timer.h"
27 e7f0ad58 bellard
28 6d6f7c28 pbrook
//#define DEBUG_CONSOLE
29 e7f0ad58 bellard
#define DEFAULT_BACKSCROLL 512
30 e7f0ad58 bellard
#define MAX_CONSOLES 12
31 e7f0ad58 bellard
32 26489844 bellard
#define QEMU_RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
33 26489844 bellard
#define QEMU_RGB(r, g, b) QEMU_RGBA(r, g, b, 0xff)
34 e7f0ad58 bellard
35 6d6f7c28 pbrook
typedef struct TextAttributes {
36 6d6f7c28 pbrook
    uint8_t fgcol:4;
37 6d6f7c28 pbrook
    uint8_t bgcol:4;
38 6d6f7c28 pbrook
    uint8_t bold:1;
39 6d6f7c28 pbrook
    uint8_t uline:1;
40 6d6f7c28 pbrook
    uint8_t blink:1;
41 6d6f7c28 pbrook
    uint8_t invers:1;
42 6d6f7c28 pbrook
    uint8_t unvisible:1;
43 6d6f7c28 pbrook
} TextAttributes;
44 6d6f7c28 pbrook
45 e7f0ad58 bellard
typedef struct TextCell {
46 e7f0ad58 bellard
    uint8_t ch;
47 6d6f7c28 pbrook
    TextAttributes t_attrib;
48 e7f0ad58 bellard
} TextCell;
49 e7f0ad58 bellard
50 e7f0ad58 bellard
#define MAX_ESC_PARAMS 3
51 e7f0ad58 bellard
52 e7f0ad58 bellard
enum TTYState {
53 e7f0ad58 bellard
    TTY_STATE_NORM,
54 e7f0ad58 bellard
    TTY_STATE_ESC,
55 e7f0ad58 bellard
    TTY_STATE_CSI,
56 e7f0ad58 bellard
};
57 e7f0ad58 bellard
58 e15d7371 bellard
typedef struct QEMUFIFO {
59 e15d7371 bellard
    uint8_t *buf;
60 e15d7371 bellard
    int buf_size;
61 e15d7371 bellard
    int count, wptr, rptr;
62 e15d7371 bellard
} QEMUFIFO;
63 e15d7371 bellard
64 9596ebb7 pbrook
static int qemu_fifo_write(QEMUFIFO *f, const uint8_t *buf, int len1)
65 e15d7371 bellard
{
66 e15d7371 bellard
    int l, len;
67 e15d7371 bellard
68 e15d7371 bellard
    l = f->buf_size - f->count;
69 e15d7371 bellard
    if (len1 > l)
70 e15d7371 bellard
        len1 = l;
71 e15d7371 bellard
    len = len1;
72 e15d7371 bellard
    while (len > 0) {
73 e15d7371 bellard
        l = f->buf_size - f->wptr;
74 e15d7371 bellard
        if (l > len)
75 e15d7371 bellard
            l = len;
76 e15d7371 bellard
        memcpy(f->buf + f->wptr, buf, l);
77 e15d7371 bellard
        f->wptr += l;
78 e15d7371 bellard
        if (f->wptr >= f->buf_size)
79 e15d7371 bellard
            f->wptr = 0;
80 e15d7371 bellard
        buf += l;
81 e15d7371 bellard
        len -= l;
82 e15d7371 bellard
    }
83 e15d7371 bellard
    f->count += len1;
84 e15d7371 bellard
    return len1;
85 e15d7371 bellard
}
86 e15d7371 bellard
87 9596ebb7 pbrook
static int qemu_fifo_read(QEMUFIFO *f, uint8_t *buf, int len1)
88 e15d7371 bellard
{
89 e15d7371 bellard
    int l, len;
90 e15d7371 bellard
91 e15d7371 bellard
    if (len1 > f->count)
92 e15d7371 bellard
        len1 = f->count;
93 e15d7371 bellard
    len = len1;
94 e15d7371 bellard
    while (len > 0) {
95 e15d7371 bellard
        l = f->buf_size - f->rptr;
96 e15d7371 bellard
        if (l > len)
97 e15d7371 bellard
            l = len;
98 e15d7371 bellard
        memcpy(buf, f->buf + f->rptr, l);
99 e15d7371 bellard
        f->rptr += l;
100 e15d7371 bellard
        if (f->rptr >= f->buf_size)
101 e15d7371 bellard
            f->rptr = 0;
102 e15d7371 bellard
        buf += l;
103 e15d7371 bellard
        len -= l;
104 e15d7371 bellard
    }
105 e15d7371 bellard
    f->count -= len1;
106 e15d7371 bellard
    return len1;
107 e15d7371 bellard
}
108 e15d7371 bellard
109 af3a9031 ths
typedef enum {
110 af3a9031 ths
    GRAPHIC_CONSOLE,
111 c21bbcfa balrog
    TEXT_CONSOLE,
112 c21bbcfa balrog
    TEXT_CONSOLE_FIXED_SIZE
113 c227f099 Anthony Liguori
} console_type_t;
114 af3a9031 ths
115 95219897 pbrook
/* ??? This is mis-named.
116 95219897 pbrook
   It is used for both text and graphical consoles.  */
117 e7f0ad58 bellard
struct TextConsole {
118 c227f099 Anthony Liguori
    console_type_t console_type;
119 e7f0ad58 bellard
    DisplayState *ds;
120 95219897 pbrook
    /* Graphic console state.  */
121 95219897 pbrook
    vga_hw_update_ptr hw_update;
122 95219897 pbrook
    vga_hw_invalidate_ptr hw_invalidate;
123 95219897 pbrook
    vga_hw_screen_dump_ptr hw_screen_dump;
124 4d3b6f6e balrog
    vga_hw_text_update_ptr hw_text_update;
125 95219897 pbrook
    void *hw;
126 95219897 pbrook
127 e7f0ad58 bellard
    int g_width, g_height;
128 e7f0ad58 bellard
    int width;
129 e7f0ad58 bellard
    int height;
130 e7f0ad58 bellard
    int total_height;
131 e7f0ad58 bellard
    int backscroll_height;
132 e7f0ad58 bellard
    int x, y;
133 adb47967 ths
    int x_saved, y_saved;
134 e7f0ad58 bellard
    int y_displayed;
135 e7f0ad58 bellard
    int y_base;
136 6d6f7c28 pbrook
    TextAttributes t_attrib_default; /* default text attributes */
137 6d6f7c28 pbrook
    TextAttributes t_attrib; /* currently active text attributes */
138 e7f0ad58 bellard
    TextCell *cells;
139 4d3b6f6e balrog
    int text_x[2], text_y[2], cursor_invalidate;
140 4104833f Paolo Bonzini
    int echo;
141 e7f0ad58 bellard
142 14778c20 pbrook
    int update_x0;
143 14778c20 pbrook
    int update_y0;
144 14778c20 pbrook
    int update_x1;
145 14778c20 pbrook
    int update_y1;
146 14778c20 pbrook
147 e7f0ad58 bellard
    enum TTYState state;
148 e7f0ad58 bellard
    int esc_params[MAX_ESC_PARAMS];
149 e7f0ad58 bellard
    int nb_esc_params;
150 e7f0ad58 bellard
151 e5b0bc44 pbrook
    CharDriverState *chr;
152 e15d7371 bellard
    /* fifo for key pressed */
153 e15d7371 bellard
    QEMUFIFO out_fifo;
154 e15d7371 bellard
    uint8_t out_fifo_buf[16];
155 e15d7371 bellard
    QEMUTimer *kbd_timer;
156 e7f0ad58 bellard
};
157 e7f0ad58 bellard
158 98b50080 Paolo Bonzini
static DisplayState *display_state;
159 e7f0ad58 bellard
static TextConsole *active_console;
160 e7f0ad58 bellard
static TextConsole *consoles[MAX_CONSOLES];
161 e7f0ad58 bellard
static int nb_consoles = 0;
162 e7f0ad58 bellard
163 95219897 pbrook
void vga_hw_update(void)
164 95219897 pbrook
{
165 adb47967 ths
    if (active_console && active_console->hw_update)
166 95219897 pbrook
        active_console->hw_update(active_console->hw);
167 95219897 pbrook
}
168 95219897 pbrook
169 95219897 pbrook
void vga_hw_invalidate(void)
170 95219897 pbrook
{
171 26572b8a Gerd Hoffmann
    if (active_console && active_console->hw_invalidate)
172 95219897 pbrook
        active_console->hw_invalidate(active_console->hw);
173 95219897 pbrook
}
174 95219897 pbrook
175 95219897 pbrook
void vga_hw_screen_dump(const char *filename)
176 95219897 pbrook
{
177 8571c055 balrog
    TextConsole *previous_active_console;
178 8571c055 balrog
179 8571c055 balrog
    previous_active_console = active_console;
180 8571c055 balrog
    active_console = consoles[0];
181 8571c055 balrog
    /* There is currently no way of specifying which screen we want to dump,
182 7b455225 aurel32
       so always dump the first one.  */
183 95219897 pbrook
    if (consoles[0]->hw_screen_dump)
184 95219897 pbrook
        consoles[0]->hw_screen_dump(consoles[0]->hw, filename);
185 8571c055 balrog
    active_console = previous_active_console;
186 95219897 pbrook
}
187 95219897 pbrook
188 c227f099 Anthony Liguori
void vga_hw_text_update(console_ch_t *chardata)
189 4d3b6f6e balrog
{
190 4d3b6f6e balrog
    if (active_console && active_console->hw_text_update)
191 4d3b6f6e balrog
        active_console->hw_text_update(active_console->hw, chardata);
192 4d3b6f6e balrog
}
193 4d3b6f6e balrog
194 e7f0ad58 bellard
/* convert a RGBA color to a color index usable in graphic primitives */
195 e7f0ad58 bellard
static unsigned int vga_get_color(DisplayState *ds, unsigned int rgba)
196 e7f0ad58 bellard
{
197 e7f0ad58 bellard
    unsigned int r, g, b, color;
198 e7f0ad58 bellard
199 0e1f5a0c aliguori
    switch(ds_get_bits_per_pixel(ds)) {
200 e7f0ad58 bellard
#if 0
201 e7f0ad58 bellard
    case 8:
202 e7f0ad58 bellard
        r = (rgba >> 16) & 0xff;
203 e7f0ad58 bellard
        g = (rgba >> 8) & 0xff;
204 e7f0ad58 bellard
        b = (rgba) & 0xff;
205 5fafdf24 ths
        color = (rgb_to_index[r] * 6 * 6) +
206 5fafdf24 ths
            (rgb_to_index[g] * 6) +
207 e7f0ad58 bellard
            (rgb_to_index[b]);
208 e7f0ad58 bellard
        break;
209 e7f0ad58 bellard
#endif
210 e7f0ad58 bellard
    case 15:
211 e7f0ad58 bellard
        r = (rgba >> 16) & 0xff;
212 e7f0ad58 bellard
        g = (rgba >> 8) & 0xff;
213 e7f0ad58 bellard
        b = (rgba) & 0xff;
214 e7f0ad58 bellard
        color = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
215 e7f0ad58 bellard
        break;
216 e7f0ad58 bellard
    case 16:
217 e7f0ad58 bellard
        r = (rgba >> 16) & 0xff;
218 e7f0ad58 bellard
        g = (rgba >> 8) & 0xff;
219 e7f0ad58 bellard
        b = (rgba) & 0xff;
220 e7f0ad58 bellard
        color = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
221 e7f0ad58 bellard
        break;
222 e7f0ad58 bellard
    case 32:
223 e7f0ad58 bellard
    default:
224 e7f0ad58 bellard
        color = rgba;
225 e7f0ad58 bellard
        break;
226 e7f0ad58 bellard
    }
227 e7f0ad58 bellard
    return color;
228 e7f0ad58 bellard
}
229 e7f0ad58 bellard
230 5fafdf24 ths
static void vga_fill_rect (DisplayState *ds,
231 e7f0ad58 bellard
                           int posx, int posy, int width, int height, uint32_t color)
232 e7f0ad58 bellard
{
233 e7f0ad58 bellard
    uint8_t *d, *d1;
234 e7f0ad58 bellard
    int x, y, bpp;
235 3b46e624 ths
236 0e1f5a0c aliguori
    bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3;
237 0e1f5a0c aliguori
    d1 = ds_get_data(ds) +
238 0e1f5a0c aliguori
        ds_get_linesize(ds) * posy + bpp * posx;
239 e7f0ad58 bellard
    for (y = 0; y < height; y++) {
240 e7f0ad58 bellard
        d = d1;
241 e7f0ad58 bellard
        switch(bpp) {
242 e7f0ad58 bellard
        case 1:
243 e7f0ad58 bellard
            for (x = 0; x < width; x++) {
244 e7f0ad58 bellard
                *((uint8_t *)d) = color;
245 e7f0ad58 bellard
                d++;
246 e7f0ad58 bellard
            }
247 e7f0ad58 bellard
            break;
248 e7f0ad58 bellard
        case 2:
249 e7f0ad58 bellard
            for (x = 0; x < width; x++) {
250 e7f0ad58 bellard
                *((uint16_t *)d) = color;
251 e7f0ad58 bellard
                d += 2;
252 e7f0ad58 bellard
            }
253 e7f0ad58 bellard
            break;
254 e7f0ad58 bellard
        case 4:
255 e7f0ad58 bellard
            for (x = 0; x < width; x++) {
256 e7f0ad58 bellard
                *((uint32_t *)d) = color;
257 e7f0ad58 bellard
                d += 4;
258 e7f0ad58 bellard
            }
259 e7f0ad58 bellard
            break;
260 e7f0ad58 bellard
        }
261 0e1f5a0c aliguori
        d1 += ds_get_linesize(ds);
262 e7f0ad58 bellard
    }
263 e7f0ad58 bellard
}
264 e7f0ad58 bellard
265 e7f0ad58 bellard
/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */
266 e7f0ad58 bellard
static void vga_bitblt(DisplayState *ds, int xs, int ys, int xd, int yd, int w, int h)
267 e7f0ad58 bellard
{
268 e7f0ad58 bellard
    const uint8_t *s;
269 e7f0ad58 bellard
    uint8_t *d;
270 e7f0ad58 bellard
    int wb, y, bpp;
271 e7f0ad58 bellard
272 0e1f5a0c aliguori
    bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3;
273 e7f0ad58 bellard
    wb = w * bpp;
274 e7f0ad58 bellard
    if (yd <= ys) {
275 0e1f5a0c aliguori
        s = ds_get_data(ds) +
276 0e1f5a0c aliguori
            ds_get_linesize(ds) * ys + bpp * xs;
277 0e1f5a0c aliguori
        d = ds_get_data(ds) +
278 0e1f5a0c aliguori
            ds_get_linesize(ds) * yd + bpp * xd;
279 e7f0ad58 bellard
        for (y = 0; y < h; y++) {
280 e7f0ad58 bellard
            memmove(d, s, wb);
281 0e1f5a0c aliguori
            d += ds_get_linesize(ds);
282 0e1f5a0c aliguori
            s += ds_get_linesize(ds);
283 e7f0ad58 bellard
        }
284 e7f0ad58 bellard
    } else {
285 0e1f5a0c aliguori
        s = ds_get_data(ds) +
286 0e1f5a0c aliguori
            ds_get_linesize(ds) * (ys + h - 1) + bpp * xs;
287 0e1f5a0c aliguori
        d = ds_get_data(ds) +
288 0e1f5a0c aliguori
            ds_get_linesize(ds) * (yd + h - 1) + bpp * xd;
289 e7f0ad58 bellard
       for (y = 0; y < h; y++) {
290 e7f0ad58 bellard
            memmove(d, s, wb);
291 0e1f5a0c aliguori
            d -= ds_get_linesize(ds);
292 0e1f5a0c aliguori
            s -= ds_get_linesize(ds);
293 e7f0ad58 bellard
        }
294 e7f0ad58 bellard
    }
295 e7f0ad58 bellard
}
296 e7f0ad58 bellard
297 e7f0ad58 bellard
/***********************************************************/
298 e7f0ad58 bellard
/* basic char display */
299 e7f0ad58 bellard
300 e7f0ad58 bellard
#define FONT_HEIGHT 16
301 e7f0ad58 bellard
#define FONT_WIDTH 8
302 e7f0ad58 bellard
303 e7f0ad58 bellard
#include "vgafont.h"
304 e7f0ad58 bellard
305 e7f0ad58 bellard
#define cbswap_32(__x) \
306 e7f0ad58 bellard
((uint32_t)( \
307 e7f0ad58 bellard
                (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
308 e7f0ad58 bellard
                (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
309 e7f0ad58 bellard
                (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
310 e7f0ad58 bellard
                (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
311 e7f0ad58 bellard
312 e2542fe2 Juan Quintela
#ifdef HOST_WORDS_BIGENDIAN
313 e7f0ad58 bellard
#define PAT(x) x
314 e7f0ad58 bellard
#else
315 e7f0ad58 bellard
#define PAT(x) cbswap_32(x)
316 e7f0ad58 bellard
#endif
317 e7f0ad58 bellard
318 e7f0ad58 bellard
static const uint32_t dmask16[16] = {
319 e7f0ad58 bellard
    PAT(0x00000000),
320 e7f0ad58 bellard
    PAT(0x000000ff),
321 e7f0ad58 bellard
    PAT(0x0000ff00),
322 e7f0ad58 bellard
    PAT(0x0000ffff),
323 e7f0ad58 bellard
    PAT(0x00ff0000),
324 e7f0ad58 bellard
    PAT(0x00ff00ff),
325 e7f0ad58 bellard
    PAT(0x00ffff00),
326 e7f0ad58 bellard
    PAT(0x00ffffff),
327 e7f0ad58 bellard
    PAT(0xff000000),
328 e7f0ad58 bellard
    PAT(0xff0000ff),
329 e7f0ad58 bellard
    PAT(0xff00ff00),
330 e7f0ad58 bellard
    PAT(0xff00ffff),
331 e7f0ad58 bellard
    PAT(0xffff0000),
332 e7f0ad58 bellard
    PAT(0xffff00ff),
333 e7f0ad58 bellard
    PAT(0xffffff00),
334 e7f0ad58 bellard
    PAT(0xffffffff),
335 e7f0ad58 bellard
};
336 e7f0ad58 bellard
337 e7f0ad58 bellard
static const uint32_t dmask4[4] = {
338 e7f0ad58 bellard
    PAT(0x00000000),
339 e7f0ad58 bellard
    PAT(0x0000ffff),
340 e7f0ad58 bellard
    PAT(0xffff0000),
341 e7f0ad58 bellard
    PAT(0xffffffff),
342 e7f0ad58 bellard
};
343 e7f0ad58 bellard
344 6d6f7c28 pbrook
static uint32_t color_table[2][8];
345 6d6f7c28 pbrook
346 6d6f7c28 pbrook
enum color_names {
347 6d6f7c28 pbrook
    COLOR_BLACK   = 0,
348 6d6f7c28 pbrook
    COLOR_RED     = 1,
349 6d6f7c28 pbrook
    COLOR_GREEN   = 2,
350 6d6f7c28 pbrook
    COLOR_YELLOW  = 3,
351 6d6f7c28 pbrook
    COLOR_BLUE    = 4,
352 6d6f7c28 pbrook
    COLOR_MAGENTA = 5,
353 6d6f7c28 pbrook
    COLOR_CYAN    = 6,
354 6d6f7c28 pbrook
    COLOR_WHITE   = 7
355 6d6f7c28 pbrook
};
356 6d6f7c28 pbrook
357 6d6f7c28 pbrook
static const uint32_t color_table_rgb[2][8] = {
358 6d6f7c28 pbrook
    {   /* dark */
359 26489844 bellard
        QEMU_RGB(0x00, 0x00, 0x00),  /* black */
360 26489844 bellard
        QEMU_RGB(0xaa, 0x00, 0x00),  /* red */
361 26489844 bellard
        QEMU_RGB(0x00, 0xaa, 0x00),  /* green */
362 26489844 bellard
        QEMU_RGB(0xaa, 0xaa, 0x00),  /* yellow */
363 26489844 bellard
        QEMU_RGB(0x00, 0x00, 0xaa),  /* blue */
364 26489844 bellard
        QEMU_RGB(0xaa, 0x00, 0xaa),  /* magenta */
365 26489844 bellard
        QEMU_RGB(0x00, 0xaa, 0xaa),  /* cyan */
366 26489844 bellard
        QEMU_RGB(0xaa, 0xaa, 0xaa),  /* white */
367 6d6f7c28 pbrook
    },
368 6d6f7c28 pbrook
    {   /* bright */
369 26489844 bellard
        QEMU_RGB(0x00, 0x00, 0x00),  /* black */
370 26489844 bellard
        QEMU_RGB(0xff, 0x00, 0x00),  /* red */
371 26489844 bellard
        QEMU_RGB(0x00, 0xff, 0x00),  /* green */
372 26489844 bellard
        QEMU_RGB(0xff, 0xff, 0x00),  /* yellow */
373 26489844 bellard
        QEMU_RGB(0x00, 0x00, 0xff),  /* blue */
374 26489844 bellard
        QEMU_RGB(0xff, 0x00, 0xff),  /* magenta */
375 26489844 bellard
        QEMU_RGB(0x00, 0xff, 0xff),  /* cyan */
376 26489844 bellard
        QEMU_RGB(0xff, 0xff, 0xff),  /* white */
377 6d6f7c28 pbrook
    }
378 e7f0ad58 bellard
};
379 e7f0ad58 bellard
380 e7f0ad58 bellard
static inline unsigned int col_expand(DisplayState *ds, unsigned int col)
381 e7f0ad58 bellard
{
382 0e1f5a0c aliguori
    switch(ds_get_bits_per_pixel(ds)) {
383 e7f0ad58 bellard
    case 8:
384 e7f0ad58 bellard
        col |= col << 8;
385 e7f0ad58 bellard
        col |= col << 16;
386 e7f0ad58 bellard
        break;
387 e7f0ad58 bellard
    case 15:
388 e7f0ad58 bellard
    case 16:
389 e7f0ad58 bellard
        col |= col << 16;
390 e7f0ad58 bellard
        break;
391 e7f0ad58 bellard
    default:
392 e7f0ad58 bellard
        break;
393 e7f0ad58 bellard
    }
394 e7f0ad58 bellard
395 e7f0ad58 bellard
    return col;
396 e7f0ad58 bellard
}
397 6d6f7c28 pbrook
#ifdef DEBUG_CONSOLE
398 6d6f7c28 pbrook
static void console_print_text_attributes(TextAttributes *t_attrib, char ch)
399 6d6f7c28 pbrook
{
400 6d6f7c28 pbrook
    if (t_attrib->bold) {
401 6d6f7c28 pbrook
        printf("b");
402 6d6f7c28 pbrook
    } else {
403 6d6f7c28 pbrook
        printf(" ");
404 6d6f7c28 pbrook
    }
405 6d6f7c28 pbrook
    if (t_attrib->uline) {
406 6d6f7c28 pbrook
        printf("u");
407 6d6f7c28 pbrook
    } else {
408 6d6f7c28 pbrook
        printf(" ");
409 6d6f7c28 pbrook
    }
410 6d6f7c28 pbrook
    if (t_attrib->blink) {
411 6d6f7c28 pbrook
        printf("l");
412 6d6f7c28 pbrook
    } else {
413 6d6f7c28 pbrook
        printf(" ");
414 6d6f7c28 pbrook
    }
415 6d6f7c28 pbrook
    if (t_attrib->invers) {
416 6d6f7c28 pbrook
        printf("i");
417 6d6f7c28 pbrook
    } else {
418 6d6f7c28 pbrook
        printf(" ");
419 6d6f7c28 pbrook
    }
420 6d6f7c28 pbrook
    if (t_attrib->unvisible) {
421 6d6f7c28 pbrook
        printf("n");
422 6d6f7c28 pbrook
    } else {
423 6d6f7c28 pbrook
        printf(" ");
424 6d6f7c28 pbrook
    }
425 6d6f7c28 pbrook
426 6d6f7c28 pbrook
    printf(" fg: %d bg: %d ch:'%2X' '%c'\n", t_attrib->fgcol, t_attrib->bgcol, ch, ch);
427 6d6f7c28 pbrook
}
428 6d6f7c28 pbrook
#endif
429 e7f0ad58 bellard
430 5fafdf24 ths
static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
431 6d6f7c28 pbrook
                          TextAttributes *t_attrib)
432 e7f0ad58 bellard
{
433 e7f0ad58 bellard
    uint8_t *d;
434 e7f0ad58 bellard
    const uint8_t *font_ptr;
435 e7f0ad58 bellard
    unsigned int font_data, linesize, xorcol, bpp;
436 e7f0ad58 bellard
    int i;
437 6d6f7c28 pbrook
    unsigned int fgcol, bgcol;
438 6d6f7c28 pbrook
439 6d6f7c28 pbrook
#ifdef DEBUG_CONSOLE
440 6d6f7c28 pbrook
    printf("x: %2i y: %2i", x, y);
441 6d6f7c28 pbrook
    console_print_text_attributes(t_attrib, ch);
442 6d6f7c28 pbrook
#endif
443 6d6f7c28 pbrook
444 6d6f7c28 pbrook
    if (t_attrib->invers) {
445 6d6f7c28 pbrook
        bgcol = color_table[t_attrib->bold][t_attrib->fgcol];
446 6d6f7c28 pbrook
        fgcol = color_table[t_attrib->bold][t_attrib->bgcol];
447 6d6f7c28 pbrook
    } else {
448 6d6f7c28 pbrook
        fgcol = color_table[t_attrib->bold][t_attrib->fgcol];
449 6d6f7c28 pbrook
        bgcol = color_table[t_attrib->bold][t_attrib->bgcol];
450 6d6f7c28 pbrook
    }
451 e7f0ad58 bellard
452 0e1f5a0c aliguori
    bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3;
453 0e1f5a0c aliguori
    d = ds_get_data(ds) +
454 0e1f5a0c aliguori
        ds_get_linesize(ds) * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;
455 0e1f5a0c aliguori
    linesize = ds_get_linesize(ds);
456 e7f0ad58 bellard
    font_ptr = vgafont16 + FONT_HEIGHT * ch;
457 e7f0ad58 bellard
    xorcol = bgcol ^ fgcol;
458 0e1f5a0c aliguori
    switch(ds_get_bits_per_pixel(ds)) {
459 e7f0ad58 bellard
    case 8:
460 e7f0ad58 bellard
        for(i = 0; i < FONT_HEIGHT; i++) {
461 e7f0ad58 bellard
            font_data = *font_ptr++;
462 6d6f7c28 pbrook
            if (t_attrib->uline
463 6d6f7c28 pbrook
                && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
464 6d6f7c28 pbrook
                font_data = 0xFFFF;
465 6d6f7c28 pbrook
            }
466 e7f0ad58 bellard
            ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
467 e7f0ad58 bellard
            ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
468 e7f0ad58 bellard
            d += linesize;
469 e7f0ad58 bellard
        }
470 e7f0ad58 bellard
        break;
471 e7f0ad58 bellard
    case 16:
472 e7f0ad58 bellard
    case 15:
473 e7f0ad58 bellard
        for(i = 0; i < FONT_HEIGHT; i++) {
474 e7f0ad58 bellard
            font_data = *font_ptr++;
475 6d6f7c28 pbrook
            if (t_attrib->uline
476 6d6f7c28 pbrook
                && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
477 6d6f7c28 pbrook
                font_data = 0xFFFF;
478 6d6f7c28 pbrook
            }
479 e7f0ad58 bellard
            ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
480 e7f0ad58 bellard
            ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
481 e7f0ad58 bellard
            ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
482 e7f0ad58 bellard
            ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
483 e7f0ad58 bellard
            d += linesize;
484 e7f0ad58 bellard
        }
485 e7f0ad58 bellard
        break;
486 e7f0ad58 bellard
    case 32:
487 e7f0ad58 bellard
        for(i = 0; i < FONT_HEIGHT; i++) {
488 e7f0ad58 bellard
            font_data = *font_ptr++;
489 6d6f7c28 pbrook
            if (t_attrib->uline && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
490 6d6f7c28 pbrook
                font_data = 0xFFFF;
491 6d6f7c28 pbrook
            }
492 e7f0ad58 bellard
            ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
493 e7f0ad58 bellard
            ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
494 e7f0ad58 bellard
            ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
495 e7f0ad58 bellard
            ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
496 e7f0ad58 bellard
            ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
497 e7f0ad58 bellard
            ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
498 e7f0ad58 bellard
            ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
499 e7f0ad58 bellard
            ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
500 e7f0ad58 bellard
            d += linesize;
501 e7f0ad58 bellard
        }
502 e7f0ad58 bellard
        break;
503 e7f0ad58 bellard
    }
504 e7f0ad58 bellard
}
505 e7f0ad58 bellard
506 e7f0ad58 bellard
static void text_console_resize(TextConsole *s)
507 e7f0ad58 bellard
{
508 e7f0ad58 bellard
    TextCell *cells, *c, *c1;
509 e7f0ad58 bellard
    int w1, x, y, last_width;
510 e7f0ad58 bellard
511 e7f0ad58 bellard
    last_width = s->width;
512 e7f0ad58 bellard
    s->width = s->g_width / FONT_WIDTH;
513 e7f0ad58 bellard
    s->height = s->g_height / FONT_HEIGHT;
514 e7f0ad58 bellard
515 e7f0ad58 bellard
    w1 = last_width;
516 e7f0ad58 bellard
    if (s->width < w1)
517 e7f0ad58 bellard
        w1 = s->width;
518 e7f0ad58 bellard
519 e7f0ad58 bellard
    cells = qemu_malloc(s->width * s->total_height * sizeof(TextCell));
520 e7f0ad58 bellard
    for(y = 0; y < s->total_height; y++) {
521 e7f0ad58 bellard
        c = &cells[y * s->width];
522 e7f0ad58 bellard
        if (w1 > 0) {
523 e7f0ad58 bellard
            c1 = &s->cells[y * last_width];
524 e7f0ad58 bellard
            for(x = 0; x < w1; x++) {
525 e7f0ad58 bellard
                *c++ = *c1++;
526 e7f0ad58 bellard
            }
527 e7f0ad58 bellard
        }
528 e7f0ad58 bellard
        for(x = w1; x < s->width; x++) {
529 e7f0ad58 bellard
            c->ch = ' ';
530 6d6f7c28 pbrook
            c->t_attrib = s->t_attrib_default;
531 e7f0ad58 bellard
            c++;
532 e7f0ad58 bellard
        }
533 e7f0ad58 bellard
    }
534 a528b80c balrog
    qemu_free(s->cells);
535 e7f0ad58 bellard
    s->cells = cells;
536 e7f0ad58 bellard
}
537 e7f0ad58 bellard
538 4d3b6f6e balrog
static inline void text_update_xy(TextConsole *s, int x, int y)
539 4d3b6f6e balrog
{
540 4d3b6f6e balrog
    s->text_x[0] = MIN(s->text_x[0], x);
541 4d3b6f6e balrog
    s->text_x[1] = MAX(s->text_x[1], x);
542 4d3b6f6e balrog
    s->text_y[0] = MIN(s->text_y[0], y);
543 4d3b6f6e balrog
    s->text_y[1] = MAX(s->text_y[1], y);
544 4d3b6f6e balrog
}
545 4d3b6f6e balrog
546 14778c20 pbrook
static void invalidate_xy(TextConsole *s, int x, int y)
547 14778c20 pbrook
{
548 14778c20 pbrook
    if (s->update_x0 > x * FONT_WIDTH)
549 14778c20 pbrook
        s->update_x0 = x * FONT_WIDTH;
550 14778c20 pbrook
    if (s->update_y0 > y * FONT_HEIGHT)
551 14778c20 pbrook
        s->update_y0 = y * FONT_HEIGHT;
552 14778c20 pbrook
    if (s->update_x1 < (x + 1) * FONT_WIDTH)
553 14778c20 pbrook
        s->update_x1 = (x + 1) * FONT_WIDTH;
554 14778c20 pbrook
    if (s->update_y1 < (y + 1) * FONT_HEIGHT)
555 14778c20 pbrook
        s->update_y1 = (y + 1) * FONT_HEIGHT;
556 14778c20 pbrook
}
557 14778c20 pbrook
558 e7f0ad58 bellard
static void update_xy(TextConsole *s, int x, int y)
559 e7f0ad58 bellard
{
560 e7f0ad58 bellard
    TextCell *c;
561 e7f0ad58 bellard
    int y1, y2;
562 e7f0ad58 bellard
563 e7f0ad58 bellard
    if (s == active_console) {
564 0e1f5a0c aliguori
        if (!ds_get_bits_per_pixel(s->ds)) {
565 4d3b6f6e balrog
            text_update_xy(s, x, y);
566 4d3b6f6e balrog
            return;
567 4d3b6f6e balrog
        }
568 4d3b6f6e balrog
569 e7f0ad58 bellard
        y1 = (s->y_base + y) % s->total_height;
570 e7f0ad58 bellard
        y2 = y1 - s->y_displayed;
571 e7f0ad58 bellard
        if (y2 < 0)
572 e7f0ad58 bellard
            y2 += s->total_height;
573 e7f0ad58 bellard
        if (y2 < s->height) {
574 e7f0ad58 bellard
            c = &s->cells[y1 * s->width + x];
575 5fafdf24 ths
            vga_putcharxy(s->ds, x, y2, c->ch,
576 6d6f7c28 pbrook
                          &(c->t_attrib));
577 14778c20 pbrook
            invalidate_xy(s, x, y2);
578 e7f0ad58 bellard
        }
579 e7f0ad58 bellard
    }
580 e7f0ad58 bellard
}
581 e7f0ad58 bellard
582 e7f0ad58 bellard
static void console_show_cursor(TextConsole *s, int show)
583 e7f0ad58 bellard
{
584 e7f0ad58 bellard
    TextCell *c;
585 e7f0ad58 bellard
    int y, y1;
586 e7f0ad58 bellard
587 e7f0ad58 bellard
    if (s == active_console) {
588 ed8276ac ths
        int x = s->x;
589 4d3b6f6e balrog
590 0e1f5a0c aliguori
        if (!ds_get_bits_per_pixel(s->ds)) {
591 4d3b6f6e balrog
            s->cursor_invalidate = 1;
592 4d3b6f6e balrog
            return;
593 4d3b6f6e balrog
        }
594 4d3b6f6e balrog
595 ed8276ac ths
        if (x >= s->width) {
596 ed8276ac ths
            x = s->width - 1;
597 ed8276ac ths
        }
598 e7f0ad58 bellard
        y1 = (s->y_base + s->y) % s->total_height;
599 e7f0ad58 bellard
        y = y1 - s->y_displayed;
600 e7f0ad58 bellard
        if (y < 0)
601 e7f0ad58 bellard
            y += s->total_height;
602 e7f0ad58 bellard
        if (y < s->height) {
603 ed8276ac ths
            c = &s->cells[y1 * s->width + x];
604 e7f0ad58 bellard
            if (show) {
605 6d6f7c28 pbrook
                TextAttributes t_attrib = s->t_attrib_default;
606 6d6f7c28 pbrook
                t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
607 ed8276ac ths
                vga_putcharxy(s->ds, x, y, c->ch, &t_attrib);
608 e7f0ad58 bellard
            } else {
609 ed8276ac ths
                vga_putcharxy(s->ds, x, y, c->ch, &(c->t_attrib));
610 e7f0ad58 bellard
            }
611 14778c20 pbrook
            invalidate_xy(s, x, y);
612 e7f0ad58 bellard
        }
613 e7f0ad58 bellard
    }
614 e7f0ad58 bellard
}
615 e7f0ad58 bellard
616 e7f0ad58 bellard
static void console_refresh(TextConsole *s)
617 e7f0ad58 bellard
{
618 e7f0ad58 bellard
    TextCell *c;
619 e7f0ad58 bellard
    int x, y, y1;
620 e7f0ad58 bellard
621 5fafdf24 ths
    if (s != active_console)
622 e7f0ad58 bellard
        return;
623 0e1f5a0c aliguori
    if (!ds_get_bits_per_pixel(s->ds)) {
624 4d3b6f6e balrog
        s->text_x[0] = 0;
625 4d3b6f6e balrog
        s->text_y[0] = 0;
626 4d3b6f6e balrog
        s->text_x[1] = s->width - 1;
627 4d3b6f6e balrog
        s->text_y[1] = s->height - 1;
628 4d3b6f6e balrog
        s->cursor_invalidate = 1;
629 4d3b6f6e balrog
        return;
630 4d3b6f6e balrog
    }
631 e7f0ad58 bellard
632 0e1f5a0c aliguori
    vga_fill_rect(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds),
633 6d6f7c28 pbrook
                  color_table[0][COLOR_BLACK]);
634 e7f0ad58 bellard
    y1 = s->y_displayed;
635 e7f0ad58 bellard
    for(y = 0; y < s->height; y++) {
636 e7f0ad58 bellard
        c = s->cells + y1 * s->width;
637 e7f0ad58 bellard
        for(x = 0; x < s->width; x++) {
638 5fafdf24 ths
            vga_putcharxy(s->ds, x, y, c->ch,
639 6d6f7c28 pbrook
                          &(c->t_attrib));
640 e7f0ad58 bellard
            c++;
641 e7f0ad58 bellard
        }
642 e7f0ad58 bellard
        if (++y1 == s->total_height)
643 e7f0ad58 bellard
            y1 = 0;
644 e7f0ad58 bellard
    }
645 e7f0ad58 bellard
    console_show_cursor(s, 1);
646 14778c20 pbrook
    dpy_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
647 e7f0ad58 bellard
}
648 e7f0ad58 bellard
649 e7f0ad58 bellard
static void console_scroll(int ydelta)
650 e7f0ad58 bellard
{
651 e7f0ad58 bellard
    TextConsole *s;
652 e7f0ad58 bellard
    int i, y1;
653 3b46e624 ths
654 e7f0ad58 bellard
    s = active_console;
655 af3a9031 ths
    if (!s || (s->console_type == GRAPHIC_CONSOLE))
656 e7f0ad58 bellard
        return;
657 e7f0ad58 bellard
658 e7f0ad58 bellard
    if (ydelta > 0) {
659 e7f0ad58 bellard
        for(i = 0; i < ydelta; i++) {
660 e7f0ad58 bellard
            if (s->y_displayed == s->y_base)
661 e7f0ad58 bellard
                break;
662 e7f0ad58 bellard
            if (++s->y_displayed == s->total_height)
663 e7f0ad58 bellard
                s->y_displayed = 0;
664 e7f0ad58 bellard
        }
665 e7f0ad58 bellard
    } else {
666 e7f0ad58 bellard
        ydelta = -ydelta;
667 e7f0ad58 bellard
        i = s->backscroll_height;
668 e7f0ad58 bellard
        if (i > s->total_height - s->height)
669 e7f0ad58 bellard
            i = s->total_height - s->height;
670 e7f0ad58 bellard
        y1 = s->y_base - i;
671 e7f0ad58 bellard
        if (y1 < 0)
672 e7f0ad58 bellard
            y1 += s->total_height;
673 e7f0ad58 bellard
        for(i = 0; i < ydelta; i++) {
674 e7f0ad58 bellard
            if (s->y_displayed == y1)
675 e7f0ad58 bellard
                break;
676 e7f0ad58 bellard
            if (--s->y_displayed < 0)
677 e7f0ad58 bellard
                s->y_displayed = s->total_height - 1;
678 e7f0ad58 bellard
        }
679 e7f0ad58 bellard
    }
680 e7f0ad58 bellard
    console_refresh(s);
681 e7f0ad58 bellard
}
682 e7f0ad58 bellard
683 e7f0ad58 bellard
static void console_put_lf(TextConsole *s)
684 e7f0ad58 bellard
{
685 e7f0ad58 bellard
    TextCell *c;
686 e7f0ad58 bellard
    int x, y1;
687 e7f0ad58 bellard
688 e7f0ad58 bellard
    s->y++;
689 e7f0ad58 bellard
    if (s->y >= s->height) {
690 e7f0ad58 bellard
        s->y = s->height - 1;
691 6d6f7c28 pbrook
692 e7f0ad58 bellard
        if (s->y_displayed == s->y_base) {
693 e7f0ad58 bellard
            if (++s->y_displayed == s->total_height)
694 e7f0ad58 bellard
                s->y_displayed = 0;
695 e7f0ad58 bellard
        }
696 e7f0ad58 bellard
        if (++s->y_base == s->total_height)
697 e7f0ad58 bellard
            s->y_base = 0;
698 e7f0ad58 bellard
        if (s->backscroll_height < s->total_height)
699 e7f0ad58 bellard
            s->backscroll_height++;
700 e7f0ad58 bellard
        y1 = (s->y_base + s->height - 1) % s->total_height;
701 e7f0ad58 bellard
        c = &s->cells[y1 * s->width];
702 e7f0ad58 bellard
        for(x = 0; x < s->width; x++) {
703 e7f0ad58 bellard
            c->ch = ' ';
704 6d6f7c28 pbrook
            c->t_attrib = s->t_attrib_default;
705 e7f0ad58 bellard
            c++;
706 e7f0ad58 bellard
        }
707 e7f0ad58 bellard
        if (s == active_console && s->y_displayed == s->y_base) {
708 0e1f5a0c aliguori
            if (!ds_get_bits_per_pixel(s->ds)) {
709 4d3b6f6e balrog
                s->text_x[0] = 0;
710 4d3b6f6e balrog
                s->text_y[0] = 0;
711 4d3b6f6e balrog
                s->text_x[1] = s->width - 1;
712 4d3b6f6e balrog
                s->text_y[1] = s->height - 1;
713 4d3b6f6e balrog
                return;
714 4d3b6f6e balrog
            }
715 4d3b6f6e balrog
716 5fafdf24 ths
            vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0,
717 5fafdf24 ths
                       s->width * FONT_WIDTH,
718 e7f0ad58 bellard
                       (s->height - 1) * FONT_HEIGHT);
719 e7f0ad58 bellard
            vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT,
720 5fafdf24 ths
                          s->width * FONT_WIDTH, FONT_HEIGHT,
721 6d6f7c28 pbrook
                          color_table[0][s->t_attrib_default.bgcol]);
722 14778c20 pbrook
            s->update_x0 = 0;
723 14778c20 pbrook
            s->update_y0 = 0;
724 14778c20 pbrook
            s->update_x1 = s->width * FONT_WIDTH;
725 14778c20 pbrook
            s->update_y1 = s->height * FONT_HEIGHT;
726 e7f0ad58 bellard
        }
727 e7f0ad58 bellard
    }
728 e7f0ad58 bellard
}
729 e7f0ad58 bellard
730 6d6f7c28 pbrook
/* Set console attributes depending on the current escape codes.
731 6d6f7c28 pbrook
 * NOTE: I know this code is not very efficient (checking every color for it
732 6d6f7c28 pbrook
 * self) but it is more readable and better maintainable.
733 6d6f7c28 pbrook
 */
734 6d6f7c28 pbrook
static void console_handle_escape(TextConsole *s)
735 6d6f7c28 pbrook
{
736 6d6f7c28 pbrook
    int i;
737 6d6f7c28 pbrook
738 6d6f7c28 pbrook
    for (i=0; i<s->nb_esc_params; i++) {
739 6d6f7c28 pbrook
        switch (s->esc_params[i]) {
740 6d6f7c28 pbrook
            case 0: /* reset all console attributes to default */
741 6d6f7c28 pbrook
                s->t_attrib = s->t_attrib_default;
742 6d6f7c28 pbrook
                break;
743 6d6f7c28 pbrook
            case 1:
744 6d6f7c28 pbrook
                s->t_attrib.bold = 1;
745 6d6f7c28 pbrook
                break;
746 6d6f7c28 pbrook
            case 4:
747 6d6f7c28 pbrook
                s->t_attrib.uline = 1;
748 6d6f7c28 pbrook
                break;
749 6d6f7c28 pbrook
            case 5:
750 6d6f7c28 pbrook
                s->t_attrib.blink = 1;
751 6d6f7c28 pbrook
                break;
752 6d6f7c28 pbrook
            case 7:
753 6d6f7c28 pbrook
                s->t_attrib.invers = 1;
754 6d6f7c28 pbrook
                break;
755 6d6f7c28 pbrook
            case 8:
756 6d6f7c28 pbrook
                s->t_attrib.unvisible = 1;
757 6d6f7c28 pbrook
                break;
758 6d6f7c28 pbrook
            case 22:
759 6d6f7c28 pbrook
                s->t_attrib.bold = 0;
760 6d6f7c28 pbrook
                break;
761 6d6f7c28 pbrook
            case 24:
762 6d6f7c28 pbrook
                s->t_attrib.uline = 0;
763 6d6f7c28 pbrook
                break;
764 6d6f7c28 pbrook
            case 25:
765 6d6f7c28 pbrook
                s->t_attrib.blink = 0;
766 6d6f7c28 pbrook
                break;
767 6d6f7c28 pbrook
            case 27:
768 6d6f7c28 pbrook
                s->t_attrib.invers = 0;
769 6d6f7c28 pbrook
                break;
770 6d6f7c28 pbrook
            case 28:
771 6d6f7c28 pbrook
                s->t_attrib.unvisible = 0;
772 6d6f7c28 pbrook
                break;
773 6d6f7c28 pbrook
            /* set foreground color */
774 6d6f7c28 pbrook
            case 30:
775 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_BLACK;
776 6d6f7c28 pbrook
                break;
777 6d6f7c28 pbrook
            case 31:
778 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_RED;
779 6d6f7c28 pbrook
                break;
780 6d6f7c28 pbrook
            case 32:
781 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_GREEN;
782 6d6f7c28 pbrook
                break;
783 6d6f7c28 pbrook
            case 33:
784 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_YELLOW;
785 6d6f7c28 pbrook
                break;
786 6d6f7c28 pbrook
            case 34:
787 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_BLUE;
788 6d6f7c28 pbrook
                break;
789 6d6f7c28 pbrook
            case 35:
790 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_MAGENTA;
791 6d6f7c28 pbrook
                break;
792 6d6f7c28 pbrook
            case 36:
793 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_CYAN;
794 6d6f7c28 pbrook
                break;
795 6d6f7c28 pbrook
            case 37:
796 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_WHITE;
797 6d6f7c28 pbrook
                break;
798 6d6f7c28 pbrook
            /* set background color */
799 6d6f7c28 pbrook
            case 40:
800 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_BLACK;
801 6d6f7c28 pbrook
                break;
802 6d6f7c28 pbrook
            case 41:
803 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_RED;
804 6d6f7c28 pbrook
                break;
805 6d6f7c28 pbrook
            case 42:
806 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_GREEN;
807 6d6f7c28 pbrook
                break;
808 6d6f7c28 pbrook
            case 43:
809 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_YELLOW;
810 6d6f7c28 pbrook
                break;
811 6d6f7c28 pbrook
            case 44:
812 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_BLUE;
813 6d6f7c28 pbrook
                break;
814 6d6f7c28 pbrook
            case 45:
815 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_MAGENTA;
816 6d6f7c28 pbrook
                break;
817 6d6f7c28 pbrook
            case 46:
818 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_CYAN;
819 6d6f7c28 pbrook
                break;
820 6d6f7c28 pbrook
            case 47:
821 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_WHITE;
822 6d6f7c28 pbrook
                break;
823 6d6f7c28 pbrook
        }
824 6d6f7c28 pbrook
    }
825 6d6f7c28 pbrook
}
826 6d6f7c28 pbrook
827 adb47967 ths
static void console_clear_xy(TextConsole *s, int x, int y)
828 adb47967 ths
{
829 adb47967 ths
    int y1 = (s->y_base + y) % s->total_height;
830 adb47967 ths
    TextCell *c = &s->cells[y1 * s->width + x];
831 adb47967 ths
    c->ch = ' ';
832 adb47967 ths
    c->t_attrib = s->t_attrib_default;
833 adb47967 ths
    update_xy(s, x, y);
834 adb47967 ths
}
835 adb47967 ths
836 e7f0ad58 bellard
static void console_putchar(TextConsole *s, int ch)
837 e7f0ad58 bellard
{
838 e7f0ad58 bellard
    TextCell *c;
839 adb47967 ths
    int y1, i;
840 adb47967 ths
    int x, y;
841 e7f0ad58 bellard
842 e7f0ad58 bellard
    switch(s->state) {
843 e7f0ad58 bellard
    case TTY_STATE_NORM:
844 e7f0ad58 bellard
        switch(ch) {
845 6d6f7c28 pbrook
        case '\r':  /* carriage return */
846 e7f0ad58 bellard
            s->x = 0;
847 e7f0ad58 bellard
            break;
848 6d6f7c28 pbrook
        case '\n':  /* newline */
849 e7f0ad58 bellard
            console_put_lf(s);
850 e7f0ad58 bellard
            break;
851 6d6f7c28 pbrook
        case '\b':  /* backspace */
852 5fafdf24 ths
            if (s->x > 0)
853 e15d7371 bellard
                s->x--;
854 6d6f7c28 pbrook
            break;
855 6d6f7c28 pbrook
        case '\t':  /* tabspace */
856 6d6f7c28 pbrook
            if (s->x + (8 - (s->x % 8)) > s->width) {
857 bd468840 bellard
                s->x = 0;
858 6d6f7c28 pbrook
                console_put_lf(s);
859 6d6f7c28 pbrook
            } else {
860 6d6f7c28 pbrook
                s->x = s->x + (8 - (s->x % 8));
861 6d6f7c28 pbrook
            }
862 6d6f7c28 pbrook
            break;
863 6d6f7c28 pbrook
        case '\a':  /* alert aka. bell */
864 6d6f7c28 pbrook
            /* TODO: has to be implemented */
865 6d6f7c28 pbrook
            break;
866 adb47967 ths
        case 14:
867 adb47967 ths
            /* SI (shift in), character set 0 (ignored) */
868 adb47967 ths
            break;
869 adb47967 ths
        case 15:
870 adb47967 ths
            /* SO (shift out), character set 1 (ignored) */
871 adb47967 ths
            break;
872 6d6f7c28 pbrook
        case 27:    /* esc (introducing an escape sequence) */
873 e7f0ad58 bellard
            s->state = TTY_STATE_ESC;
874 e7f0ad58 bellard
            break;
875 e7f0ad58 bellard
        default:
876 ed8276ac ths
            if (s->x >= s->width) {
877 ed8276ac ths
                /* line wrap */
878 ed8276ac ths
                s->x = 0;
879 ed8276ac ths
                console_put_lf(s);
880 adb47967 ths
            }
881 e7f0ad58 bellard
            y1 = (s->y_base + s->y) % s->total_height;
882 e7f0ad58 bellard
            c = &s->cells[y1 * s->width + s->x];
883 e7f0ad58 bellard
            c->ch = ch;
884 6d6f7c28 pbrook
            c->t_attrib = s->t_attrib;
885 e7f0ad58 bellard
            update_xy(s, s->x, s->y);
886 e7f0ad58 bellard
            s->x++;
887 e7f0ad58 bellard
            break;
888 e7f0ad58 bellard
        }
889 e7f0ad58 bellard
        break;
890 6d6f7c28 pbrook
    case TTY_STATE_ESC: /* check if it is a terminal escape sequence */
891 e7f0ad58 bellard
        if (ch == '[') {
892 e7f0ad58 bellard
            for(i=0;i<MAX_ESC_PARAMS;i++)
893 e7f0ad58 bellard
                s->esc_params[i] = 0;
894 e7f0ad58 bellard
            s->nb_esc_params = 0;
895 e7f0ad58 bellard
            s->state = TTY_STATE_CSI;
896 e7f0ad58 bellard
        } else {
897 e7f0ad58 bellard
            s->state = TTY_STATE_NORM;
898 e7f0ad58 bellard
        }
899 e7f0ad58 bellard
        break;
900 6d6f7c28 pbrook
    case TTY_STATE_CSI: /* handle escape sequence parameters */
901 e7f0ad58 bellard
        if (ch >= '0' && ch <= '9') {
902 e7f0ad58 bellard
            if (s->nb_esc_params < MAX_ESC_PARAMS) {
903 5fafdf24 ths
                s->esc_params[s->nb_esc_params] =
904 e7f0ad58 bellard
                    s->esc_params[s->nb_esc_params] * 10 + ch - '0';
905 e7f0ad58 bellard
            }
906 e7f0ad58 bellard
        } else {
907 e7f0ad58 bellard
            s->nb_esc_params++;
908 e7f0ad58 bellard
            if (ch == ';')
909 e7f0ad58 bellard
                break;
910 adb47967 ths
#ifdef DEBUG_CONSOLE
911 adb47967 ths
            fprintf(stderr, "escape sequence CSI%d;%d%c, %d parameters\n",
912 adb47967 ths
                    s->esc_params[0], s->esc_params[1], ch, s->nb_esc_params);
913 adb47967 ths
#endif
914 e7f0ad58 bellard
            s->state = TTY_STATE_NORM;
915 e7f0ad58 bellard
            switch(ch) {
916 adb47967 ths
            case 'A':
917 adb47967 ths
                /* move cursor up */
918 adb47967 ths
                if (s->esc_params[0] == 0) {
919 adb47967 ths
                    s->esc_params[0] = 1;
920 adb47967 ths
                }
921 adb47967 ths
                s->y -= s->esc_params[0];
922 adb47967 ths
                if (s->y < 0) {
923 adb47967 ths
                    s->y = 0;
924 adb47967 ths
                }
925 adb47967 ths
                break;
926 adb47967 ths
            case 'B':
927 adb47967 ths
                /* move cursor down */
928 adb47967 ths
                if (s->esc_params[0] == 0) {
929 adb47967 ths
                    s->esc_params[0] = 1;
930 adb47967 ths
                }
931 adb47967 ths
                s->y += s->esc_params[0];
932 adb47967 ths
                if (s->y >= s->height) {
933 adb47967 ths
                    s->y = s->height - 1;
934 adb47967 ths
                }
935 e7f0ad58 bellard
                break;
936 e7f0ad58 bellard
            case 'C':
937 adb47967 ths
                /* move cursor right */
938 adb47967 ths
                if (s->esc_params[0] == 0) {
939 adb47967 ths
                    s->esc_params[0] = 1;
940 adb47967 ths
                }
941 adb47967 ths
                s->x += s->esc_params[0];
942 adb47967 ths
                if (s->x >= s->width) {
943 adb47967 ths
                    s->x = s->width - 1;
944 adb47967 ths
                }
945 e7f0ad58 bellard
                break;
946 adb47967 ths
            case 'D':
947 adb47967 ths
                /* move cursor left */
948 adb47967 ths
                if (s->esc_params[0] == 0) {
949 adb47967 ths
                    s->esc_params[0] = 1;
950 adb47967 ths
                }
951 adb47967 ths
                s->x -= s->esc_params[0];
952 adb47967 ths
                if (s->x < 0) {
953 adb47967 ths
                    s->x = 0;
954 adb47967 ths
                }
955 adb47967 ths
                break;
956 adb47967 ths
            case 'G':
957 adb47967 ths
                /* move cursor to column */
958 adb47967 ths
                s->x = s->esc_params[0] - 1;
959 adb47967 ths
                if (s->x < 0) {
960 adb47967 ths
                    s->x = 0;
961 adb47967 ths
                }
962 adb47967 ths
                break;
963 adb47967 ths
            case 'f':
964 adb47967 ths
            case 'H':
965 adb47967 ths
                /* move cursor to row, column */
966 adb47967 ths
                s->x = s->esc_params[1] - 1;
967 adb47967 ths
                if (s->x < 0) {
968 adb47967 ths
                    s->x = 0;
969 adb47967 ths
                }
970 adb47967 ths
                s->y = s->esc_params[0] - 1;
971 adb47967 ths
                if (s->y < 0) {
972 adb47967 ths
                    s->y = 0;
973 adb47967 ths
                }
974 adb47967 ths
                break;
975 adb47967 ths
            case 'J':
976 adb47967 ths
                switch (s->esc_params[0]) {
977 adb47967 ths
                case 0:
978 adb47967 ths
                    /* clear to end of screen */
979 adb47967 ths
                    for (y = s->y; y < s->height; y++) {
980 adb47967 ths
                        for (x = 0; x < s->width; x++) {
981 adb47967 ths
                            if (y == s->y && x < s->x) {
982 adb47967 ths
                                continue;
983 adb47967 ths
                            }
984 adb47967 ths
                            console_clear_xy(s, x, y);
985 adb47967 ths
                        }
986 adb47967 ths
                    }
987 adb47967 ths
                    break;
988 adb47967 ths
                case 1:
989 adb47967 ths
                    /* clear from beginning of screen */
990 adb47967 ths
                    for (y = 0; y <= s->y; y++) {
991 adb47967 ths
                        for (x = 0; x < s->width; x++) {
992 adb47967 ths
                            if (y == s->y && x > s->x) {
993 adb47967 ths
                                break;
994 adb47967 ths
                            }
995 adb47967 ths
                            console_clear_xy(s, x, y);
996 adb47967 ths
                        }
997 adb47967 ths
                    }
998 adb47967 ths
                    break;
999 adb47967 ths
                case 2:
1000 adb47967 ths
                    /* clear entire screen */
1001 adb47967 ths
                    for (y = 0; y <= s->height; y++) {
1002 adb47967 ths
                        for (x = 0; x < s->width; x++) {
1003 adb47967 ths
                            console_clear_xy(s, x, y);
1004 adb47967 ths
                        }
1005 adb47967 ths
                    }
1006 adb47967 ths
                break;
1007 adb47967 ths
                }
1008 e7f0ad58 bellard
            case 'K':
1009 adb47967 ths
                switch (s->esc_params[0]) {
1010 adb47967 ths
                case 0:
1011 e7f0ad58 bellard
                /* clear to eol */
1012 e7f0ad58 bellard
                for(x = s->x; x < s->width; x++) {
1013 adb47967 ths
                        console_clear_xy(s, x, s->y);
1014 e7f0ad58 bellard
                }
1015 e7f0ad58 bellard
                break;
1016 adb47967 ths
                case 1:
1017 adb47967 ths
                    /* clear from beginning of line */
1018 adb47967 ths
                    for (x = 0; x <= s->x; x++) {
1019 adb47967 ths
                        console_clear_xy(s, x, s->y);
1020 adb47967 ths
                    }
1021 adb47967 ths
                    break;
1022 adb47967 ths
                case 2:
1023 adb47967 ths
                    /* clear entire line */
1024 adb47967 ths
                    for(x = 0; x < s->width; x++) {
1025 adb47967 ths
                        console_clear_xy(s, x, s->y);
1026 adb47967 ths
                    }
1027 e7f0ad58 bellard
                break;
1028 e7f0ad58 bellard
            }
1029 adb47967 ths
                break;
1030 adb47967 ths
            case 'm':
1031 6d6f7c28 pbrook
            console_handle_escape(s);
1032 e7f0ad58 bellard
            break;
1033 adb47967 ths
            case 'n':
1034 adb47967 ths
                /* report cursor position */
1035 adb47967 ths
                /* TODO: send ESC[row;colR */
1036 adb47967 ths
                break;
1037 adb47967 ths
            case 's':
1038 adb47967 ths
                /* save cursor position */
1039 adb47967 ths
                s->x_saved = s->x;
1040 adb47967 ths
                s->y_saved = s->y;
1041 adb47967 ths
                break;
1042 adb47967 ths
            case 'u':
1043 adb47967 ths
                /* restore cursor position */
1044 adb47967 ths
                s->x = s->x_saved;
1045 adb47967 ths
                s->y = s->y_saved;
1046 adb47967 ths
                break;
1047 adb47967 ths
            default:
1048 adb47967 ths
#ifdef DEBUG_CONSOLE
1049 adb47967 ths
                fprintf(stderr, "unhandled escape character '%c'\n", ch);
1050 adb47967 ths
#endif
1051 adb47967 ths
                break;
1052 adb47967 ths
            }
1053 adb47967 ths
            break;
1054 e7f0ad58 bellard
        }
1055 e7f0ad58 bellard
    }
1056 e7f0ad58 bellard
}
1057 e7f0ad58 bellard
1058 e7f0ad58 bellard
void console_select(unsigned int index)
1059 e7f0ad58 bellard
{
1060 e7f0ad58 bellard
    TextConsole *s;
1061 6d6f7c28 pbrook
1062 e7f0ad58 bellard
    if (index >= MAX_CONSOLES)
1063 e7f0ad58 bellard
        return;
1064 358664cc Stefan Hajnoczi
    if (active_console) {
1065 358664cc Stefan Hajnoczi
        active_console->g_width = ds_get_width(active_console->ds);
1066 358664cc Stefan Hajnoczi
        active_console->g_height = ds_get_height(active_console->ds);
1067 358664cc Stefan Hajnoczi
    }
1068 e7f0ad58 bellard
    s = consoles[index];
1069 e7f0ad58 bellard
    if (s) {
1070 7d957bd8 aliguori
        DisplayState *ds = s->ds;
1071 e7f0ad58 bellard
        active_console = s;
1072 68f00996 aliguori
        if (ds_get_bits_per_pixel(s->ds)) {
1073 7b5d76da aliguori
            ds->surface = qemu_resize_displaysurface(ds, s->g_width, s->g_height);
1074 68f00996 aliguori
        } else {
1075 68f00996 aliguori
            s->ds->surface->width = s->width;
1076 68f00996 aliguori
            s->ds->surface->height = s->height;
1077 68f00996 aliguori
        }
1078 7d957bd8 aliguori
        dpy_resize(s->ds);
1079 4d3b6f6e balrog
        vga_hw_invalidate();
1080 e7f0ad58 bellard
    }
1081 e7f0ad58 bellard
}
1082 e7f0ad58 bellard
1083 e7f0ad58 bellard
static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
1084 e7f0ad58 bellard
{
1085 e7f0ad58 bellard
    TextConsole *s = chr->opaque;
1086 e7f0ad58 bellard
    int i;
1087 e7f0ad58 bellard
1088 14778c20 pbrook
    s->update_x0 = s->width * FONT_WIDTH;
1089 14778c20 pbrook
    s->update_y0 = s->height * FONT_HEIGHT;
1090 14778c20 pbrook
    s->update_x1 = 0;
1091 14778c20 pbrook
    s->update_y1 = 0;
1092 e7f0ad58 bellard
    console_show_cursor(s, 0);
1093 e7f0ad58 bellard
    for(i = 0; i < len; i++) {
1094 e7f0ad58 bellard
        console_putchar(s, buf[i]);
1095 e7f0ad58 bellard
    }
1096 e7f0ad58 bellard
    console_show_cursor(s, 1);
1097 14778c20 pbrook
    if (ds_get_bits_per_pixel(s->ds) && s->update_x0 < s->update_x1) {
1098 14778c20 pbrook
        dpy_update(s->ds, s->update_x0, s->update_y0,
1099 14778c20 pbrook
                   s->update_x1 - s->update_x0,
1100 14778c20 pbrook
                   s->update_y1 - s->update_y0);
1101 14778c20 pbrook
    }
1102 e7f0ad58 bellard
    return len;
1103 e7f0ad58 bellard
}
1104 e7f0ad58 bellard
1105 6fcfafb7 bellard
static void console_send_event(CharDriverState *chr, int event)
1106 6fcfafb7 bellard
{
1107 6fcfafb7 bellard
    TextConsole *s = chr->opaque;
1108 6fcfafb7 bellard
    int i;
1109 6fcfafb7 bellard
1110 6fcfafb7 bellard
    if (event == CHR_EVENT_FOCUS) {
1111 6fcfafb7 bellard
        for(i = 0; i < nb_consoles; i++) {
1112 6fcfafb7 bellard
            if (consoles[i] == s) {
1113 6fcfafb7 bellard
                console_select(i);
1114 6fcfafb7 bellard
                break;
1115 6fcfafb7 bellard
            }
1116 6fcfafb7 bellard
        }
1117 6fcfafb7 bellard
    }
1118 6fcfafb7 bellard
}
1119 6fcfafb7 bellard
1120 e15d7371 bellard
static void kbd_send_chars(void *opaque)
1121 e15d7371 bellard
{
1122 e15d7371 bellard
    TextConsole *s = opaque;
1123 e15d7371 bellard
    int len;
1124 e15d7371 bellard
    uint8_t buf[16];
1125 3b46e624 ths
1126 e5b0bc44 pbrook
    len = qemu_chr_can_read(s->chr);
1127 e15d7371 bellard
    if (len > s->out_fifo.count)
1128 e15d7371 bellard
        len = s->out_fifo.count;
1129 e15d7371 bellard
    if (len > 0) {
1130 e15d7371 bellard
        if (len > sizeof(buf))
1131 e15d7371 bellard
            len = sizeof(buf);
1132 e15d7371 bellard
        qemu_fifo_read(&s->out_fifo, buf, len);
1133 e5b0bc44 pbrook
        qemu_chr_read(s->chr, buf, len);
1134 e15d7371 bellard
    }
1135 e15d7371 bellard
    /* characters are pending: we send them a bit later (XXX:
1136 e15d7371 bellard
       horrible, should change char device API) */
1137 e15d7371 bellard
    if (s->out_fifo.count > 0) {
1138 7bd427d8 Paolo Bonzini
        qemu_mod_timer(s->kbd_timer, qemu_get_clock_ms(rt_clock) + 1);
1139 e15d7371 bellard
    }
1140 e15d7371 bellard
}
1141 e15d7371 bellard
1142 e7f0ad58 bellard
/* called when an ascii key is pressed */
1143 e7f0ad58 bellard
void kbd_put_keysym(int keysym)
1144 e7f0ad58 bellard
{
1145 e7f0ad58 bellard
    TextConsole *s;
1146 e7f0ad58 bellard
    uint8_t buf[16], *q;
1147 e7f0ad58 bellard
    int c;
1148 e7f0ad58 bellard
1149 e7f0ad58 bellard
    s = active_console;
1150 af3a9031 ths
    if (!s || (s->console_type == GRAPHIC_CONSOLE))
1151 e7f0ad58 bellard
        return;
1152 e7f0ad58 bellard
1153 e7f0ad58 bellard
    switch(keysym) {
1154 e7f0ad58 bellard
    case QEMU_KEY_CTRL_UP:
1155 e7f0ad58 bellard
        console_scroll(-1);
1156 e7f0ad58 bellard
        break;
1157 e7f0ad58 bellard
    case QEMU_KEY_CTRL_DOWN:
1158 e7f0ad58 bellard
        console_scroll(1);
1159 e7f0ad58 bellard
        break;
1160 e7f0ad58 bellard
    case QEMU_KEY_CTRL_PAGEUP:
1161 e7f0ad58 bellard
        console_scroll(-10);
1162 e7f0ad58 bellard
        break;
1163 e7f0ad58 bellard
    case QEMU_KEY_CTRL_PAGEDOWN:
1164 e7f0ad58 bellard
        console_scroll(10);
1165 e7f0ad58 bellard
        break;
1166 e7f0ad58 bellard
    default:
1167 e15d7371 bellard
        /* convert the QEMU keysym to VT100 key string */
1168 e15d7371 bellard
        q = buf;
1169 e15d7371 bellard
        if (keysym >= 0xe100 && keysym <= 0xe11f) {
1170 e15d7371 bellard
            *q++ = '\033';
1171 e15d7371 bellard
            *q++ = '[';
1172 e15d7371 bellard
            c = keysym - 0xe100;
1173 e15d7371 bellard
            if (c >= 10)
1174 e15d7371 bellard
                *q++ = '0' + (c / 10);
1175 e15d7371 bellard
            *q++ = '0' + (c % 10);
1176 e15d7371 bellard
            *q++ = '~';
1177 e15d7371 bellard
        } else if (keysym >= 0xe120 && keysym <= 0xe17f) {
1178 e15d7371 bellard
            *q++ = '\033';
1179 e15d7371 bellard
            *q++ = '[';
1180 e15d7371 bellard
            *q++ = keysym & 0xff;
1181 4104833f Paolo Bonzini
        } else if (s->echo && (keysym == '\r' || keysym == '\n')) {
1182 4104833f Paolo Bonzini
            console_puts(s->chr, (const uint8_t *) "\r", 1);
1183 4104833f Paolo Bonzini
            *q++ = '\n';
1184 e15d7371 bellard
        } else {
1185 4104833f Paolo Bonzini
            *q++ = keysym;
1186 4104833f Paolo Bonzini
        }
1187 4104833f Paolo Bonzini
        if (s->echo) {
1188 4104833f Paolo Bonzini
            console_puts(s->chr, buf, q - buf);
1189 e15d7371 bellard
        }
1190 e5b0bc44 pbrook
        if (s->chr->chr_read) {
1191 e15d7371 bellard
            qemu_fifo_write(&s->out_fifo, buf, q - buf);
1192 e15d7371 bellard
            kbd_send_chars(s);
1193 e7f0ad58 bellard
        }
1194 e7f0ad58 bellard
        break;
1195 e7f0ad58 bellard
    }
1196 e7f0ad58 bellard
}
1197 e7f0ad58 bellard
1198 4d3b6f6e balrog
static void text_console_invalidate(void *opaque)
1199 4d3b6f6e balrog
{
1200 4d3b6f6e balrog
    TextConsole *s = (TextConsole *) opaque;
1201 68f00996 aliguori
    if (!ds_get_bits_per_pixel(s->ds) && s->console_type == TEXT_CONSOLE) {
1202 68f00996 aliguori
        s->g_width = ds_get_width(s->ds);
1203 68f00996 aliguori
        s->g_height = ds_get_height(s->ds);
1204 68f00996 aliguori
        text_console_resize(s);
1205 68f00996 aliguori
    }
1206 4d3b6f6e balrog
    console_refresh(s);
1207 4d3b6f6e balrog
}
1208 4d3b6f6e balrog
1209 c227f099 Anthony Liguori
static void text_console_update(void *opaque, console_ch_t *chardata)
1210 4d3b6f6e balrog
{
1211 4d3b6f6e balrog
    TextConsole *s = (TextConsole *) opaque;
1212 4d3b6f6e balrog
    int i, j, src;
1213 4d3b6f6e balrog
1214 4d3b6f6e balrog
    if (s->text_x[0] <= s->text_x[1]) {
1215 4d3b6f6e balrog
        src = (s->y_base + s->text_y[0]) * s->width;
1216 4d3b6f6e balrog
        chardata += s->text_y[0] * s->width;
1217 4d3b6f6e balrog
        for (i = s->text_y[0]; i <= s->text_y[1]; i ++)
1218 4d3b6f6e balrog
            for (j = 0; j < s->width; j ++, src ++)
1219 4d3b6f6e balrog
                console_write_ch(chardata ++, s->cells[src].ch |
1220 4d3b6f6e balrog
                                (s->cells[src].t_attrib.fgcol << 12) |
1221 4d3b6f6e balrog
                                (s->cells[src].t_attrib.bgcol << 8) |
1222 4d3b6f6e balrog
                                (s->cells[src].t_attrib.bold << 21));
1223 4d3b6f6e balrog
        dpy_update(s->ds, s->text_x[0], s->text_y[0],
1224 4d3b6f6e balrog
                   s->text_x[1] - s->text_x[0], i - s->text_y[0]);
1225 4d3b6f6e balrog
        s->text_x[0] = s->width;
1226 4d3b6f6e balrog
        s->text_y[0] = s->height;
1227 4d3b6f6e balrog
        s->text_x[1] = 0;
1228 4d3b6f6e balrog
        s->text_y[1] = 0;
1229 4d3b6f6e balrog
    }
1230 4d3b6f6e balrog
    if (s->cursor_invalidate) {
1231 4d3b6f6e balrog
        dpy_cursor(s->ds, s->x, s->y);
1232 4d3b6f6e balrog
        s->cursor_invalidate = 0;
1233 4d3b6f6e balrog
    }
1234 4d3b6f6e balrog
}
1235 4d3b6f6e balrog
1236 42aa98e8 aliguori
static TextConsole *get_graphic_console(DisplayState *ds)
1237 a147d62b blueswir1
{
1238 3023f332 aliguori
    int i;
1239 3023f332 aliguori
    TextConsole *s;
1240 3023f332 aliguori
    for (i = 0; i < nb_consoles; i++) {
1241 3023f332 aliguori
        s = consoles[i];
1242 42aa98e8 aliguori
        if (s->console_type == GRAPHIC_CONSOLE && s->ds == ds)
1243 3023f332 aliguori
            return s;
1244 3023f332 aliguori
    }
1245 3023f332 aliguori
    return NULL;
1246 3023f332 aliguori
}
1247 3023f332 aliguori
1248 c227f099 Anthony Liguori
static TextConsole *new_console(DisplayState *ds, console_type_t console_type)
1249 e7f0ad58 bellard
{
1250 e7f0ad58 bellard
    TextConsole *s;
1251 95219897 pbrook
    int i;
1252 e7f0ad58 bellard
1253 e7f0ad58 bellard
    if (nb_consoles >= MAX_CONSOLES)
1254 e7f0ad58 bellard
        return NULL;
1255 e7f0ad58 bellard
    s = qemu_mallocz(sizeof(TextConsole));
1256 af3a9031 ths
    if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) &&
1257 af3a9031 ths
        (console_type == GRAPHIC_CONSOLE))) {
1258 e7f0ad58 bellard
        active_console = s;
1259 af3a9031 ths
    }
1260 e7f0ad58 bellard
    s->ds = ds;
1261 af3a9031 ths
    s->console_type = console_type;
1262 af3a9031 ths
    if (console_type != GRAPHIC_CONSOLE) {
1263 95219897 pbrook
        consoles[nb_consoles++] = s;
1264 95219897 pbrook
    } else {
1265 95219897 pbrook
        /* HACK: Put graphical consoles before text consoles.  */
1266 95219897 pbrook
        for (i = nb_consoles; i > 0; i--) {
1267 af3a9031 ths
            if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE)
1268 95219897 pbrook
                break;
1269 95219897 pbrook
            consoles[i] = consoles[i - 1];
1270 95219897 pbrook
        }
1271 95219897 pbrook
        consoles[i] = s;
1272 3023f332 aliguori
        nb_consoles++;
1273 95219897 pbrook
    }
1274 95219897 pbrook
    return s;
1275 95219897 pbrook
}
1276 95219897 pbrook
1277 98b50080 Paolo Bonzini
static DisplaySurface* defaultallocator_create_displaysurface(int width, int height)
1278 98b50080 Paolo Bonzini
{
1279 98b50080 Paolo Bonzini
    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
1280 98b50080 Paolo Bonzini
1281 ffe8b821 Jes Sorensen
    int linesize = width * 4;
1282 ffe8b821 Jes Sorensen
    qemu_alloc_display(surface, width, height, linesize,
1283 ffe8b821 Jes Sorensen
                       qemu_default_pixelformat(32), 0);
1284 98b50080 Paolo Bonzini
    return surface;
1285 98b50080 Paolo Bonzini
}
1286 98b50080 Paolo Bonzini
1287 98b50080 Paolo Bonzini
static DisplaySurface* defaultallocator_resize_displaysurface(DisplaySurface *surface,
1288 98b50080 Paolo Bonzini
                                          int width, int height)
1289 98b50080 Paolo Bonzini
{
1290 ffe8b821 Jes Sorensen
    int linesize = width * 4;
1291 ffe8b821 Jes Sorensen
    qemu_alloc_display(surface, width, height, linesize,
1292 ffe8b821 Jes Sorensen
                       qemu_default_pixelformat(32), 0);
1293 ffe8b821 Jes Sorensen
    return surface;
1294 ffe8b821 Jes Sorensen
}
1295 ffe8b821 Jes Sorensen
1296 ffe8b821 Jes Sorensen
void qemu_alloc_display(DisplaySurface *surface, int width, int height,
1297 ffe8b821 Jes Sorensen
                        int linesize, PixelFormat pf, int newflags)
1298 ffe8b821 Jes Sorensen
{
1299 ffe8b821 Jes Sorensen
    void *data;
1300 98b50080 Paolo Bonzini
    surface->width = width;
1301 98b50080 Paolo Bonzini
    surface->height = height;
1302 ffe8b821 Jes Sorensen
    surface->linesize = linesize;
1303 ffe8b821 Jes Sorensen
    surface->pf = pf;
1304 ffe8b821 Jes Sorensen
    if (surface->flags & QEMU_ALLOCATED_FLAG) {
1305 ffe8b821 Jes Sorensen
        data = qemu_realloc(surface->data,
1306 ffe8b821 Jes Sorensen
                            surface->linesize * surface->height);
1307 ffe8b821 Jes Sorensen
    } else {
1308 ffe8b821 Jes Sorensen
        data = qemu_malloc(surface->linesize * surface->height);
1309 ffe8b821 Jes Sorensen
    }
1310 ffe8b821 Jes Sorensen
    surface->data = (uint8_t *)data;
1311 ffe8b821 Jes Sorensen
    surface->flags = newflags | QEMU_ALLOCATED_FLAG;
1312 98b50080 Paolo Bonzini
#ifdef HOST_WORDS_BIGENDIAN
1313 ffe8b821 Jes Sorensen
    surface->flags |= QEMU_BIG_ENDIAN_FLAG;
1314 98b50080 Paolo Bonzini
#endif
1315 98b50080 Paolo Bonzini
}
1316 98b50080 Paolo Bonzini
1317 98b50080 Paolo Bonzini
DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
1318 98b50080 Paolo Bonzini
                                              int linesize, uint8_t *data)
1319 98b50080 Paolo Bonzini
{
1320 98b50080 Paolo Bonzini
    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
1321 98b50080 Paolo Bonzini
1322 98b50080 Paolo Bonzini
    surface->width = width;
1323 98b50080 Paolo Bonzini
    surface->height = height;
1324 98b50080 Paolo Bonzini
    surface->linesize = linesize;
1325 98b50080 Paolo Bonzini
    surface->pf = qemu_default_pixelformat(bpp);
1326 98b50080 Paolo Bonzini
#ifdef HOST_WORDS_BIGENDIAN
1327 98b50080 Paolo Bonzini
    surface->flags = QEMU_BIG_ENDIAN_FLAG;
1328 98b50080 Paolo Bonzini
#endif
1329 98b50080 Paolo Bonzini
    surface->data = data;
1330 98b50080 Paolo Bonzini
1331 98b50080 Paolo Bonzini
    return surface;
1332 98b50080 Paolo Bonzini
}
1333 98b50080 Paolo Bonzini
1334 98b50080 Paolo Bonzini
static void defaultallocator_free_displaysurface(DisplaySurface *surface)
1335 98b50080 Paolo Bonzini
{
1336 98b50080 Paolo Bonzini
    if (surface == NULL)
1337 98b50080 Paolo Bonzini
        return;
1338 98b50080 Paolo Bonzini
    if (surface->flags & QEMU_ALLOCATED_FLAG)
1339 98b50080 Paolo Bonzini
        qemu_free(surface->data);
1340 98b50080 Paolo Bonzini
    qemu_free(surface);
1341 98b50080 Paolo Bonzini
}
1342 98b50080 Paolo Bonzini
1343 98b50080 Paolo Bonzini
static struct DisplayAllocator default_allocator = {
1344 98b50080 Paolo Bonzini
    defaultallocator_create_displaysurface,
1345 98b50080 Paolo Bonzini
    defaultallocator_resize_displaysurface,
1346 98b50080 Paolo Bonzini
    defaultallocator_free_displaysurface
1347 98b50080 Paolo Bonzini
};
1348 98b50080 Paolo Bonzini
1349 98b50080 Paolo Bonzini
static void dumb_display_init(void)
1350 98b50080 Paolo Bonzini
{
1351 98b50080 Paolo Bonzini
    DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
1352 98b50080 Paolo Bonzini
    ds->allocator = &default_allocator;
1353 98b50080 Paolo Bonzini
    ds->surface = qemu_create_displaysurface(ds, 640, 480);
1354 98b50080 Paolo Bonzini
    register_displaystate(ds);
1355 98b50080 Paolo Bonzini
}
1356 98b50080 Paolo Bonzini
1357 98b50080 Paolo Bonzini
/***********************************************************/
1358 98b50080 Paolo Bonzini
/* register display */
1359 98b50080 Paolo Bonzini
1360 98b50080 Paolo Bonzini
void register_displaystate(DisplayState *ds)
1361 98b50080 Paolo Bonzini
{
1362 98b50080 Paolo Bonzini
    DisplayState **s;
1363 98b50080 Paolo Bonzini
    s = &display_state;
1364 98b50080 Paolo Bonzini
    while (*s != NULL)
1365 98b50080 Paolo Bonzini
        s = &(*s)->next;
1366 98b50080 Paolo Bonzini
    ds->next = NULL;
1367 98b50080 Paolo Bonzini
    *s = ds;
1368 98b50080 Paolo Bonzini
}
1369 98b50080 Paolo Bonzini
1370 98b50080 Paolo Bonzini
DisplayState *get_displaystate(void)
1371 98b50080 Paolo Bonzini
{
1372 98b50080 Paolo Bonzini
    if (!display_state) {
1373 98b50080 Paolo Bonzini
        dumb_display_init ();
1374 98b50080 Paolo Bonzini
    }
1375 98b50080 Paolo Bonzini
    return display_state;
1376 98b50080 Paolo Bonzini
}
1377 98b50080 Paolo Bonzini
1378 98b50080 Paolo Bonzini
DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
1379 98b50080 Paolo Bonzini
{
1380 98b50080 Paolo Bonzini
    if(ds->allocator ==  &default_allocator) {
1381 98b50080 Paolo Bonzini
        DisplaySurface *surf;
1382 98b50080 Paolo Bonzini
        surf = da->create_displaysurface(ds_get_width(ds), ds_get_height(ds));
1383 98b50080 Paolo Bonzini
        defaultallocator_free_displaysurface(ds->surface);
1384 98b50080 Paolo Bonzini
        ds->surface = surf;
1385 98b50080 Paolo Bonzini
        ds->allocator = da;
1386 98b50080 Paolo Bonzini
    }
1387 98b50080 Paolo Bonzini
    return ds->allocator;
1388 98b50080 Paolo Bonzini
}
1389 98b50080 Paolo Bonzini
1390 3023f332 aliguori
DisplayState *graphic_console_init(vga_hw_update_ptr update,
1391 3023f332 aliguori
                                   vga_hw_invalidate_ptr invalidate,
1392 3023f332 aliguori
                                   vga_hw_screen_dump_ptr screen_dump,
1393 3023f332 aliguori
                                   vga_hw_text_update_ptr text_update,
1394 3023f332 aliguori
                                   void *opaque)
1395 95219897 pbrook
{
1396 95219897 pbrook
    TextConsole *s;
1397 3023f332 aliguori
    DisplayState *ds;
1398 f0f2f976 aurel32
1399 3023f332 aliguori
    ds = (DisplayState *) qemu_mallocz(sizeof(DisplayState));
1400 7b5d76da aliguori
    ds->allocator = &default_allocator; 
1401 7b5d76da aliguori
    ds->surface = qemu_create_displaysurface(ds, 640, 480);
1402 95219897 pbrook
1403 af3a9031 ths
    s = new_console(ds, GRAPHIC_CONSOLE);
1404 3023f332 aliguori
    if (s == NULL) {
1405 7b5d76da aliguori
        qemu_free_displaysurface(ds);
1406 3023f332 aliguori
        qemu_free(ds);
1407 3023f332 aliguori
        return NULL;
1408 3023f332 aliguori
    }
1409 95219897 pbrook
    s->hw_update = update;
1410 95219897 pbrook
    s->hw_invalidate = invalidate;
1411 95219897 pbrook
    s->hw_screen_dump = screen_dump;
1412 4d3b6f6e balrog
    s->hw_text_update = text_update;
1413 95219897 pbrook
    s->hw = opaque;
1414 3023f332 aliguori
1415 f0f2f976 aurel32
    register_displaystate(ds);
1416 3023f332 aliguori
    return ds;
1417 e7f0ad58 bellard
}
1418 e7f0ad58 bellard
1419 95219897 pbrook
int is_graphic_console(void)
1420 e7f0ad58 bellard
{
1421 4d3b6f6e balrog
    return active_console && active_console->console_type == GRAPHIC_CONSOLE;
1422 e7f0ad58 bellard
}
1423 e7f0ad58 bellard
1424 c21bbcfa balrog
int is_fixedsize_console(void)
1425 c21bbcfa balrog
{
1426 c21bbcfa balrog
    return active_console && active_console->console_type != TEXT_CONSOLE;
1427 c21bbcfa balrog
}
1428 c21bbcfa balrog
1429 a528b80c balrog
void console_color_init(DisplayState *ds)
1430 a528b80c balrog
{
1431 a528b80c balrog
    int i, j;
1432 a528b80c balrog
    for (j = 0; j < 2; j++) {
1433 a528b80c balrog
        for (i = 0; i < 8; i++) {
1434 f0f2f976 aurel32
            color_table[j][i] = col_expand(ds,
1435 a528b80c balrog
                   vga_get_color(ds, color_table_rgb[j][i]));
1436 a528b80c balrog
        }
1437 a528b80c balrog
    }
1438 a528b80c balrog
}
1439 a528b80c balrog
1440 2796dae0 aliguori
static int n_text_consoles;
1441 2796dae0 aliguori
static CharDriverState *text_consoles[128];
1442 2796dae0 aliguori
1443 4104833f Paolo Bonzini
static void text_console_set_echo(CharDriverState *chr, bool echo)
1444 4104833f Paolo Bonzini
{
1445 4104833f Paolo Bonzini
    TextConsole *s = chr->opaque;
1446 4104833f Paolo Bonzini
1447 4104833f Paolo Bonzini
    s->echo = echo;
1448 4104833f Paolo Bonzini
}
1449 4104833f Paolo Bonzini
1450 44b37b93 Paolo Bonzini
static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
1451 e7f0ad58 bellard
{
1452 e7f0ad58 bellard
    TextConsole *s;
1453 e7f0ad58 bellard
    static int color_inited;
1454 6d6f7c28 pbrook
1455 491e114a Paolo Bonzini
    s = chr->opaque;
1456 6ea314d9 Gerd Hoffmann
1457 e7f0ad58 bellard
    chr->chr_write = console_puts;
1458 6fcfafb7 bellard
    chr->chr_send_event = console_send_event;
1459 6fcfafb7 bellard
1460 e15d7371 bellard
    s->out_fifo.buf = s->out_fifo_buf;
1461 e15d7371 bellard
    s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
1462 7bd427d8 Paolo Bonzini
    s->kbd_timer = qemu_new_timer_ms(rt_clock, kbd_send_chars, s);
1463 3023f332 aliguori
    s->ds = ds;
1464 3b46e624 ths
1465 e7f0ad58 bellard
    if (!color_inited) {
1466 e7f0ad58 bellard
        color_inited = 1;
1467 a528b80c balrog
        console_color_init(s->ds);
1468 e7f0ad58 bellard
    }
1469 e7f0ad58 bellard
    s->y_displayed = 0;
1470 e7f0ad58 bellard
    s->y_base = 0;
1471 e7f0ad58 bellard
    s->total_height = DEFAULT_BACKSCROLL;
1472 e7f0ad58 bellard
    s->x = 0;
1473 e7f0ad58 bellard
    s->y = 0;
1474 491e114a Paolo Bonzini
    if (s->console_type == TEXT_CONSOLE) {
1475 491e114a Paolo Bonzini
        s->g_width = ds_get_width(s->ds);
1476 491e114a Paolo Bonzini
        s->g_height = ds_get_height(s->ds);
1477 491e114a Paolo Bonzini
    }
1478 6d6f7c28 pbrook
1479 4d3b6f6e balrog
    s->hw_invalidate = text_console_invalidate;
1480 4d3b6f6e balrog
    s->hw_text_update = text_console_update;
1481 4d3b6f6e balrog
    s->hw = s;
1482 4d3b6f6e balrog
1483 6d6f7c28 pbrook
    /* Set text attribute defaults */
1484 6d6f7c28 pbrook
    s->t_attrib_default.bold = 0;
1485 6d6f7c28 pbrook
    s->t_attrib_default.uline = 0;
1486 6d6f7c28 pbrook
    s->t_attrib_default.blink = 0;
1487 6d6f7c28 pbrook
    s->t_attrib_default.invers = 0;
1488 6d6f7c28 pbrook
    s->t_attrib_default.unvisible = 0;
1489 6d6f7c28 pbrook
    s->t_attrib_default.fgcol = COLOR_WHITE;
1490 6d6f7c28 pbrook
    s->t_attrib_default.bgcol = COLOR_BLACK;
1491 6d6f7c28 pbrook
    /* set current text attributes to default */
1492 6d6f7c28 pbrook
    s->t_attrib = s->t_attrib_default;
1493 e7f0ad58 bellard
    text_console_resize(s);
1494 e7f0ad58 bellard
1495 51bfa4d3 Gerd Hoffmann
    if (chr->label) {
1496 51bfa4d3 Gerd Hoffmann
        char msg[128];
1497 51bfa4d3 Gerd Hoffmann
        int len;
1498 51bfa4d3 Gerd Hoffmann
1499 735ba588 Gerd Hoffmann
        s->t_attrib.bgcol = COLOR_BLUE;
1500 51bfa4d3 Gerd Hoffmann
        len = snprintf(msg, sizeof(msg), "%s console\r\n", chr->label);
1501 51bfa4d3 Gerd Hoffmann
        console_puts(chr, (uint8_t*)msg, len);
1502 735ba588 Gerd Hoffmann
        s->t_attrib = s->t_attrib_default;
1503 51bfa4d3 Gerd Hoffmann
    }
1504 51bfa4d3 Gerd Hoffmann
1505 127338e6 Amit Shah
    qemu_chr_generic_open(chr);
1506 ceecf1d1 aurel32
    if (chr->init)
1507 ceecf1d1 aurel32
        chr->init(chr);
1508 e7f0ad58 bellard
}
1509 c60e08d9 pbrook
1510 6ea314d9 Gerd Hoffmann
CharDriverState *text_console_init(QemuOpts *opts)
1511 2796dae0 aliguori
{
1512 2796dae0 aliguori
    CharDriverState *chr;
1513 491e114a Paolo Bonzini
    TextConsole *s;
1514 491e114a Paolo Bonzini
    unsigned width;
1515 491e114a Paolo Bonzini
    unsigned height;
1516 2796dae0 aliguori
1517 2796dae0 aliguori
    chr = qemu_mallocz(sizeof(CharDriverState));
1518 2796dae0 aliguori
1519 2796dae0 aliguori
    if (n_text_consoles == 128) {
1520 2796dae0 aliguori
        fprintf(stderr, "Too many text consoles\n");
1521 2796dae0 aliguori
        exit(1);
1522 2796dae0 aliguori
    }
1523 2796dae0 aliguori
    text_consoles[n_text_consoles] = chr;
1524 2796dae0 aliguori
    n_text_consoles++;
1525 2796dae0 aliguori
1526 491e114a Paolo Bonzini
    width = qemu_opt_get_number(opts, "width", 0);
1527 491e114a Paolo Bonzini
    if (width == 0)
1528 491e114a Paolo Bonzini
        width = qemu_opt_get_number(opts, "cols", 0) * FONT_WIDTH;
1529 491e114a Paolo Bonzini
1530 491e114a Paolo Bonzini
    height = qemu_opt_get_number(opts, "height", 0);
1531 491e114a Paolo Bonzini
    if (height == 0)
1532 491e114a Paolo Bonzini
        height = qemu_opt_get_number(opts, "rows", 0) * FONT_HEIGHT;
1533 491e114a Paolo Bonzini
1534 491e114a Paolo Bonzini
    if (width == 0 || height == 0) {
1535 491e114a Paolo Bonzini
        s = new_console(NULL, TEXT_CONSOLE);
1536 491e114a Paolo Bonzini
    } else {
1537 491e114a Paolo Bonzini
        s = new_console(NULL, TEXT_CONSOLE_FIXED_SIZE);
1538 491e114a Paolo Bonzini
    }
1539 491e114a Paolo Bonzini
1540 491e114a Paolo Bonzini
    if (!s) {
1541 491e114a Paolo Bonzini
        free(chr);
1542 491e114a Paolo Bonzini
        return NULL;
1543 491e114a Paolo Bonzini
    }
1544 491e114a Paolo Bonzini
1545 491e114a Paolo Bonzini
    s->chr = chr;
1546 491e114a Paolo Bonzini
    s->g_width = width;
1547 491e114a Paolo Bonzini
    s->g_height = height;
1548 491e114a Paolo Bonzini
    chr->opaque = s;
1549 4104833f Paolo Bonzini
    chr->chr_set_echo = text_console_set_echo;
1550 2796dae0 aliguori
    return chr;
1551 2796dae0 aliguori
}
1552 2796dae0 aliguori
1553 2796dae0 aliguori
void text_consoles_set_display(DisplayState *ds)
1554 2796dae0 aliguori
{
1555 2796dae0 aliguori
    int i;
1556 2796dae0 aliguori
1557 2796dae0 aliguori
    for (i = 0; i < n_text_consoles; i++) {
1558 44b37b93 Paolo Bonzini
        text_console_do_init(text_consoles[i], ds);
1559 2796dae0 aliguori
    }
1560 2796dae0 aliguori
1561 2796dae0 aliguori
    n_text_consoles = 0;
1562 2796dae0 aliguori
}
1563 2796dae0 aliguori
1564 3023f332 aliguori
void qemu_console_resize(DisplayState *ds, int width, int height)
1565 c60e08d9 pbrook
{
1566 42aa98e8 aliguori
    TextConsole *s = get_graphic_console(ds);
1567 f497f140 aliguori
    if (!s) return;
1568 f497f140 aliguori
1569 3023f332 aliguori
    s->g_width = width;
1570 3023f332 aliguori
    s->g_height = height;
1571 3023f332 aliguori
    if (is_graphic_console()) {
1572 7b5d76da aliguori
        ds->surface = qemu_resize_displaysurface(ds, width, height);
1573 3023f332 aliguori
        dpy_resize(ds);
1574 c60e08d9 pbrook
    }
1575 c60e08d9 pbrook
}
1576 38334f76 balrog
1577 3023f332 aliguori
void qemu_console_copy(DisplayState *ds, int src_x, int src_y,
1578 3023f332 aliguori
                       int dst_x, int dst_y, int w, int h)
1579 c21bbcfa balrog
{
1580 3023f332 aliguori
    if (is_graphic_console()) {
1581 3023f332 aliguori
        dpy_copy(ds, src_x, src_y, dst_x, dst_y, w, h);
1582 38334f76 balrog
    }
1583 38334f76 balrog
}
1584 7d957bd8 aliguori
1585 0da2ea1b malc
PixelFormat qemu_different_endianness_pixelformat(int bpp)
1586 7d957bd8 aliguori
{
1587 7d957bd8 aliguori
    PixelFormat pf;
1588 7d957bd8 aliguori
1589 7d957bd8 aliguori
    memset(&pf, 0x00, sizeof(PixelFormat));
1590 7d957bd8 aliguori
1591 7d957bd8 aliguori
    pf.bits_per_pixel = bpp;
1592 7d957bd8 aliguori
    pf.bytes_per_pixel = bpp / 8;
1593 7d957bd8 aliguori
    pf.depth = bpp == 32 ? 24 : bpp;
1594 7d957bd8 aliguori
1595 7d957bd8 aliguori
    switch (bpp) {
1596 0da2ea1b malc
        case 24:
1597 0da2ea1b malc
            pf.rmask = 0x000000FF;
1598 0da2ea1b malc
            pf.gmask = 0x0000FF00;
1599 0da2ea1b malc
            pf.bmask = 0x00FF0000;
1600 0da2ea1b malc
            pf.rmax = 255;
1601 0da2ea1b malc
            pf.gmax = 255;
1602 0da2ea1b malc
            pf.bmax = 255;
1603 0da2ea1b malc
            pf.rshift = 0;
1604 0da2ea1b malc
            pf.gshift = 8;
1605 0da2ea1b malc
            pf.bshift = 16;
1606 90a1e3c0 aliguori
            pf.rbits = 8;
1607 90a1e3c0 aliguori
            pf.gbits = 8;
1608 90a1e3c0 aliguori
            pf.bbits = 8;
1609 7d957bd8 aliguori
            break;
1610 0da2ea1b malc
        case 32:
1611 0da2ea1b malc
            pf.rmask = 0x0000FF00;
1612 0da2ea1b malc
            pf.gmask = 0x00FF0000;
1613 0da2ea1b malc
            pf.bmask = 0xFF000000;
1614 0da2ea1b malc
            pf.amask = 0x00000000;
1615 0da2ea1b malc
            pf.amax = 255;
1616 0da2ea1b malc
            pf.rmax = 255;
1617 0da2ea1b malc
            pf.gmax = 255;
1618 0da2ea1b malc
            pf.bmax = 255;
1619 0da2ea1b malc
            pf.ashift = 0;
1620 0da2ea1b malc
            pf.rshift = 8;
1621 0da2ea1b malc
            pf.gshift = 16;
1622 0da2ea1b malc
            pf.bshift = 24;
1623 90a1e3c0 aliguori
            pf.rbits = 8;
1624 90a1e3c0 aliguori
            pf.gbits = 8;
1625 90a1e3c0 aliguori
            pf.bbits = 8;
1626 90a1e3c0 aliguori
            pf.abits = 8;
1627 0da2ea1b malc
            break;
1628 0da2ea1b malc
        default:
1629 0da2ea1b malc
            break;
1630 0da2ea1b malc
    }
1631 0da2ea1b malc
    return pf;
1632 0da2ea1b malc
}
1633 0da2ea1b malc
1634 0da2ea1b malc
PixelFormat qemu_default_pixelformat(int bpp)
1635 0da2ea1b malc
{
1636 0da2ea1b malc
    PixelFormat pf;
1637 0da2ea1b malc
1638 0da2ea1b malc
    memset(&pf, 0x00, sizeof(PixelFormat));
1639 0da2ea1b malc
1640 0da2ea1b malc
    pf.bits_per_pixel = bpp;
1641 0da2ea1b malc
    pf.bytes_per_pixel = bpp / 8;
1642 0da2ea1b malc
    pf.depth = bpp == 32 ? 24 : bpp;
1643 0da2ea1b malc
1644 0da2ea1b malc
    switch (bpp) {
1645 b6278084 Gerd Hoffmann
        case 15:
1646 b6278084 Gerd Hoffmann
            pf.bits_per_pixel = 16;
1647 b6278084 Gerd Hoffmann
            pf.bytes_per_pixel = 2;
1648 b6278084 Gerd Hoffmann
            pf.rmask = 0x00007c00;
1649 b6278084 Gerd Hoffmann
            pf.gmask = 0x000003E0;
1650 b6278084 Gerd Hoffmann
            pf.bmask = 0x0000001F;
1651 b6278084 Gerd Hoffmann
            pf.rmax = 31;
1652 b6278084 Gerd Hoffmann
            pf.gmax = 31;
1653 b6278084 Gerd Hoffmann
            pf.bmax = 31;
1654 b6278084 Gerd Hoffmann
            pf.rshift = 10;
1655 b6278084 Gerd Hoffmann
            pf.gshift = 5;
1656 b6278084 Gerd Hoffmann
            pf.bshift = 0;
1657 b6278084 Gerd Hoffmann
            pf.rbits = 5;
1658 b6278084 Gerd Hoffmann
            pf.gbits = 5;
1659 b6278084 Gerd Hoffmann
            pf.bbits = 5;
1660 b6278084 Gerd Hoffmann
            break;
1661 7d957bd8 aliguori
        case 16:
1662 7d957bd8 aliguori
            pf.rmask = 0x0000F800;
1663 7d957bd8 aliguori
            pf.gmask = 0x000007E0;
1664 7d957bd8 aliguori
            pf.bmask = 0x0000001F;
1665 7d957bd8 aliguori
            pf.rmax = 31;
1666 7d957bd8 aliguori
            pf.gmax = 63;
1667 7d957bd8 aliguori
            pf.bmax = 31;
1668 7d957bd8 aliguori
            pf.rshift = 11;
1669 7d957bd8 aliguori
            pf.gshift = 5;
1670 7d957bd8 aliguori
            pf.bshift = 0;
1671 90a1e3c0 aliguori
            pf.rbits = 5;
1672 90a1e3c0 aliguori
            pf.gbits = 6;
1673 90a1e3c0 aliguori
            pf.bbits = 5;
1674 7d957bd8 aliguori
            break;
1675 7d957bd8 aliguori
        case 24:
1676 0da2ea1b malc
            pf.rmask = 0x00FF0000;
1677 0da2ea1b malc
            pf.gmask = 0x0000FF00;
1678 0da2ea1b malc
            pf.bmask = 0x000000FF;
1679 0da2ea1b malc
            pf.rmax = 255;
1680 0da2ea1b malc
            pf.gmax = 255;
1681 0da2ea1b malc
            pf.bmax = 255;
1682 0da2ea1b malc
            pf.rshift = 16;
1683 0da2ea1b malc
            pf.gshift = 8;
1684 0da2ea1b malc
            pf.bshift = 0;
1685 90a1e3c0 aliguori
            pf.rbits = 8;
1686 90a1e3c0 aliguori
            pf.gbits = 8;
1687 90a1e3c0 aliguori
            pf.bbits = 8;
1688 7d957bd8 aliguori
        case 32:
1689 7d957bd8 aliguori
            pf.rmask = 0x00FF0000;
1690 7d957bd8 aliguori
            pf.gmask = 0x0000FF00;
1691 7d957bd8 aliguori
            pf.bmask = 0x000000FF;
1692 0da2ea1b malc
            pf.amax = 255;
1693 7d957bd8 aliguori
            pf.rmax = 255;
1694 7d957bd8 aliguori
            pf.gmax = 255;
1695 7d957bd8 aliguori
            pf.bmax = 255;
1696 0da2ea1b malc
            pf.ashift = 24;
1697 7d957bd8 aliguori
            pf.rshift = 16;
1698 7d957bd8 aliguori
            pf.gshift = 8;
1699 7d957bd8 aliguori
            pf.bshift = 0;
1700 90a1e3c0 aliguori
            pf.rbits = 8;
1701 90a1e3c0 aliguori
            pf.gbits = 8;
1702 90a1e3c0 aliguori
            pf.bbits = 8;
1703 90a1e3c0 aliguori
            pf.abits = 8;
1704 7d957bd8 aliguori
            break;
1705 7d957bd8 aliguori
        default:
1706 7d957bd8 aliguori
            break;
1707 7d957bd8 aliguori
    }
1708 7d957bd8 aliguori
    return pf;
1709 7d957bd8 aliguori
}