Statistics
| Branch: | Revision:

root / console.c @ 127338e6

History | View | Annotate | Download (44.5 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 e7f0ad58 bellard
static TextConsole *active_console;
158 e7f0ad58 bellard
static TextConsole *consoles[MAX_CONSOLES];
159 e7f0ad58 bellard
static int nb_consoles = 0;
160 e7f0ad58 bellard
161 95219897 pbrook
void vga_hw_update(void)
162 95219897 pbrook
{
163 adb47967 ths
    if (active_console && active_console->hw_update)
164 95219897 pbrook
        active_console->hw_update(active_console->hw);
165 95219897 pbrook
}
166 95219897 pbrook
167 95219897 pbrook
void vga_hw_invalidate(void)
168 95219897 pbrook
{
169 95219897 pbrook
    if (active_console->hw_invalidate)
170 95219897 pbrook
        active_console->hw_invalidate(active_console->hw);
171 95219897 pbrook
}
172 95219897 pbrook
173 95219897 pbrook
void vga_hw_screen_dump(const char *filename)
174 95219897 pbrook
{
175 8571c055 balrog
    TextConsole *previous_active_console;
176 8571c055 balrog
177 8571c055 balrog
    previous_active_console = active_console;
178 8571c055 balrog
    active_console = consoles[0];
179 8571c055 balrog
    /* There is currently no way of specifying which screen we want to dump,
180 7b455225 aurel32
       so always dump the first one.  */
181 95219897 pbrook
    if (consoles[0]->hw_screen_dump)
182 95219897 pbrook
        consoles[0]->hw_screen_dump(consoles[0]->hw, filename);
183 8571c055 balrog
    active_console = previous_active_console;
184 95219897 pbrook
}
185 95219897 pbrook
186 c227f099 Anthony Liguori
void vga_hw_text_update(console_ch_t *chardata)
187 4d3b6f6e balrog
{
188 4d3b6f6e balrog
    if (active_console && active_console->hw_text_update)
189 4d3b6f6e balrog
        active_console->hw_text_update(active_console->hw, chardata);
190 4d3b6f6e balrog
}
191 4d3b6f6e balrog
192 e7f0ad58 bellard
/* convert a RGBA color to a color index usable in graphic primitives */
193 e7f0ad58 bellard
static unsigned int vga_get_color(DisplayState *ds, unsigned int rgba)
194 e7f0ad58 bellard
{
195 e7f0ad58 bellard
    unsigned int r, g, b, color;
196 e7f0ad58 bellard
197 0e1f5a0c aliguori
    switch(ds_get_bits_per_pixel(ds)) {
198 e7f0ad58 bellard
#if 0
199 e7f0ad58 bellard
    case 8:
200 e7f0ad58 bellard
        r = (rgba >> 16) & 0xff;
201 e7f0ad58 bellard
        g = (rgba >> 8) & 0xff;
202 e7f0ad58 bellard
        b = (rgba) & 0xff;
203 5fafdf24 ths
        color = (rgb_to_index[r] * 6 * 6) +
204 5fafdf24 ths
            (rgb_to_index[g] * 6) +
205 e7f0ad58 bellard
            (rgb_to_index[b]);
206 e7f0ad58 bellard
        break;
207 e7f0ad58 bellard
#endif
208 e7f0ad58 bellard
    case 15:
209 e7f0ad58 bellard
        r = (rgba >> 16) & 0xff;
210 e7f0ad58 bellard
        g = (rgba >> 8) & 0xff;
211 e7f0ad58 bellard
        b = (rgba) & 0xff;
212 e7f0ad58 bellard
        color = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
213 e7f0ad58 bellard
        break;
214 e7f0ad58 bellard
    case 16:
215 e7f0ad58 bellard
        r = (rgba >> 16) & 0xff;
216 e7f0ad58 bellard
        g = (rgba >> 8) & 0xff;
217 e7f0ad58 bellard
        b = (rgba) & 0xff;
218 e7f0ad58 bellard
        color = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
219 e7f0ad58 bellard
        break;
220 e7f0ad58 bellard
    case 32:
221 e7f0ad58 bellard
    default:
222 e7f0ad58 bellard
        color = rgba;
223 e7f0ad58 bellard
        break;
224 e7f0ad58 bellard
    }
225 e7f0ad58 bellard
    return color;
226 e7f0ad58 bellard
}
227 e7f0ad58 bellard
228 5fafdf24 ths
static void vga_fill_rect (DisplayState *ds,
229 e7f0ad58 bellard
                           int posx, int posy, int width, int height, uint32_t color)
230 e7f0ad58 bellard
{
231 e7f0ad58 bellard
    uint8_t *d, *d1;
232 e7f0ad58 bellard
    int x, y, bpp;
233 3b46e624 ths
234 0e1f5a0c aliguori
    bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3;
235 0e1f5a0c aliguori
    d1 = ds_get_data(ds) +
236 0e1f5a0c aliguori
        ds_get_linesize(ds) * posy + bpp * posx;
237 e7f0ad58 bellard
    for (y = 0; y < height; y++) {
238 e7f0ad58 bellard
        d = d1;
239 e7f0ad58 bellard
        switch(bpp) {
240 e7f0ad58 bellard
        case 1:
241 e7f0ad58 bellard
            for (x = 0; x < width; x++) {
242 e7f0ad58 bellard
                *((uint8_t *)d) = color;
243 e7f0ad58 bellard
                d++;
244 e7f0ad58 bellard
            }
245 e7f0ad58 bellard
            break;
246 e7f0ad58 bellard
        case 2:
247 e7f0ad58 bellard
            for (x = 0; x < width; x++) {
248 e7f0ad58 bellard
                *((uint16_t *)d) = color;
249 e7f0ad58 bellard
                d += 2;
250 e7f0ad58 bellard
            }
251 e7f0ad58 bellard
            break;
252 e7f0ad58 bellard
        case 4:
253 e7f0ad58 bellard
            for (x = 0; x < width; x++) {
254 e7f0ad58 bellard
                *((uint32_t *)d) = color;
255 e7f0ad58 bellard
                d += 4;
256 e7f0ad58 bellard
            }
257 e7f0ad58 bellard
            break;
258 e7f0ad58 bellard
        }
259 0e1f5a0c aliguori
        d1 += ds_get_linesize(ds);
260 e7f0ad58 bellard
    }
261 e7f0ad58 bellard
}
262 e7f0ad58 bellard
263 e7f0ad58 bellard
/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */
264 e7f0ad58 bellard
static void vga_bitblt(DisplayState *ds, int xs, int ys, int xd, int yd, int w, int h)
265 e7f0ad58 bellard
{
266 e7f0ad58 bellard
    const uint8_t *s;
267 e7f0ad58 bellard
    uint8_t *d;
268 e7f0ad58 bellard
    int wb, y, bpp;
269 e7f0ad58 bellard
270 0e1f5a0c aliguori
    bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3;
271 e7f0ad58 bellard
    wb = w * bpp;
272 e7f0ad58 bellard
    if (yd <= ys) {
273 0e1f5a0c aliguori
        s = ds_get_data(ds) +
274 0e1f5a0c aliguori
            ds_get_linesize(ds) * ys + bpp * xs;
275 0e1f5a0c aliguori
        d = ds_get_data(ds) +
276 0e1f5a0c aliguori
            ds_get_linesize(ds) * yd + bpp * xd;
277 e7f0ad58 bellard
        for (y = 0; y < h; y++) {
278 e7f0ad58 bellard
            memmove(d, s, wb);
279 0e1f5a0c aliguori
            d += ds_get_linesize(ds);
280 0e1f5a0c aliguori
            s += ds_get_linesize(ds);
281 e7f0ad58 bellard
        }
282 e7f0ad58 bellard
    } else {
283 0e1f5a0c aliguori
        s = ds_get_data(ds) +
284 0e1f5a0c aliguori
            ds_get_linesize(ds) * (ys + h - 1) + bpp * xs;
285 0e1f5a0c aliguori
        d = ds_get_data(ds) +
286 0e1f5a0c aliguori
            ds_get_linesize(ds) * (yd + h - 1) + bpp * xd;
287 e7f0ad58 bellard
       for (y = 0; y < h; y++) {
288 e7f0ad58 bellard
            memmove(d, s, wb);
289 0e1f5a0c aliguori
            d -= ds_get_linesize(ds);
290 0e1f5a0c aliguori
            s -= ds_get_linesize(ds);
291 e7f0ad58 bellard
        }
292 e7f0ad58 bellard
    }
293 e7f0ad58 bellard
}
294 e7f0ad58 bellard
295 e7f0ad58 bellard
/***********************************************************/
296 e7f0ad58 bellard
/* basic char display */
297 e7f0ad58 bellard
298 e7f0ad58 bellard
#define FONT_HEIGHT 16
299 e7f0ad58 bellard
#define FONT_WIDTH 8
300 e7f0ad58 bellard
301 e7f0ad58 bellard
#include "vgafont.h"
302 e7f0ad58 bellard
303 e7f0ad58 bellard
#define cbswap_32(__x) \
304 e7f0ad58 bellard
((uint32_t)( \
305 e7f0ad58 bellard
                (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
306 e7f0ad58 bellard
                (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
307 e7f0ad58 bellard
                (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
308 e7f0ad58 bellard
                (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
309 e7f0ad58 bellard
310 e2542fe2 Juan Quintela
#ifdef HOST_WORDS_BIGENDIAN
311 e7f0ad58 bellard
#define PAT(x) x
312 e7f0ad58 bellard
#else
313 e7f0ad58 bellard
#define PAT(x) cbswap_32(x)
314 e7f0ad58 bellard
#endif
315 e7f0ad58 bellard
316 e7f0ad58 bellard
static const uint32_t dmask16[16] = {
317 e7f0ad58 bellard
    PAT(0x00000000),
318 e7f0ad58 bellard
    PAT(0x000000ff),
319 e7f0ad58 bellard
    PAT(0x0000ff00),
320 e7f0ad58 bellard
    PAT(0x0000ffff),
321 e7f0ad58 bellard
    PAT(0x00ff0000),
322 e7f0ad58 bellard
    PAT(0x00ff00ff),
323 e7f0ad58 bellard
    PAT(0x00ffff00),
324 e7f0ad58 bellard
    PAT(0x00ffffff),
325 e7f0ad58 bellard
    PAT(0xff000000),
326 e7f0ad58 bellard
    PAT(0xff0000ff),
327 e7f0ad58 bellard
    PAT(0xff00ff00),
328 e7f0ad58 bellard
    PAT(0xff00ffff),
329 e7f0ad58 bellard
    PAT(0xffff0000),
330 e7f0ad58 bellard
    PAT(0xffff00ff),
331 e7f0ad58 bellard
    PAT(0xffffff00),
332 e7f0ad58 bellard
    PAT(0xffffffff),
333 e7f0ad58 bellard
};
334 e7f0ad58 bellard
335 e7f0ad58 bellard
static const uint32_t dmask4[4] = {
336 e7f0ad58 bellard
    PAT(0x00000000),
337 e7f0ad58 bellard
    PAT(0x0000ffff),
338 e7f0ad58 bellard
    PAT(0xffff0000),
339 e7f0ad58 bellard
    PAT(0xffffffff),
340 e7f0ad58 bellard
};
341 e7f0ad58 bellard
342 6d6f7c28 pbrook
static uint32_t color_table[2][8];
343 6d6f7c28 pbrook
344 6d6f7c28 pbrook
enum color_names {
345 6d6f7c28 pbrook
    COLOR_BLACK   = 0,
346 6d6f7c28 pbrook
    COLOR_RED     = 1,
347 6d6f7c28 pbrook
    COLOR_GREEN   = 2,
348 6d6f7c28 pbrook
    COLOR_YELLOW  = 3,
349 6d6f7c28 pbrook
    COLOR_BLUE    = 4,
350 6d6f7c28 pbrook
    COLOR_MAGENTA = 5,
351 6d6f7c28 pbrook
    COLOR_CYAN    = 6,
352 6d6f7c28 pbrook
    COLOR_WHITE   = 7
353 6d6f7c28 pbrook
};
354 6d6f7c28 pbrook
355 6d6f7c28 pbrook
static const uint32_t color_table_rgb[2][8] = {
356 6d6f7c28 pbrook
    {   /* dark */
357 26489844 bellard
        QEMU_RGB(0x00, 0x00, 0x00),  /* black */
358 26489844 bellard
        QEMU_RGB(0xaa, 0x00, 0x00),  /* red */
359 26489844 bellard
        QEMU_RGB(0x00, 0xaa, 0x00),  /* green */
360 26489844 bellard
        QEMU_RGB(0xaa, 0xaa, 0x00),  /* yellow */
361 26489844 bellard
        QEMU_RGB(0x00, 0x00, 0xaa),  /* blue */
362 26489844 bellard
        QEMU_RGB(0xaa, 0x00, 0xaa),  /* magenta */
363 26489844 bellard
        QEMU_RGB(0x00, 0xaa, 0xaa),  /* cyan */
364 26489844 bellard
        QEMU_RGB(0xaa, 0xaa, 0xaa),  /* white */
365 6d6f7c28 pbrook
    },
366 6d6f7c28 pbrook
    {   /* bright */
367 26489844 bellard
        QEMU_RGB(0x00, 0x00, 0x00),  /* black */
368 26489844 bellard
        QEMU_RGB(0xff, 0x00, 0x00),  /* red */
369 26489844 bellard
        QEMU_RGB(0x00, 0xff, 0x00),  /* green */
370 26489844 bellard
        QEMU_RGB(0xff, 0xff, 0x00),  /* yellow */
371 26489844 bellard
        QEMU_RGB(0x00, 0x00, 0xff),  /* blue */
372 26489844 bellard
        QEMU_RGB(0xff, 0x00, 0xff),  /* magenta */
373 26489844 bellard
        QEMU_RGB(0x00, 0xff, 0xff),  /* cyan */
374 26489844 bellard
        QEMU_RGB(0xff, 0xff, 0xff),  /* white */
375 6d6f7c28 pbrook
    }
376 e7f0ad58 bellard
};
377 e7f0ad58 bellard
378 e7f0ad58 bellard
static inline unsigned int col_expand(DisplayState *ds, unsigned int col)
379 e7f0ad58 bellard
{
380 0e1f5a0c aliguori
    switch(ds_get_bits_per_pixel(ds)) {
381 e7f0ad58 bellard
    case 8:
382 e7f0ad58 bellard
        col |= col << 8;
383 e7f0ad58 bellard
        col |= col << 16;
384 e7f0ad58 bellard
        break;
385 e7f0ad58 bellard
    case 15:
386 e7f0ad58 bellard
    case 16:
387 e7f0ad58 bellard
        col |= col << 16;
388 e7f0ad58 bellard
        break;
389 e7f0ad58 bellard
    default:
390 e7f0ad58 bellard
        break;
391 e7f0ad58 bellard
    }
392 e7f0ad58 bellard
393 e7f0ad58 bellard
    return col;
394 e7f0ad58 bellard
}
395 6d6f7c28 pbrook
#ifdef DEBUG_CONSOLE
396 6d6f7c28 pbrook
static void console_print_text_attributes(TextAttributes *t_attrib, char ch)
397 6d6f7c28 pbrook
{
398 6d6f7c28 pbrook
    if (t_attrib->bold) {
399 6d6f7c28 pbrook
        printf("b");
400 6d6f7c28 pbrook
    } else {
401 6d6f7c28 pbrook
        printf(" ");
402 6d6f7c28 pbrook
    }
403 6d6f7c28 pbrook
    if (t_attrib->uline) {
404 6d6f7c28 pbrook
        printf("u");
405 6d6f7c28 pbrook
    } else {
406 6d6f7c28 pbrook
        printf(" ");
407 6d6f7c28 pbrook
    }
408 6d6f7c28 pbrook
    if (t_attrib->blink) {
409 6d6f7c28 pbrook
        printf("l");
410 6d6f7c28 pbrook
    } else {
411 6d6f7c28 pbrook
        printf(" ");
412 6d6f7c28 pbrook
    }
413 6d6f7c28 pbrook
    if (t_attrib->invers) {
414 6d6f7c28 pbrook
        printf("i");
415 6d6f7c28 pbrook
    } else {
416 6d6f7c28 pbrook
        printf(" ");
417 6d6f7c28 pbrook
    }
418 6d6f7c28 pbrook
    if (t_attrib->unvisible) {
419 6d6f7c28 pbrook
        printf("n");
420 6d6f7c28 pbrook
    } else {
421 6d6f7c28 pbrook
        printf(" ");
422 6d6f7c28 pbrook
    }
423 6d6f7c28 pbrook
424 6d6f7c28 pbrook
    printf(" fg: %d bg: %d ch:'%2X' '%c'\n", t_attrib->fgcol, t_attrib->bgcol, ch, ch);
425 6d6f7c28 pbrook
}
426 6d6f7c28 pbrook
#endif
427 e7f0ad58 bellard
428 5fafdf24 ths
static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
429 6d6f7c28 pbrook
                          TextAttributes *t_attrib)
430 e7f0ad58 bellard
{
431 e7f0ad58 bellard
    uint8_t *d;
432 e7f0ad58 bellard
    const uint8_t *font_ptr;
433 e7f0ad58 bellard
    unsigned int font_data, linesize, xorcol, bpp;
434 e7f0ad58 bellard
    int i;
435 6d6f7c28 pbrook
    unsigned int fgcol, bgcol;
436 6d6f7c28 pbrook
437 6d6f7c28 pbrook
#ifdef DEBUG_CONSOLE
438 6d6f7c28 pbrook
    printf("x: %2i y: %2i", x, y);
439 6d6f7c28 pbrook
    console_print_text_attributes(t_attrib, ch);
440 6d6f7c28 pbrook
#endif
441 6d6f7c28 pbrook
442 6d6f7c28 pbrook
    if (t_attrib->invers) {
443 6d6f7c28 pbrook
        bgcol = color_table[t_attrib->bold][t_attrib->fgcol];
444 6d6f7c28 pbrook
        fgcol = color_table[t_attrib->bold][t_attrib->bgcol];
445 6d6f7c28 pbrook
    } else {
446 6d6f7c28 pbrook
        fgcol = color_table[t_attrib->bold][t_attrib->fgcol];
447 6d6f7c28 pbrook
        bgcol = color_table[t_attrib->bold][t_attrib->bgcol];
448 6d6f7c28 pbrook
    }
449 e7f0ad58 bellard
450 0e1f5a0c aliguori
    bpp = (ds_get_bits_per_pixel(ds) + 7) >> 3;
451 0e1f5a0c aliguori
    d = ds_get_data(ds) +
452 0e1f5a0c aliguori
        ds_get_linesize(ds) * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;
453 0e1f5a0c aliguori
    linesize = ds_get_linesize(ds);
454 e7f0ad58 bellard
    font_ptr = vgafont16 + FONT_HEIGHT * ch;
455 e7f0ad58 bellard
    xorcol = bgcol ^ fgcol;
456 0e1f5a0c aliguori
    switch(ds_get_bits_per_pixel(ds)) {
457 e7f0ad58 bellard
    case 8:
458 e7f0ad58 bellard
        for(i = 0; i < FONT_HEIGHT; i++) {
459 e7f0ad58 bellard
            font_data = *font_ptr++;
460 6d6f7c28 pbrook
            if (t_attrib->uline
461 6d6f7c28 pbrook
                && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
462 6d6f7c28 pbrook
                font_data = 0xFFFF;
463 6d6f7c28 pbrook
            }
464 e7f0ad58 bellard
            ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
465 e7f0ad58 bellard
            ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
466 e7f0ad58 bellard
            d += linesize;
467 e7f0ad58 bellard
        }
468 e7f0ad58 bellard
        break;
469 e7f0ad58 bellard
    case 16:
470 e7f0ad58 bellard
    case 15:
471 e7f0ad58 bellard
        for(i = 0; i < FONT_HEIGHT; i++) {
472 e7f0ad58 bellard
            font_data = *font_ptr++;
473 6d6f7c28 pbrook
            if (t_attrib->uline
474 6d6f7c28 pbrook
                && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
475 6d6f7c28 pbrook
                font_data = 0xFFFF;
476 6d6f7c28 pbrook
            }
477 e7f0ad58 bellard
            ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
478 e7f0ad58 bellard
            ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
479 e7f0ad58 bellard
            ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
480 e7f0ad58 bellard
            ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
481 e7f0ad58 bellard
            d += linesize;
482 e7f0ad58 bellard
        }
483 e7f0ad58 bellard
        break;
484 e7f0ad58 bellard
    case 32:
485 e7f0ad58 bellard
        for(i = 0; i < FONT_HEIGHT; i++) {
486 e7f0ad58 bellard
            font_data = *font_ptr++;
487 6d6f7c28 pbrook
            if (t_attrib->uline && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
488 6d6f7c28 pbrook
                font_data = 0xFFFF;
489 6d6f7c28 pbrook
            }
490 e7f0ad58 bellard
            ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
491 e7f0ad58 bellard
            ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
492 e7f0ad58 bellard
            ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
493 e7f0ad58 bellard
            ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
494 e7f0ad58 bellard
            ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
495 e7f0ad58 bellard
            ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
496 e7f0ad58 bellard
            ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
497 e7f0ad58 bellard
            ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
498 e7f0ad58 bellard
            d += linesize;
499 e7f0ad58 bellard
        }
500 e7f0ad58 bellard
        break;
501 e7f0ad58 bellard
    }
502 e7f0ad58 bellard
}
503 e7f0ad58 bellard
504 e7f0ad58 bellard
static void text_console_resize(TextConsole *s)
505 e7f0ad58 bellard
{
506 e7f0ad58 bellard
    TextCell *cells, *c, *c1;
507 e7f0ad58 bellard
    int w1, x, y, last_width;
508 e7f0ad58 bellard
509 e7f0ad58 bellard
    last_width = s->width;
510 e7f0ad58 bellard
    s->width = s->g_width / FONT_WIDTH;
511 e7f0ad58 bellard
    s->height = s->g_height / FONT_HEIGHT;
512 e7f0ad58 bellard
513 e7f0ad58 bellard
    w1 = last_width;
514 e7f0ad58 bellard
    if (s->width < w1)
515 e7f0ad58 bellard
        w1 = s->width;
516 e7f0ad58 bellard
517 e7f0ad58 bellard
    cells = qemu_malloc(s->width * s->total_height * sizeof(TextCell));
518 e7f0ad58 bellard
    for(y = 0; y < s->total_height; y++) {
519 e7f0ad58 bellard
        c = &cells[y * s->width];
520 e7f0ad58 bellard
        if (w1 > 0) {
521 e7f0ad58 bellard
            c1 = &s->cells[y * last_width];
522 e7f0ad58 bellard
            for(x = 0; x < w1; x++) {
523 e7f0ad58 bellard
                *c++ = *c1++;
524 e7f0ad58 bellard
            }
525 e7f0ad58 bellard
        }
526 e7f0ad58 bellard
        for(x = w1; x < s->width; x++) {
527 e7f0ad58 bellard
            c->ch = ' ';
528 6d6f7c28 pbrook
            c->t_attrib = s->t_attrib_default;
529 e7f0ad58 bellard
            c++;
530 e7f0ad58 bellard
        }
531 e7f0ad58 bellard
    }
532 a528b80c balrog
    qemu_free(s->cells);
533 e7f0ad58 bellard
    s->cells = cells;
534 e7f0ad58 bellard
}
535 e7f0ad58 bellard
536 4d3b6f6e balrog
static inline void text_update_xy(TextConsole *s, int x, int y)
537 4d3b6f6e balrog
{
538 4d3b6f6e balrog
    s->text_x[0] = MIN(s->text_x[0], x);
539 4d3b6f6e balrog
    s->text_x[1] = MAX(s->text_x[1], x);
540 4d3b6f6e balrog
    s->text_y[0] = MIN(s->text_y[0], y);
541 4d3b6f6e balrog
    s->text_y[1] = MAX(s->text_y[1], y);
542 4d3b6f6e balrog
}
543 4d3b6f6e balrog
544 14778c20 pbrook
static void invalidate_xy(TextConsole *s, int x, int y)
545 14778c20 pbrook
{
546 14778c20 pbrook
    if (s->update_x0 > x * FONT_WIDTH)
547 14778c20 pbrook
        s->update_x0 = x * FONT_WIDTH;
548 14778c20 pbrook
    if (s->update_y0 > y * FONT_HEIGHT)
549 14778c20 pbrook
        s->update_y0 = y * FONT_HEIGHT;
550 14778c20 pbrook
    if (s->update_x1 < (x + 1) * FONT_WIDTH)
551 14778c20 pbrook
        s->update_x1 = (x + 1) * FONT_WIDTH;
552 14778c20 pbrook
    if (s->update_y1 < (y + 1) * FONT_HEIGHT)
553 14778c20 pbrook
        s->update_y1 = (y + 1) * FONT_HEIGHT;
554 14778c20 pbrook
}
555 14778c20 pbrook
556 e7f0ad58 bellard
static void update_xy(TextConsole *s, int x, int y)
557 e7f0ad58 bellard
{
558 e7f0ad58 bellard
    TextCell *c;
559 e7f0ad58 bellard
    int y1, y2;
560 e7f0ad58 bellard
561 e7f0ad58 bellard
    if (s == active_console) {
562 0e1f5a0c aliguori
        if (!ds_get_bits_per_pixel(s->ds)) {
563 4d3b6f6e balrog
            text_update_xy(s, x, y);
564 4d3b6f6e balrog
            return;
565 4d3b6f6e balrog
        }
566 4d3b6f6e balrog
567 e7f0ad58 bellard
        y1 = (s->y_base + y) % s->total_height;
568 e7f0ad58 bellard
        y2 = y1 - s->y_displayed;
569 e7f0ad58 bellard
        if (y2 < 0)
570 e7f0ad58 bellard
            y2 += s->total_height;
571 e7f0ad58 bellard
        if (y2 < s->height) {
572 e7f0ad58 bellard
            c = &s->cells[y1 * s->width + x];
573 5fafdf24 ths
            vga_putcharxy(s->ds, x, y2, c->ch,
574 6d6f7c28 pbrook
                          &(c->t_attrib));
575 14778c20 pbrook
            invalidate_xy(s, x, y2);
576 e7f0ad58 bellard
        }
577 e7f0ad58 bellard
    }
578 e7f0ad58 bellard
}
579 e7f0ad58 bellard
580 e7f0ad58 bellard
static void console_show_cursor(TextConsole *s, int show)
581 e7f0ad58 bellard
{
582 e7f0ad58 bellard
    TextCell *c;
583 e7f0ad58 bellard
    int y, y1;
584 e7f0ad58 bellard
585 e7f0ad58 bellard
    if (s == active_console) {
586 ed8276ac ths
        int x = s->x;
587 4d3b6f6e balrog
588 0e1f5a0c aliguori
        if (!ds_get_bits_per_pixel(s->ds)) {
589 4d3b6f6e balrog
            s->cursor_invalidate = 1;
590 4d3b6f6e balrog
            return;
591 4d3b6f6e balrog
        }
592 4d3b6f6e balrog
593 ed8276ac ths
        if (x >= s->width) {
594 ed8276ac ths
            x = s->width - 1;
595 ed8276ac ths
        }
596 e7f0ad58 bellard
        y1 = (s->y_base + s->y) % s->total_height;
597 e7f0ad58 bellard
        y = y1 - s->y_displayed;
598 e7f0ad58 bellard
        if (y < 0)
599 e7f0ad58 bellard
            y += s->total_height;
600 e7f0ad58 bellard
        if (y < s->height) {
601 ed8276ac ths
            c = &s->cells[y1 * s->width + x];
602 e7f0ad58 bellard
            if (show) {
603 6d6f7c28 pbrook
                TextAttributes t_attrib = s->t_attrib_default;
604 6d6f7c28 pbrook
                t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
605 ed8276ac ths
                vga_putcharxy(s->ds, x, y, c->ch, &t_attrib);
606 e7f0ad58 bellard
            } else {
607 ed8276ac ths
                vga_putcharxy(s->ds, x, y, c->ch, &(c->t_attrib));
608 e7f0ad58 bellard
            }
609 14778c20 pbrook
            invalidate_xy(s, x, y);
610 e7f0ad58 bellard
        }
611 e7f0ad58 bellard
    }
612 e7f0ad58 bellard
}
613 e7f0ad58 bellard
614 e7f0ad58 bellard
static void console_refresh(TextConsole *s)
615 e7f0ad58 bellard
{
616 e7f0ad58 bellard
    TextCell *c;
617 e7f0ad58 bellard
    int x, y, y1;
618 e7f0ad58 bellard
619 5fafdf24 ths
    if (s != active_console)
620 e7f0ad58 bellard
        return;
621 0e1f5a0c aliguori
    if (!ds_get_bits_per_pixel(s->ds)) {
622 4d3b6f6e balrog
        s->text_x[0] = 0;
623 4d3b6f6e balrog
        s->text_y[0] = 0;
624 4d3b6f6e balrog
        s->text_x[1] = s->width - 1;
625 4d3b6f6e balrog
        s->text_y[1] = s->height - 1;
626 4d3b6f6e balrog
        s->cursor_invalidate = 1;
627 4d3b6f6e balrog
        return;
628 4d3b6f6e balrog
    }
629 e7f0ad58 bellard
630 0e1f5a0c aliguori
    vga_fill_rect(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds),
631 6d6f7c28 pbrook
                  color_table[0][COLOR_BLACK]);
632 e7f0ad58 bellard
    y1 = s->y_displayed;
633 e7f0ad58 bellard
    for(y = 0; y < s->height; y++) {
634 e7f0ad58 bellard
        c = s->cells + y1 * s->width;
635 e7f0ad58 bellard
        for(x = 0; x < s->width; x++) {
636 5fafdf24 ths
            vga_putcharxy(s->ds, x, y, c->ch,
637 6d6f7c28 pbrook
                          &(c->t_attrib));
638 e7f0ad58 bellard
            c++;
639 e7f0ad58 bellard
        }
640 e7f0ad58 bellard
        if (++y1 == s->total_height)
641 e7f0ad58 bellard
            y1 = 0;
642 e7f0ad58 bellard
    }
643 e7f0ad58 bellard
    console_show_cursor(s, 1);
644 14778c20 pbrook
    dpy_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
645 e7f0ad58 bellard
}
646 e7f0ad58 bellard
647 e7f0ad58 bellard
static void console_scroll(int ydelta)
648 e7f0ad58 bellard
{
649 e7f0ad58 bellard
    TextConsole *s;
650 e7f0ad58 bellard
    int i, y1;
651 3b46e624 ths
652 e7f0ad58 bellard
    s = active_console;
653 af3a9031 ths
    if (!s || (s->console_type == GRAPHIC_CONSOLE))
654 e7f0ad58 bellard
        return;
655 e7f0ad58 bellard
656 e7f0ad58 bellard
    if (ydelta > 0) {
657 e7f0ad58 bellard
        for(i = 0; i < ydelta; i++) {
658 e7f0ad58 bellard
            if (s->y_displayed == s->y_base)
659 e7f0ad58 bellard
                break;
660 e7f0ad58 bellard
            if (++s->y_displayed == s->total_height)
661 e7f0ad58 bellard
                s->y_displayed = 0;
662 e7f0ad58 bellard
        }
663 e7f0ad58 bellard
    } else {
664 e7f0ad58 bellard
        ydelta = -ydelta;
665 e7f0ad58 bellard
        i = s->backscroll_height;
666 e7f0ad58 bellard
        if (i > s->total_height - s->height)
667 e7f0ad58 bellard
            i = s->total_height - s->height;
668 e7f0ad58 bellard
        y1 = s->y_base - i;
669 e7f0ad58 bellard
        if (y1 < 0)
670 e7f0ad58 bellard
            y1 += s->total_height;
671 e7f0ad58 bellard
        for(i = 0; i < ydelta; i++) {
672 e7f0ad58 bellard
            if (s->y_displayed == y1)
673 e7f0ad58 bellard
                break;
674 e7f0ad58 bellard
            if (--s->y_displayed < 0)
675 e7f0ad58 bellard
                s->y_displayed = s->total_height - 1;
676 e7f0ad58 bellard
        }
677 e7f0ad58 bellard
    }
678 e7f0ad58 bellard
    console_refresh(s);
679 e7f0ad58 bellard
}
680 e7f0ad58 bellard
681 e7f0ad58 bellard
static void console_put_lf(TextConsole *s)
682 e7f0ad58 bellard
{
683 e7f0ad58 bellard
    TextCell *c;
684 e7f0ad58 bellard
    int x, y1;
685 e7f0ad58 bellard
686 e7f0ad58 bellard
    s->y++;
687 e7f0ad58 bellard
    if (s->y >= s->height) {
688 e7f0ad58 bellard
        s->y = s->height - 1;
689 6d6f7c28 pbrook
690 e7f0ad58 bellard
        if (s->y_displayed == s->y_base) {
691 e7f0ad58 bellard
            if (++s->y_displayed == s->total_height)
692 e7f0ad58 bellard
                s->y_displayed = 0;
693 e7f0ad58 bellard
        }
694 e7f0ad58 bellard
        if (++s->y_base == s->total_height)
695 e7f0ad58 bellard
            s->y_base = 0;
696 e7f0ad58 bellard
        if (s->backscroll_height < s->total_height)
697 e7f0ad58 bellard
            s->backscroll_height++;
698 e7f0ad58 bellard
        y1 = (s->y_base + s->height - 1) % s->total_height;
699 e7f0ad58 bellard
        c = &s->cells[y1 * s->width];
700 e7f0ad58 bellard
        for(x = 0; x < s->width; x++) {
701 e7f0ad58 bellard
            c->ch = ' ';
702 6d6f7c28 pbrook
            c->t_attrib = s->t_attrib_default;
703 e7f0ad58 bellard
            c++;
704 e7f0ad58 bellard
        }
705 e7f0ad58 bellard
        if (s == active_console && s->y_displayed == s->y_base) {
706 0e1f5a0c aliguori
            if (!ds_get_bits_per_pixel(s->ds)) {
707 4d3b6f6e balrog
                s->text_x[0] = 0;
708 4d3b6f6e balrog
                s->text_y[0] = 0;
709 4d3b6f6e balrog
                s->text_x[1] = s->width - 1;
710 4d3b6f6e balrog
                s->text_y[1] = s->height - 1;
711 4d3b6f6e balrog
                return;
712 4d3b6f6e balrog
            }
713 4d3b6f6e balrog
714 5fafdf24 ths
            vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0,
715 5fafdf24 ths
                       s->width * FONT_WIDTH,
716 e7f0ad58 bellard
                       (s->height - 1) * FONT_HEIGHT);
717 e7f0ad58 bellard
            vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT,
718 5fafdf24 ths
                          s->width * FONT_WIDTH, FONT_HEIGHT,
719 6d6f7c28 pbrook
                          color_table[0][s->t_attrib_default.bgcol]);
720 14778c20 pbrook
            s->update_x0 = 0;
721 14778c20 pbrook
            s->update_y0 = 0;
722 14778c20 pbrook
            s->update_x1 = s->width * FONT_WIDTH;
723 14778c20 pbrook
            s->update_y1 = s->height * FONT_HEIGHT;
724 e7f0ad58 bellard
        }
725 e7f0ad58 bellard
    }
726 e7f0ad58 bellard
}
727 e7f0ad58 bellard
728 6d6f7c28 pbrook
/* Set console attributes depending on the current escape codes.
729 6d6f7c28 pbrook
 * NOTE: I know this code is not very efficient (checking every color for it
730 6d6f7c28 pbrook
 * self) but it is more readable and better maintainable.
731 6d6f7c28 pbrook
 */
732 6d6f7c28 pbrook
static void console_handle_escape(TextConsole *s)
733 6d6f7c28 pbrook
{
734 6d6f7c28 pbrook
    int i;
735 6d6f7c28 pbrook
736 6d6f7c28 pbrook
    for (i=0; i<s->nb_esc_params; i++) {
737 6d6f7c28 pbrook
        switch (s->esc_params[i]) {
738 6d6f7c28 pbrook
            case 0: /* reset all console attributes to default */
739 6d6f7c28 pbrook
                s->t_attrib = s->t_attrib_default;
740 6d6f7c28 pbrook
                break;
741 6d6f7c28 pbrook
            case 1:
742 6d6f7c28 pbrook
                s->t_attrib.bold = 1;
743 6d6f7c28 pbrook
                break;
744 6d6f7c28 pbrook
            case 4:
745 6d6f7c28 pbrook
                s->t_attrib.uline = 1;
746 6d6f7c28 pbrook
                break;
747 6d6f7c28 pbrook
            case 5:
748 6d6f7c28 pbrook
                s->t_attrib.blink = 1;
749 6d6f7c28 pbrook
                break;
750 6d6f7c28 pbrook
            case 7:
751 6d6f7c28 pbrook
                s->t_attrib.invers = 1;
752 6d6f7c28 pbrook
                break;
753 6d6f7c28 pbrook
            case 8:
754 6d6f7c28 pbrook
                s->t_attrib.unvisible = 1;
755 6d6f7c28 pbrook
                break;
756 6d6f7c28 pbrook
            case 22:
757 6d6f7c28 pbrook
                s->t_attrib.bold = 0;
758 6d6f7c28 pbrook
                break;
759 6d6f7c28 pbrook
            case 24:
760 6d6f7c28 pbrook
                s->t_attrib.uline = 0;
761 6d6f7c28 pbrook
                break;
762 6d6f7c28 pbrook
            case 25:
763 6d6f7c28 pbrook
                s->t_attrib.blink = 0;
764 6d6f7c28 pbrook
                break;
765 6d6f7c28 pbrook
            case 27:
766 6d6f7c28 pbrook
                s->t_attrib.invers = 0;
767 6d6f7c28 pbrook
                break;
768 6d6f7c28 pbrook
            case 28:
769 6d6f7c28 pbrook
                s->t_attrib.unvisible = 0;
770 6d6f7c28 pbrook
                break;
771 6d6f7c28 pbrook
            /* set foreground color */
772 6d6f7c28 pbrook
            case 30:
773 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_BLACK;
774 6d6f7c28 pbrook
                break;
775 6d6f7c28 pbrook
            case 31:
776 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_RED;
777 6d6f7c28 pbrook
                break;
778 6d6f7c28 pbrook
            case 32:
779 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_GREEN;
780 6d6f7c28 pbrook
                break;
781 6d6f7c28 pbrook
            case 33:
782 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_YELLOW;
783 6d6f7c28 pbrook
                break;
784 6d6f7c28 pbrook
            case 34:
785 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_BLUE;
786 6d6f7c28 pbrook
                break;
787 6d6f7c28 pbrook
            case 35:
788 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_MAGENTA;
789 6d6f7c28 pbrook
                break;
790 6d6f7c28 pbrook
            case 36:
791 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_CYAN;
792 6d6f7c28 pbrook
                break;
793 6d6f7c28 pbrook
            case 37:
794 6d6f7c28 pbrook
                s->t_attrib.fgcol=COLOR_WHITE;
795 6d6f7c28 pbrook
                break;
796 6d6f7c28 pbrook
            /* set background color */
797 6d6f7c28 pbrook
            case 40:
798 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_BLACK;
799 6d6f7c28 pbrook
                break;
800 6d6f7c28 pbrook
            case 41:
801 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_RED;
802 6d6f7c28 pbrook
                break;
803 6d6f7c28 pbrook
            case 42:
804 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_GREEN;
805 6d6f7c28 pbrook
                break;
806 6d6f7c28 pbrook
            case 43:
807 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_YELLOW;
808 6d6f7c28 pbrook
                break;
809 6d6f7c28 pbrook
            case 44:
810 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_BLUE;
811 6d6f7c28 pbrook
                break;
812 6d6f7c28 pbrook
            case 45:
813 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_MAGENTA;
814 6d6f7c28 pbrook
                break;
815 6d6f7c28 pbrook
            case 46:
816 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_CYAN;
817 6d6f7c28 pbrook
                break;
818 6d6f7c28 pbrook
            case 47:
819 6d6f7c28 pbrook
                s->t_attrib.bgcol=COLOR_WHITE;
820 6d6f7c28 pbrook
                break;
821 6d6f7c28 pbrook
        }
822 6d6f7c28 pbrook
    }
823 6d6f7c28 pbrook
}
824 6d6f7c28 pbrook
825 adb47967 ths
static void console_clear_xy(TextConsole *s, int x, int y)
826 adb47967 ths
{
827 adb47967 ths
    int y1 = (s->y_base + y) % s->total_height;
828 adb47967 ths
    TextCell *c = &s->cells[y1 * s->width + x];
829 adb47967 ths
    c->ch = ' ';
830 adb47967 ths
    c->t_attrib = s->t_attrib_default;
831 adb47967 ths
    c++;
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 3023f332 aliguori
DisplayState *graphic_console_init(vga_hw_update_ptr update,
1269 3023f332 aliguori
                                   vga_hw_invalidate_ptr invalidate,
1270 3023f332 aliguori
                                   vga_hw_screen_dump_ptr screen_dump,
1271 3023f332 aliguori
                                   vga_hw_text_update_ptr text_update,
1272 3023f332 aliguori
                                   void *opaque)
1273 95219897 pbrook
{
1274 95219897 pbrook
    TextConsole *s;
1275 3023f332 aliguori
    DisplayState *ds;
1276 f0f2f976 aurel32
1277 3023f332 aliguori
    ds = (DisplayState *) qemu_mallocz(sizeof(DisplayState));
1278 7b5d76da aliguori
    ds->allocator = &default_allocator; 
1279 7b5d76da aliguori
    ds->surface = qemu_create_displaysurface(ds, 640, 480);
1280 95219897 pbrook
1281 af3a9031 ths
    s = new_console(ds, GRAPHIC_CONSOLE);
1282 3023f332 aliguori
    if (s == NULL) {
1283 7b5d76da aliguori
        qemu_free_displaysurface(ds);
1284 3023f332 aliguori
        qemu_free(ds);
1285 3023f332 aliguori
        return NULL;
1286 3023f332 aliguori
    }
1287 95219897 pbrook
    s->hw_update = update;
1288 95219897 pbrook
    s->hw_invalidate = invalidate;
1289 95219897 pbrook
    s->hw_screen_dump = screen_dump;
1290 4d3b6f6e balrog
    s->hw_text_update = text_update;
1291 95219897 pbrook
    s->hw = opaque;
1292 3023f332 aliguori
1293 f0f2f976 aurel32
    register_displaystate(ds);
1294 3023f332 aliguori
    return ds;
1295 e7f0ad58 bellard
}
1296 e7f0ad58 bellard
1297 95219897 pbrook
int is_graphic_console(void)
1298 e7f0ad58 bellard
{
1299 4d3b6f6e balrog
    return active_console && active_console->console_type == GRAPHIC_CONSOLE;
1300 e7f0ad58 bellard
}
1301 e7f0ad58 bellard
1302 c21bbcfa balrog
int is_fixedsize_console(void)
1303 c21bbcfa balrog
{
1304 c21bbcfa balrog
    return active_console && active_console->console_type != TEXT_CONSOLE;
1305 c21bbcfa balrog
}
1306 c21bbcfa balrog
1307 a528b80c balrog
void console_color_init(DisplayState *ds)
1308 a528b80c balrog
{
1309 a528b80c balrog
    int i, j;
1310 a528b80c balrog
    for (j = 0; j < 2; j++) {
1311 a528b80c balrog
        for (i = 0; i < 8; i++) {
1312 f0f2f976 aurel32
            color_table[j][i] = col_expand(ds,
1313 a528b80c balrog
                   vga_get_color(ds, color_table_rgb[j][i]));
1314 a528b80c balrog
        }
1315 a528b80c balrog
    }
1316 a528b80c balrog
}
1317 a528b80c balrog
1318 2796dae0 aliguori
static int n_text_consoles;
1319 2796dae0 aliguori
static CharDriverState *text_consoles[128];
1320 6ea314d9 Gerd Hoffmann
static QemuOpts *text_console_opts[128];
1321 2796dae0 aliguori
1322 6ea314d9 Gerd Hoffmann
static void text_console_do_init(CharDriverState *chr, DisplayState *ds, QemuOpts *opts)
1323 e7f0ad58 bellard
{
1324 e7f0ad58 bellard
    TextConsole *s;
1325 af3a9031 ths
    unsigned width;
1326 af3a9031 ths
    unsigned height;
1327 e7f0ad58 bellard
    static int color_inited;
1328 6d6f7c28 pbrook
1329 6ea314d9 Gerd Hoffmann
    width = qemu_opt_get_number(opts, "width", 0);
1330 6ea314d9 Gerd Hoffmann
    if (width == 0)
1331 6ea314d9 Gerd Hoffmann
        width = qemu_opt_get_number(opts, "cols", 0) * FONT_WIDTH;
1332 6ea314d9 Gerd Hoffmann
1333 6ea314d9 Gerd Hoffmann
    height = qemu_opt_get_number(opts, "height", 0);
1334 6ea314d9 Gerd Hoffmann
    if (height == 0)
1335 6ea314d9 Gerd Hoffmann
        height = qemu_opt_get_number(opts, "rows", 0) * FONT_HEIGHT;
1336 6ea314d9 Gerd Hoffmann
1337 6ea314d9 Gerd Hoffmann
    if (width == 0 || height == 0) {
1338 6ea314d9 Gerd Hoffmann
        s = new_console(ds, TEXT_CONSOLE);
1339 6ea314d9 Gerd Hoffmann
        width = ds_get_width(s->ds);
1340 6ea314d9 Gerd Hoffmann
        height = ds_get_height(s->ds);
1341 6ea314d9 Gerd Hoffmann
    } else {
1342 6ea314d9 Gerd Hoffmann
        s = new_console(ds, TEXT_CONSOLE_FIXED_SIZE);
1343 6ea314d9 Gerd Hoffmann
    }
1344 6ea314d9 Gerd Hoffmann
1345 e7f0ad58 bellard
    if (!s) {
1346 e7f0ad58 bellard
        free(chr);
1347 fdb868e4 aliguori
        return;
1348 e7f0ad58 bellard
    }
1349 e7f0ad58 bellard
    chr->opaque = s;
1350 e7f0ad58 bellard
    chr->chr_write = console_puts;
1351 6fcfafb7 bellard
    chr->chr_send_event = console_send_event;
1352 6fcfafb7 bellard
1353 e5b0bc44 pbrook
    s->chr = chr;
1354 e15d7371 bellard
    s->out_fifo.buf = s->out_fifo_buf;
1355 e15d7371 bellard
    s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
1356 e15d7371 bellard
    s->kbd_timer = qemu_new_timer(rt_clock, kbd_send_chars, s);
1357 3023f332 aliguori
    s->ds = ds;
1358 3b46e624 ths
1359 e7f0ad58 bellard
    if (!color_inited) {
1360 e7f0ad58 bellard
        color_inited = 1;
1361 a528b80c balrog
        console_color_init(s->ds);
1362 e7f0ad58 bellard
    }
1363 e7f0ad58 bellard
    s->y_displayed = 0;
1364 e7f0ad58 bellard
    s->y_base = 0;
1365 e7f0ad58 bellard
    s->total_height = DEFAULT_BACKSCROLL;
1366 e7f0ad58 bellard
    s->x = 0;
1367 e7f0ad58 bellard
    s->y = 0;
1368 af3a9031 ths
    s->g_width = width;
1369 af3a9031 ths
    s->g_height = height;
1370 6d6f7c28 pbrook
1371 4d3b6f6e balrog
    s->hw_invalidate = text_console_invalidate;
1372 4d3b6f6e balrog
    s->hw_text_update = text_console_update;
1373 4d3b6f6e balrog
    s->hw = s;
1374 4d3b6f6e balrog
1375 6d6f7c28 pbrook
    /* Set text attribute defaults */
1376 6d6f7c28 pbrook
    s->t_attrib_default.bold = 0;
1377 6d6f7c28 pbrook
    s->t_attrib_default.uline = 0;
1378 6d6f7c28 pbrook
    s->t_attrib_default.blink = 0;
1379 6d6f7c28 pbrook
    s->t_attrib_default.invers = 0;
1380 6d6f7c28 pbrook
    s->t_attrib_default.unvisible = 0;
1381 6d6f7c28 pbrook
    s->t_attrib_default.fgcol = COLOR_WHITE;
1382 6d6f7c28 pbrook
    s->t_attrib_default.bgcol = COLOR_BLACK;
1383 6d6f7c28 pbrook
    /* set current text attributes to default */
1384 6d6f7c28 pbrook
    s->t_attrib = s->t_attrib_default;
1385 e7f0ad58 bellard
    text_console_resize(s);
1386 e7f0ad58 bellard
1387 127338e6 Amit Shah
    qemu_chr_generic_open(chr);
1388 ceecf1d1 aurel32
    if (chr->init)
1389 ceecf1d1 aurel32
        chr->init(chr);
1390 e7f0ad58 bellard
}
1391 c60e08d9 pbrook
1392 6ea314d9 Gerd Hoffmann
CharDriverState *text_console_init(QemuOpts *opts)
1393 2796dae0 aliguori
{
1394 2796dae0 aliguori
    CharDriverState *chr;
1395 2796dae0 aliguori
1396 2796dae0 aliguori
    chr = qemu_mallocz(sizeof(CharDriverState));
1397 2796dae0 aliguori
1398 2796dae0 aliguori
    if (n_text_consoles == 128) {
1399 2796dae0 aliguori
        fprintf(stderr, "Too many text consoles\n");
1400 2796dae0 aliguori
        exit(1);
1401 2796dae0 aliguori
    }
1402 2796dae0 aliguori
    text_consoles[n_text_consoles] = chr;
1403 6ea314d9 Gerd Hoffmann
    text_console_opts[n_text_consoles] = opts;
1404 2796dae0 aliguori
    n_text_consoles++;
1405 2796dae0 aliguori
1406 2796dae0 aliguori
    return chr;
1407 2796dae0 aliguori
}
1408 2796dae0 aliguori
1409 2796dae0 aliguori
void text_consoles_set_display(DisplayState *ds)
1410 2796dae0 aliguori
{
1411 2796dae0 aliguori
    int i;
1412 2796dae0 aliguori
1413 2796dae0 aliguori
    for (i = 0; i < n_text_consoles; i++) {
1414 6ea314d9 Gerd Hoffmann
        text_console_do_init(text_consoles[i], ds, text_console_opts[i]);
1415 6ea314d9 Gerd Hoffmann
        qemu_opts_del(text_console_opts[i]);
1416 6ea314d9 Gerd Hoffmann
        text_console_opts[i] = NULL;
1417 2796dae0 aliguori
    }
1418 2796dae0 aliguori
1419 2796dae0 aliguori
    n_text_consoles = 0;
1420 2796dae0 aliguori
}
1421 2796dae0 aliguori
1422 3023f332 aliguori
void qemu_console_resize(DisplayState *ds, int width, int height)
1423 c60e08d9 pbrook
{
1424 42aa98e8 aliguori
    TextConsole *s = get_graphic_console(ds);
1425 f497f140 aliguori
    if (!s) return;
1426 f497f140 aliguori
1427 3023f332 aliguori
    s->g_width = width;
1428 3023f332 aliguori
    s->g_height = height;
1429 3023f332 aliguori
    if (is_graphic_console()) {
1430 7b5d76da aliguori
        ds->surface = qemu_resize_displaysurface(ds, width, height);
1431 3023f332 aliguori
        dpy_resize(ds);
1432 c60e08d9 pbrook
    }
1433 c60e08d9 pbrook
}
1434 38334f76 balrog
1435 3023f332 aliguori
void qemu_console_copy(DisplayState *ds, int src_x, int src_y,
1436 3023f332 aliguori
                       int dst_x, int dst_y, int w, int h)
1437 c21bbcfa balrog
{
1438 3023f332 aliguori
    if (is_graphic_console()) {
1439 3023f332 aliguori
        dpy_copy(ds, src_x, src_y, dst_x, dst_y, w, h);
1440 38334f76 balrog
    }
1441 38334f76 balrog
}
1442 7d957bd8 aliguori
1443 0da2ea1b malc
PixelFormat qemu_different_endianness_pixelformat(int bpp)
1444 7d957bd8 aliguori
{
1445 7d957bd8 aliguori
    PixelFormat pf;
1446 7d957bd8 aliguori
1447 7d957bd8 aliguori
    memset(&pf, 0x00, sizeof(PixelFormat));
1448 7d957bd8 aliguori
1449 7d957bd8 aliguori
    pf.bits_per_pixel = bpp;
1450 7d957bd8 aliguori
    pf.bytes_per_pixel = bpp / 8;
1451 7d957bd8 aliguori
    pf.depth = bpp == 32 ? 24 : bpp;
1452 7d957bd8 aliguori
1453 7d957bd8 aliguori
    switch (bpp) {
1454 0da2ea1b malc
        case 24:
1455 0da2ea1b malc
            pf.rmask = 0x000000FF;
1456 0da2ea1b malc
            pf.gmask = 0x0000FF00;
1457 0da2ea1b malc
            pf.bmask = 0x00FF0000;
1458 0da2ea1b malc
            pf.rmax = 255;
1459 0da2ea1b malc
            pf.gmax = 255;
1460 0da2ea1b malc
            pf.bmax = 255;
1461 0da2ea1b malc
            pf.rshift = 0;
1462 0da2ea1b malc
            pf.gshift = 8;
1463 0da2ea1b malc
            pf.bshift = 16;
1464 90a1e3c0 aliguori
            pf.rbits = 8;
1465 90a1e3c0 aliguori
            pf.gbits = 8;
1466 90a1e3c0 aliguori
            pf.bbits = 8;
1467 7d957bd8 aliguori
            break;
1468 0da2ea1b malc
        case 32:
1469 0da2ea1b malc
            pf.rmask = 0x0000FF00;
1470 0da2ea1b malc
            pf.gmask = 0x00FF0000;
1471 0da2ea1b malc
            pf.bmask = 0xFF000000;
1472 0da2ea1b malc
            pf.amask = 0x00000000;
1473 0da2ea1b malc
            pf.amax = 255;
1474 0da2ea1b malc
            pf.rmax = 255;
1475 0da2ea1b malc
            pf.gmax = 255;
1476 0da2ea1b malc
            pf.bmax = 255;
1477 0da2ea1b malc
            pf.ashift = 0;
1478 0da2ea1b malc
            pf.rshift = 8;
1479 0da2ea1b malc
            pf.gshift = 16;
1480 0da2ea1b malc
            pf.bshift = 24;
1481 90a1e3c0 aliguori
            pf.rbits = 8;
1482 90a1e3c0 aliguori
            pf.gbits = 8;
1483 90a1e3c0 aliguori
            pf.bbits = 8;
1484 90a1e3c0 aliguori
            pf.abits = 8;
1485 0da2ea1b malc
            break;
1486 0da2ea1b malc
        default:
1487 0da2ea1b malc
            break;
1488 0da2ea1b malc
    }
1489 0da2ea1b malc
    return pf;
1490 0da2ea1b malc
}
1491 0da2ea1b malc
1492 0da2ea1b malc
PixelFormat qemu_default_pixelformat(int bpp)
1493 0da2ea1b malc
{
1494 0da2ea1b malc
    PixelFormat pf;
1495 0da2ea1b malc
1496 0da2ea1b malc
    memset(&pf, 0x00, sizeof(PixelFormat));
1497 0da2ea1b malc
1498 0da2ea1b malc
    pf.bits_per_pixel = bpp;
1499 0da2ea1b malc
    pf.bytes_per_pixel = bpp / 8;
1500 0da2ea1b malc
    pf.depth = bpp == 32 ? 24 : bpp;
1501 0da2ea1b malc
1502 0da2ea1b malc
    switch (bpp) {
1503 7d957bd8 aliguori
        case 16:
1504 7d957bd8 aliguori
            pf.rmask = 0x0000F800;
1505 7d957bd8 aliguori
            pf.gmask = 0x000007E0;
1506 7d957bd8 aliguori
            pf.bmask = 0x0000001F;
1507 7d957bd8 aliguori
            pf.rmax = 31;
1508 7d957bd8 aliguori
            pf.gmax = 63;
1509 7d957bd8 aliguori
            pf.bmax = 31;
1510 7d957bd8 aliguori
            pf.rshift = 11;
1511 7d957bd8 aliguori
            pf.gshift = 5;
1512 7d957bd8 aliguori
            pf.bshift = 0;
1513 90a1e3c0 aliguori
            pf.rbits = 5;
1514 90a1e3c0 aliguori
            pf.gbits = 6;
1515 90a1e3c0 aliguori
            pf.bbits = 5;
1516 7d957bd8 aliguori
            break;
1517 7d957bd8 aliguori
        case 24:
1518 0da2ea1b malc
            pf.rmask = 0x00FF0000;
1519 0da2ea1b malc
            pf.gmask = 0x0000FF00;
1520 0da2ea1b malc
            pf.bmask = 0x000000FF;
1521 0da2ea1b malc
            pf.rmax = 255;
1522 0da2ea1b malc
            pf.gmax = 255;
1523 0da2ea1b malc
            pf.bmax = 255;
1524 0da2ea1b malc
            pf.rshift = 16;
1525 0da2ea1b malc
            pf.gshift = 8;
1526 0da2ea1b malc
            pf.bshift = 0;
1527 90a1e3c0 aliguori
            pf.rbits = 8;
1528 90a1e3c0 aliguori
            pf.gbits = 8;
1529 90a1e3c0 aliguori
            pf.bbits = 8;
1530 7d957bd8 aliguori
        case 32:
1531 7d957bd8 aliguori
            pf.rmask = 0x00FF0000;
1532 7d957bd8 aliguori
            pf.gmask = 0x0000FF00;
1533 7d957bd8 aliguori
            pf.bmask = 0x000000FF;
1534 0da2ea1b malc
            pf.amax = 255;
1535 7d957bd8 aliguori
            pf.rmax = 255;
1536 7d957bd8 aliguori
            pf.gmax = 255;
1537 7d957bd8 aliguori
            pf.bmax = 255;
1538 0da2ea1b malc
            pf.ashift = 24;
1539 7d957bd8 aliguori
            pf.rshift = 16;
1540 7d957bd8 aliguori
            pf.gshift = 8;
1541 7d957bd8 aliguori
            pf.bshift = 0;
1542 90a1e3c0 aliguori
            pf.rbits = 8;
1543 90a1e3c0 aliguori
            pf.gbits = 8;
1544 90a1e3c0 aliguori
            pf.bbits = 8;
1545 90a1e3c0 aliguori
            pf.abits = 8;
1546 7d957bd8 aliguori
            break;
1547 7d957bd8 aliguori
        default:
1548 7d957bd8 aliguori
            break;
1549 7d957bd8 aliguori
    }
1550 7d957bd8 aliguori
    return pf;
1551 7d957bd8 aliguori
}
1552 7d957bd8 aliguori
1553 7b5d76da aliguori
DisplaySurface* defaultallocator_create_displaysurface(int width, int height)
1554 7d957bd8 aliguori
{
1555 7d957bd8 aliguori
    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
1556 7d957bd8 aliguori
1557 7d957bd8 aliguori
    surface->width = width;
1558 7d957bd8 aliguori
    surface->height = height;
1559 7b5d76da aliguori
    surface->linesize = width * 4;
1560 7b5d76da aliguori
    surface->pf = qemu_default_pixelformat(32);
1561 e2542fe2 Juan Quintela
#ifdef HOST_WORDS_BIGENDIAN
1562 7d957bd8 aliguori
    surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
1563 7d957bd8 aliguori
#else
1564 7d957bd8 aliguori
    surface->flags = QEMU_ALLOCATED_FLAG;
1565 7d957bd8 aliguori
#endif
1566 7d957bd8 aliguori
    surface->data = (uint8_t*) qemu_mallocz(surface->linesize * surface->height);
1567 7d957bd8 aliguori
1568 7d957bd8 aliguori
    return surface;
1569 7d957bd8 aliguori
}
1570 7d957bd8 aliguori
1571 7b5d76da aliguori
DisplaySurface* defaultallocator_resize_displaysurface(DisplaySurface *surface,
1572 7b5d76da aliguori
                                          int width, int height)
1573 7d957bd8 aliguori
{
1574 7d957bd8 aliguori
    surface->width = width;
1575 7d957bd8 aliguori
    surface->height = height;
1576 7b5d76da aliguori
    surface->linesize = width * 4;
1577 7b5d76da aliguori
    surface->pf = qemu_default_pixelformat(32);
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 e2542fe2 Juan Quintela
#ifdef HOST_WORDS_BIGENDIAN
1583 7d957bd8 aliguori
    surface->flags = QEMU_ALLOCATED_FLAG | QEMU_BIG_ENDIAN_FLAG;
1584 7d957bd8 aliguori
#else
1585 7d957bd8 aliguori
    surface->flags = QEMU_ALLOCATED_FLAG;
1586 7d957bd8 aliguori
#endif
1587 7d957bd8 aliguori
1588 7d957bd8 aliguori
    return surface;
1589 7d957bd8 aliguori
}
1590 7d957bd8 aliguori
1591 7d957bd8 aliguori
DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
1592 7d957bd8 aliguori
                                              int linesize, uint8_t *data)
1593 7d957bd8 aliguori
{
1594 7d957bd8 aliguori
    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
1595 7d957bd8 aliguori
1596 7d957bd8 aliguori
    surface->width = width;
1597 7d957bd8 aliguori
    surface->height = height;
1598 7d957bd8 aliguori
    surface->linesize = linesize;
1599 7d957bd8 aliguori
    surface->pf = qemu_default_pixelformat(bpp);
1600 e2542fe2 Juan Quintela
#ifdef HOST_WORDS_BIGENDIAN
1601 7d957bd8 aliguori
    surface->flags = QEMU_BIG_ENDIAN_FLAG;
1602 7d957bd8 aliguori
#endif
1603 7d957bd8 aliguori
    surface->data = data;
1604 7d957bd8 aliguori
1605 7d957bd8 aliguori
    return surface;
1606 7d957bd8 aliguori
}
1607 7d957bd8 aliguori
1608 7b5d76da aliguori
void defaultallocator_free_displaysurface(DisplaySurface *surface)
1609 7d957bd8 aliguori
{
1610 7d957bd8 aliguori
    if (surface == NULL)
1611 7d957bd8 aliguori
        return;
1612 7d957bd8 aliguori
    if (surface->flags & QEMU_ALLOCATED_FLAG)
1613 7d957bd8 aliguori
        qemu_free(surface->data);
1614 7d957bd8 aliguori
    qemu_free(surface);
1615 7d957bd8 aliguori
}