Statistics
| Branch: | Revision:

root / console.c @ 0da2ea1b

History | View | Annotate | Download (44.7 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 c60e08d9 pbrook
#define DEFAULT_MONITOR_SIZE "800x600"
32 e7f0ad58 bellard
33 26489844 bellard
#define QEMU_RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
34 26489844 bellard
#define QEMU_RGB(r, g, b) QEMU_RGBA(r, g, b, 0xff)
35 e7f0ad58 bellard
36 6d6f7c28 pbrook
typedef struct TextAttributes {
37 6d6f7c28 pbrook
    uint8_t fgcol:4;
38 6d6f7c28 pbrook
    uint8_t bgcol:4;
39 6d6f7c28 pbrook
    uint8_t bold:1;
40 6d6f7c28 pbrook
    uint8_t uline:1;
41 6d6f7c28 pbrook
    uint8_t blink:1;
42 6d6f7c28 pbrook
    uint8_t invers:1;
43 6d6f7c28 pbrook
    uint8_t unvisible:1;
44 6d6f7c28 pbrook
} TextAttributes;
45 6d6f7c28 pbrook
46 e7f0ad58 bellard
typedef struct TextCell {
47 e7f0ad58 bellard
    uint8_t ch;
48 6d6f7c28 pbrook
    TextAttributes t_attrib;
49 e7f0ad58 bellard
} TextCell;
50 e7f0ad58 bellard
51 e7f0ad58 bellard
#define MAX_ESC_PARAMS 3
52 e7f0ad58 bellard
53 e7f0ad58 bellard
enum TTYState {
54 e7f0ad58 bellard
    TTY_STATE_NORM,
55 e7f0ad58 bellard
    TTY_STATE_ESC,
56 e7f0ad58 bellard
    TTY_STATE_CSI,
57 e7f0ad58 bellard
};
58 e7f0ad58 bellard
59 e15d7371 bellard
typedef struct QEMUFIFO {
60 e15d7371 bellard
    uint8_t *buf;
61 e15d7371 bellard
    int buf_size;
62 e15d7371 bellard
    int count, wptr, rptr;
63 e15d7371 bellard
} QEMUFIFO;
64 e15d7371 bellard
65 9596ebb7 pbrook
static int qemu_fifo_write(QEMUFIFO *f, const uint8_t *buf, int len1)
66 e15d7371 bellard
{
67 e15d7371 bellard
    int l, len;
68 e15d7371 bellard
69 e15d7371 bellard
    l = f->buf_size - f->count;
70 e15d7371 bellard
    if (len1 > l)
71 e15d7371 bellard
        len1 = l;
72 e15d7371 bellard
    len = len1;
73 e15d7371 bellard
    while (len > 0) {
74 e15d7371 bellard
        l = f->buf_size - f->wptr;
75 e15d7371 bellard
        if (l > len)
76 e15d7371 bellard
            l = len;
77 e15d7371 bellard
        memcpy(f->buf + f->wptr, buf, l);
78 e15d7371 bellard
        f->wptr += l;
79 e15d7371 bellard
        if (f->wptr >= f->buf_size)
80 e15d7371 bellard
            f->wptr = 0;
81 e15d7371 bellard
        buf += l;
82 e15d7371 bellard
        len -= l;
83 e15d7371 bellard
    }
84 e15d7371 bellard
    f->count += len1;
85 e15d7371 bellard
    return len1;
86 e15d7371 bellard
}
87 e15d7371 bellard
88 9596ebb7 pbrook
static int qemu_fifo_read(QEMUFIFO *f, uint8_t *buf, int len1)
89 e15d7371 bellard
{
90 e15d7371 bellard
    int l, len;
91 e15d7371 bellard
92 e15d7371 bellard
    if (len1 > f->count)
93 e15d7371 bellard
        len1 = f->count;
94 e15d7371 bellard
    len = len1;
95 e15d7371 bellard
    while (len > 0) {
96 e15d7371 bellard
        l = f->buf_size - f->rptr;
97 e15d7371 bellard
        if (l > len)
98 e15d7371 bellard
            l = len;
99 e15d7371 bellard
        memcpy(buf, f->buf + f->rptr, l);
100 e15d7371 bellard
        f->rptr += l;
101 e15d7371 bellard
        if (f->rptr >= f->buf_size)
102 e15d7371 bellard
            f->rptr = 0;
103 e15d7371 bellard
        buf += l;
104 e15d7371 bellard
        len -= l;
105 e15d7371 bellard
    }
106 e15d7371 bellard
    f->count -= len1;
107 e15d7371 bellard
    return len1;
108 e15d7371 bellard
}
109 e15d7371 bellard
110 af3a9031 ths
typedef enum {
111 af3a9031 ths
    GRAPHIC_CONSOLE,
112 c21bbcfa balrog
    TEXT_CONSOLE,
113 c21bbcfa balrog
    TEXT_CONSOLE_FIXED_SIZE
114 af3a9031 ths
} console_type_t;
115 af3a9031 ths
116 95219897 pbrook
/* ??? This is mis-named.
117 95219897 pbrook
   It is used for both text and graphical consoles.  */
118 e7f0ad58 bellard
struct TextConsole {
119 af3a9031 ths
    console_type_t console_type;
120 e7f0ad58 bellard
    DisplayState *ds;
121 95219897 pbrook
    /* Graphic console state.  */
122 95219897 pbrook
    vga_hw_update_ptr hw_update;
123 95219897 pbrook
    vga_hw_invalidate_ptr hw_invalidate;
124 95219897 pbrook
    vga_hw_screen_dump_ptr hw_screen_dump;
125 4d3b6f6e balrog
    vga_hw_text_update_ptr hw_text_update;
126 95219897 pbrook
    void *hw;
127 95219897 pbrook
128 e7f0ad58 bellard
    int g_width, g_height;
129 e7f0ad58 bellard
    int width;
130 e7f0ad58 bellard
    int height;
131 e7f0ad58 bellard
    int total_height;
132 e7f0ad58 bellard
    int backscroll_height;
133 e7f0ad58 bellard
    int x, y;
134 adb47967 ths
    int x_saved, y_saved;
135 e7f0ad58 bellard
    int y_displayed;
136 e7f0ad58 bellard
    int y_base;
137 6d6f7c28 pbrook
    TextAttributes t_attrib_default; /* default text attributes */
138 6d6f7c28 pbrook
    TextAttributes t_attrib; /* currently active text attributes */
139 e7f0ad58 bellard
    TextCell *cells;
140 4d3b6f6e balrog
    int text_x[2], text_y[2], cursor_invalidate;
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 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 95219897 pbrook
    if (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 4d3b6f6e balrog
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 e7f0ad58 bellard
#ifdef 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
    c++;
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 7d957bd8 aliguori
    active_console->g_width = ds_get_width(active_console->ds);
1065 7d957bd8 aliguori
    active_console->g_height = ds_get_height(active_console->ds);
1066 e7f0ad58 bellard
    s = consoles[index];
1067 e7f0ad58 bellard
    if (s) {
1068 7d957bd8 aliguori
        DisplayState *ds = s->ds;
1069 e7f0ad58 bellard
        active_console = s;
1070 68f00996 aliguori
        if (ds_get_bits_per_pixel(s->ds)) {
1071 68f00996 aliguori
            ds->surface = qemu_resize_displaysurface(ds->surface, s->g_width,
1072 68f00996 aliguori
                    s->g_height, 32, 4 * s->g_width);
1073 68f00996 aliguori
        } else {
1074 68f00996 aliguori
            s->ds->surface->width = s->width;
1075 68f00996 aliguori
            s->ds->surface->height = s->height;
1076 68f00996 aliguori
        }
1077 7d957bd8 aliguori
        dpy_resize(s->ds);
1078 4d3b6f6e balrog
        vga_hw_invalidate();
1079 e7f0ad58 bellard
    }
1080 e7f0ad58 bellard
}
1081 e7f0ad58 bellard
1082 e7f0ad58 bellard
static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
1083 e7f0ad58 bellard
{
1084 e7f0ad58 bellard
    TextConsole *s = chr->opaque;
1085 e7f0ad58 bellard
    int i;
1086 e7f0ad58 bellard
1087 14778c20 pbrook
    s->update_x0 = s->width * FONT_WIDTH;
1088 14778c20 pbrook
    s->update_y0 = s->height * FONT_HEIGHT;
1089 14778c20 pbrook
    s->update_x1 = 0;
1090 14778c20 pbrook
    s->update_y1 = 0;
1091 e7f0ad58 bellard
    console_show_cursor(s, 0);
1092 e7f0ad58 bellard
    for(i = 0; i < len; i++) {
1093 e7f0ad58 bellard
        console_putchar(s, buf[i]);
1094 e7f0ad58 bellard
    }
1095 e7f0ad58 bellard
    console_show_cursor(s, 1);
1096 14778c20 pbrook
    if (ds_get_bits_per_pixel(s->ds) && s->update_x0 < s->update_x1) {
1097 14778c20 pbrook
        dpy_update(s->ds, s->update_x0, s->update_y0,
1098 14778c20 pbrook
                   s->update_x1 - s->update_x0,
1099 14778c20 pbrook
                   s->update_y1 - s->update_y0);
1100 14778c20 pbrook
    }
1101 e7f0ad58 bellard
    return len;
1102 e7f0ad58 bellard
}
1103 e7f0ad58 bellard
1104 6fcfafb7 bellard
static void console_send_event(CharDriverState *chr, int event)
1105 6fcfafb7 bellard
{
1106 6fcfafb7 bellard
    TextConsole *s = chr->opaque;
1107 6fcfafb7 bellard
    int i;
1108 6fcfafb7 bellard
1109 6fcfafb7 bellard
    if (event == CHR_EVENT_FOCUS) {
1110 6fcfafb7 bellard
        for(i = 0; i < nb_consoles; i++) {
1111 6fcfafb7 bellard
            if (consoles[i] == s) {
1112 6fcfafb7 bellard
                console_select(i);
1113 6fcfafb7 bellard
                break;
1114 6fcfafb7 bellard
            }
1115 6fcfafb7 bellard
        }
1116 6fcfafb7 bellard
    }
1117 6fcfafb7 bellard
}
1118 6fcfafb7 bellard
1119 e15d7371 bellard
static void kbd_send_chars(void *opaque)
1120 e15d7371 bellard
{
1121 e15d7371 bellard
    TextConsole *s = opaque;
1122 e15d7371 bellard
    int len;
1123 e15d7371 bellard
    uint8_t buf[16];
1124 3b46e624 ths
1125 e5b0bc44 pbrook
    len = qemu_chr_can_read(s->chr);
1126 e15d7371 bellard
    if (len > s->out_fifo.count)
1127 e15d7371 bellard
        len = s->out_fifo.count;
1128 e15d7371 bellard
    if (len > 0) {
1129 e15d7371 bellard
        if (len > sizeof(buf))
1130 e15d7371 bellard
            len = sizeof(buf);
1131 e15d7371 bellard
        qemu_fifo_read(&s->out_fifo, buf, len);
1132 e5b0bc44 pbrook
        qemu_chr_read(s->chr, buf, len);
1133 e15d7371 bellard
    }
1134 e15d7371 bellard
    /* characters are pending: we send them a bit later (XXX:
1135 e15d7371 bellard
       horrible, should change char device API) */
1136 e15d7371 bellard
    if (s->out_fifo.count > 0) {
1137 e15d7371 bellard
        qemu_mod_timer(s->kbd_timer, qemu_get_clock(rt_clock) + 1);
1138 e15d7371 bellard
    }
1139 e15d7371 bellard
}
1140 e15d7371 bellard
1141 e7f0ad58 bellard
/* called when an ascii key is pressed */
1142 e7f0ad58 bellard
void kbd_put_keysym(int keysym)
1143 e7f0ad58 bellard
{
1144 e7f0ad58 bellard
    TextConsole *s;
1145 e7f0ad58 bellard
    uint8_t buf[16], *q;
1146 e7f0ad58 bellard
    int c;
1147 e7f0ad58 bellard
1148 e7f0ad58 bellard
    s = active_console;
1149 af3a9031 ths
    if (!s || (s->console_type == GRAPHIC_CONSOLE))
1150 e7f0ad58 bellard
        return;
1151 e7f0ad58 bellard
1152 e7f0ad58 bellard
    switch(keysym) {
1153 e7f0ad58 bellard
    case QEMU_KEY_CTRL_UP:
1154 e7f0ad58 bellard
        console_scroll(-1);
1155 e7f0ad58 bellard
        break;
1156 e7f0ad58 bellard
    case QEMU_KEY_CTRL_DOWN:
1157 e7f0ad58 bellard
        console_scroll(1);
1158 e7f0ad58 bellard
        break;
1159 e7f0ad58 bellard
    case QEMU_KEY_CTRL_PAGEUP:
1160 e7f0ad58 bellard
        console_scroll(-10);
1161 e7f0ad58 bellard
        break;
1162 e7f0ad58 bellard
    case QEMU_KEY_CTRL_PAGEDOWN:
1163 e7f0ad58 bellard
        console_scroll(10);
1164 e7f0ad58 bellard
        break;
1165 e7f0ad58 bellard
    default:
1166 e15d7371 bellard
        /* convert the QEMU keysym to VT100 key string */
1167 e15d7371 bellard
        q = buf;
1168 e15d7371 bellard
        if (keysym >= 0xe100 && keysym <= 0xe11f) {
1169 e15d7371 bellard
            *q++ = '\033';
1170 e15d7371 bellard
            *q++ = '[';
1171 e15d7371 bellard
            c = keysym - 0xe100;
1172 e15d7371 bellard
            if (c >= 10)
1173 e15d7371 bellard
                *q++ = '0' + (c / 10);
1174 e15d7371 bellard
            *q++ = '0' + (c % 10);
1175 e15d7371 bellard
            *q++ = '~';
1176 e15d7371 bellard
        } else if (keysym >= 0xe120 && keysym <= 0xe17f) {
1177 e15d7371 bellard
            *q++ = '\033';
1178 e15d7371 bellard
            *q++ = '[';
1179 e15d7371 bellard
            *q++ = keysym & 0xff;
1180 e15d7371 bellard
        } else {
1181 e7f0ad58 bellard
                *q++ = keysym;
1182 e15d7371 bellard
        }
1183 e5b0bc44 pbrook
        if (s->chr->chr_read) {
1184 e15d7371 bellard
            qemu_fifo_write(&s->out_fifo, buf, q - buf);
1185 e15d7371 bellard
            kbd_send_chars(s);
1186 e7f0ad58 bellard
        }
1187 e7f0ad58 bellard
        break;
1188 e7f0ad58 bellard
    }
1189 e7f0ad58 bellard
}
1190 e7f0ad58 bellard
1191 4d3b6f6e balrog
static void text_console_invalidate(void *opaque)
1192 4d3b6f6e balrog
{
1193 4d3b6f6e balrog
    TextConsole *s = (TextConsole *) opaque;
1194 68f00996 aliguori
    if (!ds_get_bits_per_pixel(s->ds) && s->console_type == TEXT_CONSOLE) {
1195 68f00996 aliguori
        s->g_width = ds_get_width(s->ds);
1196 68f00996 aliguori
        s->g_height = ds_get_height(s->ds);
1197 68f00996 aliguori
        text_console_resize(s);
1198 68f00996 aliguori
    }
1199 4d3b6f6e balrog
    console_refresh(s);
1200 4d3b6f6e balrog
}
1201 4d3b6f6e balrog
1202 4d3b6f6e balrog
static void text_console_update(void *opaque, console_ch_t *chardata)
1203 4d3b6f6e balrog
{
1204 4d3b6f6e balrog
    TextConsole *s = (TextConsole *) opaque;
1205 4d3b6f6e balrog
    int i, j, src;
1206 4d3b6f6e balrog
1207 4d3b6f6e balrog
    if (s->text_x[0] <= s->text_x[1]) {
1208 4d3b6f6e balrog
        src = (s->y_base + s->text_y[0]) * s->width;
1209 4d3b6f6e balrog
        chardata += s->text_y[0] * s->width;
1210 4d3b6f6e balrog
        for (i = s->text_y[0]; i <= s->text_y[1]; i ++)
1211 4d3b6f6e balrog
            for (j = 0; j < s->width; j ++, src ++)
1212 4d3b6f6e balrog
                console_write_ch(chardata ++, s->cells[src].ch |
1213 4d3b6f6e balrog
                                (s->cells[src].t_attrib.fgcol << 12) |
1214 4d3b6f6e balrog
                                (s->cells[src].t_attrib.bgcol << 8) |
1215 4d3b6f6e balrog
                                (s->cells[src].t_attrib.bold << 21));
1216 4d3b6f6e balrog
        dpy_update(s->ds, s->text_x[0], s->text_y[0],
1217 4d3b6f6e balrog
                   s->text_x[1] - s->text_x[0], i - s->text_y[0]);
1218 4d3b6f6e balrog
        s->text_x[0] = s->width;
1219 4d3b6f6e balrog
        s->text_y[0] = s->height;
1220 4d3b6f6e balrog
        s->text_x[1] = 0;
1221 4d3b6f6e balrog
        s->text_y[1] = 0;
1222 4d3b6f6e balrog
    }
1223 4d3b6f6e balrog
    if (s->cursor_invalidate) {
1224 4d3b6f6e balrog
        dpy_cursor(s->ds, s->x, s->y);
1225 4d3b6f6e balrog
        s->cursor_invalidate = 0;
1226 4d3b6f6e balrog
    }
1227 4d3b6f6e balrog
}
1228 4d3b6f6e balrog
1229 42aa98e8 aliguori
static TextConsole *get_graphic_console(DisplayState *ds)
1230 a147d62b blueswir1
{
1231 3023f332 aliguori
    int i;
1232 3023f332 aliguori
    TextConsole *s;
1233 3023f332 aliguori
    for (i = 0; i < nb_consoles; i++) {
1234 3023f332 aliguori
        s = consoles[i];
1235 42aa98e8 aliguori
        if (s->console_type == GRAPHIC_CONSOLE && s->ds == ds)
1236 3023f332 aliguori
            return s;
1237 3023f332 aliguori
    }
1238 3023f332 aliguori
    return NULL;
1239 3023f332 aliguori
}
1240 3023f332 aliguori
1241 af3a9031 ths
static TextConsole *new_console(DisplayState *ds, console_type_t console_type)
1242 e7f0ad58 bellard
{
1243 e7f0ad58 bellard
    TextConsole *s;
1244 95219897 pbrook
    int i;
1245 e7f0ad58 bellard
1246 e7f0ad58 bellard
    if (nb_consoles >= MAX_CONSOLES)
1247 e7f0ad58 bellard
        return NULL;
1248 e7f0ad58 bellard
    s = qemu_mallocz(sizeof(TextConsole));
1249 e7f0ad58 bellard
    if (!s) {
1250 e7f0ad58 bellard
        return NULL;
1251 e7f0ad58 bellard
    }
1252 af3a9031 ths
    if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) &&
1253 af3a9031 ths
        (console_type == GRAPHIC_CONSOLE))) {
1254 e7f0ad58 bellard
        active_console = s;
1255 af3a9031 ths
    }
