Statistics
| Branch: | Revision:

root / console.c @ 8b7968f7

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