1256 e7f0ad58 bellard
    s->ds = ds;
1257 af3a9031 ths
    s->console_type = console_type;
1258 af3a9031 ths
    if (console_type != GRAPHIC_CONSOLE) {
1259 95219897 pbrook
        consoles[nb_consoles++] = s;
1260 95219897 pbrook
    } else {
1261 95219897 pbrook
        /* HACK: Put graphical consoles before text consoles.  */
1262 95219897 pbrook
        for (i = nb_consoles; i > 0; i--) {
1263 af3a9031 ths
            if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE)
1264 95219897 pbrook
                break;
1265 95219897 pbrook
            consoles[i] = consoles[i - 1];
1266 95219897 pbrook
        }
1267 95219897 pbrook
        consoles[i] = s;
1268 3023f332 aliguori
        nb_consoles++;
1269 95219897 pbrook
    }
1270 95219897 pbrook
    return s;
1271 95219897 pbrook
}
1272 95219897 pbrook
1273 3023f332 aliguori
DisplayState *graphic_console_init(vga_hw_update_ptr update,
1274 3023f332 aliguori
                                   vga_hw_invalidate_ptr invalidate,
1275 3023f332 aliguori
                                   vga_hw_screen_dump_ptr screen_dump,
1276 3023f332 aliguori
                                   vga_hw_text_update_ptr text_update,
1277 3023f332 aliguori
                                   void *opaque)
1278 95219897 pbrook
{
1279 95219897 pbrook
    TextConsole *s;
1280 3023f332 aliguori
    DisplayState *ds;
1281 f0f2f976 aurel32
1282 3023f332 aliguori
    ds = (DisplayState *) qemu_mallocz(sizeof(DisplayState));
1283 3023f332 aliguori
    if (ds == NULL)
1284 3023f332 aliguori
        return NULL;
1285 3023f332 aliguori
    ds->surface = qemu_create_displaysurface(640, 480, 32, 640 * 4);
1286 95219897 pbrook
1287 af3a9031 ths
    s = new_console(ds, GRAPHIC_CONSOLE);
1288 3023f332 aliguori
    if (s == NULL) {
1289 3023f332 aliguori
        qemu_free_displaysurface(ds->surface);
1290 3023f332 aliguori
        qemu_free(ds);
1291 3023f332 aliguori
        return NULL;
1292 3023f332 aliguori
    }
1293 95219897 pbrook
    s->hw_update = update;
1294 95219897 pbrook
    s->hw_invalidate = invalidate;
1295 95219897 pbrook
    s->hw_screen_dump = screen_dump;
1296 4d3b6f6e balrog
    s->hw_text_update = text_update;
1297 95219897 pbrook
    s->hw = opaque;
1298 3023f332 aliguori
1299 f0f2f976 aurel32
    register_displaystate(ds);
1300 3023f332 aliguori
    return ds;
1301 e7f0ad58 bellard
}
1302 e7f0ad58 bellard
1303 95219897 pbrook
int is_graphic_console(void)
1304 e7f0ad58 bellard
{
1305 4d3b6f6e balrog
    return active_console && active_console->console_type == GRAPHIC_CONSOLE;
1306 e7f0ad58 bellard
}
1307 e7f0ad58 bellard
1308 c21bbcfa balrog
int is_fixedsize_console(void)
1309 c21bbcfa balrog
{
1310 c21bbcfa balrog
    return active_console && active_console->console_type != TEXT_CONSOLE;
1311 c21bbcfa balrog
}
1312 c21bbcfa balrog
1313 a528b80c balrog
void console_color_init(DisplayState *ds)
1314 a528b80c balrog
{
1315 a528b80c balrog
    int i, j;
1316 a528b80c balrog
    for (j = 0; j < 2; j++) {
1317 a528b80c balrog
        for (i = 0; i < 8; i++) {
1318 f0f2f976 aurel32
            color_table[j][i] = col_expand(ds,
1319 a528b80c balrog
                   vga_get_color(ds, color_table_rgb[j][i]));
1320 a528b80c balrog
        }
1321 a528b80c balrog
    }
1322 a528b80c balrog
}
1323 a528b80c balrog
1324 2796dae0 aliguori
static int n_text_consoles;
1325 2796dae0 aliguori
static CharDriverState *text_consoles[128];
1326 2796dae0 aliguori
static char *text_console_strs[128];
1327 2796dae0 aliguori
1328 2796dae0 aliguori
static void text_console_do_init(CharDriverState *chr, DisplayState *ds, const char *p)
1329 e7f0ad58 bellard
{
1330 e7f0ad58 bellard
    TextConsole *s;
1331 af3a9031 ths
    unsigned width;
1332 af3a9031 ths
    unsigned height;
1333 e7f0ad58 bellard
    static int color_inited;
1334 6d6f7c28 pbrook
1335 c21bbcfa balrog
    s = new_console(ds, (p == 0) ? TEXT_CONSOLE : TEXT_CONSOLE_FIXED_SIZE);
1336 e7f0ad58 bellard
    if (!s) {
1337 e7f0ad58 bellard
        free(chr);
1338 fdb868e4 aliguori
        return;
1339 e7f0ad58 bellard
    }
1340 e7f0ad58 bellard
    chr->opaque = s;
1341 e7f0ad58 bellard
    chr->chr_write = console_puts;
1342 6fcfafb7 bellard
    chr->chr_send_event = console_send_event;
1343 6fcfafb7 bellard
1344 e5b0bc44 pbrook
    s->chr = chr;
1345 e15d7371 bellard
    s->out_fifo.buf = s->out_fifo_buf;
1346 e15d7371 bellard
    s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
1347 e15d7371 bellard
    s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);
1348 3023f332 aliguori
    s->ds = ds;
1349 3b46e624 ths
1350 e7f0ad58 bellard
    if (!color_inited) {
1351 e7f0ad58 bellard
        color_inited = 1;
1352 a528b80c balrog
        console_color_init(s->ds);
1353 e7f0ad58 bellard
    }
1354 e7f0ad58 bellard
    s->y_displayed = 0;
1355 e7f0ad58 bellard
    s->y_base = 0;
1356 e7f0ad58 bellard
    s->total_height = DEFAULT_BACKSCROLL;
1357 e7f0ad58 bellard
    s->x = 0;
1358 e7f0ad58 bellard
    s->y = 0;
1359 0e1f5a0c aliguori
    width = ds_get_width(s->ds);
1360 0e1f5a0c aliguori
    height = ds_get_height(s->ds);
1361 af3a9031 ths
    if (p != 0) {
1362 af3a9031 ths
        width = strtoul(p, (char **)&p, 10);
1363 af3a9031 ths
        if (*p == 'C') {
1364 af3a9031 ths
            p++;
1365 af3a9031 ths
            width *= FONT_WIDTH;
1366 af3a9031 ths
        }
1367 af3a9031 ths
        if (*p == 'x') {
1368 af3a9031 ths
            p++;
1369 af3a9031 ths
            height = strtoul(p, (char **)&p, 10);
1370 af3a9031 ths
            if (*p == 'C') {
1371 af3a9031 ths
                p++;
1372 af3a9031 ths
                height *= FONT_HEIGHT;
1373 af3a9031 ths
            }
1374 af3a9031 ths
        }
1375 af3a9031 ths
    }
1376 af3a9031 ths
    s->g_width = width;
1377 af3a9031 ths
    s->g_height = height;
1378 6d6f7c28 pbrook
1379 4d3b6f6e balrog
    s->hw_invalidate = text_console_invalidate;
1380 4d3b6f6e balrog
    s->hw_text_update = text_console_update;
1381 4d3b6f6e balrog
    s->hw = s;
1382 4d3b6f6e balrog
1383 6d6f7c28 pbrook
    /* Set text attribute defaults */
1384 6d6f7c28 pbrook
    s->t_attrib_default.bold = 0;
1385 6d6f7c28 pbrook
    s->t_attrib_default.uline = 0;
1386 6d6f7c28 pbrook
    s->t_attrib_default.blink = 0;
1387 6d6f7c28 pbrook
    s->t_attrib_default.invers = 0;
1388 6d6f7c28 pbrook
    s->t_attrib_default.unvisible = 0;
1389 6d6f7c28 pbrook
    s->t_attrib_default.fgcol = COLOR_WHITE;
1390 6d6f7c28 pbrook
    s->t_attrib_default.bgcol = COLOR_BLACK;
1391 6d6f7c28 pbrook
    /* set current text attributes to default */
1392 6d6f7c28 pbrook
    s->t_attrib = s->t_attrib_default;
1393 e7f0ad58 bellard
    text_console_resize(s);
1394 e7f0ad58 bellard
1395 86e94dea ths
    qemu_chr_reset(chr);
1396 ceecf1d1 aurel32
    if (chr->init)
1397 ceecf1d1 aurel32
        chr->init(chr);
1398 e7f0ad58 bellard
}
1399 c60e08d9 pbrook
1400 2796dae0 aliguori
CharDriverState *text_console_init(const char *p)
1401 2796dae0 aliguori
{
1402 2796dae0 aliguori
    CharDriverState *chr;
1403 2796dae0 aliguori
1404 2796dae0 aliguori
    chr = qemu_mallocz(sizeof(CharDriverState));
1405 2796dae0 aliguori
    if (!chr)
1406 2796dae0 aliguori
        return NULL;
1407 2796dae0 aliguori
1408 2796dae0 aliguori
    if (n_text_consoles == 128) {
1409 2796dae0 aliguori
        fprintf(stderr, "Too many text consoles\n");
1410 2796dae0 aliguori
        exit(1);
1411 2796dae0 aliguori
    }
1412 2796dae0 aliguori
    text_consoles[n_text_consoles] = chr;
1413 2796dae0 aliguori
    text_console_strs[n_text_consoles] = p ? qemu_strdup(p) : NULL;
1414 2796dae0 aliguori
    n_text_consoles++;
1415 2796dae0 aliguori
1416 2796dae0 aliguori
    return chr;
1417 2796dae0 aliguori
}
1418 2796dae0 aliguori
1419 2796dae0 aliguori
void text_consoles_set_display(DisplayState *ds)
1420 2796dae0 aliguori
{
1421 2796dae0 aliguori
    int i;
1422 2796dae0 aliguori
1423 2796dae0 aliguori
    for (i = 0; i < n_text_consoles; i++) {
1424 2796dae0 aliguori
        text_console_do_init(text_consoles[i], ds, text_console_strs[i]);
1425 2796dae0 aliguori
        qemu_free(text_console_strs[i]);
1426 2796dae0 aliguori
    }
1427 2796dae0 aliguori
1428 2796dae0 aliguori
    n_text_consoles = 0;
1429 2796dae0 aliguori
}
1430 2796dae0 aliguori
1431 3023f332 aliguori
void qemu_console_resize(DisplayState *ds, int width, int height)
1432 c60e08d9 pbrook
{
1433 42aa98e8 aliguori
    TextConsole *s = get_graphic_console(ds);
1434 f497f140 aliguori
    if (!s) return;
1435 f497f140 aliguori
1436 3023f332 aliguori
    s->g_width = width;
1437 3023f332 aliguori
    s->g_height = height;
1438 3023f332 aliguori
    if (is_graphic_console()) {
1439 7d957bd8 aliguori
        ds->surface = qemu_resize_displaysurface(ds->surface, width, height, 32, 4 * width);
1440 3023f332 aliguori
        dpy_resize(ds);
1441 c60e08d9 pbrook
    }
1442 c60e08d9 pbrook
}
1443 38334f76 balrog
1444 3023f332 aliguori
void qemu_console_copy(DisplayState *ds, int src_x, int src_y,
1445 3023f332 aliguori
                       int dst_x, int dst_y, int w, int h)
1446 c21bbcfa balrog
{
1447 3023f332 aliguori
    if (is_graphic_console()) {
1448 3023f332 aliguori
        dpy_copy(ds, src_x, src_y, dst_x, dst_y, w, h);
1449 38334f76 balrog
    }
1450 38334f76 balrog
}
1451 7d957bd8 aliguori
1452 0da2ea1b malc
PixelFormat qemu_different_endianness_pixelformat(int bpp)
1453 7d957bd8 aliguori
{
1454 7d957bd8 aliguori
    PixelFormat pf;
1455 7d957bd8 aliguori
1456 7d957bd8 aliguori
    memset(&pf, 0x00, sizeof(PixelFormat));
1457 7d957bd8 aliguori
1458 7d957bd8 aliguori
    pf.bits_per_pixel = bpp;
1459 7d957bd8 aliguori
    pf.bytes_per_pixel = bpp / 8;
1460 7d957bd8 aliguori
    pf.depth = bpp == 32 ? 24 : bpp;
1461 7d957bd8 aliguori
1462 7d957bd8 aliguori
    switch (bpp) {
1463 0da2ea1b malc
        case 24:
1464 0da2ea1b malc
            pf.rmask = 0x000000FF;
1465 0da2ea1b malc
            pf.gmask = 0x0000FF00;
1466 0da2ea1b malc
            pf.bmask = 0x00FF0000;
1467 0da2ea1b malc
            pf.rmax = 255;
1468 0da2ea1b malc
            pf.gmax = 255;
1469 0da2ea1b malc
            pf.bmax = 255;
1470 0da2ea1b malc
            pf.rshift = 0;
1471 0da2ea1b malc
            pf.gshift = 8;
1472 0da2ea1b malc
            pf.bshift = 16;
1473 7d957bd8 aliguori
            break;
1474 0da2ea1b malc
        case 32:
1475 0da2ea1b malc
            pf.rmask = 0x0000FF00;
1476 0da2ea1b malc
            pf.gmask = 0x00FF0000;
1477 0da2ea1b malc
            pf.bmask = 0xFF000000;
1478 0da2ea1b malc
            pf.amask = 0x00000000;
1479 0da2ea1b malc
            pf.amax = 255;
1480 0da2ea1b malc
            pf.rmax = 255;
1481 0da2ea1b malc
            pf.gmax = 255;
1482 0da2ea1b malc
            pf.bmax = 255;
1483 0da2ea1b malc
            pf.ashift = 0;
1484 0da2ea1b malc
            pf.rshift = 8;
1485 0da2ea1b malc
            pf.gshift = 16;
1486 0da2ea1b malc
            pf.bshift = 24;
1487 0da2ea1b malc
            break;
1488 0da2ea1b malc
        default:
1489 0da2ea1b malc
            break;
1490 0da2ea1b malc
    }
1491 0da2ea1b malc
    return pf;
1492 0da2ea1b malc
}
1493 0da2ea1b malc
1494 0da2ea1b malc
PixelFormat qemu_default_pixelformat(int bpp)
1495 0da2ea1b malc
{
1496 0da2ea1b malc
    PixelFormat pf;
1497 0da2ea1b malc
1498 0da2ea1b malc
    memset(&pf, 0x00, sizeof(PixelFormat));
1499 0da2ea1b malc
1500 0da2ea1b malc
    pf.bits_per_pixel = bpp;
1501 0da2ea1b malc
    pf.bytes_per_pixel = bpp / 8;
1502 0da2ea1b malc
    pf.depth = bpp == 32 ? 24 : bpp;
1503 0da2ea1b malc
1504 0da2ea1b malc
    switch (bpp) {
1505 7d957bd8 aliguori
        case 16:
1506 7d957bd8 aliguori
            pf.rmask = 0x0000F800;
1507 7d957bd8 aliguori
            pf.gmask = 0x000007E0;
1508 7d957bd8 aliguori
            pf.bmask = 0x0000001F;
1509 7d957bd8 aliguori
            pf.rmax = 31;
1510 7d957bd8 aliguori
            pf.gmax = 63;
1511 7d957bd8 aliguori
            pf.bmax = 31;
1512 7d957bd8 aliguori
            pf.rshift = 11;
1513 7d957bd8 aliguori
            pf.gshift = 5;
1514 7d957bd8 aliguori
            pf.bshift = 0;
1515 7d957bd8 aliguori
            break;
1516 7d957bd8 aliguori
        case 24:
1517 0da2ea1b malc
            pf.rmask = 0x00FF0000;
1518 0da2ea1b malc
            pf.gmask = 0x0000FF00;
1519 0da2ea1b malc
            pf.bmask = 0x000000FF;
1520 0da2ea1b malc
            pf.rmax = 255;
1521 0da2ea1b malc
            pf.gmax = 255;
1522 0da2ea1b malc
            pf.bmax = 255;
1523 0da2ea1b malc
            pf.rshift = 16;
1524 0da2ea1b malc
            pf.gshift = 8;
1525 0da2ea1b malc
            pf.bshift = 0;
1526 7d957bd8 aliguori
        case 32:
1527 7d957bd8 aliguori
            pf.rmask = 0x00FF0000;
1528 7d957bd8 aliguori
            pf.gmask = 0x0000FF00;
1529 7d957bd8 aliguori
            pf.bmask = 0x000000FF;
1530 0da2ea1b malc
            pf.amax = 255;
1531 7d957bd8 aliguori
            pf.rmax = 255;
1532 7d957bd8 aliguori
            pf.gmax = 255;
1533 7d957bd8 aliguori
            pf.bmax = 255;
1534 0da2ea1b malc
            pf.ashift = 24;
1535 7d957bd8 aliguori
            pf.rshift = 16;
1536 7d957bd8 aliguori
            pf.gshift = 8;
1537 7d957bd8 aliguori
            pf.bshift = 0;
1538 7d957bd8 aliguori
            break;
1539 7d957bd8 aliguori
        default:
1540 7d957bd8 aliguori
            break;
1541 7d957bd8 aliguori
    }
1542 7d957bd8 aliguori
    return pf;
1543 7d957bd8 aliguori
}
1544 7d957bd8 aliguori
1545 7d957bd8 aliguori
DisplaySurface* qemu_create_displaysurface(int width, int height, int bpp, int linesize)
1546 7d957bd8 aliguori
{
1547 7d957bd8 aliguori
    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
1548 7d957bd8 aliguori
    if (surface == NULL) {
1549 7d957bd8 aliguori
        fprintf(stderr, "qemu_create_displaysurface: malloc failed\n");
1550 7d957bd8 aliguori
        exit(1);
1551 7d957bd8 aliguori
    }
1552 7d957bd8 aliguori
1553 7d957bd8 aliguori
    surface->width = width;
1554 7d957bd8 aliguori
    surface->height = height;
1555 7d957bd8 aliguori
    surface->linesize = linesize;
1556 7d957bd8 aliguori
    surface->pf = qemu_default_pixelformat(bpp);
1557 7d957bd8 aliguori
#ifdef WORDS_BIGENDIAN
1558 7d957bd8 aliguori
    surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
1559 7d957bd8 aliguori
#else
1560 7d957bd8 aliguori
    surface->flags = QEMU_ALLOCATED_FLAG;
1561 7d957bd8 aliguori
#endif
1562 7d957bd8 aliguori
    surface->data = (uint8_t*) qemu_mallocz(surface->linesize * surface->height);
1563 7d957bd8 aliguori
    if (surface->data == NULL) {
1564 7d957bd8 aliguori
        fprintf(stderr, "qemu_create_displaysurface: malloc failed\n");
1565 7d957bd8 aliguori
        exit(1);
1566 7d957bd8 aliguori
    }
1567 7d957bd8 aliguori
1568 7d957bd8 aliguori
    return surface;
1569 7d957bd8 aliguori
}
1570 7d957bd8 aliguori
1571 7d957bd8 aliguori
DisplaySurface* qemu_resize_displaysurface(DisplaySurface *surface,
1572 7d957bd8 aliguori
                                          int width, int height, int bpp, int linesize)
1573 7d957bd8 aliguori
{
1574 7d957bd8 aliguori
    surface->width = width;
1575 7d957bd8 aliguori
    surface->height = height;
1576 7d957bd8 aliguori
    surface->linesize = linesize;
1577 7d957bd8 aliguori
    surface->pf = qemu_default_pixelformat(bpp);
1578 7d957bd8 aliguori
    if (surface->flags & QEMU_ALLOCATED_FLAG)
1579 7d957bd8 aliguori
        surface->data = (uint8_t*) qemu_realloc(surface->data, surface->linesize * surface->height);
1580 7d957bd8 aliguori
    else
1581 7d957bd8 aliguori
        surface->data = (uint8_t*) qemu_malloc(surface->linesize * surface->height);
1582 7d957bd8 aliguori
    if (surface->data == NULL) {
1583 7d957bd8 aliguori
        fprintf(stderr, "qemu_resize_displaysurface: malloc failed\n");
1584 7d957bd8 aliguori
        exit(1);
1585 7d957bd8 aliguori
    }
1586 7d957bd8 aliguori
#ifdef WORDS_BIGENDIAN
1587 7d957bd8 aliguori
    surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
1588 7d957bd8 aliguori
#else
1589 7d957bd8 aliguori
    surface->flags = QEMU_ALLOCATED_FLAG;
1590 7d957bd8 aliguori
#endif
1591 7d957bd8 aliguori
1592 7d957bd8 aliguori
    return surface;
1593 7d957bd8 aliguori
}
1594 7d957bd8 aliguori
1595 7d957bd8 aliguori
DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
1596 7d957bd8 aliguori
                                              int linesize, uint8_t *data)
1597 7d957bd8 aliguori
{
1598 7d957bd8 aliguori
    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
1599 7d957bd8 aliguori
    if (surface == NULL) {
1600 7d957bd8 aliguori
        fprintf(stderr, "qemu_create_displaysurface_from: malloc failed\n");
1601 7d957bd8 aliguori
        exit(1);
1602 7d957bd8 aliguori
    }
1603 7d957bd8 aliguori
1604 7d957bd8 aliguori
    surface->width = width;
1605 7d957bd8 aliguori
    surface->height = height;
1606 7d957bd8 aliguori
    surface->linesize = linesize;
1607 7d957bd8 aliguori
    surface->pf = qemu_default_pixelformat(bpp);
1608 7d957bd8 aliguori
#ifdef WORDS_BIGENDIAN
1609 7d957bd8 aliguori
    surface->flags = QEMU_BIG_ENDIAN_FLAG;
1610 7d957bd8 aliguori
#endif
1611 7d957bd8 aliguori
    surface->data = data;
1612 7d957bd8 aliguori
1613 7d957bd8 aliguori
    return surface;
1614 7d957bd8 aliguori
}
1615 7d957bd8 aliguori
1616 7d957bd8 aliguori
void qemu_free_displaysurface(DisplaySurface *surface)
1617 7d957bd8 aliguori
{
1618 7d957bd8 aliguori
    if (surface == NULL)
1619 7d957bd8 aliguori
        return;
1620 7d957bd8 aliguori
    if (surface->flags & QEMU_ALLOCATED_FLAG)
1621 7d957bd8 aliguori
        qemu_free(surface->data);
1622 7d957bd8 aliguori
    qemu_free(surface);
1623 7d957bd8 aliguori
}